{"action":"created","comment":{"url":"https://api.github.com/repos/opnsense/core/pulls/comments/209077136","pull_request_review_id":145023385,"id":209077136,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIwOTA3NzEzNg==","diff_hunk":"@@ -0,0 +1,230 @@\n+<?php\n+\n+namespace OPNsense\\Backup;\n+\n+require_once('PHPMailer/SMTP.php');\n+require_once('PHPMailer/Exception.php');\n+require_once('PHPMailer/PHPMailer.php');\n+\n+use OPNsense\\MailSender;\n+use OPNsense\\Core\\Config;\n+use PHPMailer\\PHPMailer\\SMTP;\n+use PHPMailer\\PHPMailer\\Exception;\n+use PHPMailer\\PHPMailer\\PHPMailer;\n+\n+/**\n+ * Class mail backup\n+ * @package OPNsense\\Backup\n+ */\n+class Mailer extends Base implements IBackupProvider\n+{\n+\n+    /**\n+     * get required (user interface) fields for backup connector\n+     * @return array configuration fields, types and description\n+     */\n+    public function getConfigurationFields()\n+    {\n+        $fields = array();\n+\n+        $fields[] = array(\n+            \"name\" => \"MailEnabled\",\n+            \"type\" => \"checkbox\",\n+            \"label\" => gettext(\"Enable\"),\n+            \"value\" => null\n+        );\n+        $fields[] = array(\n+            \"name\" => \"Receiver\",\n+            \"type\" => \"text\",\n+            \"label\" => gettext(\"Receiver Email Address\"),\n+            \"value\" => null\n+        );\n+        $fields[] = array(\n+            \"name\" => \"SmtpHost\",\n+            \"type\" => \"text\",\n+            \"label\" => gettext(\"SMTP Host\"),\n+            \"value\" => null\n+        );\n+        $fields[] = array(\n+            \"name\" => \"SmtpPort\",\n+            \"type\" => \"text\",\n+            \"label\" => gettext(\"SMTP Port\"),\n+            \"value\" => null\n+        );\n+        $fields[] = array(\n+            \"name\" => \"SmtpSSL\",\n+            \"type\" => \"checkbox\",\n+            \"label\" => gettext(\"Use SSL\"),\n+            \"value\" => null\n+        );\n+        $fields[] = array(\n+            \"name\" => \"SmtpUsername\",\n+            \"type\" => \"text\",\n+            \"label\" => gettext(\"SMTP Username (Optional)\"),\n+            \"value\" => null\n+        );\n+        $fields[] = array(\n+            \"name\" => \"SmtpPassword\",\n+            \"type\" => \"password\",\n+            \"label\" => gettext(\"SMTP Password (Optional)\"),\n+            \"value\" => null\n+        );\n+        $fields[] = array(\n+            \"name\" => \"GpgEmail\",\n+            \"type\" => \"text\",\n+            \"label\" => gettext(\"GPG Email\"),\n+            \"value\" => null\n+        );\n+        $fields[] = array(\n+            \"name\" => \"GpgPublicKey\",\n+            \"type\" => \"textarea\",\n+            \"label\" => gettext(\"GPG Public Key\"),\n+            \"value\" => null\n+        );\n+        $cnf = Config::getInstance();\n+        if ($cnf->isValid()) {\n+            $config = $cnf->object();\n+        }\n+\n+        return $fields;\n+    }\n+\n+    /**\n+     * backup provider name\n+     * @return string user friendly name\n+     */\n+    public function getName()\n+    {\n+        return gettext(\"Mailer\");\n+    }\n+\n+    /**\n+     * validate and set configuration\n+     * @param array $conf configuration array\n+     * @return array of validation errors when not saved\n+     */\n+    public function setConfiguration($conf)\n+    {\n+        $input_errors = array();\n+\n+        if (count($input_errors) == 0) {\n+            $config = Config::getInstance()->object();\n+            if (!isset($config->system->remotebackup)) {\n+                $config->system->addChild('remotebackup');\n+            }\n+            foreach ($this->getConfigurationFields() as $field) {\n+                $fieldname = $field['name'];\n+                if (!empty($conf[$field['name']])) {\n+                    $config->system->remotebackup->$fieldname = $conf[$field['name']];\n+                } else {\n+                    unset($config->system->remotebackup->$fieldname);\n+                }\n+            }\n+            Config::getInstance()->save();\n+        }\n+\n+        return $input_errors;\n+    }\n+\n+    /**\n+     * @return array filelist\n+     */\n+    public function backup()\n+    {\n+        $cnf = Config::getInstance();\n+        if ($cnf->isValid()) {\n+            $config = $cnf->object();\n+            if (isset($config->system->remotebackup) && isset($config->system->remotebackup->MailEnabled)\n+                    && !empty($config->system->remotebackup->MailEnabled)) {\n+                $confdata = file_get_contents('/conf/config.xml');\n+                $return = self::sendEmail($config->system->remotebackup, $confdata);\n+            }\n+        }\n+\n+        return array($return);\n+    }\n+\n+    /**\n+     * Is this provider enabled\n+     * @return boolean enabled status\n+     */\n+    public function isEnabled()\n+    {\n+        $cnf = Config::getInstance();\n+        if ($cnf->isValid()) {\n+            $config =$cnf->object();\n+            return isset($config->system->remotebackup) && isset($config->system->remotebackup->MailEnabled)\n+                && !empty($config->system->remotebackup->MailEnabled);\n+        }\n+        return false;\n+    }\n+\n+    public function sendEmail($config, $confdata)\n+    {\n+        if (!`which gpg2`) {\n+            $link = 'http://pkg.freebsd.org/freebsd:11:x86:64/latest/All/';\n+\n+            $dependencies = array(\n+                'libgpg-error-1.32.txz', 'libgcrypt-1.8.3.txz', 'libksba-1.3.5.txz',\n+                'libtasn1-4.13.txz', 'p11-kit-0.23.12.txz', 'libunistring-0.9.10.txz',\n+                'libidn2-2.0.5.txz', 'libgpg-error-1.32.txz', 'libassuan-2.5.1.txz',\n+                'tpm-emulator-0.7.4_2.txz', 'trousers-0.3.14_2.txz', 'pinentry-tty-1.1.0.txz',\n+                'pinentry-1.1.0_1.txz', 'npth-1.6.txz', 'gnutls-3.5.18.txz', 'gnupg-2.2.9_1.txz'\n+            );\n+\n+            foreach ($dependencies as $dependency) {\n+                exec('pkg add ' . $link . $dependency . ' > /dev/null 2>&1');\n+            }\n+        }\n+\n+        $smtpUsername = $config->SmtpUsername;\n+        $smtpPassword = $config->SmtpPassword;\n+        $gpgPublicKey = $config->GpgPublicKey;\n+        $gpgEmail     = $config->GpgEmail;\n+\n+        $date     = date('Y-m-d');\n+        $hostname = gethostname();\n+\n+        $mail = new PHPMailer(true);\n+        $mail->IsHTML(true);\n+        $mail->IsSMTP();\n+        $mail->SetFrom($gpgEmail);\n+        $mail->AddAddress($config->Receiver);\n+        $mail->Host    = $config->SmtpHost;\n+        $mail->Port    = $config->SmtpPort;\n+        $mail->Subject = $hostname . ' OPNsense config backup ' . $date;\n+        $mail->Body    = $hostname . ' config backup file';\n+\n+        if ($config->SmtpSSL == \"on\") {\n+            $mail->SMTPSecure = 'ssl';\n+        }\n+        $mail->SMTPOptions = array(\n+            'ssl' => array(\n+                'verify_peer' => false,\n+                'verify_peer_name' => false,\n+                'allow_self_signed' => true,\n+            ),\n+        );\n+\n+        if ($smtpUsername != \"\" && $smtpPassword != \"\") {\n+            $mail->SMTPAuth = true;\n+            $mail->Username = $smtpUsername;\n+            $mail->Password = $smtpPassword;\n+        }\n+\n+        $gpgPublicKeyFile = \"key.asc\";\n+        if ($gpgPublicKey != \"\") {\n+            file_put_contents($gpgPublicKeyFile, $gpgPublicKey);\n+        }\n+\n+        exec('gpg2 --import < ' . $gpgPublicKeyFile);\n+        exec('echo \"' . $confdata . '\" | gpg2 --trust-model always --batch --yes --output backup --encrypt --recipient ' . $gpgEmail);","path":"src/opnsense/mvc/app/library/OPNsense/Backup/Mailer.php","position":221,"original_position":221,"commit_id":"829c4e52379ca66d533e83313b11408baa18a854","original_commit_id":"473e65a6c5f4b66c3146c7a037dc0861c98cf268","user":{"login":"fabianfrz","id":3713914,"node_id":"MDQ6VXNlcjM3MTM5MTQ=","avatar_url":"https://avatars1.githubusercontent.com/u/3713914?v=4","gravatar_id":"","url":"https://api.github.com/users/fabianfrz","html_url":"https://github.com/fabianfrz","followers_url":"https://api.github.com/users/fabianfrz/followers","following_url":"https://api.github.com/users/fabianfrz/following{/other_user}","gists_url":"https://api.github.com/users/fabianfrz/gists{/gist_id}","starred_url":"https://api.github.com/users/fabianfrz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fabianfrz/subscriptions","organizations_url":"https://api.github.com/users/fabianfrz/orgs","repos_url":"https://api.github.com/users/fabianfrz/repos","events_url":"https://api.github.com/users/fabianfrz/events{/privacy}","received_events_url":"https://api.github.com/users/fabianfrz/received_events","type":"User","site_admin":false},"body":"https://secure.php.net/manual/de/function.proc-open.php for the command calls and shellescapearg for the aguments.","created_at":"2018-08-09T20:59:42Z","updated_at":"2018-08-09T20:59:42Z","html_url":"https://github.com/opnsense/core/pull/2615#discussion_r209077136","pull_request_url":"https://api.github.com/repos/opnsense/core/pulls/2615","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/opnsense/core/pulls/comments/209077136"},"html":{"href":"https://github.com/opnsense/core/pull/2615#discussion_r209077136"},"pull_request":{"href":"https://api.github.com/repos/opnsense/core/pulls/2615"}},"in_reply_to_id":208680588},"pull_request":{"url":"https://api.github.com/repos/opnsense/core/pulls/2615","id":206963577,"node_id":"MDExOlB1bGxSZXF1ZXN0MjA2OTYzNTc3","html_url":"https://github.com/opnsense/core/pull/2615","diff_url":"https://github.com/opnsense/core/pull/2615.diff","patch_url":"https://github.com/opnsense/core/pull/2615.patch","issue_url":"https://api.github.com/repos/opnsense/core/issues/2615","number":2615,"state":"open","locked":false,"title":"Allow sending configuration backups to email","user":{"login":"machadovilaca","id":21959383,"node_id":"MDQ6VXNlcjIxOTU5Mzgz","avatar_url":"https://avatars1.githubusercontent.com/u/21959383?v=4","gravatar_id":"","url":"https://api.github.com/users/machadovilaca","html_url":"https://github.com/machadovilaca","followers_url":"https://api.github.com/users/machadovilaca/followers","following_url":"https://api.github.com/users/machadovilaca/following{/other_user}","gists_url":"https://api.github.com/users/machadovilaca/gists{/gist_id}","starred_url":"https://api.github.com/users/machadovilaca/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/machadovilaca/subscriptions","organizations_url":"https://api.github.com/users/machadovilaca/orgs","repos_url":"https://api.github.com/users/machadovilaca/repos","events_url":"https://api.github.com/users/machadovilaca/events{/privacy}","received_events_url":"https://api.github.com/users/machadovilaca/received_events","type":"User","site_admin":false},"body":"<img width=\"1440\" alt=\"screen shot 2018-08-08 at 11 35 49\" src=\"https://user-images.githubusercontent.com/21959383/43832395-3aed0616-9aff-11e8-803c-642c322344ec.png\">\r\n","created_at":"2018-08-08T10:36:21Z","updated_at":"2018-08-09T20:59:42Z","closed_at":null,"merged_at":null,"merge_commit_sha":"70df46e1ec8925d78bec83961b84607573df05ff","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/opnsense/core/pulls/2615/commits","review_comments_url":"https://api.github.com/repos/opnsense/core/pulls/2615/comments","review_comment_url":"https://api.github.com/repos/opnsense/core/pulls/comments{/number}","comments_url":"https://api.github.com/repos/opnsense/core/issues/2615/comments","statuses_url":"https://api.github.com/repos/opnsense/core/statuses/829c4e52379ca66d533e83313b11408baa18a854","head":{"label":"machadovilaca:jv-add_mailer_to_backups","ref":"jv-add_mailer_to_backups","sha":"829c4e52379ca66d533e83313b11408baa18a854","user":{"login":"machadovilaca","id":21959383,"node_id":"MDQ6VXNlcjIxOTU5Mzgz","avatar_url":"https://avatars1.githubusercontent.com/u/21959383?v=4","gravatar_id":"","url":"https://api.github.com/users/machadovilaca","html_url":"https://github.com/machadovilaca","followers_url":"https://api.github.com/users/machadovilaca/followers","following_url":"https://api.github.com/users/machadovilaca/following{/other_user}","gists_url":"https://api.github.com/users/machadovilaca/gists{/gist_id}","starred_url":"https://api.github.com/users/machadovilaca/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/machadovilaca/subscriptions","organizations_url":"https://api.github.com/users/machadovilaca/orgs","repos_url":"https://api.github.com/users/machadovilaca/repos","events_url":"https://api.github.com/users/machadovilaca/events{/privacy}","received_events_url":"https://api.github.com/users/machadovilaca/received_events","type":"User","site_admin":false},"repo":{"id":139568403,"node_id":"MDEwOlJlcG9zaXRvcnkxMzk1Njg0MDM=","name":"opnsense-core","full_name":"machadovilaca/opnsense-core","owner":{"login":"machadovilaca","id":21959383,"node_id":"MDQ6VXNlcjIxOTU5Mzgz","avatar_url":"https://avatars1.githubusercontent.com/u/21959383?v=4","gravatar_id":"","url":"https://api.github.com/users/machadovilaca","html_url":"https://github.com/machadovilaca","followers_url":"https://api.github.com/users/machadovilaca/followers","following_url":"https://api.github.com/users/machadovilaca/following{/other_user}","gists_url":"https://api.github.com/users/machadovilaca/gists{/gist_id}","starred_url":"https://api.github.com/users/machadovilaca/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/machadovilaca/subscriptions","organizations_url":"https://api.github.com/users/machadovilaca/orgs","repos_url":"https://api.github.com/users/machadovilaca/repos","events_url":"https://api.github.com/users/machadovilaca/events{/privacy}","received_events_url":"https://api.github.com/users/machadovilaca/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/machadovilaca/opnsense-core","description":"OPNsense GUI, API and systems backend","fork":true,"url":"https://api.github.com/repos/machadovilaca/opnsense-core","forks_url":"https://api.github.com/repos/machadovilaca/opnsense-core/forks","keys_url":"https://api.github.com/repos/machadovilaca/opnsense-core/keys{/key_id}","collaborators_url":"https://api.github.com/repos/machadovilaca/opnsense-core/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/machadovilaca/opnsense-core/teams","hooks_url":"https://api.github.com/repos/machadovilaca/opnsense-core/hooks","issue_events_url":"https://api.github.com/repos/machadovilaca/opnsense-core/issues/events{/number}","events_url":"https://api.github.com/repos/machadovilaca/opnsense-core/events","assignees_url":"https://api.github.com/repos/machadovilaca/opnsense-core/assignees{/user}","branches_url":"https://api.github.com/repos/machadovilaca/opnsense-core/branches{/branch}","tags_url":"https://api.github.com/repos/machadovilaca/opnsense-core/tags","blobs_url":"https://api.github.com/repos/machadovilaca/opnsense-core/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/machadovilaca/opnsense-core/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/machadovilaca/opnsense-core/git/refs{/sha}","trees_url":"https://api.github.com/repos/machadovilaca/opnsense-core/git/trees{/sha}","statuses_url":"https://api.github.com/repos/machadovilaca/opnsense-core/statuses/{sha}","languages_url":"https://api.github.com/repos/machadovilaca/opnsense-core/languages","stargazers_url":"https://api.github.com/repos/machadovilaca/opnsense-core/stargazers","contributors_url":"https://api.github.com/repos/machadovilaca/opnsense-core/contributors","subscribers_url":"https://api.github.com/repos/machadovilaca/opnsense-core/subscribers","subscription_url":"https://api.github.com/repos/machadovilaca/opnsense-core/subscription","commits_url":"https://api.github.com/repos/machadovilaca/opnsense-core/commits{/sha}","git_commits_url":"https://api.github.com/repos/machadovilaca/opnsense-core/git/commits{/sha}","comments_url":"https://api.github.com/repos/machadovilaca/opnsense-core/comments{/number}","issue_comment_url":"https://api.github.com/repos/machadovilaca/opnsense-core/issues/comments{/number}","contents_url":"https://api.github.com/repos/machadovilaca/opnsense-core/contents/{+path}","compare_url":"https://api.github.com/repos/machadovilaca/opnsense-core/compare/{base}...{head}","merges_url":"https://api.github.com/repos/machadovilaca/opnsense-core/merges","archive_url":"https://api.github.com/repos/machadovilaca/opnsense-core/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/machadovilaca/opnsense-core/downloads","issues_url":"https://api.github.com/repos/machadovilaca/opnsense-core/issues{/number}","pulls_url":"https://api.github.com/repos/machadovilaca/opnsense-core/pulls{/number}","milestones_url":"https://api.github.com/repos/machadovilaca/opnsense-core/milestones{/number}","notifications_url":"https://api.github.com/repos/machadovilaca/opnsense-core/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/machadovilaca/opnsense-core/labels{/name}","releases_url":"https://api.github.com/repos/machadovilaca/opnsense-core/releases{/id}","deployments_url":"https://api.github.com/repos/machadovilaca/opnsense-core/deployments","created_at":"2018-07-03T10:40:31Z","updated_at":"2018-08-08T10:31:51Z","pushed_at":"2018-08-09T08:04:41Z","git_url":"git://github.com/machadovilaca/opnsense-core.git","ssh_url":"git@github.com:machadovilaca/opnsense-core.git","clone_url":"https://github.com/machadovilaca/opnsense-core.git","svn_url":"https://github.com/machadovilaca/opnsense-core","homepage":"https://opnsense.org/","size":62176,"stargazers_count":0,"watchers_count":0,"language":"PHP","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"bsd-2-clause","name":"BSD 2-Clause \"Simplified\" License","spdx_id":"BSD-2-Clause","url":"https://api.github.com/licenses/bsd-2-clause","node_id":"MDc6TGljZW5zZTQ="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"opnsense:master","ref":"master","sha":"eab47cb67f50804262608fe1824e84b4d683bc41","user":{"login":"opnsense","id":9979117,"node_id":"MDEyOk9yZ2FuaXphdGlvbjk5NzkxMTc=","avatar_url":"https://avatars3.githubusercontent.com/u/9979117?v=4","gravatar_id":"","url":"https://api.github.com/users/opnsense","html_url":"https://github.com/opnsense","followers_url":"https://api.github.com/users/opnsense/followers","following_url":"https://api.github.com/users/opnsense/following{/other_user}","gists_url":"https://api.github.com/users/opnsense/gists{/gist_id}","starred_url":"https://api.github.com/users/opnsense/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/opnsense/subscriptions","organizations_url":"https://api.github.com/users/opnsense/orgs","repos_url":"https://api.github.com/users/opnsense/repos","events_url":"https://api.github.com/users/opnsense/events{/privacy}","received_events_url":"https://api.github.com/users/opnsense/received_events","type":"Organization","site_admin":false},"repo":{"id":27965134,"node_id":"MDEwOlJlcG9zaXRvcnkyNzk2NTEzNA==","name":"core","full_name":"opnsense/core","owner":{"login":"opnsense","id":9979117,"node_id":"MDEyOk9yZ2FuaXphdGlvbjk5NzkxMTc=","avatar_url":"https://avatars3.githubusercontent.com/u/9979117?v=4","gravatar_id":"","url":"https://api.github.com/users/opnsense","html_url":"https://github.com/opnsense","followers_url":"https://api.github.com/users/opnsense/followers","following_url":"https://api.github.com/users/opnsense/following{/other_user}","gists_url":"https://api.github.com/users/opnsense/gists{/gist_id}","starred_url":"https://api.github.com/users/opnsense/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/opnsense/subscriptions","organizations_url":"https://api.github.com/users/opnsense/orgs","repos_url":"https://api.github.com/users/opnsense/repos","events_url":"https://api.github.com/users/opnsense/events{/privacy}","received_events_url":"https://api.github.com/users/opnsense/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/opnsense/core","description":"OPNsense GUI, API and systems backend","fork":false,"url":"https://api.github.com/repos/opnsense/core","forks_url":"https://api.github.com/repos/opnsense/core/forks","keys_url":"https://api.github.com/repos/opnsense/core/keys{/key_id}","collaborators_url":"https://api.github.com/repos/opnsense/core/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/opnsense/core/teams","hooks_url":"https://api.github.com/repos/opnsense/core/hooks","issue_events_url":"https://api.github.com/repos/opnsense/core/issues/events{/number}","events_url":"https://api.github.com/repos/opnsense/core/events","assignees_url":"https://api.github.com/repos/opnsense/core/assignees{/user}","branches_url":"https://api.github.com/repos/opnsense/core/branches{/branch}","tags_url":"https://api.github.com/repos/opnsense/core/tags","blobs_url":"https://api.github.com/repos/opnsense/core/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/opnsense/core/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/opnsense/core/git/refs{/sha}","trees_url":"https://api.github.com/repos/opnsense/core/git/trees{/sha}","statuses_url":"https://api.github.com/repos/opnsense/core/statuses/{sha}","languages_url":"https://api.github.com/repos/opnsense/core/languages","stargazers_url":"https://api.github.com/repos/opnsense/core/stargazers","contributors_url":"https://api.github.com/repos/opnsense/core/contributors","subscribers_url":"https://api.github.com/repos/opnsense/core/subscribers","subscription_url":"https://api.github.com/repos/opnsense/core/subscription","commits_url":"https://api.github.com/repos/opnsense/core/commits{/sha}","git_commits_url":"https://api.github.com/repos/opnsense/core/git/commits{/sha}","comments_url":"https://api.github.com/repos/opnsense/core/comments{/number}","issue_comment_url":"https://api.github.com/repos/opnsense/core/issues/comments{/number}","contents_url":"https://api.github.com/repos/opnsense/core/contents/{+path}","compare_url":"https://api.github.com/repos/opnsense/core/compare/{base}...{head}","merges_url":"https://api.github.com/repos/opnsense/core/merges","archive_url":"https://api.github.com/repos/opnsense/core/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/opnsense/core/downloads","issues_url":"https://api.github.com/repos/opnsense/core/issues{/number}","pulls_url":"https://api.github.com/repos/opnsense/core/pulls{/number}","milestones_url":"https://api.github.com/repos/opnsense/core/milestones{/number}","notifications_url":"https://api.github.com/repos/opnsense/core/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/opnsense/core/labels{/name}","releases_url":"https://api.github.com/repos/opnsense/core/releases{/id}","deployments_url":"https://api.github.com/repos/opnsense/core/deployments","created_at":"2014-12-13T15:43:50Z","updated_at":"2018-08-09T18:53:43Z","pushed_at":"2018-08-09T20:54:04Z","git_url":"git://github.com/opnsense/core.git","ssh_url":"git@github.com:opnsense/core.git","clone_url":"https://github.com/opnsense/core.git","svn_url":"https://github.com/opnsense/core","homepage":"https://opnsense.org/","size":62373,"stargazers_count":621,"watchers_count":621,"language":"PHP","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":218,"mirror_url":null,"archived":false,"open_issues_count":185,"license":{"key":"bsd-2-clause","name":"BSD 2-Clause \"Simplified\" License","spdx_id":"BSD-2-Clause","url":"https://api.github.com/licenses/bsd-2-clause","node_id":"MDc6TGljZW5zZTQ="},"forks":218,"open_issues":185,"watchers":621,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/opnsense/core/pulls/2615"},"html":{"href":"https://github.com/opnsense/core/pull/2615"},"issue":{"href":"https://api.github.com/repos/opnsense/core/issues/2615"},"comments":{"href":"https://api.github.com/repos/opnsense/core/issues/2615/comments"},"review_comments":{"href":"https://api.github.com/repos/opnsense/core/pulls/2615/comments"},"review_comment":{"href":"https://api.github.com/repos/opnsense/core/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/opnsense/core/pulls/2615/commits"},"statuses":{"href":"https://api.github.com/repos/opnsense/core/statuses/829c4e52379ca66d533e83313b11408baa18a854"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"fabianfrz"}}