{"action":"created","comment":{"url":"https://api.github.com/repos/dotCMS/core/pulls/comments/349735815","pull_request_review_id":321731837,"id":349735815,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDM0OTczNTgxNQ==","diff_hunk":"@@ -0,0 +1,354 @@\n+package com.dotcms.content.elasticsearch.util;\n+\n+import static java.nio.charset.StandardCharsets.US_ASCII;\n+import static java.util.regex.Pattern.CASE_INSENSITIVE;\n+import static javax.crypto.Cipher.DECRYPT_MODE;\n+\n+import com.dotmarketing.util.Config;\n+import com.dotmarketing.util.Logger;\n+import com.liferay.util.FileUtil;\n+import java.io.ByteArrayInputStream;\n+import java.io.File;\n+import java.io.FileInputStream;\n+import java.io.IOException;\n+import java.io.InputStreamReader;\n+import java.io.Reader;\n+import java.nio.CharBuffer;\n+import java.nio.file.Files;\n+import java.nio.file.Paths;\n+import java.nio.file.StandardCopyOption;\n+import java.security.GeneralSecurityException;\n+import java.security.KeyFactory;\n+import java.security.KeyStore;\n+import java.security.KeyStoreException;\n+import java.security.PrivateKey;\n+import java.security.cert.Certificate;\n+import java.security.cert.CertificateException;\n+import java.security.cert.CertificateFactory;\n+import java.security.cert.X509Certificate;\n+import java.security.spec.InvalidKeySpecException;\n+import java.security.spec.PKCS8EncodedKeySpec;\n+import java.util.ArrayList;\n+import java.util.Base64;\n+import java.util.List;\n+import java.util.Optional;\n+import java.util.regex.Matcher;\n+import java.util.regex.Pattern;\n+import javax.crypto.Cipher;\n+import javax.crypto.EncryptedPrivateKeyInfo;\n+import javax.crypto.SecretKey;\n+import javax.crypto.SecretKeyFactory;\n+import javax.crypto.spec.PBEKeySpec;\n+import javax.net.ssl.SSLContext;\n+import javax.security.auth.x500.X500Principal;\n+import org.apache.http.Header;\n+import org.apache.http.HttpHost;\n+import org.apache.http.auth.AuthScope;\n+import org.apache.http.auth.UsernamePasswordCredentials;\n+import org.apache.http.impl.client.BasicCredentialsProvider;\n+import org.apache.http.message.BasicHeader;\n+import org.apache.http.ssl.SSLContexts;\n+import org.elasticsearch.client.Node;\n+import org.elasticsearch.client.RestClient;\n+import org.elasticsearch.client.RestClientBuilder;\n+import org.elasticsearch.client.RestHighLevelClient;\n+import org.jetbrains.annotations.NotNull;\n+\n+/**\n+ * Default high level client to handle API requests in Elastic\n+ */\n+public class DotRestHighLevelClientProvider extends RestHighLevelClientProvider {\n+\n+    private static final String ES_CONFIG_DIR = \"config\";\n+    private static final String ES_PATH_HOME = \"es.path.home\";\n+    private static final String ES_PATH_HOME_DEFAULT_VALUE = \"WEB-INF/elasticsearch\";\n+\n+    private static final String BASIC_AUTH_TYPE = \"BASIC\";\n+\n+    private static final String JWT_AUTH_TYPE = \"JWT\";\n+\n+    private RestHighLevelClient client;\n+\n+    private static SSLContext sslContextFromPem;\n+\n+    DotRestHighLevelClientProvider() {\n+        try {\n+            final RestClientBuilder clientBuilder = getClientBuilder(getCredentialsProvider());\n+            client = new RestHighLevelClient(clientBuilder);\n+        } catch (IOException | GeneralSecurityException e) {\n+            Logger.error(DotRestHighLevelClientProvider.class,\n+                    \"Error setting credentials for Elastic RestHighLevel Client\", e);\n+        }\n+    }\n+\n+    private BasicCredentialsProvider getCredentialsProvider() throws IOException, GeneralSecurityException {\n+        final String esAuthType = getESAuthType();\n+\n+        //Loading TLS certificates\n+        if (Config.getBooleanProperty(\"ES_TLS_ENABLED\", true)) {\n+            loadTLSCertificates();\n+        }\n+\n+        final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();\n+\n+        //Loading basic credentials if set\n+        if (esAuthType.equals(BASIC_AUTH_TYPE)) {\n+            credentialsProvider.setCredentials(AuthScope.ANY,\n+                    new UsernamePasswordCredentials(\n+                            Config.getStringProperty(\"ES_AUTH_BASIC_USER\", null),\n+                            Config.getStringProperty(\"ES_AUTH_BASIC_PASSWORD\", null)));\n+            Logger.info(DotRestHighLevelClientProvider.class,\n+                    \"Initializing Elastic RestHighLevelClient using Basic authentication\");\n+        }\n+\n+        return credentialsProvider;\n+    }\n+\n+    private RestClientBuilder getClientBuilder(final BasicCredentialsProvider credentialsProvider) {\n+        final String esAuthType = getESAuthType();\n+\n+        final RestClientBuilder clientBuilder = RestClient\n+                .builder(new HttpHost(Config.getStringProperty(\"ES_HOSTNAME\", \"127.0.0.1\"),\n+                        Config.getIntProperty(\"ES_PORT\", 9200), \"https\"))\n+                .setHttpClientConfigCallback((httpClientBuilder) -> {\n+                    if (sslContextFromPem != null) {\n+                        httpClientBuilder\n+                                .setSSLContext(sslContextFromPem);\n+                    }\n+                    httpClientBuilder\n+                            .setDefaultCredentialsProvider(credentialsProvider);\n+                    return httpClientBuilder;\n+                })\n+                .setFailureListener(new RestClient.FailureListener() {\n+                    public void onFailure(Node node) {\n+                        Logger.error(this, node.toString());\n+                    }\n+                });\n+\n+        //Loading token if JWT authentication is set\n+        if (esAuthType.equals(JWT_AUTH_TYPE)) {\n+            clientBuilder.setDefaultHeaders(new Header[]{new BasicHeader(\"Authorization\",\n+                    \"Bearer \" + Config.getStringProperty(\"ES_AUTH_JWT_TOKEN\", null))});\n+            Logger.info(DotRestHighLevelClientProvider.class,\n+                    \"Initializing Elastic RestHighLevelClient using JWT authentication\");\n+        }\n+\n+        return clientBuilder;\n+    }\n+\n+    private String getESAuthType() {\n+        return Config.getStringProperty(\"ES_AUTH_TYPE\", BASIC_AUTH_TYPE);\n+    }\n+\n+    private void loadTLSCertificates() throws IOException, GeneralSecurityException {\n+        String clientCertPath = getCertPath(\"ES_AUTH_TLS_CLIENT_CERT\", \"elasticsearch.pem\");\n+        String clientKeyPath = getCertPath(\"ES_AUTH_TLS_CLIENT_KEY\", \"elasticsearch.key\");\n+        String serverCertPath = getCertPath(\"ES_AUTH_TLS_CA_CERT\", \"root-ca.pem\");\n+\n+        sslContextFromPem = SSLContexts\n+                .custom()\n+                .loadKeyMaterial(PemReader\n+                        .loadKeyStore(\n+                                Paths.get(clientCertPath).toFile(),\n+                                Paths.get(clientKeyPath).toFile(),\n+                                Optional.empty()), \"\".toCharArray())\n+                .loadTrustMaterial(PemReader.loadTrustStore(\n+                        Paths.get(serverCertPath).toFile()), null)\n+                .build();\n+        Logger.info(DotRestHighLevelClientProvider.class,\n+                \"Initializing Elastic RestHighLevelClient using TLS certificates\");\n+    }\n+\n+    @NotNull\n+    private String getCertPath(final String propertyName, final String fileName) throws IOException {\n+        String clientCertPath = Config.getStringProperty(propertyName, null);\n+        if (clientCertPath == null || !Files.exists(Paths.get(clientCertPath))) {\n+\n+            String assetsRealPath = Config.getStringProperty(\"ASSET_REAL_PATH\",\n+                    FileUtil.getRealPath(Config.getStringProperty(\"ASSET_PATH\", \"/assets\")));\n+\n+            clientCertPath = assetsRealPath + File.separator + \"certs\" + File.separator + fileName;\n+\n+            if (!Files.exists(Paths.get(clientCertPath))) {\n+                File directory = new File(assetsRealPath + File.separator + \"certs\");\n+                if (!directory.exists()){\n+                    directory.mkdirs();\n+                }\n+\n+                Files.copy(Paths.get(getESPathHome() + File.separator + ES_CONFIG_DIR\n+                                + File.separator + fileName), Paths.get(clientCertPath),\n+                        StandardCopyOption.COPY_ATTRIBUTES);\n+            }\n+        }\n+        return clientCertPath;\n+    }\n+\n+\n+\n+    private String getESPathHome() {\n+        String esPathHome = Config\n+                .getStringProperty(ES_PATH_HOME, ES_PATH_HOME_DEFAULT_VALUE);\n+\n+        esPathHome =\n+                !new File(esPathHome).isAbsolute() ? FileUtil.getRealPath(esPathHome) : esPathHome;\n+\n+        return esPathHome;\n+    }\n+\n+    public RestHighLevelClient getClient() {\n+        return client;\n+    }\n+\n+    public void setClient(final RestHighLevelClient theClient) {\n+        if(theClient!=null) {\n+            client = theClient;\n+        }\n+    }\n+\n+    public void close() throws IOException {\n+        if(client!=null) {\n+            client.close();\n+        }\n+    }\n+\n+    /*\n+     * Copyright 2014 The Netty Project\n+     *\n+     * The Netty Project licenses this file to you under the Apache License,\n+     * version 2.0 (the \"License\"); you may not use this file except in compliance\n+     * with the License. You may obtain a copy of the License at:\n+     *\n+     *   http://www.apache.org/licenses/LICENSE-2.0\n+     *\n+     * Unless required by applicable law or agreed to in writing, software\n+     * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n+     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n+     * License for the specific language governing permissions and limitations\n+     * under the License.\n+     */\n+    private static final class PemReader {\n+\n+        private static final Pattern CERT_PATTERN = Pattern.compile(\n+                \"-+BEGIN\\\\s+.*CERTIFICATE[^-]*-+(?:\\\\s|\\\\r|\\\\n)+\" + // Header\n+                        \"([a-z0-9+/=\\\\r\\\\n]+)\" +                    // Base64 text\n+                        \"-+END\\\\s+.*CERTIFICATE[^-]*-+\",            // Footer\n+                CASE_INSENSITIVE);\n+\n+        private static final Pattern KEY_PATTERN = Pattern.compile(\n+                \"-+BEGIN\\\\s+.*PRIVATE\\\\s+KEY[^-]*-+(?:\\\\s|\\\\r|\\\\n)+\" + // Header\n+                        \"([a-z0-9+/=\\\\r\\\\n]+)\" +                       // Base64 text\n+                        \"-+END\\\\s+.*PRIVATE\\\\s+KEY[^-]*-+\",            // Footer\n+                CASE_INSENSITIVE);\n+\n+        private PemReader() {\n+\n+        }\n+\n+        private static KeyStore loadTrustStore(File certificateChainFile)\n+                throws IOException, GeneralSecurityException {\n+            KeyStore keyStore = KeyStore.getInstance(\"JKS\");\n+            keyStore.load(null, null);\n+\n+            List<X509Certificate> certificateChain = readCertificateChain(certificateChainFile);\n+            for (X509Certificate certificate : certificateChain) {\n+                X500Principal principal = certificate.getSubjectX500Principal();\n+                keyStore.setCertificateEntry(principal.getName(\"RFC2253\"), certificate);\n+            }\n+            return keyStore;\n+        }\n+\n+        private static KeyStore loadKeyStore(File certificateChainFile, File privateKeyFile,\n+                Optional<String> keyPassword)\n+                throws IOException, GeneralSecurityException {\n+            PKCS8EncodedKeySpec encodedKeySpec = readPrivateKey(privateKeyFile, keyPassword);\n+            PrivateKey key;\n+            try {\n+                KeyFactory keyFactory = KeyFactory.getInstance(\"RSA\");\n+                key = keyFactory.generatePrivate(encodedKeySpec);\n+            } catch (InvalidKeySpecException ignore) {\n+                KeyFactory keyFactory = KeyFactory.getInstance(\"DSA\");\n+                key = keyFactory.generatePrivate(encodedKeySpec);\n+            }\n+\n+            List<X509Certificate> certificateChain = readCertificateChain(certificateChainFile);\n+            if (certificateChain.isEmpty()) {\n+                throw new CertificateException(\n+                        \"Certificate file does not contain any certificates: \"\n+                                + certificateChainFile);\n+            }\n+\n+            KeyStore keyStore = KeyStore.getInstance(\"JKS\");\n+            keyStore.load(null, null);\n+            keyStore.setKeyEntry(\"key\", key, keyPassword.orElse(\"\").toCharArray(),\n+                    certificateChain.stream().toArray(\n+                            Certificate[]::new));\n+            return keyStore;\n+        }\n+\n+        private static PKCS8EncodedKeySpec readPrivateKey(File keyFile,\n+                Optional<String> keyPassword)\n+                throws IOException, GeneralSecurityException {\n+            String content = readFile(keyFile);\n+\n+            Matcher matcher = KEY_PATTERN.matcher(content);\n+            if (!matcher.find()) {\n+                throw new KeyStoreException(\"found no private key: \" + keyFile);\n+            }\n+            byte[] encodedKey = base64Decode(matcher.group(1));\n+\n+            if (!keyPassword.isPresent()) {\n+                return new PKCS8EncodedKeySpec(encodedKey);\n+            }\n+\n+            EncryptedPrivateKeyInfo encryptedPrivateKeyInfo = new EncryptedPrivateKeyInfo(\n+                    encodedKey);\n+            SecretKeyFactory keyFactory = SecretKeyFactory\n+                    .getInstance(encryptedPrivateKeyInfo.getAlgName());\n+            SecretKey secretKey = keyFactory","path":"dotCMS/src/main/java/com/dotcms/content/elasticsearch/util/DotRestHighLevelClientProvider.java","position":307,"original_position":307,"commit_id":"1e4a2fdabb125607d84633cd9e141ef930e0ec34","original_commit_id":"1e4a2fdabb125607d84633cd9e141ef930e0ec34","user":{"login":"dev-dotcms","id":29232833,"node_id":"MDQ6VXNlcjI5MjMyODMz","avatar_url":"https://avatars2.githubusercontent.com/u/29232833?v=4","gravatar_id":"","url":"https://api.github.com/users/dev-dotcms","html_url":"https://github.com/dev-dotcms","followers_url":"https://api.github.com/users/dev-dotcms/followers","following_url":"https://api.github.com/users/dev-dotcms/following{/other_user}","gists_url":"https://api.github.com/users/dev-dotcms/gists{/gist_id}","starred_url":"https://api.github.com/users/dev-dotcms/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dev-dotcms/subscriptions","organizations_url":"https://api.github.com/users/dev-dotcms/orgs","repos_url":"https://api.github.com/users/dev-dotcms/repos","events_url":"https://api.github.com/users/dev-dotcms/events{/privacy}","received_events_url":"https://api.github.com/users/dev-dotcms/received_events","type":"User","site_admin":false},"body":"![Codacy](https://app.codacy.com/assets/images/favicon.png) Issue found: [Local variable 'secretKey' could be declared final](https://app.codacy.com/app/dotCMS/core/pullRequest?prid=3712629)","created_at":"2019-11-22T18:33:58Z","updated_at":"2019-11-22T18:33:59Z","html_url":"https://github.com/dotCMS/core/pull/16727#discussion_r349735815","pull_request_url":"https://api.github.com/repos/dotCMS/core/pulls/16727","author_association":"NONE","_links":{"self":{"href":"https://api.github.com/repos/dotCMS/core/pulls/comments/349735815"},"html":{"href":"https://github.com/dotCMS/core/pull/16727#discussion_r349735815"},"pull_request":{"href":"https://api.github.com/repos/dotCMS/core/pulls/16727"}}},"pull_request":{"url":"https://api.github.com/repos/dotCMS/core/pulls/16727","id":287702867,"node_id":"MDExOlB1bGxSZXF1ZXN0Mjg3NzAyODY3","html_url":"https://github.com/dotCMS/core/pull/16727","diff_url":"https://github.com/dotCMS/core/pull/16727.diff","patch_url":"https://github.com/dotCMS/core/pull/16727.patch","issue_url":"https://api.github.com/repos/dotCMS/core/issues/16727","number":16727,"state":"open","locked":false,"title":"Issue 15942 External ES","user":{"login":"dsilvam","id":1576794,"node_id":"MDQ6VXNlcjE1NzY3OTQ=","avatar_url":"https://avatars3.githubusercontent.com/u/1576794?v=4","gravatar_id":"","url":"https://api.github.com/users/dsilvam","html_url":"https://github.com/dsilvam","followers_url":"https://api.github.com/users/dsilvam/followers","following_url":"https://api.github.com/users/dsilvam/following{/other_user}","gists_url":"https://api.github.com/users/dsilvam/gists{/gist_id}","starred_url":"https://api.github.com/users/dsilvam/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dsilvam/subscriptions","organizations_url":"https://api.github.com/users/dsilvam/orgs","repos_url":"https://api.github.com/users/dsilvam/repos","events_url":"https://api.github.com/users/dsilvam/events{/privacy}","received_events_url":"https://api.github.com/users/dsilvam/received_events","type":"User","site_admin":false},"body":"","created_at":"2019-06-12T22:49:38Z","updated_at":"2019-11-22T18:33:59Z","closed_at":null,"merged_at":null,"merge_commit_sha":"767579183b938e00fcc7d570e03c5b1acaa589c9","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/dotCMS/core/pulls/16727/commits","review_comments_url":"https://api.github.com/repos/dotCMS/core/pulls/16727/comments","review_comment_url":"https://api.github.com/repos/dotCMS/core/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dotCMS/core/issues/16727/comments","statuses_url":"https://api.github.com/repos/dotCMS/core/statuses/1e4a2fdabb125607d84633cd9e141ef930e0ec34","head":{"label":"dotCMS:issue-15942","ref":"issue-15942","sha":"1e4a2fdabb125607d84633cd9e141ef930e0ec34","user":{"login":"dotCMS","id":1005263,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEwMDUyNjM=","avatar_url":"https://avatars3.githubusercontent.com/u/1005263?v=4","gravatar_id":"","url":"https://api.github.com/users/dotCMS","html_url":"https://github.com/dotCMS","followers_url":"https://api.github.com/users/dotCMS/followers","following_url":"https://api.github.com/users/dotCMS/following{/other_user}","gists_url":"https://api.github.com/users/dotCMS/gists{/gist_id}","starred_url":"https://api.github.com/users/dotCMS/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotCMS/subscriptions","organizations_url":"https://api.github.com/users/dotCMS/orgs","repos_url":"https://api.github.com/users/dotCMS/repos","events_url":"https://api.github.com/users/dotCMS/events{/privacy}","received_events_url":"https://api.github.com/users/dotCMS/received_events","type":"Organization","site_admin":false},"repo":{"id":3729629,"node_id":"MDEwOlJlcG9zaXRvcnkzNzI5NjI5","name":"core","full_name":"dotCMS/core","private":false,"owner":{"login":"dotCMS","id":1005263,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEwMDUyNjM=","avatar_url":"https://avatars3.githubusercontent.com/u/1005263?v=4","gravatar_id":"","url":"https://api.github.com/users/dotCMS","html_url":"https://github.com/dotCMS","followers_url":"https://api.github.com/users/dotCMS/followers","following_url":"https://api.github.com/users/dotCMS/following{/other_user}","gists_url":"https://api.github.com/users/dotCMS/gists{/gist_id}","starred_url":"https://api.github.com/users/dotCMS/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotCMS/subscriptions","organizations_url":"https://api.github.com/users/dotCMS/orgs","repos_url":"https://api.github.com/users/dotCMS/repos","events_url":"https://api.github.com/users/dotCMS/events{/privacy}","received_events_url":"https://api.github.com/users/dotCMS/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/dotCMS/core","description":"Source Code for dotCMS Java Enterprise Content Management System","fork":false,"url":"https://api.github.com/repos/dotCMS/core","forks_url":"https://api.github.com/repos/dotCMS/core/forks","keys_url":"https://api.github.com/repos/dotCMS/core/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dotCMS/core/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dotCMS/core/teams","hooks_url":"https://api.github.com/repos/dotCMS/core/hooks","issue_events_url":"https://api.github.com/repos/dotCMS/core/issues/events{/number}","events_url":"https://api.github.com/repos/dotCMS/core/events","assignees_url":"https://api.github.com/repos/dotCMS/core/assignees{/user}","branches_url":"https://api.github.com/repos/dotCMS/core/branches{/branch}","tags_url":"https://api.github.com/repos/dotCMS/core/tags","blobs_url":"https://api.github.com/repos/dotCMS/core/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dotCMS/core/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dotCMS/core/git/refs{/sha}","trees_url":"https://api.github.com/repos/dotCMS/core/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dotCMS/core/statuses/{sha}","languages_url":"https://api.github.com/repos/dotCMS/core/languages","stargazers_url":"https://api.github.com/repos/dotCMS/core/stargazers","contributors_url":"https://api.github.com/repos/dotCMS/core/contributors","subscribers_url":"https://api.github.com/repos/dotCMS/core/subscribers","subscription_url":"https://api.github.com/repos/dotCMS/core/subscription","commits_url":"https://api.github.com/repos/dotCMS/core/commits{/sha}","git_commits_url":"https://api.github.com/repos/dotCMS/core/git/commits{/sha}","comments_url":"https://api.github.com/repos/dotCMS/core/comments{/number}","issue_comment_url":"https://api.github.com/repos/dotCMS/core/issues/comments{/number}","contents_url":"https://api.github.com/repos/dotCMS/core/contents/{+path}","compare_url":"https://api.github.com/repos/dotCMS/core/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dotCMS/core/merges","archive_url":"https://api.github.com/repos/dotCMS/core/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dotCMS/core/downloads","issues_url":"https://api.github.com/repos/dotCMS/core/issues{/number}","pulls_url":"https://api.github.com/repos/dotCMS/core/pulls{/number}","milestones_url":"https://api.github.com/repos/dotCMS/core/milestones{/number}","notifications_url":"https://api.github.com/repos/dotCMS/core/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dotCMS/core/labels{/name}","releases_url":"https://api.github.com/repos/dotCMS/core/releases{/id}","deployments_url":"https://api.github.com/repos/dotCMS/core/deployments","created_at":"2012-03-15T15:24:14Z","updated_at":"2019-11-21T14:14:10Z","pushed_at":"2019-11-22T18:17:19Z","git_url":"git://github.com/dotCMS/core.git","ssh_url":"git@github.com:dotCMS/core.git","clone_url":"https://github.com/dotCMS/core.git","svn_url":"https://github.com/dotCMS/core","homepage":"http://dotcms.com","size":384058,"stargazers_count":525,"watchers_count":525,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":354,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":270,"license":{"key":"gpl-3.0","name":"GNU General Public License v3.0","spdx_id":"GPL-3.0","url":"https://api.github.com/licenses/gpl-3.0","node_id":"MDc6TGljZW5zZTk="},"forks":354,"open_issues":270,"watchers":525,"default_branch":"master"}},"base":{"label":"dotCMS:master","ref":"master","sha":"c25fd9fdc8ddfdb4045bb31e8f19dd1f882044b4","user":{"login":"dotCMS","id":1005263,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEwMDUyNjM=","avatar_url":"https://avatars3.githubusercontent.com/u/1005263?v=4","gravatar_id":"","url":"https://api.github.com/users/dotCMS","html_url":"https://github.com/dotCMS","followers_url":"https://api.github.com/users/dotCMS/followers","following_url":"https://api.github.com/users/dotCMS/following{/other_user}","gists_url":"https://api.github.com/users/dotCMS/gists{/gist_id}","starred_url":"https://api.github.com/users/dotCMS/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotCMS/subscriptions","organizations_url":"https://api.github.com/users/dotCMS/orgs","repos_url":"https://api.github.com/users/dotCMS/repos","events_url":"https://api.github.com/users/dotCMS/events{/privacy}","received_events_url":"https://api.github.com/users/dotCMS/received_events","type":"Organization","site_admin":false},"repo":{"id":3729629,"node_id":"MDEwOlJlcG9zaXRvcnkzNzI5NjI5","name":"core","full_name":"dotCMS/core","private":false,"owner":{"login":"dotCMS","id":1005263,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEwMDUyNjM=","avatar_url":"https://avatars3.githubusercontent.com/u/1005263?v=4","gravatar_id":"","url":"https://api.github.com/users/dotCMS","html_url":"https://github.com/dotCMS","followers_url":"https://api.github.com/users/dotCMS/followers","following_url":"https://api.github.com/users/dotCMS/following{/other_user}","gists_url":"https://api.github.com/users/dotCMS/gists{/gist_id}","starred_url":"https://api.github.com/users/dotCMS/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotCMS/subscriptions","organizations_url":"https://api.github.com/users/dotCMS/orgs","repos_url":"https://api.github.com/users/dotCMS/repos","events_url":"https://api.github.com/users/dotCMS/events{/privacy}","received_events_url":"https://api.github.com/users/dotCMS/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/dotCMS/core","description":"Source Code for dotCMS Java Enterprise Content Management System","fork":false,"url":"https://api.github.com/repos/dotCMS/core","forks_url":"https://api.github.com/repos/dotCMS/core/forks","keys_url":"https://api.github.com/repos/dotCMS/core/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dotCMS/core/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dotCMS/core/teams","hooks_url":"https://api.github.com/repos/dotCMS/core/hooks","issue_events_url":"https://api.github.com/repos/dotCMS/core/issues/events{/number}","events_url":"https://api.github.com/repos/dotCMS/core/events","assignees_url":"https://api.github.com/repos/dotCMS/core/assignees{/user}","branches_url":"https://api.github.com/repos/dotCMS/core/branches{/branch}","tags_url":"https://api.github.com/repos/dotCMS/core/tags","blobs_url":"https://api.github.com/repos/dotCMS/core/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dotCMS/core/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dotCMS/core/git/refs{/sha}","trees_url":"https://api.github.com/repos/dotCMS/core/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dotCMS/core/statuses/{sha}","languages_url":"https://api.github.com/repos/dotCMS/core/languages","stargazers_url":"https://api.github.com/repos/dotCMS/core/stargazers","contributors_url":"https://api.github.com/repos/dotCMS/core/contributors","subscribers_url":"https://api.github.com/repos/dotCMS/core/subscribers","subscription_url":"https://api.github.com/repos/dotCMS/core/subscription","commits_url":"https://api.github.com/repos/dotCMS/core/commits{/sha}","git_commits_url":"https://api.github.com/repos/dotCMS/core/git/commits{/sha}","comments_url":"https://api.github.com/repos/dotCMS/core/comments{/number}","issue_comment_url":"https://api.github.com/repos/dotCMS/core/issues/comments{/number}","contents_url":"https://api.github.com/repos/dotCMS/core/contents/{+path}","compare_url":"https://api.github.com/repos/dotCMS/core/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dotCMS/core/merges","archive_url":"https://api.github.com/repos/dotCMS/core/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dotCMS/core/downloads","issues_url":"https://api.github.com/repos/dotCMS/core/issues{/number}","pulls_url":"https://api.github.com/repos/dotCMS/core/pulls{/number}","milestones_url":"https://api.github.com/repos/dotCMS/core/milestones{/number}","notifications_url":"https://api.github.com/repos/dotCMS/core/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dotCMS/core/labels{/name}","releases_url":"https://api.github.com/repos/dotCMS/core/releases{/id}","deployments_url":"https://api.github.com/repos/dotCMS/core/deployments","created_at":"2012-03-15T15:24:14Z","updated_at":"2019-11-21T14:14:10Z","pushed_at":"2019-11-22T18:17:19Z","git_url":"git://github.com/dotCMS/core.git","ssh_url":"git@github.com:dotCMS/core.git","clone_url":"https://github.com/dotCMS/core.git","svn_url":"https://github.com/dotCMS/core","homepage":"http://dotcms.com","size":384058,"stargazers_count":525,"watchers_count":525,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":354,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":270,"license":{"key":"gpl-3.0","name":"GNU General Public License v3.0","spdx_id":"GPL-3.0","url":"https://api.github.com/licenses/gpl-3.0","node_id":"MDc6TGljZW5zZTk="},"forks":354,"open_issues":270,"watchers":525,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dotCMS/core/pulls/16727"},"html":{"href":"https://github.com/dotCMS/core/pull/16727"},"issue":{"href":"https://api.github.com/repos/dotCMS/core/issues/16727"},"comments":{"href":"https://api.github.com/repos/dotCMS/core/issues/16727/comments"},"review_comments":{"href":"https://api.github.com/repos/dotCMS/core/pulls/16727/comments"},"review_comment":{"href":"https://api.github.com/repos/dotCMS/core/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dotCMS/core/pulls/16727/commits"},"statuses":{"href":"https://api.github.com/repos/dotCMS/core/statuses/1e4a2fdabb125607d84633cd9e141ef930e0ec34"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"dev-dotcms"}}