keycloak-aplcache
Changes
model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/UsernameLoginFailureEntity.java 2(+1 -1)
model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProvider.java 2(+1 -1)
model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/MemUserSessionProvider.java 5(+3 -2)
Details
diff --git a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/UsernameLoginFailureEntity.java b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/UsernameLoginFailureEntity.java
index 899d80e..c62e474 100755
--- a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/UsernameLoginFailureEntity.java
+++ b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/UsernameLoginFailureEntity.java
@@ -18,7 +18,7 @@ import java.io.Serializable;
@NamedQueries({
@NamedQuery(name="getAllFailures", query="select failure from UsernameLoginFailureEntity failure"),
@NamedQuery(name = "removeLoginFailuresByRealm", query = "delete from UsernameLoginFailureEntity f where f.realmId = :realmId"),
- @NamedQuery(name = "removeLoginFailuresByUser", query = "delete from UsernameLoginFailureEntity f where f.realmId = :realmId and f.username = :username")
+ @NamedQuery(name = "removeLoginFailuresByUser", query = "delete from UsernameLoginFailureEntity f where f.realmId = :realmId and (f.username = :username or f.username = :email)")
})
@IdClass(UsernameLoginFailureEntity.Key.class)
public class UsernameLoginFailureEntity {
diff --git a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProvider.java b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProvider.java
index 92e416b..4c51b96 100644
--- a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProvider.java
+++ b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProvider.java
@@ -243,7 +243,7 @@ public class JpaUserSessionProvider implements UserSessionProvider {
@Override
public void onUserRemoved(RealmModel realm, UserModel user) {
removeUserSessions(realm, user);
- em.createNamedQuery("removeLoginFailuresByUser").setParameter("username", user.getUsername()).executeUpdate();
+ em.createNamedQuery("removeLoginFailuresByUser").setParameter("realmId", realm.getId()).setParameter("username", user.getUsername()).setParameter("email", user.getEmail()).executeUpdate();
}
@Override
diff --git a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/MemUserSessionProvider.java b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/MemUserSessionProvider.java
index 56d4755..6bd79f9 100755
--- a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/MemUserSessionProvider.java
+++ b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/MemUserSessionProvider.java
@@ -207,13 +207,13 @@ public class MemUserSessionProvider implements UserSessionProvider {
@Override
public UsernameLoginFailureModel getUserLoginFailure(RealmModel realm, String username) {
- UsernameLoginFailureEntity entity = loginFailures.get(new UsernameLoginFailureKey(username, realm.getId()));
+ UsernameLoginFailureEntity entity = loginFailures.get(new UsernameLoginFailureKey(realm.getId(), username));
return entity != null ? new UsernameLoginFailureAdapter(entity) : null;
}
@Override
public UsernameLoginFailureModel addUserLoginFailure(RealmModel realm, String username) {
- UsernameLoginFailureKey key = new UsernameLoginFailureKey(username, realm.getId());
+ UsernameLoginFailureKey key = new UsernameLoginFailureKey(realm.getId(), username);
UsernameLoginFailureEntity entity = new UsernameLoginFailureEntity(username, realm.getId());
if (loginFailures.putIfAbsent(key, entity) != null) {
throw new ModelDuplicateException();
@@ -259,6 +259,7 @@ public class MemUserSessionProvider implements UserSessionProvider {
removeUserSessions(realm, user);
loginFailures.remove(new UsernameLoginFailureKey(realm.getId(), user.getUsername()));
+ loginFailures.remove(new UsernameLoginFailureKey(realm.getId(), user.getEmail()));
}
@Override
diff --git a/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/MongoUserSessionProvider.java b/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/MongoUserSessionProvider.java
index 3fdfdba..bc2e8d0 100755
--- a/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/MongoUserSessionProvider.java
+++ b/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/MongoUserSessionProvider.java
@@ -262,6 +262,12 @@ public class MongoUserSessionProvider implements UserSessionProvider {
@Override
public void onUserRemoved(RealmModel realm, UserModel user) {
removeUserSessions(realm, user);
+
+ DBObject query = new QueryBuilder()
+ .or(new BasicDBObject("username", user.getUsername()), new BasicDBObject("username", user.getEmail()))
+ .and("realmId").is(realm.getId())
+ .get();
+ mongoStore.removeEntities(MongoUsernameLoginFailureEntity.class, query, invocationContext);
}
@Override
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java
index f2c168c..3a57cc9 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java
@@ -10,6 +10,8 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
+import org.keycloak.models.UsernameLoginFailureModel;
+import org.keycloak.services.managers.UserManager;
import org.keycloak.testsuite.rule.KeycloakRule;
import org.keycloak.util.Time;
@@ -36,8 +38,8 @@ public class UserSessionProviderTest {
public void before() {
session = kc.startSession();
realm = session.realms().getRealm("test");
- session.users().addUser(realm, "user1");
- session.users().addUser(realm, "user2");
+ session.users().addUser(realm, "user1").setEmail("user1@localhost");
+ session.users().addUser(realm, "user2").setEmail("user2@localhost");
}
@After
@@ -46,8 +48,10 @@ public class UserSessionProviderTest {
session.sessions().removeUserSessions(realm);
UserModel user1 = session.users().getUserByUsername("user1", realm);
UserModel user2 = session.users().getUserByUsername("user2", realm);
- session.users().removeUser(realm, user1);
- session.users().removeUser(realm, user2);
+
+ UserManager um = new UserManager(session);
+ um.removeUser(realm, user1);
+ um.removeUser(realm, user2);
kc.stopSession(session, true);
}
@@ -280,6 +284,56 @@ public class UserSessionProviderTest {
assertEquals(1, session.sessions().getActiveUserSessions(realm, realm.findClient("third-party")));
}
+ @Test
+ public void loginFailures() {
+ UsernameLoginFailureModel failure1 = session.sessions().addUserLoginFailure(realm, "user1");
+ failure1.incrementFailures();
+
+ UsernameLoginFailureModel failure2 = session.sessions().addUserLoginFailure(realm, "user2");
+ failure2.incrementFailures();
+ failure2.incrementFailures();
+
+ resetSession();
+
+ failure1 = session.sessions().getUserLoginFailure(realm, "user1");
+ assertEquals(1, failure1.getNumFailures());
+
+ failure2 = session.sessions().getUserLoginFailure(realm, "user2");
+ assertEquals(2, failure2.getNumFailures());
+
+ resetSession();
+
+ failure1 = session.sessions().getUserLoginFailure(realm, "user1");
+ failure1.clearFailures();
+
+ resetSession();
+
+ failure1 = session.sessions().getUserLoginFailure(realm, "user1");
+ assertEquals(0, failure1.getNumFailures());
+ }
+
+ @Test
+ public void testOnUserRemoved() {
+ createSessions();
+
+ session.sessions().addUserLoginFailure(realm, "user1");
+ session.sessions().addUserLoginFailure(realm, "user1@localhost");
+ session.sessions().addUserLoginFailure(realm, "user2");
+
+ resetSession();
+
+ session.sessions().onUserRemoved(realm, session.users().getUserByUsername("user1", realm));
+
+ resetSession();
+
+ assertTrue(session.sessions().getUserSessions(realm, session.users().getUserByUsername("user1", realm)).isEmpty());
+ assertFalse(session.sessions().getUserSessions(realm, session.users().getUserByUsername("user2", realm)).isEmpty());
+
+ assertNull(session.sessions().getUserLoginFailure(realm, "user1"));
+ assertNull(session.sessions().getUserLoginFailure(realm, "user1@localhost"));
+ assertNotNull(session.sessions().getUserLoginFailure(realm, "user2"));
+ }
+
private UserSessionModel[] createSessions() {
UserSessionModel[] sessions = new UserSessionModel[3];
sessions[0] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "user1", "127.0.0.1", "form", true);