keycloak-memoizeit

test user fed registration spi

7/23/2016 9:55:06 AM

Details

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 6d7ea98..d6837aa 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
@@ -1019,18 +1019,11 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
             copy.add(entity);
 
         }
-        Collections.sort(copy, new Comparator<StorageProviderEntity>() {
-
-            @Override
-            public int compare(StorageProviderEntity o1, StorageProviderEntity o2) {
-                return o1.getPriority() - o2.getPriority();
-            }
-
-        });
         List<StorageProviderModel> result = new LinkedList<>();
         for (StorageProviderEntity entity : copy) {
             result.add(toModel(entity));
         }
+        Collections.sort(result, StorageProviderModel.comparator);
 
         return Collections.unmodifiableList(result);
     }
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 5c9c589..cb6bba7 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
@@ -1311,20 +1311,13 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
             copy.add(entity);
 
         }
-        Collections.sort(copy, new Comparator<StorageProviderEntity>() {
-
-            @Override
-            public int compare(StorageProviderEntity o1, StorageProviderEntity o2) {
-                return o1.getPriority() - o2.getPriority();
-            }
-
-        });
         List<StorageProviderModel> result = new LinkedList<>();
         for (StorageProviderEntity entity : copy) {
             result.add(new StorageProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName()
                     ));
         }
 
+        Collections.sort(result, StorageProviderModel.comparator);
         return Collections.unmodifiableList(result);
     }
 
diff --git a/server-spi/src/main/java/org/keycloak/models/UserProvider.java b/server-spi/src/main/java/org/keycloak/models/UserProvider.java
index 982453e..24b6106 100755
--- a/server-spi/src/main/java/org/keycloak/models/UserProvider.java
+++ b/server-spi/src/main/java/org/keycloak/models/UserProvider.java
@@ -22,7 +22,7 @@ import org.keycloak.storage.StorageProviderModel;
 import org.keycloak.storage.user.UserCredentialValidatorProvider;
 import org.keycloak.storage.user.UserLookupProvider;
 import org.keycloak.storage.user.UserQueryProvider;
-import org.keycloak.storage.user.UserUpdateProvider;
+import org.keycloak.storage.user.UserRegistrationProvider;
 
 import java.util.List;
 import java.util.Set;
@@ -35,7 +35,7 @@ public interface UserProvider extends Provider,
         UserLookupProvider,
         UserQueryProvider,
         UserCredentialValidatorProvider,
