diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js index 47af934c03..2c50ff74e0 100755 --- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js @@ -1033,7 +1033,7 @@ module.factory('PasswordPolicy', function() { p.toString = function(policies) { if (!policies || policies.length == 0) { - return null; + return ""; } var policyString = ""; diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-events.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-events.html index 9bd6db2ea8..ad3a43343e 100755 --- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-events.html +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-events.html @@ -30,7 +30,7 @@
- +
@@ -52,7 +52,7 @@ Time - Event + Event Type Details diff --git a/model/api/src/main/java/org/keycloak/models/UserFederationManager.java b/model/api/src/main/java/org/keycloak/models/UserFederationManager.java index a98618559f..41d5386cf8 100755 --- a/model/api/src/main/java/org/keycloak/models/UserFederationManager.java +++ b/model/api/src/main/java/org/keycloak/models/UserFederationManager.java @@ -26,7 +26,7 @@ public class UserFederationManager implements UserProvider { @Override public UserModel addUser(RealmModel realm, String id, String username, boolean addDefaultRoles) { - UserModel user = session.userStorage().addUser(realm, id, username, addDefaultRoles); + UserModel user = session.userStorage().addUser(realm, id, username.toLowerCase(), addDefaultRoles); return registerWithFederation(realm, user); } @@ -38,7 +38,7 @@ public class UserFederationManager implements UserProvider { @Override public UserModel addUser(RealmModel realm, String username) { - UserModel user = session.userStorage().addUser(realm, username); + UserModel user = session.userStorage().addUser(realm, username.toLowerCase()); return registerWithFederation(realm, user); } @@ -144,7 +144,7 @@ public class UserFederationManager implements UserProvider { @Override public UserModel getUserByUsername(String username, RealmModel realm) { - UserModel user = session.userStorage().getUserByUsername(username, realm); + UserModel user = session.userStorage().getUserByUsername(username.toLowerCase(), realm); if (user != null) { user = validateAndProxyUser(realm, user); if (user != null) return user; @@ -159,7 +159,7 @@ public class UserFederationManager implements UserProvider { @Override public UserModel getUserByEmail(String email, RealmModel realm) { - UserModel user = session.userStorage().getUserByEmail(email, realm); + UserModel user = session.userStorage().getUserByEmail(email.toLowerCase(), realm); if (user != null) { user = validateAndProxyUser(realm, user); if (user != null) return user; @@ -251,11 +251,11 @@ public class UserFederationManager implements UserProvider { attributes.put(UserModel.FIRST_NAME, firstName); attributes.put(UserModel.LAST_NAME, lastName); } else if (search.indexOf('@') > -1) { - attributes.put(UserModel.USERNAME, search.trim()); - attributes.put(UserModel.EMAIL, search.trim()); + attributes.put(UserModel.USERNAME, search.trim().toLowerCase()); + attributes.put(UserModel.EMAIL, search.trim().toLowerCase()); } else { attributes.put(UserModel.LAST_NAME, search.trim()); - attributes.put(UserModel.USERNAME, search.trim()); + attributes.put(UserModel.USERNAME, search.trim().toLowerCase()); } federationLoad(realm, attributes); return query(new PaginatedQuery() { diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheUserProvider.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheUserProvider.java index 8dbb0449ce..97f3c6c995 100755 --- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheUserProvider.java +++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheUserProvider.java @@ -142,6 +142,9 @@ public class DefaultCacheUserProvider implements CacheUserProvider { @Override public UserModel getUserByUsername(String username, RealmModel realm) { + + username = username.toLowerCase(); + if (!cache.isEnabled()) return getDelegate().getUserByUsername(username, realm); if (realmInvalidations.contains(realm.getId())) { return getDelegate().getUserByUsername(username, realm); @@ -165,6 +168,9 @@ public class DefaultCacheUserProvider implements CacheUserProvider { @Override public UserModel getUserByEmail(String email, RealmModel realm) { + + email = email.toLowerCase(); + if (!cache.isEnabled()) return getDelegate().getUserByEmail(email, realm); if (realmInvalidations.contains(realm.getId())) { return getDelegate().getUserByEmail(email, realm); diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java index c94c068fb9..2b00c1cc7a 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java @@ -50,7 +50,7 @@ public class JpaUserProvider implements UserProvider { UserEntity entity = new UserEntity(); entity.setId(id); - entity.setUsername(username); + entity.setUsername(username.toLowerCase()); entity.setRealmId(realm.getId()); em.persist(entity); em.flush(); @@ -73,7 +73,7 @@ public class JpaUserProvider implements UserProvider { @Override public UserModel addUser(RealmModel realm, String username) { - return addUser(realm, KeycloakModelUtils.generateId(), username, true); + return addUser(realm, KeycloakModelUtils.generateId(), username.toLowerCase(), true); } @Override @@ -96,7 +96,7 @@ public class JpaUserProvider implements UserProvider { entity.setRealmId(realm.getId()); entity.setIdentityProvider(identity.getIdentityProvider()); entity.setUserId(identity.getUserId()); - entity.setUserName(identity.getUserName()); + entity.setUserName(identity.getUserName().toLowerCase()); entity.setToken(identity.getToken()); UserEntity userEntity = em.getReference(UserEntity.class, user.getId()); entity.setUser(userEntity); @@ -190,7 +190,7 @@ public class JpaUserProvider implements UserProvider { @Override public UserModel getUserByUsername(String username, RealmModel realm) { TypedQuery query = em.createNamedQuery("getRealmUserByUsername", UserEntity.class); - query.setParameter("username", username); + query.setParameter("username", username.toLowerCase()); query.setParameter("realmId", realm.getId()); List results = query.getResultList(); if (results.size() == 0) return null; @@ -200,7 +200,7 @@ public class JpaUserProvider implements UserProvider { @Override public UserModel getUserByEmail(String email, RealmModel realm) { TypedQuery query = em.createNamedQuery("getRealmUserByEmail", UserEntity.class); - query.setParameter("email", email); + query.setParameter("email", email.toLowerCase()); query.setParameter("realmId", realm.getId()); List results = query.getResultList(); return results.isEmpty() ? null : new UserAdapter(realm, em, results.get(0)); diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java index 5babac03c9..bd41eff37d 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java @@ -60,7 +60,7 @@ public class MongoUserProvider implements UserProvider { @Override public UserModel getUserByUsername(String username, RealmModel realm) { DBObject query = new QueryBuilder() - .and("username").is(username) + .and("username").is(username.toLowerCase()) .and("realmId").is(realm.getId()) .get(); MongoUserEntity user = getMongoStore().loadSingleEntity(MongoUserEntity.class, query, invocationContext); @@ -75,7 +75,7 @@ public class MongoUserProvider implements UserProvider { @Override public UserModel getUserByEmail(String email, RealmModel realm) { DBObject query = new QueryBuilder() - .and("email").is(email) + .and("email").is(email.toLowerCase()) .and("realmId").is(realm.getId()) .get(); MongoUserEntity user = getMongoStore().loadSingleEntity(MongoUserEntity.class, query, invocationContext); @@ -256,7 +256,7 @@ public class MongoUserProvider implements UserProvider { @Override public UserAdapter addUser(RealmModel realm, String id, String username, boolean addDefaultRoles) { - UserAdapter userModel = addUserEntity(realm, id, username); + UserAdapter userModel = addUserEntity(realm, id, username.toLowerCase()); if (addDefaultRoles) { for (String r : realm.getDefaultRoles()) { @@ -302,7 +302,7 @@ public class MongoUserProvider implements UserProvider { FederatedIdentityEntity federatedIdentityEntity = new FederatedIdentityEntity(); federatedIdentityEntity.setIdentityProvider(identity.getIdentityProvider()); federatedIdentityEntity.setUserId(identity.getUserId()); - federatedIdentityEntity.setUserName(identity.getUserName()); + federatedIdentityEntity.setUserName(identity.getUserName().toLowerCase()); federatedIdentityEntity.setToken(identity.getToken()); getMongoStore().pushItemToList(userEntity, "federatedIdentities", federatedIdentityEntity, true, invocationContext); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/UserTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/UserTest.java index 41b577837a..d2c76dd022 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/UserTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/UserTest.java @@ -30,7 +30,7 @@ public class UserTest extends AbstractClientTest { } @Test - public void createDuplicatedUser() { + public void createDuplicatedUser1() { createUser(); try { @@ -42,7 +42,80 @@ public class UserTest extends AbstractClientTest { assertEquals(409, e.getResponse().getStatus()); } } + + @Test + public void createDuplicatedUser2() { + createUser(); + try { + UserRepresentation user = new UserRepresentation(); + user.setUsername("user2"); + user.setEmail("user1@localhost"); + realm.users().create(user); + fail("Expected failure"); + } catch (ClientErrorException e) { + assertEquals(409, e.getResponse().getStatus()); + } + } + + @Test + public void createDuplicatedUser3() { + createUser(); + + try { + UserRepresentation user = new UserRepresentation(); + user.setUsername("User1"); + realm.users().create(user); + fail("Expected failure"); + } catch (ClientErrorException e) { + assertEquals(409, e.getResponse().getStatus()); + } + } + + @Test + public void createDuplicatedUser4() { + createUser(); + + try { + UserRepresentation user = new UserRepresentation(); + user.setUsername("USER1"); + realm.users().create(user); + fail("Expected failure"); + } catch (ClientErrorException e) { + assertEquals(409, e.getResponse().getStatus()); + } + } + + @Test + public void createDuplicatedUser5() { + createUser(); + + try { + UserRepresentation user = new UserRepresentation(); + user.setUsername("user2"); + user.setEmail("User1@localhost"); + realm.users().create(user); + fail("Expected failure"); + } catch (ClientErrorException e) { + assertEquals(409, e.getResponse().getStatus()); + } + } + + @Test + public void createDuplicatedUser6() { + createUser(); + + try { + UserRepresentation user = new UserRepresentation(); + user.setUsername("user2"); + user.setEmail("user1@LOCALHOST"); + realm.users().create(user); + fail("Expected failure"); + } catch (ClientErrorException e) { + assertEquals(409, e.getResponse().getStatus()); + } + } + private void createUsers() { for (int i = 1; i < 10; i++) { UserRepresentation user = new UserRepresentation(); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java index 74f3ff914d..506013b70b 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java @@ -166,7 +166,7 @@ public class ImportTest extends AbstractModelTest { } else if ("google".equals(federatedIdentityModel.getIdentityProvider())) { googleFound = true; Assert.assertEquals(federatedIdentityModel.getUserId(), "google1"); - Assert.assertEquals(federatedIdentityModel.getUserName(), "mySocialUser@gmail.com"); + Assert.assertEquals(federatedIdentityModel.getUserName(), "mysocialuser@gmail.com"); } else if ("twitter".equals(federatedIdentityModel.getIdentityProvider())) { twitterFound = true; Assert.assertEquals(federatedIdentityModel.getUserId(), "twitter1");