{"action":"created","comment":{"url":"https://api.github.com/repos/Jasig/cas/pulls/comments/37185184","id":37185184,"diff_hunk":"@@ -1,219 +1,234 @@\n-/*\r\n- * Licensed to Apereo under one or more contributor license\r\n- * agreements. See the NOTICE file distributed with this work\r\n- * for additional information regarding copyright ownership.\r\n- * Apereo licenses this file to you under the Apache License,\r\n- * Version 2.0 (the \"License\"); you may not use this file\r\n- * except in compliance with the License.  You may obtain a\r\n- * copy of the License at the following location:\r\n- *\r\n- *   http://www.apache.org/licenses/LICENSE-2.0\r\n- *\r\n- * Unless required by applicable law or agreed to in writing,\r\n- * software distributed under the License is distributed on an\r\n- * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r\n- * KIND, either express or implied.  See the License for the\r\n- * specific language governing permissions and limitations\r\n- * under the License.\r\n- */\r\n-package org.jasig.cas.support.openid.authentication.principal;\r\n-\r\n-import org.apache.commons.lang3.builder.HashCodeBuilder;\r\n-import org.jasig.cas.CentralAuthenticationService;\r\n-import org.jasig.cas.authentication.principal.AbstractWebApplicationService;\r\n-import org.jasig.cas.authentication.principal.DefaultResponse;\r\n-import org.jasig.cas.authentication.principal.Response;\r\n-import org.jasig.cas.ticket.TicketException;\r\n-import org.jasig.cas.util.ApplicationContextProvider;\r\n-import org.openid4java.association.Association;\r\n-import org.openid4java.message.AuthRequest;\r\n-import org.openid4java.message.Message;\r\n-import org.openid4java.message.MessageException;\r\n-import org.openid4java.message.ParameterList;\r\n-import org.openid4java.server.ServerManager;\r\n-import org.slf4j.Logger;\r\n-import org.slf4j.LoggerFactory;\r\n-import org.springframework.util.StringUtils;\r\n-\r\n-import javax.servlet.http.HttpServletRequest;\r\n-import java.util.HashMap;\r\n-import java.util.Map;\r\n-\r\n-/**\r\n- * @author Scott Battaglia\r\n- * @since 3.1\r\n- */\r\n-public final class OpenIdService extends AbstractWebApplicationService {\r\n-    \r\n-    /** The Constant LOGGER. */\r\n-    protected static final Logger LOGGER = LoggerFactory.getLogger(OpenIdService.class);\r\n-\r\n-    private static final long serialVersionUID = 5776500133123291301L;\r\n-\r\n-    private static final String CONST_PARAM_SERVICE = \"openid.return_to\";\r\n-\r\n-    private final String identity;\r\n-\r\n-    private final String artifactId;\r\n-\r\n-    private final ParameterList requestParameters;\r\n-\r\n-    /**\r\n-     * Instantiates a new OpenID service.\r\n-     *\r\n-     * @param id the id\r\n-     * @param originalUrl the original url\r\n-     * @param artifactId the artifact id\r\n-     * @param openIdIdentity the OpenID identity\r\n-     * @param signature the signature\r\n-     * @param parameterList the parameter list\r\n-     */\r\n-    protected OpenIdService(final String id, final String originalUrl,\r\n-            final String artifactId, final String openIdIdentity,\r\n-            final String signature, final ParameterList parameterList) {\r\n-        super(id, originalUrl, artifactId);\r\n-        this.identity = openIdIdentity;\r\n-        this.artifactId = artifactId;\r\n-        this.requestParameters = parameterList;\r\n-    }\r\n-\r\n-    /**\r\n-     * Generates an Openid response.\r\n-     * If no ticketId is found, response is negative.\r\n-     * If we have a ticket id, then we check if we have an association.\r\n-     * If so, we ask OpenId server manager to generate the answer according with the existing association.\r\n-     * If not, we send back an answer with the ticket id as association handle.\r\n-     * This will force the consumer to ask a verification, which will validate the service ticket.\r\n-     * @param ticketId the service ticket to provide to the service.\r\n-     * @return the generated authentication answer\r\n-     */\r\n-    @Override\r\n-    public Response getResponse(final String ticketId) {\r\n-        final Map<String, String> parameters = new HashMap<>();\r\n-        if (ticketId != null) {\r\n-\r\n-            final ServerManager manager = (ServerManager) ApplicationContextProvider.getApplicationContext().getBean(\"serverManager\");\r\n-            final CentralAuthenticationService cas = ApplicationContextProvider.getApplicationContext()\r\n-                                                .getBean(\"centralAuthenticationService\", CentralAuthenticationService.class);\r\n-            boolean associated = false;\r\n-            boolean associationValid = true;\r\n-            try {\r\n-                final AuthRequest authReq = AuthRequest.createAuthRequest(requestParameters, manager.getRealmVerifier());\r\n-                final Map parameterMap = authReq.getParameterMap();\r\n-                if (parameterMap != null && parameterMap.size() > 0) {\r\n-                    final String assocHandle = (String) parameterMap.get(\"openid.assoc_handle\");\r\n-                    if (assocHandle != null) {\r\n-                        final Association association = manager.getSharedAssociations().load(assocHandle);\r\n-                        if (association != null) {\r\n-                            associated = true;\r\n-                            if (association.hasExpired()) {\r\n-                                associationValid = false;\r\n-                            }\r\n-                        }\r\n-\r\n-                    }\r\n-                }\r\n-            } catch (final MessageException me) {\r\n-                LOGGER.error(\"Message exception : {}\", me.getMessage(), me);\r\n-            }\r\n-\r\n-            boolean successFullAuthentication = true;\r\n-            try {\r\n-                if (associated) {\r\n-                    if (associationValid) {\r\n-                        cas.validateServiceTicket(ticketId, this);\r\n-                        LOGGER.info(\"Validated openid ticket\");\r\n-                    } else {\r\n-                        successFullAuthentication = false;\r\n-                    }\r\n-                }\r\n-            } catch (final TicketException te) {\r\n-                LOGGER.error(\"Could not validate ticket : {}\", te.getMessage(), te);\r\n-                successFullAuthentication = false;\r\n-            }\r\n-\r\n-            // We sign directly (final 'true') because we don't add extensions\r\n-            // response message can be either a DirectError or an AuthSuccess here.\r\n-            // Anyway, handling is the same : send the response message\r\n-            final Message response = manager.authResponse(requestParameters,\r\n-                    this.identity,\r\n-                    this.identity,\r\n-                    successFullAuthentication,\r\n-                    true);\r\n-            parameters.putAll(response.getParameterMap());\r\n-            if (!associated) {\r\n-                parameters.put(\"openid.assoc_handle\", ticketId);\r\n-            }\r\n-        } else {\r\n-            parameters.put(\"openid.mode\", \"cancel\");\r\n-        }\r\n-        return DefaultResponse.getRedirectResponse(getOriginalUrl(), parameters);\r\n-    }\r\n-\r\n-    /**\r\n-     * Return that the service is already logged out.\r\n-     *\r\n-     * @return that the service is already logged out.\r\n-     */\r\n-    @Override\r\n-    public boolean isLoggedOutAlready() {\r\n-        return true;\r\n-    }\r\n-\r\n-    /**\r\n-     * Creates the service from the request.\r\n-     *\r\n-     * @param request the request\r\n-     * @return the OpenID service\r\n-     */\r\n-    public static OpenIdService createServiceFrom(\r\n-            final HttpServletRequest request) {\r\n-        final String service = request.getParameter(CONST_PARAM_SERVICE);\r\n-        final String openIdIdentity = request.getParameter(\"openid.identity\");\r\n-        final String signature = request.getParameter(\"openid.sig\");\r\n-\r\n-        if (openIdIdentity == null || !StringUtils.hasText(service)) {\r\n-            return null;\r\n-        }\r\n-\r\n-        final String id = cleanupUrl(service);\r\n-        final String artifactId = request.getParameter(\"openid.assoc_handle\");\r\n-        final ParameterList paramList = new ParameterList(request.getParameterMap());\r\n-\r\n-        return new OpenIdService(id, service, artifactId, openIdIdentity,\r\n-                signature, paramList);\r\n-    }\r\n-\r\n-    @Override\r\n-    public int hashCode() {\r\n-        return new HashCodeBuilder()\r\n-                .append(this.identity)\r\n-                .toHashCode();\r\n-    }\r\n-\r\n-    @Override\r\n-    public boolean equals(final Object obj) {\r\n-        if (this == obj) {\r\n-            return true;\r\n-        }\r\n-        if (!super.equals(obj)) {\r\n-            return false;\r\n-        }\r\n-        if (getClass() != obj.getClass()) {\r\n-            return false;\r\n-        }\r\n-        final OpenIdService other = (OpenIdService) obj;\r\n-        if (this.identity == null) {\r\n-            if (other.identity != null) {\r\n-                return false;\r\n-            }\r\n-        } else if (!this.identity.equals(other.identity)) {\r\n-            return false;\r\n-        }\r\n-        return true;\r\n-    }\r\n-\r\n-    public String getIdentity() {\r\n-        return this.identity;\r\n-    }\r\n-}\r\n+/*\n+ * Licensed to Apereo under one or more contributor license\n+ * agreements. See the NOTICE file distributed with this work\n+ * for additional information regarding copyright ownership.\n+ * Apereo licenses this file to you under the Apache License,\n+ * Version 2.0 (the \"License\"); you may not use this file\n+ * except in compliance with the License.  You may obtain a\n+ * copy of the License at the following location:\n+ *\n+ *   http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing,\n+ * software distributed under the License is distributed on an\n+ * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n+ * KIND, either express or implied.  See the License for the\n+ * specific language governing permissions and limitations\n+ * under the License.\n+ */\n+package org.jasig.cas.support.openid.authentication.principal;\n+\n+import org.apache.commons.lang3.builder.HashCodeBuilder;\n+import org.jasig.cas.CentralAuthenticationService;\n+import org.jasig.cas.authentication.principal.AbstractWebApplicationService;\n+import org.jasig.cas.authentication.principal.DefaultResponse;\n+import org.jasig.cas.authentication.principal.Response;\n+import org.jasig.cas.support.openid.web.support.OpenIdUserNameExtractor;\n+import org.jasig.cas.ticket.TicketException;\n+import org.jasig.cas.util.ApplicationContextProvider;\n+import org.jasig.cas.validation.Assertion;\n+import org.openid4java.association.Association;\n+import org.openid4java.message.AuthRequest;\n+import org.openid4java.message.Message;\n+import org.openid4java.message.MessageException;\n+import org.openid4java.message.ParameterList;\n+import org.openid4java.server.ServerManager;\n+import org.slf4j.Logger;\n+import org.slf4j.LoggerFactory;\n+import org.springframework.util.StringUtils;\n+\n+import javax.servlet.http.HttpServletRequest;\n+import java.util.HashMap;\n+import java.util.Map;\n+\n+/**\n+ * @author Scott Battaglia\n+ * @since 3.1\n+ */\n+public final class OpenIdService extends AbstractWebApplicationService {\n+\n+    /** The Constant LOGGER. */\n+    protected static final Logger LOGGER = LoggerFactory.getLogger(OpenIdService.class);\n+\n+    private static final long serialVersionUID = 5776500133123291301L;\n+\n+    private static final String CONST_PARAM_SERVICE = \"openid.return_to\";\n+\n+    private final String identity;\n+\n+    private final String artifactId;\n+\n+    private final ParameterList requestParameters;\n+\n+    private final String openIdPrefixUrl;\n+\n+    /**\n+     * Instantiates a new OpenID service.\n+     *\n+     * @param id the id\n+     * @param originalUrl the original url\n+     * @param artifactId the artifact id\n+     * @param openIdIdentity the OpenID identity\n+     * @param signature the signature\n+     * @param parameterList the parameter list\n+     * @param openIdPrefixUrl the prefix url for OpenID\n+     */\n+    protected OpenIdService(final String id, final String originalUrl,\n+            final String artifactId, final String openIdIdentity,\n+            final String signature, final ParameterList parameterList,\n+                            final String openIdPrefixUrl) {\n+        super(id, originalUrl, artifactId);\n+        this.identity = openIdIdentity;\n+        this.artifactId = artifactId;\n+        this.requestParameters = parameterList;\n+        this.openIdPrefixUrl = openIdPrefixUrl;\n+    }\n+\n+    /**\n+     * Generates an Openid response.\n+     * If no ticketId is found, response is negative.\n+     * If we have a ticket id, then we check if we have an association.\n+     * If so, we ask OpenId server manager to generate the answer according with the existing association.\n+     * If not, we send back an answer with the ticket id as association handle.\n+     * This will force the consumer to ask a verification, which will validate the service ticket.\n+     * @param ticketId the service ticket to provide to the service.\n+     * @return the generated authentication answer\n+     */\n+    @Override\n+    public Response getResponse(final String ticketId) {\n+        final Map<String, String> parameters = new HashMap<>();\n+        if (ticketId != null) {\n+\n+            final ServerManager manager = (ServerManager) ApplicationContextProvider.getApplicationContext().getBean(\"serverManager\");\n+            final CentralAuthenticationService cas = ApplicationContextProvider.getApplicationContext()\n+                                                .getBean(\"centralAuthenticationService\", CentralAuthenticationService.class);\n+            boolean associated = false;\n+            boolean associationValid = true;\n+            try {\n+                final AuthRequest authReq = AuthRequest.createAuthRequest(requestParameters, manager.getRealmVerifier());\n+                final Map parameterMap = authReq.getParameterMap();\n+                if (parameterMap != null && parameterMap.size() > 0) {\n+                    final String assocHandle = (String) parameterMap.get(\"openid.assoc_handle\");\n+                    if (assocHandle != null) {\n+                        final Association association = manager.getSharedAssociations().load(assocHandle);\n+                        if (association != null) {\n+                            associated = true;\n+                            if (association.hasExpired()) {\n+                                associationValid = false;\n+                            }\n+                        }\n+\n+                    }\n+                }\n+            } catch (final MessageException me) {\n+                LOGGER.error(\"Message exception : {}\", me.getMessage(), me);\n+            }\n+\n+            boolean successFullAuthentication = true;\n+            Assertion assertion = null;\n+            try {\n+                if (associated) {\n+                    if (associationValid) {\n+                        assertion = cas.validateServiceTicket(ticketId, this);\n+                        LOGGER.info(\"Validated openid ticket\");\n+                    } else {\n+                        successFullAuthentication = false;\n+                    }\n+                }\n+            } catch (final TicketException te) {\n+                LOGGER.error(\"Could not validate ticket : {}\", te.getMessage(), te);\n+                successFullAuthentication = false;\n+            }\n+\n+            final String id;","path":"cas-server-support-openid/src/main/java/org/jasig/cas/support/openid/authentication/principal/OpenIdService.java","position":362,"original_position":362,"commit_id":"7e801e23f0139a76b7241f475747d8ac98e71a40","original_commit_id":"7e801e23f0139a76b7241f475747d8ac98e71a40","user":{"login":"leleuj","id":1038508,"avatar_url":"https://avatars.githubusercontent.com/u/1038508?v=3","gravatar_id":"","url":"https://api.github.com/users/leleuj","html_url":"https://github.com/leleuj","followers_url":"https://api.github.com/users/leleuj/followers","following_url":"https://api.github.com/users/leleuj/following{/other_user}","gists_url":"https://api.github.com/users/leleuj/gists{/gist_id}","starred_url":"https://api.github.com/users/leleuj/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/leleuj/subscriptions","organizations_url":"https://api.github.com/users/leleuj/orgs","repos_url":"https://api.github.com/users/leleuj/repos","events_url":"https://api.github.com/users/leleuj/events{/privacy}","received_events_url":"https://api.github.com/users/leleuj/received_events","type":"User","site_admin":false},"body":"Here is the change: if the `openid.identifier` is to be defined, we use the principal found in the assertion.","created_at":"2015-08-17T13:07:26Z","updated_at":"2015-08-17T13:07:26Z","html_url":"https://github.com/Jasig/cas/pull/1093#discussion_r37185184","pull_request_url":"https://api.github.com/repos/Jasig/cas/pulls/1093","_links":{"self":{"href":"https://api.github.com/repos/Jasig/cas/pulls/comments/37185184"},"html":{"href":"https://github.com/Jasig/cas/pull/1093#discussion_r37185184"},"pull_request":{"href":"https://api.github.com/repos/Jasig/cas/pulls/1093"}}},"pull_request":{"url":"https://api.github.com/repos/Jasig/cas/pulls/1093","id":42585512,"html_url":"https://github.com/Jasig/cas/pull/1093","diff_url":"https://github.com/Jasig/cas/pull/1093.diff","patch_url":"https://github.com/Jasig/cas/pull/1093.patch","issue_url":"https://api.github.com/repos/Jasig/cas/issues/1093","number":1093,"state":"open","locked":false,"title":"Support openid.identity=http://specs.openid.net/auth/2.0/identifier_select","user":{"login":"leleuj","id":1038508,"avatar_url":"https://avatars.githubusercontent.com/u/1038508?v=3","gravatar_id":"","url":"https://api.github.com/users/leleuj","html_url":"https://github.com/leleuj","followers_url":"https://api.github.com/users/leleuj/followers","following_url":"https://api.github.com/users/leleuj/following{/other_user}","gists_url":"https://api.github.com/users/leleuj/gists{/gist_id}","starred_url":"https://api.github.com/users/leleuj/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/leleuj/subscriptions","organizations_url":"https://api.github.com/users/leleuj/orgs","repos_url":"https://api.github.com/users/leleuj/repos","events_url":"https://api.github.com/users/leleuj/events{/privacy}","received_events_url":"https://api.github.com/users/leleuj/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-08-17T13:05:22Z","updated_at":"2015-08-17T13:07:26Z","closed_at":null,"merged_at":null,"merge_commit_sha":"038b8474e7d196b0f50af4cd9be05690abdd470a","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/Jasig/cas/pulls/1093/commits","review_comments_url":"https://api.github.com/repos/Jasig/cas/pulls/1093/comments","review_comment_url":"https://api.github.com/repos/Jasig/cas/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Jasig/cas/issues/1093/comments","statuses_url":"https://api.github.com/repos/Jasig/cas/statuses/7e801e23f0139a76b7241f475747d8ac98e71a40","head":{"label":"leleuj:cas-930","ref":"cas-930","sha":"7e801e23f0139a76b7241f475747d8ac98e71a40","user":{"login":"leleuj","id":1038508,"avatar_url":"https://avatars.githubusercontent.com/u/1038508?v=3","gravatar_id":"","url":"https://api.github.com/users/leleuj","html_url":"https://github.com/leleuj","followers_url":"https://api.github.com/users/leleuj/followers","following_url":"https://api.github.com/users/leleuj/following{/other_user}","gists_url":"https://api.github.com/users/leleuj/gists{/gist_id}","starred_url":"https://api.github.com/users/leleuj/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/leleuj/subscriptions","organizations_url":"https://api.github.com/users/leleuj/orgs","repos_url":"https://api.github.com/users/leleuj/repos","events_url":"https://api.github.com/users/leleuj/events{/privacy}","received_events_url":"https://api.github.com/users/leleuj/received_events","type":"User","site_admin":false},"repo":{"id":2370939,"name":"cas","full_name":"leleuj/cas","owner":{"login":"leleuj","id":1038508,"avatar_url":"https://avatars.githubusercontent.com/u/1038508?v=3","gravatar_id":"","url":"https://api.github.com/users/leleuj","html_url":"https://github.com/leleuj","followers_url":"https://api.github.com/users/leleuj/followers","following_url":"https://api.github.com/users/leleuj/following{/other_user}","gists_url":"https://api.github.com/users/leleuj/gists{/gist_id}","starred_url":"https://api.github.com/users/leleuj/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/leleuj/subscriptions","organizations_url":"https://api.github.com/users/leleuj/orgs","repos_url":"https://api.github.com/users/leleuj/repos","events_url":"https://api.github.com/users/leleuj/events{/privacy}","received_events_url":"https://api.github.com/users/leleuj/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/leleuj/cas","description":"Jasig CAS - Single Sign On for the Web","fork":true,"url":"https://api.github.com/repos/leleuj/cas","forks_url":"https://api.github.com/repos/leleuj/cas/forks","keys_url":"https://api.github.com/repos/leleuj/cas/keys{/key_id}","collaborators_url":"https://api.github.com/repos/leleuj/cas/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/leleuj/cas/teams","hooks_url":"https://api.github.com/repos/leleuj/cas/hooks","issue_events_url":"https://api.github.com/repos/leleuj/cas/issues/events{/number}","events_url":"https://api.github.com/repos/leleuj/cas/events","assignees_url":"https://api.github.com/repos/leleuj/cas/assignees{/user}","branches_url":"https://api.github.com/repos/leleuj/cas/branches{/branch}","tags_url":"https://api.github.com/repos/leleuj/cas/tags","blobs_url":"https://api.github.com/repos/leleuj/cas/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/leleuj/cas/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/leleuj/cas/git/refs{/sha}","trees_url":"https://api.github.com/repos/leleuj/cas/git/trees{/sha}","statuses_url":"https://api.github.com/repos/leleuj/cas/statuses/{sha}","languages_url":"https://api.github.com/repos/leleuj/cas/languages","stargazers_url":"https://api.github.com/repos/leleuj/cas/stargazers","contributors_url":"https://api.github.com/repos/leleuj/cas/contributors","subscribers_url":"https://api.github.com/repos/leleuj/cas/subscribers","subscription_url":"https://api.github.com/repos/leleuj/cas/subscription","commits_url":"https://api.github.com/repos/leleuj/cas/commits{/sha}","git_commits_url":"https://api.github.com/repos/leleuj/cas/git/commits{/sha}","comments_url":"https://api.github.com/repos/leleuj/cas/comments{/number}","issue_comment_url":"https://api.github.com/repos/leleuj/cas/issues/comments{/number}","contents_url":"https://api.github.com/repos/leleuj/cas/contents/{+path}","compare_url":"https://api.github.com/repos/leleuj/cas/compare/{base}...{head}","merges_url":"https://api.github.com/repos/leleuj/cas/merges","archive_url":"https://api.github.com/repos/leleuj/cas/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/leleuj/cas/downloads","issues_url":"https://api.github.com/repos/leleuj/cas/issues{/number}","pulls_url":"https://api.github.com/repos/leleuj/cas/pulls{/number}","milestones_url":"https://api.github.com/repos/leleuj/cas/milestones{/number}","notifications_url":"https://api.github.com/repos/leleuj/cas/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/leleuj/cas/labels{/name}","releases_url":"https://api.github.com/repos/leleuj/cas/releases{/id}","created_at":"2011-09-12T12:30:36Z","updated_at":"2014-11-17T15:34:37Z","pushed_at":"2015-08-17T13:04:44Z","git_url":"git://github.com/leleuj/cas.git","ssh_url":"git@github.com:leleuj/cas.git","clone_url":"https://github.com/leleuj/cas.git","svn_url":"https://github.com/leleuj/cas","homepage":"http://www.jasig.org/cas","size":36403,"stargazers_count":2,"watchers_count":2,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":2,"default_branch":"master"}},"base":{"label":"Jasig:master","ref":"master","sha":"a24c7aef825f586963f86aa08b73a47ec5eb260a","user":{"login":"Jasig","id":884285,"avatar_url":"https://avatars.githubusercontent.com/u/884285?v=3","gravatar_id":"","url":"https://api.github.com/users/Jasig","html_url":"https://github.com/Jasig","followers_url":"https://api.github.com/users/Jasig/followers","following_url":"https://api.github.com/users/Jasig/following{/other_user}","gists_url":"https://api.github.com/users/Jasig/gists{/gist_id}","starred_url":"https://api.github.com/users/Jasig/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Jasig/subscriptions","organizations_url":"https://api.github.com/users/Jasig/orgs","repos_url":"https://api.github.com/users/Jasig/repos","events_url":"https://api.github.com/users/Jasig/events{/privacy}","received_events_url":"https://api.github.com/users/Jasig/received_events","type":"Organization","site_admin":false},"repo":{"id":2352744,"name":"cas","full_name":"Jasig/cas","owner":{"login":"Jasig","id":884285,"avatar_url":"https://avatars.githubusercontent.com/u/884285?v=3","gravatar_id":"","url":"https://api.github.com/users/Jasig","html_url":"https://github.com/Jasig","followers_url":"https://api.github.com/users/Jasig/followers","following_url":"https://api.github.com/users/Jasig/following{/other_user}","gists_url":"https://api.github.com/users/Jasig/gists{/gist_id}","starred_url":"https://api.github.com/users/Jasig/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Jasig/subscriptions","organizations_url":"https://api.github.com/users/Jasig/orgs","repos_url":"https://api.github.com/users/Jasig/repos","events_url":"https://api.github.com/users/Jasig/events{/privacy}","received_events_url":"https://api.github.com/users/Jasig/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Jasig/cas","description":"Apereo CAS - Single Sign On for the Web","fork":false,"url":"https://api.github.com/repos/Jasig/cas","forks_url":"https://api.github.com/repos/Jasig/cas/forks","keys_url":"https://api.github.com/repos/Jasig/cas/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Jasig/cas/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Jasig/cas/teams","hooks_url":"https://api.github.com/repos/Jasig/cas/hooks","issue_events_url":"https://api.github.com/repos/Jasig/cas/issues/events{/number}","events_url":"https://api.github.com/repos/Jasig/cas/events","assignees_url":"https://api.github.com/repos/Jasig/cas/assignees{/user}","branches_url":"https://api.github.com/repos/Jasig/cas/branches{/branch}","tags_url":"https://api.github.com/repos/Jasig/cas/tags","blobs_url":"https://api.github.com/repos/Jasig/cas/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Jasig/cas/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Jasig/cas/git/refs{/sha}","trees_url":"https://api.github.com/repos/Jasig/cas/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Jasig/cas/statuses/{sha}","languages_url":"https://api.github.com/repos/Jasig/cas/languages","stargazers_url":"https://api.github.com/repos/Jasig/cas/stargazers","contributors_url":"https://api.github.com/repos/Jasig/cas/contributors","subscribers_url":"https://api.github.com/repos/Jasig/cas/subscribers","subscription_url":"https://api.github.com/repos/Jasig/cas/subscription","commits_url":"https://api.github.com/repos/Jasig/cas/commits{/sha}","git_commits_url":"https://api.github.com/repos/Jasig/cas/git/commits{/sha}","comments_url":"https://api.github.com/repos/Jasig/cas/comments{/number}","issue_comment_url":"https://api.github.com/repos/Jasig/cas/issues/comments{/number}","contents_url":"https://api.github.com/repos/Jasig/cas/contents/{+path}","compare_url":"https://api.github.com/repos/Jasig/cas/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Jasig/cas/merges","archive_url":"https://api.github.com/repos/Jasig/cas/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Jasig/cas/downloads","issues_url":"https://api.github.com/repos/Jasig/cas/issues{/number}","pulls_url":"https://api.github.com/repos/Jasig/cas/pulls{/number}","milestones_url":"https://api.github.com/repos/Jasig/cas/milestones{/number}","notifications_url":"https://api.github.com/repos/Jasig/cas/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Jasig/cas/labels{/name}","releases_url":"https://api.github.com/repos/Jasig/cas/releases{/id}","created_at":"2011-09-09T01:36:42Z","updated_at":"2015-08-17T07:39:28Z","pushed_at":"2015-08-17T13:05:22Z","git_url":"git://github.com/Jasig/cas.git","ssh_url":"git@github.com:Jasig/cas.git","clone_url":"https://github.com/Jasig/cas.git","svn_url":"https://github.com/Jasig/cas","homepage":"http://jasig.github.io/cas/","size":541429,"stargazers_count":813,"watchers_count":813,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":621,"mirror_url":null,"open_issues_count":68,"forks":621,"open_issues":68,"watchers":813,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Jasig/cas/pulls/1093"},"html":{"href":"https://github.com/Jasig/cas/pull/1093"},"issue":{"href":"https://api.github.com/repos/Jasig/cas/issues/1093"},"comments":{"href":"https://api.github.com/repos/Jasig/cas/issues/1093/comments"},"review_comments":{"href":"https://api.github.com/repos/Jasig/cas/pulls/1093/comments"},"review_comment":{"href":"https://api.github.com/repos/Jasig/cas/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Jasig/cas/pulls/1093/commits"},"statuses":{"href":"https://api.github.com/repos/Jasig/cas/statuses/7e801e23f0139a76b7241f475747d8ac98e71a40"}}}}