keycloak-aplcache

finish protocol refactoring

10/1/2014 3:19:59 PM

Details

diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OpenIDConnectService.java b/services/src/main/java/org/keycloak/protocol/oidc/OpenIDConnectService.java
index 674f594..71d7b19 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/OpenIDConnectService.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/OpenIDConnectService.java
@@ -631,7 +631,6 @@ public class OpenIDConnectService {
      *
      */
     private class FrontPageInitializer {
-        protected String code;
         protected String clientId;
         protected String redirect;
         protected String state;
@@ -642,11 +641,7 @@ public class OpenIDConnectService {
         protected ClientSessionModel clientSession;
 
         public Response processInput() {
-            if (code != null) {
-                event.detail(Details.CODE_ID, code);
-            } else {
-                event.client(clientId).detail(Details.REDIRECT_URI, redirect).detail(Details.RESPONSE_TYPE, "code");
-            }
+            event.client(clientId).detail(Details.REDIRECT_URI, redirect).detail(Details.RESPONSE_TYPE, "code");
             if (!checkSsl()) {
                 event.error(Errors.SSL_REQUIRED);
                 return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required");
@@ -657,65 +652,43 @@ public class OpenIDConnectService {
             }
 
             clientSession = null;
-            if (code != null) {
-                ClientSessionCode clientCode = ClientSessionCode.parse(code, session, realm);
-                if (clientCode == null) {
-                    event.error(Errors.INVALID_CODE);
-                    return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown code, please login again through your application.");
-                }
-                if (!clientCode.isValid(ClientSessionModel.Action.AUTHENTICATE)) {
-                    event.error(Errors.INVALID_CODE);
-                    return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid code, please login again through your application.");
-                }
-                clientSession = clientCode.getClientSession();
-                if (!clientSession.getAuthMethod().equals(OpenIDConnect.LOGIN_PROTOCOL)) {
-                    event.error(Errors.INVALID_CODE);
-                    return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid protocol, please login again through your application.");
-                }
-                state = clientSession.getNote(OpenIDConnect.STATE_PARAM);
-                scopeParam = clientSession.getNote(OpenIDConnect.SCOPE_PARAM);
-                responseType = clientSession.getNote(OpenIDConnect.RESPONSE_TYPE_PARAM);
-                loginHint = clientSession.getNote(OpenIDConnect.LOGIN_HINT_PARAM);
-                prompt = clientSession.getNote(OpenIDConnect.PROMPT_PARAM);
-            } else {
-                if (state == null) {
-                    event.error(Errors.STATE_PARAM_NOT_FOUND);
-                    return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid state param.");
+            if (state == null) {
+                event.error(Errors.STATE_PARAM_NOT_FOUND);
+                return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid state param.");
 
-                }
-                ClientModel client = realm.findClient(clientId);
-                if (client == null) {
-                    event.error(Errors.CLIENT_NOT_FOUND);
-                    return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown login requester.");
-                }
+            }
+            ClientModel client = realm.findClient(clientId);
+            if (client == null) {
+                event.error(Errors.CLIENT_NOT_FOUND);
+                return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown login requester.");
+            }
 
-                if (!client.isEnabled()) {
-                    event.error(Errors.CLIENT_DISABLED);
-                    return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Login requester not enabled.");
-                }
-                if ((client instanceof ApplicationModel) && ((ApplicationModel)client).isBearerOnly()) {
-                    event.error(Errors.NOT_ALLOWED);
-                    return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Bearer-only applications are not allowed to initiate browser login");
-                }
-                if (client.isDirectGrantsOnly()) {
-                    event.error(Errors.NOT_ALLOWED);
-                    return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "direct-grants-only clients are not allowed to initiate browser login");
-                }
-                redirect = verifyRedirectUri(uriInfo, redirect, realm, client);
-                if (redirect == null) {
-                    event.error(Errors.INVALID_REDIRECT_URI);
-                    return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid redirect_uri.");
-                }
-                clientSession = session.sessions().createClientSession(realm, client);
-                clientSession.setAuthMethod(OpenIDConnect.LOGIN_PROTOCOL);
-                clientSession.setRedirectUri(redirect);
-                clientSession.setAction(ClientSessionModel.Action.AUTHENTICATE);
-                clientSession.setNote(OpenIDConnect.STATE_PARAM, state);
-                if (scopeParam != null) clientSession.setNote(OpenIDConnect.SCOPE_PARAM, scopeParam);
-                if (responseType != null) clientSession.setNote(OpenIDConnect.RESPONSE_TYPE_PARAM, responseType);
-                if (loginHint != null) clientSession.setNote(OpenIDConnect.LOGIN_HINT_PARAM, loginHint);
-                if (prompt != null) clientSession.setNote(OpenIDConnect.PROMPT_PARAM, prompt);
+            if (!client.isEnabled()) {
+                event.error(Errors.CLIENT_DISABLED);
+                return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Login requester not enabled.");
+            }
+            if ((client instanceof ApplicationModel) && ((ApplicationModel)client).isBearerOnly()) {
+                event.error(Errors.NOT_ALLOWED);
+                return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Bearer-only applications are not allowed to initiate browser login");
+            }
+            if (client.isDirectGrantsOnly()) {
+                event.error(Errors.NOT_ALLOWED);
+                return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "direct-grants-only clients are not allowed to initiate browser login");
+            }
+            redirect = verifyRedirectUri(uriInfo, redirect, realm, client);
+            if (redirect == null) {
+                event.error(Errors.INVALID_REDIRECT_URI);
+                return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid redirect_uri.");
             }
+            clientSession = session.sessions().createClientSession(realm, client);
+            clientSession.setAuthMethod(OpenIDConnect.LOGIN_PROTOCOL);
+            clientSession.setRedirectUri(redirect);
+            clientSession.setAction(ClientSessionModel.Action.AUTHENTICATE);
+            clientSession.setNote(OpenIDConnect.STATE_PARAM, state);
+            if (scopeParam != null) clientSession.setNote(OpenIDConnect.SCOPE_PARAM, scopeParam);
+            if (responseType != null) clientSession.setNote(OpenIDConnect.RESPONSE_TYPE_PARAM, responseType);
+            if (loginHint != null) clientSession.setNote(OpenIDConnect.LOGIN_HINT_PARAM, loginHint);
+            if (prompt != null) clientSession.setNote(OpenIDConnect.PROMPT_PARAM, prompt);
             return null;
         }
     }
@@ -726,7 +699,6 @@ public class OpenIDConnectService {
      * @See <a href="http://tools.ietf.org/html/rfc6749#section-4.1">http://tools.ietf.org/html/rfc6749#section-4.1</a>
      *
      *
-     * @param code
      * @param responseType
      * @param redirect
      * @param clientId
@@ -737,8 +709,7 @@ public class OpenIDConnectService {
      */
     @Path("login")
     @GET
-    public Response loginPage(@QueryParam("code") String code,
-                              @QueryParam(OpenIDConnect.RESPONSE_TYPE_PARAM) String responseType,
+    public Response loginPage(@QueryParam(OpenIDConnect.RESPONSE_TYPE_PARAM) String responseType,
                               @QueryParam(OpenIDConnect.REDIRECT_URI_PARAM) String redirect,
                               @QueryParam(OpenIDConnect.CLIENT_ID_PARAM) String clientId,
                               @QueryParam(OpenIDConnect.SCOPE_PARAM) String scopeParam,
@@ -747,7 +718,6 @@ public class OpenIDConnectService {
                               @QueryParam(OpenIDConnect.LOGIN_HINT_PARAM) String loginHint) {
         event.event(EventType.LOGIN);
         FrontPageInitializer pageInitializer = new FrontPageInitializer();
-        pageInitializer.code = code;
         pageInitializer.responseType = responseType;
         pageInitializer.redirect = redirect;
         pageInitializer.clientId = clientId;
@@ -758,14 +728,6 @@ public class OpenIDConnectService {
         Response response = pageInitializer.processInput();
         if (response != null) return response;
         ClientSessionModel clientSession = pageInitializer.clientSession;
-        code = pageInitializer.code;
-        responseType = pageInitializer.responseType;
-        redirect = pageInitializer.redirect;
-        clientId = pageInitializer.clientId ;
-        scopeParam = pageInitializer.scopeParam;
-        state = pageInitializer.state;
-        prompt = pageInitializer.prompt;
-        loginHint = pageInitializer.loginHint;
 
 
 
@@ -822,8 +784,7 @@ public class OpenIDConnectService {
      */
     @Path("registrations")
     @GET
-    public Response registerPage(@QueryParam("code") String code,
-                                 @QueryParam(OpenIDConnect.RESPONSE_TYPE_PARAM) String responseType,
+    public Response registerPage(@QueryParam(OpenIDConnect.RESPONSE_TYPE_PARAM) String responseType,
                                  @QueryParam(OpenIDConnect.REDIRECT_URI_PARAM) String redirect,
                                  @QueryParam(OpenIDConnect.CLIENT_ID_PARAM) String clientId,
                                  @QueryParam(OpenIDConnect.SCOPE_PARAM) String scopeParam,
@@ -835,7 +796,6 @@ public class OpenIDConnectService {
         }
 
         FrontPageInitializer pageInitializer = new FrontPageInitializer();
-        pageInitializer.code = code;
         pageInitializer.responseType = responseType;
         pageInitializer.redirect = redirect;
         pageInitializer.clientId = clientId;
diff --git a/services/src/main/java/org/keycloak/services/resources/AccountService.java b/services/src/main/java/org/keycloak/services/resources/AccountService.java
index 99550a3..3b3e3cf 100755
--- a/services/src/main/java/org/keycloak/services/resources/AccountService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java
@@ -742,7 +742,7 @@ public class AccountService {
 
     private Response login(String path) {
         OAuthRedirect oauth = new OAuthRedirect();
-        String authUrl = Urls.realmLoginPage(uriInfo.getBaseUri(), realm.getName()).toString();
+        String authUrl = OpenIDConnectService.loginPageUrl(uriInfo).build(realm.getName()).toString();
         oauth.setAuthUrl(authUrl);
 
         oauth.setClientId(Constants.ACCOUNT_MANAGEMENT_APP);
diff --git a/services/src/main/java/org/keycloak/services/resources/flows/Urls.java b/services/src/main/java/org/keycloak/services/resources/flows/Urls.java
index af0efa4..2e4148e 100755
--- a/services/src/main/java/org/keycloak/services/resources/flows/Urls.java
+++ b/services/src/main/java/org/keycloak/services/resources/flows/Urls.java
@@ -138,10 +138,10 @@ public class Urls {
     }
 
     public static URI realmLoginPage(URI baseUri, String realmId) {
-        return tokenBase(baseUri).path(OpenIDConnectService.class, "loginPage").build(realmId);
+        return requiredActionsBase(baseUri).path(LoginActionsService.class, "loginPage").build(realmId);
     }
 
-    public static UriBuilder realmLogout(URI baseUri) {
+    private static UriBuilder realmLogout(URI baseUri) {
         return tokenBase(baseUri).path(OpenIDConnectService.class, "logout");
     }
 
@@ -150,7 +150,7 @@ public class Urls {
     }
 
     public static URI realmRegisterPage(URI baseUri, String realmId) {
-        return tokenBase(baseUri).path(OpenIDConnectService.class, "registerPage").build(realmId);
+        return requiredActionsBase(baseUri).path(LoginActionsService.class, "registerPage").build(realmId);
     }
 
     public static URI realmInstalledAppUrnCallback(URI baseUri, String realmId) {
@@ -161,10 +161,6 @@ public class Urls {
         return requiredActionsBase(baseUri).path(LoginActionsService.class, "processConsent").build(realmId);
     }
 
-    public static URI realmCode(URI baseUri, String realmId) {
-        return tokenBase(baseUri).path(OpenIDConnectService.class, "accessCodeToToken").build(realmId);
-    }
-
     public static UriBuilder socialBase(URI baseUri) {
         return UriBuilder.fromUri(baseUri).path(SocialResource.class);
     }
diff --git a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
index 3a0e6d6..c6bcc8c 100755
--- a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
+++ b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
@@ -22,6 +22,7 @@
 package org.keycloak.services.resources;
 
 import org.jboss.logging.Logger;
+import org.jboss.resteasy.specimpl.MultivaluedMapImpl;
 import org.jboss.resteasy.spi.HttpRequest;
 import org.keycloak.ClientConnection;
 import org.keycloak.email.EmailException;
@@ -44,6 +45,7 @@ import org.keycloak.models.UserSessionModel;
 import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.models.utils.TimeBasedOTP;
 import org.keycloak.protocol.LoginProtocol;
+import org.keycloak.protocol.oidc.OpenIDConnect;
 import org.keycloak.protocol.oidc.OpenIDConnectService;
 import org.keycloak.protocol.oidc.TokenManager;
 import org.keycloak.representations.PasswordToken;
@@ -61,6 +63,7 @@ import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Cookie;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedMap;
@@ -153,6 +156,15 @@ public class LoginActionsService {
         Response response;
 
         boolean check(String code, ClientSessionModel.Action requiredAction) {
+            if (!check(code)) return false;
+            if (!clientCode.isValid(requiredAction)) {
+                event.error(Errors.INVALID_CODE);
+                response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid code, please login again through your application.");
+            }
+            return true;
+        }
+
+        public boolean check(String code) {
             if (!checkSsl()) {
                 event.error(Errors.SSL_REQUIRED);
                 response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required");
@@ -169,15 +181,69 @@ public class LoginActionsService {
                 response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown code, please login again through your application.");
                 return false;
             }
-            if (!clientCode.isValid(requiredAction)) {
-                event.error(Errors.INVALID_CODE);
-                response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid code, please login again through your application.");
-            }
             return true;
         }
     }
 
     /**
+     * protocol independent login page entry point
+     *
+     *
+     * @param code
+     * @return
+     */
+    @Path("login")
+    @GET
+    public Response loginPage(@QueryParam("code") String code) {
+        event.event(EventType.LOGIN);
+        Checks checks = new Checks();
+        if (!checks.check(code)) {
+            return checks.response;
+        }
+        event.detail(Details.CODE_ID, code);
+        ClientSessionCode clientSessionCode = checks.clientCode;
+        ClientSessionModel clientSession = clientSessionCode.getClientSession();
+
+
+
+        LoginFormsProvider forms = Flows.forms(session, realm, clientSession.getClient(), uriInfo)
+                .setClientSessionCode(clientSessionCode.getCode());
+
+        return forms.createLogin();
+    }
+
+    /**
+     * protocol independent registration page entry point
+     *
+     * @param code
+     * @return
+     */
+    @Path("registration")
+    @GET
+    public Response registerPage(@QueryParam("code") String code) {
+        event.event(EventType.REGISTER);
+        if (!realm.isRegistrationAllowed()) {
+            event.error(Errors.REGISTRATION_DISABLED);
+            return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Registration not allowed");
+        }
+
+        Checks checks = new Checks();
+        if (!checks.check(code)) {
+            return checks.response;
+        }
+        event.detail(Details.CODE_ID, code);
+        ClientSessionCode clientSessionCode = checks.clientCode;
+        ClientSessionModel clientSession = clientSessionCode.getClientSession();
+
+
+        authManager.expireIdentityCookie(realm, uriInfo, clientConnection);
+
+        return Flows.forms(session, realm, clientSession.getClient(), uriInfo)
+                .setClientSessionCode(clientSessionCode.getCode())
+                .createRegistration();
+    }
+
+    /**
      * URL called after login page.  YOU SHOULD NEVER INVOKE THIS DIRECTLY!
      *
      * @param code
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
index 8ee9330..4fe0131 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
@@ -25,6 +25,7 @@ import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.ClassRule;
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.keycloak.events.Details;
@@ -156,12 +157,12 @@ public class AccountTest {
         });
     }
 
-//    @Test
-//    @Ignore
-//    public void runit() throws Exception {
-//        Thread.sleep(10000000);
-//
-//    }
+    @Test
+    @Ignore
+    public void runit() throws Exception {
+        Thread.sleep(10000000);
+
+    }