keycloak-memoizeit

Merge pull request #3024 from stianst/KEYCLOAK-3267 KEYCLOAK-3267

7/13/2016 2:37:52 AM

Details

diff --git a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
index 1c6f23d..c7cbc62 100755
--- a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
+++ b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
@@ -55,6 +55,7 @@ import org.keycloak.provider.ProviderFactory;
 import org.keycloak.representations.AccessToken;
 import org.keycloak.services.managers.AppAuthManager;
 import org.keycloak.services.managers.AuthenticationManager.AuthResult;
+import org.keycloak.services.managers.BruteForceProtector;
 import org.keycloak.services.managers.ClientSessionCode;
 import org.keycloak.services.messages.Messages;
 import org.keycloak.services.ErrorResponse;
@@ -338,8 +339,10 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
             return ErrorPage.error(session, Messages.ACCOUNT_DISABLED);
         }
         if (realm.isBruteForceProtected()) {
-            event.error(Errors.USER_TEMPORARILY_DISABLED);
-            return ErrorPage.error(session, Messages.ACCOUNT_DISABLED);
+            if (session.getProvider(BruteForceProtector.class).isTemporarilyDisabled(session, realm, user)) {
+                event.error(Errors.USER_TEMPORARILY_DISABLED);
+                return ErrorPage.error(session, Messages.ACCOUNT_DISABLED);
+            }
         }
         return null;
     }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBrokerTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBrokerTest.java
index aa44d85..a2a16b4 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBrokerTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBrokerTest.java
@@ -9,15 +9,21 @@ import org.keycloak.representations.idm.ClientRepresentation;
 import org.keycloak.representations.idm.IdentityProviderRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
+import org.keycloak.services.messages.Messages;
 import org.keycloak.testsuite.AbstractKeycloakTest;
 import org.keycloak.testsuite.Assert;
+import org.keycloak.testsuite.pages.AccountPasswordPage;
+import org.keycloak.testsuite.pages.ErrorPage;
 import org.keycloak.testsuite.pages.LoginPage;
 import org.keycloak.testsuite.pages.UpdateAccountInformationPage;
+import org.keycloak.testsuite.util.RealmBuilder;
 
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
 import java.util.List;
 
+import static org.jgroups.util.Util.assertTrue;
+import static org.junit.Assert.assertEquals;
 import static org.keycloak.testsuite.admin.ApiUtil.createUserWithAdminClient;
 import static org.keycloak.testsuite.admin.ApiUtil.resetUserPassword;
 
@@ -42,9 +48,16 @@ public abstract class AbstractBrokerTest extends AbstractKeycloakTest {
 
     @Page
     protected LoginPage accountLoginPage;
+
     @Page
     protected UpdateAccountInformationPage updateAccountInformationPage;
 
+    @Page
+    protected AccountPasswordPage accountPasswordPage;
+
+    @Page
+    protected ErrorPage errorPage;
+
     @Override
     public void addTestRealms(List<RealmRepresentation> testRealms) {
         RealmRepresentation providerRealm = createProviderRealm();
@@ -171,6 +184,60 @@ public abstract class AbstractBrokerTest extends AbstractKeycloakTest {
         testSingleLogout();
     }
 
+    @Test
+    public void loginWithExistingUser() {
+        logInAsUserInIDP();
+
+        Integer userCount = adminClient.realm(consumerRealmName()).users().count();
+
+        driver.navigate().to(getAccountUrl(consumerRealmName()));
+
+        log.debug("Clicking social " + getIDPAlias());
+        accountLoginPage.clickSocial(getIDPAlias());
+
+        Assert.assertTrue("Driver should be on the provider realm page right now", driver.getCurrentUrl().contains("/auth/realms/" + providerRealmName() + "/"));
+
+        accountLoginPage.login(getUserLogin(), getUserPassword());
+
+        System.out.println(driver.getPageSource());
+        assertEquals(accountPage.buildUri().toASCIIString().replace("master", "consumer") + "/", driver.getCurrentUrl());
+
+        assertEquals(userCount, adminClient.realm(consumerRealmName()).users().count());
+    }
+
+    // KEYCLOAK-3267
+    @Test
+    public void loginWithExistingUserWithBruteForceEnabled() {
+        adminClient.realm(consumerRealmName()).update(RealmBuilder.create().bruteForceProtected(true).failureFactor(2).build());
+
+        loginWithExistingUser();
+
+        driver.navigate().to(getAccountPasswordUrl(consumerRealmName()));
+
+        accountPasswordPage.changePassword("password", "password");
+
+        driver.navigate().to(getAuthRoot()
+                + "/auth/realms/" + providerRealmName()
+                + "/protocol/" + "openid-connect"
+                + "/logout");
+
+        driver.navigate().to(getAccountUrl(consumerRealmName()));
+
+        accountLoginPage.login(getUserLogin(), "invalid");
+        accountLoginPage.login(getUserLogin(), "invalid");
+        accountLoginPage.login(getUserLogin(), "invalid");
+
+        assertEquals("Invalid username or password.", accountLoginPage.getError());
+
+        accountLoginPage.clickSocial(getIDPAlias());
+
+        Assert.assertTrue("Driver should be on the provider realm page right now", driver.getCurrentUrl().contains("/auth/realms/" + providerRealmName() + "/"));
+
+        accountLoginPage.login(getUserLogin(), getUserPassword());
+
+        assertEquals("Account is disabled, contact admin.", errorPage.getError());
+    }
+
     protected void testSingleLogout() {
         log.debug("Testing single log out");
 
@@ -203,4 +270,8 @@ public abstract class AbstractBrokerTest extends AbstractKeycloakTest {
     private String getAccountUrl(String realmName) {
         return getAuthRoot() + "/auth/realms/" + realmName + "/account";
     }
+
+    private String getAccountPasswordUrl(String realmName) {
+        return getAuthRoot() + "/auth/realms/" + realmName + "/account/password";
+    }
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RealmBuilder.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RealmBuilder.java
index fe46b58..23b100e 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RealmBuilder.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RealmBuilder.java
@@ -137,6 +137,16 @@ public class RealmBuilder {
         return this;
     }
 
+    public RealmBuilder bruteForceProtected(boolean bruteForceProtected) {
+        rep.setBruteForceProtected(bruteForceProtected);
+        return this;
+    }
+
+    public RealmBuilder failureFactor(int failureFactor) {
+        rep.setFailureFactor(failureFactor);
+        return this;
+    }
+
     public RealmBuilder otpDigits(int i) {
         rep.setOtpPolicyDigits(i);
         return this;