keycloak-memoizeit

Merge pull request #527 from patriot1burke/master move

7/16/2014 1:08:50 PM

Changes

Details

diff --git a/authentication/authentication-model/src/main/java/org/keycloak/authentication/model/AbstractModelAuthenticationProvider.java b/authentication/authentication-model/src/main/java/org/keycloak/authentication/model/AbstractModelAuthenticationProvider.java
index 1ac023f..63c0ec5 100755
--- a/authentication/authentication-model/src/main/java/org/keycloak/authentication/model/AbstractModelAuthenticationProvider.java
+++ b/authentication/authentication-model/src/main/java/org/keycloak/authentication/model/AbstractModelAuthenticationProvider.java
@@ -52,7 +52,7 @@ public abstract class AbstractModelAuthenticationProvider implements Authenticat
         RealmModel realm = getRealm(currentRealm, config);
         UserModel user = KeycloakModelUtils.findUserByNameOrEmail(keycloakSession, realm, username);
 
-        boolean result = realm.validatePassword(user, password);
+        boolean result = keycloakSession.users().validCredentials(realm, user, UserCredentialModel.password(password));
         return result ? AuthProviderStatus.SUCCESS : AuthProviderStatus.INVALID_CREDENTIALS;
     }
 
diff --git a/model/api/src/main/java/org/keycloak/models/RealmModel.java b/model/api/src/main/java/org/keycloak/models/RealmModel.java
index d515c98..d437c9b 100755
--- a/model/api/src/main/java/org/keycloak/models/RealmModel.java
+++ b/model/api/src/main/java/org/keycloak/models/RealmModel.java
@@ -106,10 +106,6 @@ public interface RealmModel extends RoleContainerModel {
 
     void setPasswordPolicy(PasswordPolicy policy);
 
-    boolean validatePassword(UserModel user, String password);
-
-    boolean validateTOTP(UserModel user, String password, String token);
-
     RoleModel getRoleById(String id);
 
     List<String> getDefaultRoles();
diff --git a/model/api/src/main/java/org/keycloak/models/UserCredentialModel.java b/model/api/src/main/java/org/keycloak/models/UserCredentialModel.java
index d096b97..4c5275b 100755
--- a/model/api/src/main/java/org/keycloak/models/UserCredentialModel.java
+++ b/model/api/src/main/java/org/keycloak/models/UserCredentialModel.java
@@ -35,6 +35,13 @@ public class UserCredentialModel {
         return model;
     }
 
+    public static UserCredentialModel totp(String key) {
+        UserCredentialModel model = new UserCredentialModel();
+        model.setType(TOTP);
+        model.setValue(key);
+        return model;
+    }
+
     public static UserCredentialModel generateSecret() {
         UserCredentialModel model = new UserCredentialModel();
         model.setType(SECRET);
diff --git a/model/api/src/main/java/org/keycloak/models/UserProvider.java b/model/api/src/main/java/org/keycloak/models/UserProvider.java
index b5a9a26..4898642 100755
--- a/model/api/src/main/java/org/keycloak/models/UserProvider.java
+++ b/model/api/src/main/java/org/keycloak/models/UserProvider.java
@@ -33,6 +33,7 @@ public interface UserProvider extends Provider {
     void preRemove(RealmModel realm);
     void preRemove(RoleModel role);
 
-
+    boolean validCredentials(RealmModel realm, UserModel user, List<UserCredentialModel> input);
+    boolean validCredentials(RealmModel realm, UserModel user, UserCredentialModel... input);
     void close();
 }
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 f44bbd5..dbb465c 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
@@ -5,6 +5,7 @@ import org.keycloak.models.KeycloakTransaction;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.SocialLinkModel;
+import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserProvider;
 import org.keycloak.models.cache.entities.CachedUser;
@@ -232,6 +233,16 @@ public class DefaultCacheUserProvider implements CacheUserProvider {
     }
 
     @Override
+    public boolean validCredentials(RealmModel realm, UserModel user, List<UserCredentialModel> input) {
+        return getDelegate().validCredentials(realm, user, input);
+    }
+
+    @Override
+    public boolean validCredentials(RealmModel realm, UserModel user, UserCredentialModel... input) {
+        return getDelegate().validCredentials(realm, user, input);
+    }
+
+    @Override
     public void preRemove(RealmModel realm) {
         realmInvalidations.add(realm.getId());
         getDelegate().preRemove(realm);
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProvider.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProvider.java
index 36f5669..ce2858d 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProvider.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProvider.java
@@ -1,16 +1,13 @@
 package org.keycloak.models.cache;
 
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakTransaction;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.SocialLinkModel;
+import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserProvider;
-import org.keycloak.models.cache.entities.CachedUser;
 
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -115,6 +112,16 @@ public class NoCacheUserProvider implements CacheUserProvider {
     }
 
     @Override
+    public boolean validCredentials(RealmModel realm, UserModel user, List<UserCredentialModel> input) {
+        return getDelegate().validCredentials(realm, user, input);
+    }
+
+    @Override
+    public boolean validCredentials(RealmModel realm, UserModel user, UserCredentialModel... input) {
+        return getDelegate().validCredentials(realm, user, input);
+    }
+
+    @Override
     public void preRemove(RealmModel realm) {
         getDelegate().preRemove(realm);
     }
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java
index 94121a0..acf9fb6 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java
@@ -3,7 +3,7 @@ package org.keycloak.models.cache;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.AuthenticationProviderModel;
 import org.keycloak.models.ClientModel;
-import org.keycloak.models.CredentialValidation;
+import org.keycloak.models.utils.CredentialValidation;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.RealmModel;
@@ -376,22 +376,6 @@ public class RealmAdapter implements RealmModel {
     }
 
     @Override
-    public boolean validatePassword(UserModel user, String password) {
-        return CredentialValidation.validatePassword(this, user, password);
-    }
-
-    @Override
-    public boolean validateTOTP(UserModel user, String password, String token) {
-        if (!validatePassword(user, password)) return false;
-        for (UserCredentialValueModel cred : user.getCredentialsDirectly()) {
-            if (cred.getType().equals(UserCredentialModel.TOTP)) {
-                return new TimeBasedOTP().validate(token, cred.getValue().getBytes());
-            }
-        }
-        return false;
-    }
-
-    @Override
     public RoleModel getRoleById(String id) {
         if (updated != null) return updated.getRoleById(id);
         return cacheSession.getRoleById(id, this);
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 01e32ec..ccdec22 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
@@ -5,6 +5,7 @@ import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.SocialLinkModel;
+import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserProvider;
 import org.keycloak.models.jpa.entities.RealmEntity;
@@ -12,6 +13,7 @@ import org.keycloak.models.jpa.entities.RoleEntity;
 import org.keycloak.models.jpa.entities.SocialLinkEntity;
 import org.keycloak.models.jpa.entities.UserEntity;
 import org.keycloak.models.jpa.entities.UserRoleMappingEntity;
+import org.keycloak.models.utils.CredentialValidation;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
 import javax.persistence.EntityManager;
@@ -274,4 +276,13 @@ public class JpaUserProvider implements UserProvider {
         return (entity != null) ? new SocialLinkModel(entity.getSocialProvider(), entity.getSocialUserId(), entity.getSocialUsername()) : null;
     }
 
+    @Override
+    public boolean validCredentials(RealmModel realm, UserModel user, List<UserCredentialModel> input) {
+        return CredentialValidation.validCredentials(realm, user, input);
+    }
+
+    @Override
+    public boolean validCredentials(RealmModel realm, UserModel user, UserCredentialModel... input) {
+        return CredentialValidation.validCredentials(realm, user, input);
+    }
 }
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
index 6157ee9..06a302d 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
@@ -3,7 +3,7 @@ package org.keycloak.models.jpa;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.AuthenticationProviderModel;
 import org.keycloak.models.ClientModel;
-import org.keycloak.models.CredentialValidation;
+import org.keycloak.models.utils.CredentialValidation;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.PasswordPolicy;
@@ -796,22 +796,6 @@ public class RealmAdapter implements RealmModel {
     }
 
     @Override
-    public boolean validatePassword(UserModel user, String password) {
-        return CredentialValidation.validatePassword(this, user, password);
-    }
-
-    @Override
-    public boolean validateTOTP(UserModel user, String password, String token) {
-        if (!validatePassword(user, password)) return false;
-        for (UserCredentialValueModel cred : user.getCredentialsDirectly()) {
-            if (cred.getType().equals(UserCredentialModel.TOTP)) {
-                return new TimeBasedOTP().validate(token, cred.getValue().getBytes());
-            }
-        }
-        return false;
-    }
-
-    @Override
     public PasswordPolicy getPasswordPolicy() {
         if (passwordPolicy == null) {
             passwordPolicy = new PasswordPolicy(realm.getPasswordPolicy());
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 f14f645..f9411e1 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
@@ -9,10 +9,12 @@ import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.SocialLinkModel;
+import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserProvider;
 import org.keycloak.models.entities.SocialLinkEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoUserEntity;
+import org.keycloak.models.utils.CredentialValidation;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -311,4 +313,14 @@ public class MongoUserProvider implements UserProvider {
     public void preRemove(RoleModel role) {
         // todo not sure what to do for this
     }
+
+    @Override
+    public boolean validCredentials(RealmModel realm, UserModel user, List<UserCredentialModel> input) {
+        return CredentialValidation.validCredentials(realm, user, input);
+    }
+
+    @Override
+    public boolean validCredentials(RealmModel realm, UserModel user, UserCredentialModel... input) {
+        return CredentialValidation.validCredentials(realm, user, input);
+    }
 }
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
index 410bc9f..00e690a 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
@@ -7,7 +7,7 @@ import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.AuthenticationProviderModel;
 import org.keycloak.models.ClientModel;
-import org.keycloak.models.CredentialValidation;
+import org.keycloak.models.utils.CredentialValidation;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmProvider;
 import org.keycloak.models.OAuthClientModel;
@@ -723,22 +723,6 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
         return result;
     }
 
-    @Override
-    public boolean validatePassword(UserModel user, String password) {
-        return CredentialValidation.validatePassword(this, user, password);
-    }
-
-    @Override
-    public boolean validateTOTP(UserModel user, String password, String token) {
-        if (!validatePassword(user, password)) return false;
-        for (UserCredentialValueModel cred : user.getCredentialsDirectly()) {
-            if (cred.getType().equals(UserCredentialModel.TOTP)) {
-                return new TimeBasedOTP().validate(token, cred.getValue().getBytes());
-            }
-        }
-        return false;
-    }
-
     protected void updateRealm() {
         super.updateMongoEntity();
     }
diff --git a/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java b/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java
index edb4e40..ab40eb8 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java
@@ -15,6 +15,7 @@ import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserCredentialValueModel;
 import org.keycloak.models.UserModel;
+import org.keycloak.models.UserProvider;
 import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.services.managers.RealmManager;
@@ -129,16 +130,17 @@ public class AdapterTest extends AbstractModelTest {
     @Test
     public void testCredentialValidation() throws Exception {
         test1CreateRealm();
-        UserModel user = realmManager.getSession().users().addUser(realmModel, "bburke");
+        UserProvider userProvider = realmManager.getSession().users();
+        UserModel user = userProvider.addUser(realmModel, "bburke");
         UserCredentialModel cred = new UserCredentialModel();
         cred.setType(CredentialRepresentation.PASSWORD);
         cred.setValue("geheim");
         user.updateCredential(cred);
-        Assert.assertTrue(realmModel.validatePassword(user, "geheim"));
+        Assert.assertTrue(userProvider.validCredentials(realmModel, user, UserCredentialModel.password("geheim")));
         List<UserCredentialValueModel> creds = user.getCredentialsDirectly();
         Assert.assertEquals(creds.get(0).getHashIterations(), 1);
         realmModel.setPasswordPolicy( new PasswordPolicy("hashIterations(200)"));
-        Assert.assertTrue(realmModel.validatePassword(user, "geheim"));
+        Assert.assertTrue(userProvider.validCredentials(realmModel, user, UserCredentialModel.password("geheim")));
         creds = user.getCredentialsDirectly();
         Assert.assertEquals(creds.get(0).getHashIterations(), 200);
         realmModel.setPasswordPolicy( new PasswordPolicy("hashIterations(1)"));
diff --git a/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersLDAPTest.java b/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersLDAPTest.java
index 90c074c..0ebecd6 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersLDAPTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersLDAPTest.java
@@ -158,7 +158,7 @@ public class AuthProvidersLDAPTest extends AbstractModelTest {
         Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(session, null, realm, formData));
 
         // Password updated just in LDAP, so validating directly in realm should fail
-        Assert.assertFalse(realm.validatePassword(john, "password-updated"));
+        Assert.assertFalse(session.users().validCredentials(realm, john, UserCredentialModel.password("password-updated")));
 
         // Switch to not allow updating passwords in ldap
         AuthProvidersExternalModelTest.setPasswordUpdateForProvider(false, AuthProviderConstants.PROVIDER_NAME_PICKETLINK, realm);
diff --git a/model/tests/src/test/java/org/keycloak/model/test/MultipleRealmsTest.java b/model/tests/src/test/java/org/keycloak/model/test/MultipleRealmsTest.java
index 3aa4d4b..73cc6ad 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/MultipleRealmsTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/MultipleRealmsTest.java
@@ -9,6 +9,7 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
+import org.keycloak.models.UserProvider;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@@ -31,8 +32,9 @@ public class MultipleRealmsTest extends AbstractModelTest {
 
     @Test
     public void testUsers() {
-        UserModel r1user1 = realmManager.getSession().users().getUserByUsername("user1", realm1);
-        UserModel r2user1 = realmManager.getSession().users().getUserByUsername("user1", realm2);
+        UserProvider userProvider = realmManager.getSession().users();
+        UserModel r1user1 = userProvider.getUserByUsername("user1", realm1);
+        UserModel r2user1 = userProvider.getUserByUsername("user1", realm2);
         Assert.assertEquals(r1user1.getUsername(), r2user1.getUsername());
         Assert.assertNotEquals(r1user1.getId(), r2user1.getId());
 
@@ -40,22 +42,22 @@ public class MultipleRealmsTest extends AbstractModelTest {
         r1user1.updateCredential(UserCredentialModel.password("pass1"));
         r2user1.updateCredential(UserCredentialModel.password("pass2"));
 
-        Assert.assertTrue(realm1.validatePassword(r1user1, "pass1"));
-        Assert.assertFalse(realm1.validatePassword(r1user1, "pass2"));
-        Assert.assertFalse(realm2.validatePassword(r2user1, "pass1"));
-        Assert.assertTrue(realm2.validatePassword(r2user1, "pass2"));
+        Assert.assertTrue(userProvider.validCredentials(realm1, r1user1, UserCredentialModel.password("pass1")));
+        Assert.assertFalse(userProvider.validCredentials(realm1, r1user1, UserCredentialModel.password("pass2")));
+        Assert.assertFalse(userProvider.validCredentials(realm2, r2user1, UserCredentialModel.password("pass1")));
+        Assert.assertTrue(userProvider.validCredentials(realm2, r2user1, UserCredentialModel.password("pass2")));
 
         // Test searching
-        Assert.assertEquals(2, realmManager.getSession().users().searchForUser("user", realm1).size());
+        Assert.assertEquals(2, userProvider.searchForUser("user", realm1).size());
 
         commit();
         realm1 = model.getRealm("id1");
         realm2 = model.getRealm("id2");
 
-        realmManager.getSession().users().removeUser(realm1, "user1");
-        realmManager.getSession().users().removeUser(realm1, "user2");
-        Assert.assertEquals(0, realmManager.getSession().users().searchForUser("user", realm1).size());
-        Assert.assertEquals(2, realmManager.getSession().users().searchForUser("user", realm2).size());
+        userProvider.removeUser(realm1, "user1");
+        userProvider.removeUser(realm1, "user2");
+        Assert.assertEquals(0, userProvider.searchForUser("user", realm1).size());
+        Assert.assertEquals(2, userProvider.searchForUser("user", realm2).size());
     }
 
     @Test
diff --git a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
index 8ce0a51..b2e3cc2 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -11,6 +11,7 @@ import org.keycloak.models.AuthenticationLinkModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RequiredCredentialModel;
+import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
 import org.keycloak.models.utils.KeycloakModelUtils;
@@ -296,7 +297,7 @@ public class AuthenticationManager {
                 }
 
                 logger.debug("validating TOTP");
-                if (!realm.validateTOTP(user, password, token)) {
+                if (!session.users().validCredentials(realm, user, UserCredentialModel.totp(token))) {
                     return AuthenticationStatus.INVALID_CREDENTIALS;
                 }
             } else {
diff --git a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/ReadUsersWorker.java b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/ReadUsersWorker.java
index a858767..d9c36d5 100755
--- a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/ReadUsersWorker.java
+++ b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/ReadUsersWorker.java
@@ -6,6 +6,7 @@ import org.apache.log.Logger;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.SocialLinkModel;
+import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
 
 import java.util.concurrent.atomic.AtomicInteger;
@@ -101,7 +102,7 @@ public class ReadUsersWorker implements Worker {
 
             // Validate password (shoould be same as username)
             if (readPassword) {
-                realm.validatePassword(user, username);
+                session.users().validCredentials(realm, user, UserCredentialModel.password(username));
             }
 
             // Read socialLinks of user