keycloak-aplcache

passing tests

6/5/2015 2:49:24 PM

Details

diff --git a/model/api/src/main/java/org/keycloak/models/AuthenticationExecutionModel.java b/model/api/src/main/java/org/keycloak/models/AuthenticationExecutionModel.java
index 79a2b67..12cb4fd 100755
--- a/model/api/src/main/java/org/keycloak/models/AuthenticationExecutionModel.java
+++ b/model/api/src/main/java/org/keycloak/models/AuthenticationExecutionModel.java
@@ -1,10 +1,20 @@
 package org.keycloak.models;
 
+import java.util.Comparator;
+
 /**
 * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
 * @version $Revision: 1 $
 */
 public class AuthenticationExecutionModel {
+    public static class ExecutionComparator implements Comparator<AuthenticationExecutionModel> {
+        public static final ExecutionComparator SINGLETON = new ExecutionComparator();
+
+        @Override
+        public int compare(AuthenticationExecutionModel o1, AuthenticationExecutionModel o2) {
+            return o1.priority - o2.priority;
+        }
+    }
 
     private String id;
     private String authenticator;
diff --git a/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java b/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java
index bf97994..2bc6e61 100755
--- a/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java
+++ b/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java
@@ -20,6 +20,7 @@ import org.keycloak.services.managers.BruteForceProtector;
 
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -332,6 +333,7 @@ public class AuthenticationProcessor {
     }
 
     public Response authenticate() throws AuthException {
+        logger.info("AUTHENTICATE");
         event.event(EventType.LOGIN);
         event.client(clientSession.getClient().getClientId())
                 .detail(Details.REDIRECT_URI, clientSession.getRedirectUri())
@@ -381,7 +383,7 @@ public class AuthenticationProcessor {
     public Response finishAuthentication() {
         event.success();
         RealmModel realm = clientSession.getRealm();
-        return AuthenticationManager.redirectAfterSuccessfulFlow(session, realm , userSession, clientSession, request, uriInfo, connection);
+        return AuthenticationManager.redirectAfterSuccessfulFlow(session, realm, userSession, clientSession, request, uriInfo, connection);
 
     }
 
@@ -393,11 +395,13 @@ public class AuthenticationProcessor {
         }
         List<AuthenticationExecutionModel> executions = realm.getAuthenticationExecutions(flowId);
         if (executions == null) return null;
+        Collections.sort(executions, AuthenticationExecutionModel.ExecutionComparator.SINGLETON);
         Response alternativeChallenge = null;
         AuthenticationExecutionModel challengedAlternativeExecution = null;
         boolean alternativeSuccessful = false;
         for (AuthenticationExecutionModel model : executions) {
             if (isProcessed(model)) {
+                logger.info("execution is processed");
                 if (!alternativeSuccessful && model.isAlternative() && isSuccessful(model)) alternativeSuccessful = true;
                 continue;
             }
@@ -421,6 +425,7 @@ public class AuthenticationProcessor {
             AuthenticatorModel authenticatorModel = realm.getAuthenticatorById(model.getAuthenticator());
             AuthenticatorFactory factory = (AuthenticatorFactory)session.getKeycloakSessionFactory().getProviderFactory(Authenticator.class, authenticatorModel.getProviderId());
             Authenticator authenticator = factory.create(authenticatorModel);
+            logger.info("authenticator: " + authenticatorModel.getProviderId());
             UserModel authUser = clientSession.getAuthenticatedUser();
 
             if (authenticator.requiresUser() && authUser == null){
@@ -428,7 +433,7 @@ public class AuthenticationProcessor {
                     clientSession.setAuthenticatorStatus(challengedAlternativeExecution.getId(), UserSessionModel.AuthenticatorStatus.CHALLENGED);
                     return alternativeChallenge;
                 }
-                throw new AuthException(Error.UNKNOWN_USER);
+                throw new AuthException("authenticator: " + authenticatorModel.getProviderId(), Error.UNKNOWN_USER);
             }
             boolean configuredFor = false;
             if (authenticator.requiresUser() && authUser != null) {
@@ -436,6 +441,7 @@ public class AuthenticationProcessor {
                 if (!configuredFor) {
                     if (model.isRequired()) {
                         if (model.isUserSetupAllowed()) {
+                            logger.info("authenticator SETUP_REQUIRED: " + authenticatorModel.getProviderId());
                             clientSession.setAuthenticatorStatus(model.getId(), UserSessionModel.AuthenticatorStatus.SETUP_REQUIRED);
                             String requiredAction = authenticator.getRequiredAction();
                             if (!authUser.getRequiredActions().contains(requiredAction)) {
@@ -455,15 +461,18 @@ public class AuthenticationProcessor {
             authenticator.authenticate(context);
             Status result = context.getStatus();
             if (result == Status.SUCCESS){
+                logger.info("authenticator SUCCESS: " + authenticatorModel.getProviderId());
                 clientSession.setAuthenticatorStatus(model.getId(), UserSessionModel.AuthenticatorStatus.SUCCESS);
                 if (model.isAlternative()) alternativeSuccessful = true;
                 continue;
             } else if (result == Status.FAILED) {
+                logger.info("authenticator FAILED: " + authenticatorModel.getProviderId());
                 logUserFailure();
                 clientSession.setAuthenticatorStatus(model.getId(), UserSessionModel.AuthenticatorStatus.FAILED);
                 if (context.challenge != null) return context.challenge;
                 throw new AuthException(context.error);
             } else if (result == Status.CHALLENGE) {
+                logger.info("authenticator CHALLENGE: " + authenticatorModel.getProviderId());
                 if (model.isRequired() || (model.isOptional() && configuredFor)) {
                     clientSession.setAuthenticatorStatus(model.getId(), UserSessionModel.AuthenticatorStatus.CHALLENGED);
                     return context.challenge;
@@ -476,16 +485,19 @@ public class AuthenticationProcessor {
                 }
                 continue;
             } else if (result == Status.FAILURE_CHALLENGE) {
+                logger.info("authenticator FAILURE_CHALLENGE: " + authenticatorModel.getProviderId());
                 logUserFailure();
                 clientSession.setAuthenticatorStatus(model.getId(), UserSessionModel.AuthenticatorStatus.CHALLENGED);
                 return context.challenge;
             } else if (result == Status.ATTEMPTED) {
+                logger.info("authenticator ATTEMPTED: " + authenticatorModel.getProviderId());
                 if (model.getRequirement() == AuthenticationExecutionModel.Requirement.REQUIRED) {
                     throw new AuthException(Error.INVALID_CREDENTIALS);
                 }
                 clientSession.setAuthenticatorStatus(model.getId(), UserSessionModel.AuthenticatorStatus.ATTEMPTED);
                 continue;
             } else {
+                logger.info("authenticator INTERNAL_ERROR: " + authenticatorModel.getProviderId());
                 logger.error("Unknown result status");
                 throw new AuthException(Error.INTERNAL_ERROR);
             }
@@ -508,10 +520,15 @@ public class AuthenticationProcessor {
 
     protected Response authenticationComplete() {
         String username = clientSession.getAuthenticatedUser().getUsername();
+        String rememberMe = clientSession.getNote(Details.REMEMBER_ME);
+        boolean remember = rememberMe != null && rememberMe.equalsIgnoreCase("true");
         if (userSession == null) { // if no authenticator attached a usersession
-            userSession = session.sessions().createUserSession(realm, clientSession.getAuthenticatedUser(), username, connection.getRemoteAddr(), "form", false, null, null);
+            userSession = session.sessions().createUserSession(realm, clientSession.getAuthenticatedUser(), username, connection.getRemoteAddr(), clientSession.getAuthMethod(), remember, null, null);
             userSession.setState(UserSessionModel.State.LOGGING_IN);
         }
+        if (remember) {
+            event.detail(Details.REMEMBER_ME, "true");
+        }
         TokenManager.attachClientSession(userSession, clientSession);
         event.user(userSession.getUser())
              .detail(Details.USERNAME, username)
diff --git a/services/src/main/java/org/keycloak/authentication/Authenticator.java b/services/src/main/java/org/keycloak/authentication/Authenticator.java
index ee9d435..63abd76 100755
--- a/services/src/main/java/org/keycloak/authentication/Authenticator.java
+++ b/services/src/main/java/org/keycloak/authentication/Authenticator.java
@@ -15,5 +15,4 @@ public interface Authenticator extends Provider {
     boolean configuredFor(KeycloakSession session, RealmModel realm, UserModel user);
     String getRequiredAction();
 
-
 }
diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/LoginFormUsernameAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/LoginFormUsernameAuthenticator.java
index 14ae6a1..6550d13 100755
--- a/services/src/main/java/org/keycloak/authentication/authenticators/LoginFormUsernameAuthenticator.java
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/LoginFormUsernameAuthenticator.java
@@ -24,6 +24,7 @@ import javax.ws.rs.core.Response;
  * @version $Revision: 1 $
  */
 public class LoginFormUsernameAuthenticator extends AbstractFormAuthenticator implements Authenticator {
+    public static final String FORM_USERNAME = "FORM_USERNAME";
     protected AuthenticatorModel model;
 
     public LoginFormUsernameAuthenticator(AuthenticatorModel model) {
@@ -35,9 +36,14 @@ public class LoginFormUsernameAuthenticator extends AbstractFormAuthenticator im
         if (!isActionUrl(context)) {
             MultivaluedMap<String, String> formData = new MultivaluedMapImpl<>();
             String loginHint = context.getClientSession().getNote(OIDCLoginProtocol.LOGIN_HINT_PARAM);
-            if (loginHint == null) {
-                loginHint = AuthenticationManager.getRememberMeUsername(context.getRealm(), context.getHttpRequest().getHttpHeaders());
+
+            String rememberMeUsername = AuthenticationManager.getRememberMeUsername(context.getRealm(), context.getHttpRequest().getHttpHeaders());
+
+            if (loginHint != null || rememberMeUsername != null) {
                 if (loginHint != null) {
+                    formData.add(AuthenticationManager.FORM_USERNAME, loginHint);
+                } else {
+                    formData.add(AuthenticationManager.FORM_USERNAME, rememberMeUsername);
                     formData.add("rememberMe", "on");
                 }
             }
@@ -83,9 +89,15 @@ public class LoginFormUsernameAuthenticator extends AbstractFormAuthenticator im
             return;
         }
         context.getEvent().detail(Details.USERNAME, username);
-        context.getClientSession().setNote("FORM_USERNAME", username);
+        context.getClientSession().setNote(FORM_USERNAME, username);
         UserModel user = KeycloakModelUtils.findUserByNameOrEmail(context.getSession(), context.getRealm(), username);
         if (invalidUser(context, user)) return;
+        String rememberMe = inputData.getFirst("rememberMe");
+        boolean remember = rememberMe != null && rememberMe.equalsIgnoreCase("on");
+        if (remember) {
+            context.getClientSession().setNote(Details.REMEMBER_ME, "true");
+            context.getEvent().detail(Details.REMEMBER_ME, "true");
+        }
         context.setUser(user);
         context.success();
     }
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 5bfabae..6585f2d 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
@@ -216,8 +216,9 @@ public class AccountTest {
         changePasswordPage.open();
         loginPage.login("test-user@localhost", "password");
 
-        String sessionId = events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent().getSessionId();
-
+        Event event = events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
+        String sessionId = event.getSessionId();
+        String userId = event.getUserId();
         changePasswordPage.changePassword("", "new-password", "new-password");
 
         Assert.assertEquals("Please specify password.", profilePage.getError());
@@ -241,7 +242,7 @@ public class AccountTest {
 
         Assert.assertEquals("Invalid username or password.", loginPage.getError());
 
-        events.expectLogin().session((String) null).user((String)null).error("invalid_user_credentials").assertEvent();
+        events.expectLogin().session((String) null).user(userId).error("invalid_user_credentials").assertEvent();
 
         loginPage.open();
         loginPage.login("test-user@localhost", "new-password");
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java
index 0d6b4cf..b814f62 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java
@@ -26,11 +26,15 @@ import org.junit.Before;
 import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
+import org.keycloak.authentication.authenticators.OTPFormAuthenticator;
+import org.keycloak.authentication.authenticators.OTPFormAuthenticatorFactory;
 import org.keycloak.events.Details;
 import org.keycloak.events.Event;
 import org.keycloak.events.EventType;
+import org.keycloak.models.AuthenticationExecutionModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
+import org.keycloak.models.utils.DefaultAuthenticationFlows;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.testsuite.AssertEvents;
 import org.keycloak.testsuite.MailUtil;
@@ -46,6 +50,7 @@ import org.keycloak.testsuite.rule.KeycloakRule;
 import org.keycloak.testsuite.rule.KeycloakRule.KeycloakSetup;
 import org.keycloak.testsuite.rule.WebResource;
 import org.keycloak.testsuite.rule.WebRule;
+import org.keycloak.testsuite.utils.CredentialHelper;
 import org.openqa.selenium.WebDriver;
 
 import javax.mail.MessagingException;
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java
index e13fa0e..4a86f78 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java
@@ -144,28 +144,4 @@ public class LoginTotpTest {
 
         events.expectLogin().error("invalid_user_credentials").session((String) null).assertEvent();
     }
-
-    @Test
-    public void loginWithTotpExpiredPasswordToken() throws Exception {
-        try {
-            loginPage.open();
-            loginPage.login("test-user@localhost", "password");
-
-            loginTotpPage.assertCurrent();
-
-            Time.setOffset(350);
-
-            loginTotpPage.login(totp.generate("totpSecret"));
-
-            loginPage.assertCurrent();
-            Assert.assertEquals("Invalid username or password.", loginPage.getError());
-
-            AssertEvents.ExpectedEvent expectedEvent = events.expectLogin().error("invalid_user_credentials")
-                    .session((String) null);
-            expectedEvent.assertEvent();
-        } finally {
-            Time.setOffset(0);
-        }
-    }
-
 }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LogoutTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LogoutTest.java
index 561fcd6..e026c69 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LogoutTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LogoutTest.java
@@ -123,7 +123,7 @@ public class LogoutTest {
 
         // Check session 1 logged-in
         oauth.openLoginForm();
-        events.expectLogin().session(sessionId).detail(Details.AUTH_METHOD, "sso").removeDetail(Details.USERNAME).assertEvent();
+        events.expectLogin().session(sessionId).removeDetail(Details.USERNAME).assertEvent();
 
          //  Logout session 1 by redirect
         driver.navigate().to(oauth.getLogoutUrl(AppPage.baseUrl, null));
@@ -140,7 +140,7 @@ public class LogoutTest {
 
         // Check session 3 logged-in
         oauth.openLoginForm();
-        events.expectLogin().session(sessionId3).detail(Details.AUTH_METHOD, "sso").removeDetail(Details.USERNAME).assertEvent();
+        events.expectLogin().session(sessionId3).removeDetail(Details.USERNAME).assertEvent();
     }
 
 }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/utils/CredentialHelper.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/utils/CredentialHelper.java
index 3018fac..a88d8b1 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/utils/CredentialHelper.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/utils/CredentialHelper.java
@@ -34,6 +34,14 @@ public class CredentialHelper {
         }
     }
 
+    public static AuthenticationExecutionModel.Requirement getRequirement(RealmModel realm, String authenticatorProviderId, String flowAlias) {
+        AuthenticatorModel authenticator = findAuthenticatorByProviderId(realm, authenticatorProviderId);
+        AuthenticationFlowModel flow =  findAuthenticatorFlowByAlias(realm, flowAlias);
+        AuthenticationExecutionModel execution = findExecutionByAuthenticator(realm, flow.getId(), authenticator.getId());
+        return execution.getRequirement();
+
+    }
+
     public static void requireAuthentication(RealmModel realm, String authenticatorProviderId, String flowAlias) {
         AuthenticationExecutionModel.Requirement requirement = AuthenticationExecutionModel.Requirement.REQUIRED;
         authenticationRequirement(realm, authenticatorProviderId, flowAlias, requirement);