-        UserUpdateProvider {
+        UserRegistrationProvider {
     // Note: The reason there are so many query methods here is for layering a cache on top of an persistent KeycloakSession
 
     public void addFederatedIdentity(RealmModel realm, UserModel user, FederatedIdentityModel socialLink);
diff --git a/server-spi/src/main/java/org/keycloak/storage/StorageProviderModel.java b/server-spi/src/main/java/org/keycloak/storage/StorageProviderModel.java
index 910df81..823a500 100755
--- a/server-spi/src/main/java/org/keycloak/storage/StorageProviderModel.java
+++ b/server-spi/src/main/java/org/keycloak/storage/StorageProviderModel.java
@@ -18,6 +18,7 @@
 package org.keycloak.storage;
 
 import java.io.Serializable;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -29,6 +30,13 @@ import java.util.Map;
  */
 public class StorageProviderModel implements Serializable {
 
+    public static Comparator<StorageProviderModel> comparator = new Comparator<StorageProviderModel>() {
+        @Override
+        public int compare(StorageProviderModel o1, StorageProviderModel o2) {
+            return o1.priority - o2.priority;
+        }
+    };
+
     private String id;
     private String providerName;
     private Map<String, String> config = new HashMap<String, String>();
diff --git a/server-spi/src/main/java/org/keycloak/storage/UserStorageManager.java b/server-spi/src/main/java/org/keycloak/storage/UserStorageManager.java
index db39190..b6e6028 100755
--- a/server-spi/src/main/java/org/keycloak/storage/UserStorageManager.java
+++ b/server-spi/src/main/java/org/keycloak/storage/UserStorageManager.java
@@ -38,7 +38,7 @@ import org.keycloak.storage.user.UserLookupProvider;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserProvider;
 import org.keycloak.storage.user.UserQueryProvider;
-import org.keycloak.storage.user.UserUpdateProvider;
+import org.keycloak.storage.user.UserRegistrationProvider;
 import org.keycloak.models.utils.CredentialValidation;
 import org.keycloak.storage.federated.UserFederatedStorageProvider;
 
@@ -106,7 +106,7 @@ public class UserStorageManager implements UserProvider {
 
     @Override
     public UserModel addUser(RealmModel realm, String id, String username, boolean addDefaultRoles, boolean addDefaultRequiredActions) {
-        UserUpdateProvider registry = getFirstStorageProvider(realm, UserUpdateProvider.class);
+        UserRegistrationProvider registry = getFirstStorageProvider(realm, UserRegistrationProvider.class);
         if (registry != null) {
             return registry.addUser(realm, id, username, addDefaultRoles, addDefaultRequiredActions);
         }
@@ -115,7 +115,7 @@ public class UserStorageManager implements UserProvider {
 
     @Override
     public UserModel addUser(RealmModel realm, String username) {
-        UserUpdateProvider registry = getFirstStorageProvider(realm, UserUpdateProvider.class);
+        UserRegistrationProvider registry = getFirstStorageProvider(realm, UserRegistrationProvider.class);
         if (registry != null) {
             return registry.addUser(realm, username);
         }
@@ -139,7 +139,7 @@ public class UserStorageManager implements UserProvider {
         if (storageId.getProviderId() == null) {
             return localStorage().removeUser(realm, user);
         }
-        UserUpdateProvider registry = (UserUpdateProvider)getStorageProvider(realm, storageId.getProviderId());
+        UserRegistrationProvider registry = (UserRegistrationProvider)getStorageProvider(realm, storageId.getProviderId());
         if (registry == null) {
             throw new ModelException("Could not resolve StorageProvider: " + storageId.getProviderId());
         }
@@ -446,11 +446,11 @@ public class UserStorageManager implements UserProvider {
     @Override
     public void grantToAllUsers(RealmModel realm, RoleModel role) {
         // not federation-aware for now
-        List<UserUpdateProvider> storageProviders = getStorageProviders(realm, UserUpdateProvider.class);
-        LinkedList<UserUpdateProvider> providers = new LinkedList<>();
+        List<UserRegistrationProvider> storageProviders = getStorageProviders(realm, UserRegistrationProvider.class);
+        LinkedList<UserRegistrationProvider> providers = new LinkedList<>();
         providers.add(localStorage());
         providers.addAll(storageProviders);
-        for (UserUpdateProvider provider : providers) {
+        for (UserRegistrationProvider provider : providers) {
             provider.grantToAllUsers(realm, role);
         }
     }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/UserFederationStorageTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/UserFederationStorageTest.java
index 58d0ed0..ee55d14 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/UserFederationStorageTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/UserFederationStorageTest.java
@@ -29,6 +29,7 @@ import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.cache.infinispan.UserAdapter;
 import org.keycloak.services.managers.RealmManager;
+import org.keycloak.storage.StorageId;
 import org.keycloak.storage.StorageProviderModel;
 import org.keycloak.testsuite.OAuthClient;
 import org.keycloak.testsuite.pages.AppPage;
@@ -47,12 +48,18 @@ import java.util.Set;
  * @version $Revision: 1 $
  */
 public class UserFederationStorageTest {
+    public static StorageProviderModel memoryProvider = null;
     @ClassRule
     public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
 
         @Override
         public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
             StorageProviderModel model = new StorageProviderModel();
+            model.setDisplayName("memory");
+            model.setPriority(0);
+            model.setProviderName(UserMapStorageFactory.PROVIDER_ID);
+            memoryProvider = appRealm.addStorageProvider(model);
+            model = new StorageProviderModel();
             model.setDisplayName("read-only-user-props");
             model.setPriority(1);
             model.setProviderName(UserPropertyFileStorageFactory.PROVIDER_ID);
@@ -238,4 +245,24 @@ public class UserFederationStorageTest {
         keycloakRule.stopSession(session, true);
     }
 
+    @Test
+    public void testRegistration() {
+        KeycloakSession session = keycloakRule.startSession();
+        RealmModel realm = session.realms().getRealmByName("test");
+        UserModel user = session.users().addUser(realm, "memuser");
+        user.updateCredential(UserCredentialModel.password("password"));
+        keycloakRule.stopSession(session, true);
+        loginSuccessAndLogout("memuser", "password");
+
+        session = keycloakRule.startSession();
+        realm = session.realms().getRealmByName("test");
+        user = session.users().getUserByUsername("memuser", realm);
+        Assert.assertEquals(memoryProvider.getId(), StorageId.resolveProviderId(user));
+        Assert.assertEquals(0, user.getCredentialsDirectly().size());
+        session.users().removeUser(realm, user);
+        Assert.assertNull(session.users().getUserByUsername("memuser", realm));
+        keycloakRule.stopSession(session, true);
+
+    }
+
 }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/UserMapStorage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/UserMapStorage.java
new file mode 100644
index 0000000..daed4ad
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/UserMapStorage.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.testsuite.federation.storage;
+
+import org.keycloak.models.GroupModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.storage.StorageId;
+import org.keycloak.storage.StorageProvider;
+import org.keycloak.storage.StorageProviderModel;
+import org.keycloak.storage.adapter.AbstractUserAdapterFederatedStorage;
+import org.keycloak.storage.user.UserCredentialValidatorProvider;
+import org.keycloak.storage.user.UserLookupProvider;
+import org.keycloak.storage.user.UserRegistrationProvider;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class UserMapStorage implements UserLookupProvider, StorageProvider, UserCredentialValidatorProvider, UserRegistrationProvider {
+
+    protected Map<String, String> userPasswords;
+    protected StorageProviderModel model;
+    protected KeycloakSession session;
+
+    public UserMapStorage(KeycloakSession session, StorageProviderModel model, Map<String, String> userPasswords) {
+        this.session = session;
+        this.model = model;
+        this.userPasswords = userPasswords;
+    }
+
+
+    @Override
+    public UserModel getUserById(String id, RealmModel realm) {
+        StorageId storageId = new StorageId(id);
+        final String username = storageId.getStorageId();
+        if (!userPasswords.containsKey(username)) return null;
+
+        return createUser(realm, username);
+    }
+
+    private UserModel createUser(RealmModel realm, String username) {
+        return new AbstractUserAdapterFederatedStorage(session, realm,  model) {
+            @Override
+            public String getUsername() {
+                return username;
+            }
+
+            @Override
+            public void setUsername(String username) {
+                throw new RuntimeException("Unsupported");
+            }
+
+            @Override
+            public void updateCredential(UserCredentialModel cred) {
+                if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
+                    userPasswords.put(username, cred.getValue());
+                } else {
+                    super.updateCredential(cred);
+                }
+            }
+        };
+    }
+
+    @Override
+    public UserModel getUserByUsername(String username, RealmModel realm) {
+        if (!userPasswords.containsKey(username)) return null;
+
+        return createUser(realm, username);
+    }
+
+    @Override
+    public UserModel getUserByEmail(String email, RealmModel realm) {
+        return null;
+    }
+
+    @Override
+    public UserModel addUser(RealmModel realm, String id, String username, boolean addDefaultRoles, boolean addDefaultRequiredActions) {
+        userPasswords.put(username, "");
+        return createUser(realm, username);
+    }
+
+    @Override
+    public UserModel addUser(RealmModel realm, String username) {
+        userPasswords.put(username, "");
+        return createUser(realm, username);
+    }
+
+    @Override
+    public boolean removeUser(RealmModel realm, UserModel user) {
+        return userPasswords.remove(user.getUsername()) != null;
+    }
+
+    @Override
+    public void grantToAllUsers(RealmModel realm, RoleModel role) {
+
+    }
+
+    @Override
+    public void preRemove(RealmModel realm) {
+
+    }
+
+    @Override
+    public void preRemove(RealmModel realm, GroupModel group) {
+
+    }
+
+    @Override
+    public void preRemove(RealmModel realm, RoleModel role) {
+
+    }
+
+    @Override
+    public void preRemove(RealmModel realm, StorageProviderModel model) {
+
+    }
+
+    @Override
+    public boolean validCredentials(KeycloakSession session, RealmModel realm, UserModel user, List<UserCredentialModel> input) {
+        for (UserCredentialModel cred : input) {
+            if (!cred.getType().equals(UserCredentialModel.PASSWORD)) return false;
+            String password = (String)userPasswords.get(user.getUsername());
+            if (password == null) return false;
+            if (!password.equals(cred.getValue())) return false;
+        }
+        return true;
+    }
+
+
+
+    @Override
+    public void close() {
+
+    }
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/UserMapStorageFactory.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/UserMapStorageFactory.java
new file mode 100644
index 0000000..f80a11d
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/UserMapStorageFactory.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.testsuite.federation.storage;
+
+import org.keycloak.Config;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.storage.StorageProvider;
+import org.keycloak.storage.StorageProviderFactory;
+import org.keycloak.storage.StorageProviderModel;
+
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class UserMapStorageFactory implements StorageProviderFactory<UserMapStorage> {
+
+
+    public static final String PROVIDER_ID = "user-password-map";
+
+    protected Map<String, String> userPasswords = new Hashtable<>();
+
+    @Override
+    public UserMapStorage getInstance(KeycloakSession session, StorageProviderModel model) {
+        return new UserMapStorage(session, model, userPasswords);
+    }
+
+    @Override
+    public String getId() {
+        return PROVIDER_ID;
+    }
+
+    @Override
+    public StorageProvider create(KeycloakSession session) {
+        return null;
+    }
+
+    @Override
+    public void init(Config.Scope config) {
+
+    }
+
+    @Override
+    public void postInit(KeycloakSessionFactory factory) {
+
+    }
+
+    @Override
+    public void close() {
+
+    }
+}
diff --git a/testsuite/integration/src/test/resources/META-INF/services/org.keycloak.storage.StorageProviderFactory b/testsuite/integration/src/test/resources/META-INF/services/org.keycloak.storage.StorageProviderFactory
index 001e16b..efbed13 100644
--- a/testsuite/integration/src/test/resources/META-INF/services/org.keycloak.storage.StorageProviderFactory
+++ b/testsuite/integration/src/test/resources/META-INF/services/org.keycloak.storage.StorageProviderFactory
@@ -1 +1,2 @@
-org.keycloak.testsuite.federation.storage.UserPropertyFileStorageFactory
\ No newline at end of file
+org.keycloak.testsuite.federation.storage.UserPropertyFileStorageFactory
+org.keycloak.testsuite.federation.storage.UserMapStorageFactory
\ No newline at end of file