diff --git a/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionCredentialProvider.java b/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionCredentialProvider.java index 77f30838be..9156be1c8b 100644 --- a/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionCredentialProvider.java +++ b/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionCredentialProvider.java @@ -78,7 +78,7 @@ public class SecretQuestionCredentialProvider implements CredentialProvider, Cre creds.get(0).setValue(credInput.getValue()); session.userCredentialManager().updateCredential(realm, user, creds.get(0)); } - session.getUserCache().evict(realm, user); + session.userCache().evict(realm, user); return true; } @@ -86,7 +86,7 @@ public class SecretQuestionCredentialProvider implements CredentialProvider, Cre public void disableCredentialType(RealmModel realm, UserModel user, String credentialType) { if (!SECRET_QUESTION.equals(credentialType)) return; session.userCredentialManager().disableCredentialType(realm, user, credentialType); - session.getUserCache().evict(realm, user); + session.userCache().evict(realm, user); } diff --git a/examples/providers/federation-provider/README.md b/examples/providers/federation-provider/README.md deleted file mode 100755 index ae02fc85c4..0000000000 --- a/examples/providers/federation-provider/README.md +++ /dev/null @@ -1,26 +0,0 @@ -Example User Federation Provider -=================================================== - -This is an example of user federation backed by a simple properties file. This properties file only contains username/password -key pairs. To deploy, build this directory then take the jar and copy it to providers directory. Alternatively you can deploy as a module by running: - - KEYCLOAK_HOME/bin/jboss-cli.sh --command="module add --name=org.keycloak.examples.userprops --resources=target/federation-properties-example.jar --dependencies=org.keycloak.keycloak-core,org.keycloak.keycloak-server-spi,org.keycloak.keycloak-server-spi-private" - -Then registering the provider by editing `standalone/configuration/standalone.xml` and adding the module to the providers element: - - - ... - module:org.keycloak.examples.userprops - - -You will then have to restart the authentication server. - -The ClasspathPropertiesFederationProvider is an example of a readonly provider. If you go to the Users/Federation - page of the admin console you will see this provider listed under "classpath-properties. To configure this provider you -specify a classpath to a properties file in the "path" field of the admin page for this plugin. This example includes -a "test-users.properties" within the JAR that you can use as the variable. - -The FilePropertiesFederationProvider is an example of a writable provider. It synchronizes changes made to -username and password with the properties file. If you go to the Users/Federation page of the admin console you will -see this provider listed under "file-properties". To configure this provider you specify a fully qualified file path to -a properties file in the "path" field of the admin page for this plugin. diff --git a/examples/providers/federation-provider/src/main/java/org/keycloak/examples/federation/properties/BasePropertiesFederationFactory.java b/examples/providers/federation-provider/src/main/java/org/keycloak/examples/federation/properties/BasePropertiesFederationFactory.java deleted file mode 100755 index e9ec451af5..0000000000 --- a/examples/providers/federation-provider/src/main/java/org/keycloak/examples/federation/properties/BasePropertiesFederationFactory.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * 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.examples.federation.properties; - -import org.keycloak.Config; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.KeycloakSessionFactory; -import org.keycloak.models.KeycloakSessionTask; -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserFederationProvider; -import org.keycloak.models.UserFederationProviderFactory; -import org.keycloak.models.UserFederationProviderModel; -import org.keycloak.models.UserFederationSyncResult; -import org.keycloak.models.UserModel; -import org.keycloak.models.UserProvider; -import org.keycloak.models.utils.KeycloakModelUtils; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Date; -import java.util.HashSet; -import java.util.Properties; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public abstract class BasePropertiesFederationFactory implements UserFederationProviderFactory { - static final Set configOptions = new HashSet(); - protected ConcurrentHashMap files = new ConcurrentHashMap(); - - static { - configOptions.add("path"); - } - - @Override - public UserFederationProvider getInstance(KeycloakSession session, UserFederationProviderModel model) { - // first get the path to our properties file from the stored configuration of this provider instance. - String path = model.getConfig().get("path"); - if (path == null) { - throw new IllegalStateException("Path attribute not configured for provider"); - } - // see if we already loaded the config file - Properties props = files.get(path); - if (props != null) return createProvider(session, model, props); - - - props = new Properties(); - InputStream is = getPropertiesFileStream(path); - try { - props.load(is); - is.close(); - } catch (IOException e) { - throw new RuntimeException(e); - } - // remember the properties file for next time - files.put(path, props); - return createProvider(session, model, props); - } - - protected abstract InputStream getPropertiesFileStream(String path); - - protected abstract BasePropertiesFederationProvider createProvider(KeycloakSession session, UserFederationProviderModel model, Properties props); - - /** - * List the configuration options to render and display in the admin console's generic management page for this - * plugin - * - * @return - */ - @Override - public Set getConfigurationOptions() { - return configOptions; - } - - @Override - public UserFederationProvider create(KeycloakSession session) { - return null; - } - - /** - * You can import additional plugin configuration from standalone.xml here. - * - * @param config - */ - @Override - public void init(Config.Scope config) { - - } - - @Override - public void postInit(KeycloakSessionFactory factory) { - - } - - @Override - public void close() { - - } - - @Override - public UserFederationSyncResult syncAllUsers(KeycloakSessionFactory sessionFactory, final String realmId, final UserFederationProviderModel model) { - final UserFederationSyncResult syncResult = new UserFederationSyncResult(); - - KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() { - - @Override - public void run(KeycloakSession session) { - RealmModel realm = session.realms().getRealm(realmId); - BasePropertiesFederationProvider federationProvider = (BasePropertiesFederationProvider)getInstance(session, model); - Set allUsernames = federationProvider.getProperties().stringPropertyNames(); - UserProvider localProvider = session.userStorage(); - for (String username : allUsernames) { - UserModel localUser = localProvider.getUserByUsername(username, realm); - - if (localUser == null) { - // New user, let's import him - UserModel imported = federationProvider.getUserByUsername(realm, username); - if (imported != null) { - syncResult.increaseAdded(); - } - } - } - } - - }); - - return syncResult; - } - - @Override - public UserFederationSyncResult syncChangedUsers(KeycloakSessionFactory sessionFactory, final String realmId, final UserFederationProviderModel model, Date lastSync) { - return syncAllUsers(sessionFactory, realmId, model); - } -} diff --git a/examples/providers/federation-provider/src/main/java/org/keycloak/examples/federation/properties/BasePropertiesFederationProvider.java b/examples/providers/federation-provider/src/main/java/org/keycloak/examples/federation/properties/BasePropertiesFederationProvider.java deleted file mode 100755 index 3ee3a0b779..0000000000 --- a/examples/providers/federation-provider/src/main/java/org/keycloak/examples/federation/properties/BasePropertiesFederationProvider.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * 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.examples.federation.properties; - -import org.keycloak.credential.CredentialInput; -import org.keycloak.models.CredentialValidationOutput; -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.UserFederationProvider; -import org.keycloak.models.UserFederationProviderModel; -import org.keycloak.models.UserModel; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public abstract class BasePropertiesFederationProvider implements UserFederationProvider { - protected static final Set supportedCredentialTypes = new HashSet(); - protected KeycloakSession session; - protected Properties properties; - protected UserFederationProviderModel model; - - public BasePropertiesFederationProvider(KeycloakSession session, UserFederationProviderModel model, Properties properties) { - this.session = session; - this.model = model; - this.properties = properties; - } - - static - { - supportedCredentialTypes.add(UserCredentialModel.PASSWORD); - } - - - public KeycloakSession getSession() { - return session; - } - - public Properties getProperties() { - return properties; - } - - public UserFederationProviderModel getModel() { - return model; - } - - @Override - public UserModel getUserByUsername(RealmModel realm, String username) { - String password = properties.getProperty(username); - if (password != null) { - UserModel userModel = session.userStorage().addUser(realm, username); - userModel.setEnabled(true); - userModel.setFederationLink(model.getId()); - return userModel; - } - return null; - } - - @Override - public UserModel getUserByEmail(RealmModel realm, String email) { - return null; - } - - /** - * We only search for Usernames as that is all that is stored in the properties file. Not that if the user - * does exist in the properties file, we only import it if the user hasn't been imported already. - * - * @param attributes - * @param realm - * @param maxResults - * @return - */ - @Override - public List searchByAttributes(Map attributes, RealmModel realm, int maxResults) { - String username = attributes.get(USERNAME); - if (username != null) { - // make sure user isn't already in storage - if (session.userStorage().getUserByUsername(username, realm) == null) { - // user is not already imported, so let's import it until local storage. - UserModel user = getUserByUsername(realm, username); - if (user != null) { - List list = new ArrayList(1); - list.add(user); - return list; - } - } - } - return Collections.emptyList(); - } - - @Override - public List getGroupMembers(RealmModel realm, GroupModel group, int firstResult, int maxResults) { - return Collections.emptyList(); - } - - @Override - public void preRemove(RealmModel realm) { - // complete We don't care about the realm being removed - } - - @Override - public void preRemove(RealmModel realm, RoleModel role) { - // complete we dont'care if a role is removed - - } - - @Override - public void preRemove(RealmModel realm, GroupModel group) { - // complete we dont'care if a role is removed - - } - - /** - * See if the user is still in the properties file - * - * @param local - * @return - */ - @Override - public boolean isValid(RealmModel realm, UserModel local) { - return properties.containsKey(local.getUsername()); - } - - @Override - public Set getSupportedCredentialTypes() { - return supportedCredentialTypes; - } - - @Override - public boolean isValid(RealmModel realm, UserModel user, CredentialInput input) { - if (!supportsCredentialType(input.getType()) || !(input instanceof UserCredentialModel)) return false; - - UserCredentialModel cred = (UserCredentialModel)input; - String password = properties.getProperty(user.getUsername()); - if (password == null) return false; - return password.equals(cred.getValue()); - } - - @Override - public boolean isConfiguredFor(RealmModel realm, UserModel user, String credentialType) { - return getSupportedCredentialTypes().contains(credentialType); - } - - @Override - public boolean supportsCredentialType(String credentialType) { - return getSupportedCredentialTypes().contains(credentialType); - } - - @Override - public CredentialValidationOutput validCredentials(RealmModel realm, UserCredentialModel credential) { - return CredentialValidationOutput.failed(); - } - - @Override - public void close() { - - } -} diff --git a/examples/providers/federation-provider/src/main/java/org/keycloak/examples/federation/properties/FilePropertiesFederationProvider.java b/examples/providers/federation-provider/src/main/java/org/keycloak/examples/federation/properties/FilePropertiesFederationProvider.java deleted file mode 100755 index f8262f129a..0000000000 --- a/examples/providers/federation-provider/src/main/java/org/keycloak/examples/federation/properties/FilePropertiesFederationProvider.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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.examples.federation.properties; - -import org.keycloak.credential.CredentialInput; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserFederationProviderModel; -import org.keycloak.models.UserModel; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Collections; -import java.util.Properties; -import java.util.Set; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public class FilePropertiesFederationProvider extends BasePropertiesFederationProvider { - - public FilePropertiesFederationProvider(KeycloakSession session, Properties properties, UserFederationProviderModel model) { - super(session, model, properties); - } - - /** - * Keycloak will call this method if it finds an imported UserModel. Here we proxy the UserModel with - * a Writable proxy which will synchronize updates to username and password back to the properties file - * - * @param local - * @return - */ - @Override - public UserModel validateAndProxy(RealmModel realm, UserModel local) { - if (isValid(realm, local)) { - return new WritableUserModelProxy(local, this); - } else { - return null; - } - } - - /** - * Adding new users is supported - * - * @return - */ - @Override - public boolean synchronizeRegistrations() { - return true; - } - - public void save() { - String path = getModel().getConfig().get("path"); - try { - FileOutputStream fos = new FileOutputStream(path); - properties.store(fos, ""); - fos.close(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - /** - * Update the properties file with the new user. - * - * @param realm - * @param user - * @return - */ - @Override - public UserModel register(RealmModel realm, UserModel user) { - synchronized (properties) { - properties.setProperty(user.getUsername(), ""); - save(); - } - return validateAndProxy(realm, user); - } - - @Override - public boolean removeUser(RealmModel realm, UserModel user) { - synchronized (properties) { - if (properties.remove(user.getUsername()) == null) return false; - save(); - return true; - } - } - - @Override - public boolean updateCredential(RealmModel realm, UserModel user, CredentialInput input) { - return false; - } - - @Override - public void disableCredentialType(RealmModel realm, UserModel user, String credentialType) { - - } - - @Override - public Set getDisableableCredentialTypes(RealmModel realm, UserModel user) { - return Collections.EMPTY_SET; - } -} diff --git a/examples/providers/federation-provider/src/main/java/org/keycloak/examples/federation/properties/WritableUserModelProxy.java b/examples/providers/federation-provider/src/main/java/org/keycloak/examples/federation/properties/WritableUserModelProxy.java deleted file mode 100755 index c133675684..0000000000 --- a/examples/providers/federation-provider/src/main/java/org/keycloak/examples/federation/properties/WritableUserModelProxy.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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.examples.federation.properties; - -import org.keycloak.models.UserModel; -import org.keycloak.models.utils.UserModelDelegate; - -import java.util.Properties; - -/** - * Proxy that will synchronize password updates to the properties file. - * - * @author Bill Burke - * @version $Revision: 1 $ - */ -public class WritableUserModelProxy extends UserModelDelegate { - protected FilePropertiesFederationProvider provider; - - public WritableUserModelProxy(UserModel delegate, FilePropertiesFederationProvider provider) { - super(delegate); - this.provider = provider; - } - - - /** - * Updates the properties file if the username changes. If you have a more complex user storage, you can - * override other methods on UserModel to synchronize updates back to your external storage. - * - * @param username - */ - @Override - public void setUsername(String username) { - if (delegate.getUsername().equals(username)) return; - delegate.setUsername(username); - Properties properties = provider.getProperties(); - synchronized (properties) { - if (properties.containsKey(username)) { - throw new IllegalStateException("Can't change username to existing user"); - } - String password = (String) properties.remove(username); - if (password == null) { - throw new IllegalStateException("User doesn't exist"); - } - properties.setProperty(username, password); - provider.save(); - } - - } - -} diff --git a/examples/providers/federation-provider/src/main/resources/META-INF/services/org.keycloak.models.UserFederationProviderFactory b/examples/providers/federation-provider/src/main/resources/META-INF/services/org.keycloak.models.UserFederationProviderFactory deleted file mode 100755 index 77da29906c..0000000000 --- a/examples/providers/federation-provider/src/main/resources/META-INF/services/org.keycloak.models.UserFederationProviderFactory +++ /dev/null @@ -1,19 +0,0 @@ -# -# 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. -# - -org.keycloak.examples.federation.properties.ClasspathPropertiesFederationFactory -org.keycloak.examples.federation.properties.FilePropertiesFederationFactory \ No newline at end of file diff --git a/examples/providers/pom.xml b/examples/providers/pom.xml index 9310fe1576..c9be81d3bb 100755 --- a/examples/providers/pom.xml +++ b/examples/providers/pom.xml @@ -33,10 +33,10 @@ event-listener-sysout event-store-mem - federation-provider authenticator rest domain-extension + user-storage-simple user-storage-jpa diff --git a/examples/providers/user-storage-simple/README.md b/examples/providers/user-storage-simple/README.md new file mode 100755 index 0000000000..6549f8ed05 --- /dev/null +++ b/examples/providers/user-storage-simple/README.md @@ -0,0 +1,19 @@ +Example User Federation Provider +=================================================== + +This is an example of user storage backed by a simple properties file. This properties file only contains username/password +key pairs. To deploy this provider you must have Keycloak running in standalone or standalone-ha mode. Then type the follow maven command: + + mvn clean install wildfly:deploy + + + +The ClasspathPropertiesStorageProvider is an example of a readonly provider. If you go to the Users/Federation + page of the admin console you will see this provider listed under "classpath-properties. To configure this provider you +specify a classpath to a properties file in the "path" field of the admin page for this plugin. This example includes +a "test-users.properties" within the JAR that you can use as the variable. + +The FilePropertiesStorageProvider is an example of a writable provider. It synchronizes changes made to +username and password with the properties file. If you go to the Users/Federation page of the admin console you will +see this provider listed under "file-properties". To configure this provider you specify a fully qualified file path to +a properties file in the "path" field of the admin page for this plugin. diff --git a/examples/providers/federation-provider/pom.xml b/examples/providers/user-storage-simple/pom.xml similarity index 69% rename from examples/providers/federation-provider/pom.xml rename to examples/providers/user-storage-simple/pom.xml index 7313b9cb4a..099510323d 100755 --- a/examples/providers/federation-provider/pom.xml +++ b/examples/providers/user-storage-simple/pom.xml @@ -23,11 +23,11 @@ 2.4.1.Final-SNAPSHOT - Properties Authentication Provider Example + UserStorageProvider Simple Example 4.0.0 - federation-properties-example + user-storage-properties-example jar @@ -41,11 +41,6 @@ keycloak-server-spi provided - - org.keycloak - keycloak-server-spi-private - provided - org.jboss.logging jboss-logging @@ -54,6 +49,23 @@ - federation-properties-example + user-storage-properties-example + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + org.wildfly.plugins + wildfly-maven-plugin + + false + + + diff --git a/examples/providers/user-storage-simple/src/main/java/org/keycloak/examples/federation/properties/BasePropertiesStorageFactory.java b/examples/providers/user-storage-simple/src/main/java/org/keycloak/examples/federation/properties/BasePropertiesStorageFactory.java new file mode 100755 index 0000000000..c5bacdd0f9 --- /dev/null +++ b/examples/providers/user-storage-simple/src/main/java/org/keycloak/examples/federation/properties/BasePropertiesStorageFactory.java @@ -0,0 +1,69 @@ +/* + * 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.examples.federation.properties; + +import org.keycloak.component.ComponentModel; +import org.keycloak.models.KeycloakSession; +import org.keycloak.storage.UserStorageProviderFactory; +import org.keycloak.storage.UserStorageProviderModel; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public abstract class BasePropertiesStorageFactory implements UserStorageProviderFactory { + protected ConcurrentHashMap files = new ConcurrentHashMap(); + + + @Override + public T create(KeycloakSession session, ComponentModel model) { + // first get the path to our properties file from the stored configuration of this provider instance. + String path = model.getConfig().getFirst("path"); + if (path == null) { + throw new IllegalStateException("Path attribute not configured for provider"); + } + // see if we already loaded the config file + Properties props = files.get(path); + if (props != null) return (T)createProvider(session, new UserStorageProviderModel(model), props); + + + props = new Properties(); + InputStream is = getPropertiesFileStream(path); + if (is != null) { + try { + props.load(is); + is.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + // remember the properties file for next time + files.put(path, props); + return (T)createProvider(session, new UserStorageProviderModel(model), props); + } + + protected abstract InputStream getPropertiesFileStream(String path); + + protected abstract BasePropertiesStorageProvider createProvider(KeycloakSession session, UserStorageProviderModel model, Properties props); + +} diff --git a/examples/providers/user-storage-simple/src/main/java/org/keycloak/examples/federation/properties/BasePropertiesStorageProvider.java b/examples/providers/user-storage-simple/src/main/java/org/keycloak/examples/federation/properties/BasePropertiesStorageProvider.java new file mode 100755 index 0000000000..6a18864ebe --- /dev/null +++ b/examples/providers/user-storage-simple/src/main/java/org/keycloak/examples/federation/properties/BasePropertiesStorageProvider.java @@ -0,0 +1,138 @@ +/* + * 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.examples.federation.properties; + +import org.keycloak.credential.CredentialInput; +import org.keycloak.credential.CredentialInputValidator; +import org.keycloak.credential.CredentialModel; +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.UserStorageProvider; +import org.keycloak.storage.UserStorageProviderModel; +import org.keycloak.storage.user.UserLookupProvider; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public abstract class BasePropertiesStorageProvider implements + UserStorageProvider, + UserLookupProvider, + CredentialInputValidator +{ + public static final String UNSET_PASSWORD="#$!-UNSET-PASSWORD"; + + protected KeycloakSession session; + protected Properties properties; + protected UserStorageProviderModel model; + // map of loaded users in this transaction + protected Map loadedUsers = new HashMap<>(); + + public BasePropertiesStorageProvider(KeycloakSession session, UserStorageProviderModel model, Properties properties) { + this.session = session; + this.model = model; + this.properties = properties; + } + + public KeycloakSession getSession() { + return session; + } + + public Properties getProperties() { + return properties; + } + + @Override + public UserModel getUserByUsername(String username, RealmModel realm) { + UserModel adapter = loadedUsers.get(username); + if (adapter == null) { + String password = properties.getProperty(username); + if (password != null) { + adapter = createAdapter(realm, username); + loadedUsers.put(username, adapter); + } + } + return adapter; + } + + @Override + public UserModel getUserById(String id, RealmModel realm) { + StorageId storageId = new StorageId(id); + String username = storageId.getExternalId(); + return getUserByUsername(username, realm); + } + + protected abstract UserModel createAdapter(RealmModel realm, String username); + + @Override + public UserModel getUserByEmail(String email, RealmModel realm) { + return null; + } + + @Override + public void preRemove(RealmModel realm) { + // complete We don't care about the realm being removed + } + + @Override + public void preRemove(RealmModel realm, RoleModel role) { + // complete we dont'care if a role is removed + + } + + @Override + public void preRemove(RealmModel realm, GroupModel group) { + // complete we dont'care if a role is removed + + } + + @Override + public boolean isValid(RealmModel realm, UserModel user, CredentialInput input) { + if (!supportsCredentialType(input.getType()) || !(input instanceof UserCredentialModel)) return false; + + UserCredentialModel cred = (UserCredentialModel)input; + String password = properties.getProperty(user.getUsername()); + if (password == null || password.equals(UNSET_PASSWORD)) return false; + return password.equals(cred.getValue()); + } + + @Override + public boolean isConfiguredFor(RealmModel realm, UserModel user, String credentialType) { + String password = properties.getProperty(user.getUsername()); + return credentialType.equals(CredentialModel.PASSWORD) && password != null && !password.equals(UNSET_PASSWORD); + } + + @Override + public boolean supportsCredentialType(String credentialType) { + return credentialType.equals(CredentialModel.PASSWORD); + } + + @Override + public void close() { + + } +} diff --git a/examples/providers/federation-provider/src/main/java/org/keycloak/examples/federation/properties/ClasspathPropertiesFederationFactory.java b/examples/providers/user-storage-simple/src/main/java/org/keycloak/examples/federation/properties/ClasspathPropertiesStorageFactory.java similarity index 57% rename from examples/providers/federation-provider/src/main/java/org/keycloak/examples/federation/properties/ClasspathPropertiesFederationFactory.java rename to examples/providers/user-storage-simple/src/main/java/org/keycloak/examples/federation/properties/ClasspathPropertiesStorageFactory.java index 03877d3219..2c0bb946d7 100755 --- a/examples/providers/federation-provider/src/main/java/org/keycloak/examples/federation/properties/ClasspathPropertiesFederationFactory.java +++ b/examples/providers/user-storage-simple/src/main/java/org/keycloak/examples/federation/properties/ClasspathPropertiesStorageFactory.java @@ -18,22 +18,40 @@ package org.keycloak.examples.federation.properties; import org.keycloak.models.KeycloakSession; -import org.keycloak.models.UserFederationProviderModel; +import org.keycloak.provider.ProviderConfigProperty; +import org.keycloak.provider.ProviderConfigurationBuilder; +import org.keycloak.storage.UserStorageProviderModel; import java.io.InputStream; +import java.util.List; import java.util.Properties; /** * @author Bill Burke * @version $Revision: 1 $ */ -public class ClasspathPropertiesFederationFactory extends BasePropertiesFederationFactory { +public class ClasspathPropertiesStorageFactory extends BasePropertiesStorageFactory { public static final String PROVIDER_NAME = "classpath-properties"; + protected static final List configProperties; + + static { + configProperties = ProviderConfigurationBuilder.create() + .property().name("path") + .type(ProviderConfigProperty.STRING_TYPE) + .label("Classpath") + .helpText("Classpath of properties file") + .add().build(); + } @Override - protected BasePropertiesFederationProvider createProvider(KeycloakSession session, UserFederationProviderModel model, Properties props) { - return new ClasspathPropertiesFederationProvider(session, model, props); + public List getConfigProperties() { + return configProperties; + } + + @Override + protected BasePropertiesStorageProvider createProvider(KeycloakSession session, UserStorageProviderModel model, Properties props) { + return new ClasspathPropertiesStorageProvider(session, model, props); } protected InputStream getPropertiesFileStream(String path) { diff --git a/examples/providers/federation-provider/src/main/java/org/keycloak/examples/federation/properties/ClasspathPropertiesFederationProvider.java b/examples/providers/user-storage-simple/src/main/java/org/keycloak/examples/federation/properties/ClasspathPropertiesStorageProvider.java similarity index 51% rename from examples/providers/federation-provider/src/main/java/org/keycloak/examples/federation/properties/ClasspathPropertiesFederationProvider.java rename to examples/providers/user-storage-simple/src/main/java/org/keycloak/examples/federation/properties/ClasspathPropertiesStorageProvider.java index 19f9f75cf2..cf33b869e6 100755 --- a/examples/providers/federation-provider/src/main/java/org/keycloak/examples/federation/properties/ClasspathPropertiesFederationProvider.java +++ b/examples/providers/user-storage-simple/src/main/java/org/keycloak/examples/federation/properties/ClasspathPropertiesStorageProvider.java @@ -18,73 +18,45 @@ package org.keycloak.examples.federation.properties; import org.keycloak.credential.CredentialInput; +import org.keycloak.credential.CredentialInputUpdater; +import org.keycloak.credential.CredentialModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; -import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserModel; +import org.keycloak.storage.ReadOnlyException; +import org.keycloak.storage.UserStorageProviderModel; +import org.keycloak.storage.adapter.AbstractUserAdapter; import java.util.Collections; import java.util.Properties; import java.util.Set; /** + * Creates a read-only user. Implements CredentialInputUpdater so that passwords cannot be updated + * * @author Bill Burke * @version $Revision: 1 $ */ -public class ClasspathPropertiesFederationProvider extends BasePropertiesFederationProvider { +public class ClasspathPropertiesStorageProvider extends BasePropertiesStorageProvider implements CredentialInputUpdater { - public ClasspathPropertiesFederationProvider(KeycloakSession session, UserFederationProviderModel model, Properties properties) { + public ClasspathPropertiesStorageProvider(KeycloakSession session, UserStorageProviderModel model, Properties properties) { super(session, model, properties); } - /** - * Keycloak will call this method if it finds an imported UserModel. Here we proxy the UserModel with - * a Readonly proxy which will barf if password is updated. - * - * @param local - * @return - */ @Override - public UserModel validateAndProxy(RealmModel realm, UserModel local) { - if (isValid(realm, local)) { - return new ReadonlyUserModelProxy(local); - } else { - return null; - } - } - - /** - * The properties file is readonly so don't suppport registration. - * - * @return - */ - @Override - public boolean synchronizeRegistrations() { - return false; - } - - /** - * The properties file is readonly so don't suppport registration. - * - * @return - */ - @Override - public UserModel register(RealmModel realm, UserModel user) { - throw new IllegalStateException("Registration not supported"); - } - - /** - * The properties file is readonly so don't removing a user - * - * @return - */ - @Override - public boolean removeUser(RealmModel realm, UserModel user) { - throw new IllegalStateException("Remove not supported"); + protected UserModel createAdapter(RealmModel realm, String username) { + return new AbstractUserAdapter(session, realm, model) { + @Override + public String getUsername() { + return username; + } + }; } @Override public boolean updateCredential(RealmModel realm, UserModel user, CredentialInput input) { + if (input.getType().equals(CredentialModel.PASSWORD)) throw new ReadOnlyException("user is read only for this update"); + return false; } diff --git a/examples/providers/federation-provider/src/main/java/org/keycloak/examples/federation/properties/FilePropertiesFederationFactory.java b/examples/providers/user-storage-simple/src/main/java/org/keycloak/examples/federation/properties/FilePropertiesStorageFactory.java similarity index 59% rename from examples/providers/federation-provider/src/main/java/org/keycloak/examples/federation/properties/FilePropertiesFederationFactory.java rename to examples/providers/user-storage-simple/src/main/java/org/keycloak/examples/federation/properties/FilePropertiesStorageFactory.java index b492ee352d..f1cad0c5f3 100755 --- a/examples/providers/federation-provider/src/main/java/org/keycloak/examples/federation/properties/FilePropertiesFederationFactory.java +++ b/examples/providers/user-storage-simple/src/main/java/org/keycloak/examples/federation/properties/FilePropertiesStorageFactory.java @@ -18,30 +18,48 @@ package org.keycloak.examples.federation.properties; import org.keycloak.models.KeycloakSession; -import org.keycloak.models.UserFederationProviderModel; +import org.keycloak.provider.ProviderConfigProperty; +import org.keycloak.provider.ProviderConfigurationBuilder; +import org.keycloak.storage.UserStorageProviderModel; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; +import java.util.List; import java.util.Properties; /** * @author Bill Burke * @version $Revision: 1 $ */ -public class FilePropertiesFederationFactory extends BasePropertiesFederationFactory { +public class FilePropertiesStorageFactory extends BasePropertiesStorageFactory { public static final String PROVIDER_NAME = "file-properties"; + protected static final List configProperties; + + static { + configProperties = ProviderConfigurationBuilder.create() + .property().name("path") + .type(ProviderConfigProperty.STRING_TYPE) + .label("Path") + .helpText("File path to properties file") + .add().build(); + } @Override - protected BasePropertiesFederationProvider createProvider(KeycloakSession session, UserFederationProviderModel model, Properties props) { - return new FilePropertiesFederationProvider(session, props, model); + public List getConfigProperties() { + return configProperties; + } + + @Override + protected BasePropertiesStorageProvider createProvider(KeycloakSession session, UserStorageProviderModel model, Properties props) { + return new FilePropertiesStorageProvider(session, props, model); } protected InputStream getPropertiesFileStream(String path) { try { return new FileInputStream(path); } catch (FileNotFoundException e) { - throw new RuntimeException(e); + return null; } } diff --git a/examples/providers/user-storage-simple/src/main/java/org/keycloak/examples/federation/properties/FilePropertiesStorageProvider.java b/examples/providers/user-storage-simple/src/main/java/org/keycloak/examples/federation/properties/FilePropertiesStorageProvider.java new file mode 100755 index 0000000000..514a8e4198 --- /dev/null +++ b/examples/providers/user-storage-simple/src/main/java/org/keycloak/examples/federation/properties/FilePropertiesStorageProvider.java @@ -0,0 +1,134 @@ +/* + * 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.examples.federation.properties; + +import org.keycloak.credential.CredentialInput; +import org.keycloak.credential.CredentialInputUpdater; +import org.keycloak.credential.CredentialModel; +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.ReadOnlyException; +import org.keycloak.storage.UserStorageProviderModel; +import org.keycloak.storage.adapter.AbstractUserAdapterFederatedStorage; +import org.keycloak.storage.user.UserRegistrationProvider; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.HashSet; +import java.util.Properties; +import java.util.Set; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public class FilePropertiesStorageProvider extends BasePropertiesStorageProvider implements + UserRegistrationProvider, + CredentialInputUpdater +{ + + public FilePropertiesStorageProvider(KeycloakSession session, Properties properties, UserStorageProviderModel model) { + super(session, model, properties); + } + + public void save() { + String path = model.getConfig().getFirst("path"); + try { + FileOutputStream fos = new FileOutputStream(path); + properties.store(fos, ""); + fos.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public boolean removeUser(RealmModel realm, UserModel user) { + synchronized (properties) { + if (properties.remove(user.getUsername()) == null) return false; + save(); + return true; + } + } + + @Override + protected UserModel createAdapter(RealmModel realm, String username) { + return new AbstractUserAdapterFederatedStorage(session, realm, model) { + @Override + public String getUsername() { + return username; + } + + @Override + public void setUsername(String username) { + throw new ReadOnlyException("Cannot edit username"); + } + }; + } + + @Override + public UserModel addUser(RealmModel realm, String username) { + synchronized (properties) { + properties.setProperty(username, UNSET_PASSWORD); + save(); + } + return createAdapter(realm, username); + } + + @Override + public void grantToAllUsers(RealmModel realm, RoleModel role) { + // unsupported + } + + @Override + public boolean updateCredential(RealmModel realm, UserModel user, CredentialInput input) { + if (!(input instanceof UserCredentialModel)) return false; + UserCredentialModel cred = (UserCredentialModel)input; + if (!cred.getType().equals(CredentialModel.PASSWORD)) return false; + synchronized (properties) { + properties.setProperty(user.getUsername(), cred.getValue()); + save(); + } + return true; + } + + @Override + public void disableCredentialType(RealmModel realm, UserModel user, String credentialType) { + if (!credentialType.equals(CredentialModel.PASSWORD)) return; + synchronized (properties) { + properties.setProperty(user.getUsername(), UNSET_PASSWORD); + save(); + } + + } + + private static final Set disableableTypes = new HashSet<>(); + + static { + disableableTypes.add(CredentialModel.PASSWORD); + } + + @Override + public Set getDisableableCredentialTypes(RealmModel realm, UserModel user) { + + return disableableTypes; + } +} diff --git a/examples/providers/user-storage-simple/src/main/resources/META-INF/services/org.keycloak.storage.UserStorageProviderFactory b/examples/providers/user-storage-simple/src/main/resources/META-INF/services/org.keycloak.storage.UserStorageProviderFactory new file mode 100644 index 0000000000..f203c13655 --- /dev/null +++ b/examples/providers/user-storage-simple/src/main/resources/META-INF/services/org.keycloak.storage.UserStorageProviderFactory @@ -0,0 +1,2 @@ +org.keycloak.examples.federation.properties.ClasspathPropertiesStorageFactory +org.keycloak.examples.federation.properties.FilePropertiesStorageFactory \ No newline at end of file diff --git a/examples/providers/federation-provider/src/main/resources/test-users.properties b/examples/providers/user-storage-simple/src/main/resources/test-users.properties similarity index 100% rename from examples/providers/federation-provider/src/main/resources/test-users.properties rename to examples/providers/user-storage-simple/src/main/resources/test-users.properties diff --git a/examples/providers/federation-provider/src/main/resources/test2-users.properties b/examples/providers/user-storage-simple/src/main/resources/test2-users.properties similarity index 100% rename from examples/providers/federation-provider/src/main/resources/test2-users.properties rename to examples/providers/user-storage-simple/src/main/resources/test2-users.properties diff --git a/federation/kerberos/src/main/java/org/keycloak/federation/kerberos/KerberosConfig.java b/federation/kerberos/src/main/java/org/keycloak/federation/kerberos/KerberosConfig.java index 83b9837d67..26badf9273 100644 --- a/federation/kerberos/src/main/java/org/keycloak/federation/kerberos/KerberosConfig.java +++ b/federation/kerberos/src/main/java/org/keycloak/federation/kerberos/KerberosConfig.java @@ -20,9 +20,6 @@ package org.keycloak.federation.kerberos; import org.keycloak.common.constants.KerberosConstants; import org.keycloak.component.ComponentModel; import org.keycloak.models.LDAPConstants; -import org.keycloak.models.UserFederationProvider; -import org.keycloak.models.UserFederationProviderModel; -import org.keycloak.storage.UserStorageProvider; import org.keycloak.storage.UserStorageProvider.EditMode; /** diff --git a/federation/kerberos/src/main/java/org/keycloak/federation/kerberos/KerberosFederationProvider.java b/federation/kerberos/src/main/java/org/keycloak/federation/kerberos/KerberosFederationProvider.java index c0ce9419a1..fd9a4ab194 100755 --- a/federation/kerberos/src/main/java/org/keycloak/federation/kerberos/KerberosFederationProvider.java +++ b/federation/kerberos/src/main/java/org/keycloak/federation/kerberos/KerberosFederationProvider.java @@ -33,8 +33,6 @@ import org.keycloak.models.ModelReadOnlyException; import org.keycloak.models.RealmModel; import org.keycloak.models.RoleModel; import org.keycloak.models.UserCredentialModel; -import org.keycloak.models.UserFederationProvider; -import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserModel; import org.keycloak.models.UserManager; import org.keycloak.storage.UserStorageProvider; @@ -44,8 +42,6 @@ import org.keycloak.storage.user.UserLookupProvider; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Set; diff --git a/federation/kerberos/src/main/java/org/keycloak/federation/kerberos/KerberosFederationProviderFactory.java b/federation/kerberos/src/main/java/org/keycloak/federation/kerberos/KerberosFederationProviderFactory.java index e7aa027212..a33a0f145d 100755 --- a/federation/kerberos/src/main/java/org/keycloak/federation/kerberos/KerberosFederationProviderFactory.java +++ b/federation/kerberos/src/main/java/org/keycloak/federation/kerberos/KerberosFederationProviderFactory.java @@ -21,28 +21,19 @@ import org.jboss.logging.Logger; import org.keycloak.Config; import org.keycloak.common.constants.KerberosConstants; import org.keycloak.component.ComponentModel; -import org.keycloak.component.ComponentValidationException; import org.keycloak.federation.kerberos.impl.KerberosServerSubjectAuthenticator; import org.keycloak.federation.kerberos.impl.KerberosUsernamePasswordAuthenticator; import org.keycloak.federation.kerberos.impl.SPNEGOAuthenticator; import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.models.LDAPConstants; -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserFederationProvider; -import org.keycloak.models.UserFederationProviderFactory; -import org.keycloak.models.UserFederationProviderModel; -import org.keycloak.models.UserFederationSyncResult; import org.keycloak.provider.ProviderConfigProperty; import org.keycloak.provider.ProviderConfigurationBuilder; import org.keycloak.storage.UserStorageProvider; import org.keycloak.storage.UserStorageProviderFactory; import org.keycloak.storage.UserStorageProviderModel; -import java.util.Collections; -import java.util.Date; import java.util.List; -import java.util.Set; /** * Factory for standalone Kerberos federation provider. Standalone means that it's not backed by LDAP. For Kerberos backed by LDAP (like MS AD or ApacheDS environment) diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProvider.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProvider.java index 4d91efbd1a..3fd8340608 100755 --- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProvider.java +++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProvider.java @@ -596,7 +596,7 @@ public class LDAPStorageProvider implements UserStorageProvider, logger.warnf("User with username [%s] aready exists and is linked to provider [%s] but is not valid. Stale LDAP_ID on local user is: %s", username, model.getName(), user.getFirstAttribute(LDAPConstants.LDAP_ID)); logger.warn("Will re-create user"); - session.getUserCache().evict(realm, user); + session.userCache().evict(realm, user); new UserManager(session).removeUser(realm, user, session.userLocalStorage()); } } diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProviderFactory.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProviderFactory.java index 86db2d9968..6d4ceb6007 100755 --- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProviderFactory.java +++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProviderFactory.java @@ -495,7 +495,7 @@ public class LDAPStorageProviderFactory implements UserStorageProviderFactoryBruno Oliveira * @version $Revision: 1 $ diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmAdapter.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmAdapter.java index 204c0ed316..2cca4472fa 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmAdapter.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmAdapter.java @@ -35,8 +35,6 @@ import org.keycloak.models.RealmModel; import org.keycloak.models.RequiredActionProviderModel; import org.keycloak.models.RequiredCredentialModel; import org.keycloak.models.RoleModel; -import org.keycloak.models.UserFederationMapperModel; -import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.cache.CachedRealmModel; import org.keycloak.models.cache.infinispan.entities.CachedRealm; import org.keycloak.storage.UserStorageProvider; @@ -1244,7 +1242,7 @@ public class RealmAdapter implements CachedRealmModel { if (parentId != null && !parentId.equals(getId())) { ComponentModel parent = getComponent(parentId); if (parent != null && UserStorageProvider.class.getName().equals(parent.getProviderType())) { - session.getUserCache().evict(this); + session.userCache().evict(this); } } } diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java index 0dd4d5d167..c40ac8c51a 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java @@ -32,7 +32,6 @@ import org.keycloak.models.ProtocolMapperModel; import org.keycloak.models.RealmModel; import org.keycloak.models.RoleModel; import org.keycloak.models.UserConsentModel; -import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserModel; import org.keycloak.models.UserProvider; import org.keycloak.models.cache.CachedUserModel; @@ -53,9 +52,7 @@ import org.keycloak.storage.StorageId; import org.keycloak.storage.UserStorageProvider; import org.keycloak.storage.UserStorageProviderModel; -import java.text.DateFormat; import java.util.Calendar; -import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; @@ -852,12 +849,6 @@ public class UserCacheSession implements UserCache { } - @Override - public void preRemove(RealmModel realm, UserFederationProviderModel link) { - addRealmInvalidation(realm.getId()); // easier to just invalidate whole realm - getDelegate().preRemove(realm, link); - } - @Override public void preRemove(RealmModel realm, ClientModel client) { addRealmInvalidation(realm.getId()); // easier to just invalidate whole 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 9633f845ca..d69e021228 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 @@ -23,7 +23,6 @@ import org.keycloak.component.ComponentModel; import org.keycloak.credential.CredentialModel; import org.keycloak.credential.UserCredentialStore; import org.keycloak.models.ClientModel; -import org.keycloak.models.CredentialValidationOutput; import org.keycloak.models.FederatedIdentityModel; import org.keycloak.models.GroupModel; import org.keycloak.models.KeycloakSession; @@ -34,8 +33,6 @@ import org.keycloak.models.RealmModel; import org.keycloak.models.RequiredActionProviderModel; import org.keycloak.models.RoleModel; import org.keycloak.models.UserConsentModel; -import org.keycloak.models.UserCredentialModel; -import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserModel; import org.keycloak.models.UserProvider; import org.keycloak.models.jpa.entities.CredentialAttributeEntity; @@ -383,12 +380,6 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore { .setParameter("realmId", realm.getId()).executeUpdate(); } - @Override - public void preRemove(RealmModel realm, UserFederationProviderModel link) { - String linkId = link.getId(); - removeUserDataByLink(realm, linkId); - } - public void removeUserDataByLink(RealmModel realm, String linkId) { int num = em.createNamedQuery("deleteUserRoleMappingsByRealmAndLink") .setParameter("realmId", realm.getId()) 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 3fd4e77ecb..b3f58b4f1f 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 @@ -31,7 +31,6 @@ import org.keycloak.models.GroupModel; import org.keycloak.models.IdentityProviderMapperModel; import org.keycloak.models.IdentityProviderModel; import org.keycloak.models.KeycloakSession; -import org.keycloak.models.ModelDuplicateException; import org.keycloak.models.ModelException; import org.keycloak.models.OTPPolicy; import org.keycloak.models.PasswordPolicy; @@ -39,9 +38,6 @@ import org.keycloak.models.RealmModel; import org.keycloak.models.RequiredActionProviderModel; import org.keycloak.models.RequiredCredentialModel; import org.keycloak.models.RoleModel; -import org.keycloak.models.UserFederationMapperModel; -import org.keycloak.models.UserFederationProviderCreationEventImpl; -import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.jpa.entities.AuthenticationExecutionEntity; import org.keycloak.models.jpa.entities.AuthenticationFlowEntity; import org.keycloak.models.jpa.entities.AuthenticatorConfigEntity; @@ -58,8 +54,6 @@ import org.keycloak.models.jpa.entities.RealmEntity; import org.keycloak.models.jpa.entities.RequiredActionProviderEntity; import org.keycloak.models.jpa.entities.RequiredCredentialEntity; import org.keycloak.models.jpa.entities.RoleEntity; -import org.keycloak.models.jpa.entities.UserFederationMapperEntity; -import org.keycloak.models.jpa.entities.UserFederationProviderEntity; import org.keycloak.models.utils.ComponentUtil; import org.keycloak.models.utils.KeycloakModelUtils; @@ -68,7 +62,6 @@ import javax.persistence.TypedQuery; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -1214,18 +1207,6 @@ public class RealmAdapter implements RealmModel, JpaModel { return mapping; } - protected UserFederationMapperModel entityToModel(UserFederationMapperEntity entity) { - UserFederationMapperModel mapper = new UserFederationMapperModel(); - mapper.setId(entity.getId()); - mapper.setName(entity.getName()); - mapper.setFederationProviderId(entity.getFederationProvider().getId()); - mapper.setFederationMapperType(entity.getFederationMapperType()); - Map config = new HashMap(); - if (entity.getConfig() != null) config.putAll(entity.getConfig()); - mapper.setConfig(config); - return mapper; - } - @Override public AuthenticationFlowModel getBrowserFlow() { String flowId = realm.getBrowserFlow(); diff --git a/model/jpa/src/main/java/org/keycloak/storage/jpa/JpaUserFederatedStorageProvider.java b/model/jpa/src/main/java/org/keycloak/storage/jpa/JpaUserFederatedStorageProvider.java index e1f2bd498d..12228720df 100644 --- a/model/jpa/src/main/java/org/keycloak/storage/jpa/JpaUserFederatedStorageProvider.java +++ b/model/jpa/src/main/java/org/keycloak/storage/jpa/JpaUserFederatedStorageProvider.java @@ -30,18 +30,11 @@ import org.keycloak.models.ProtocolMapperModel; import org.keycloak.models.RealmModel; import org.keycloak.models.RoleModel; import org.keycloak.models.UserConsentModel; -import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserModel; import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.storage.StorageId; import org.keycloak.storage.UserStorageProvider; -import org.keycloak.storage.federated.UserAttributeFederatedStorage; -import org.keycloak.storage.federated.UserBrokerLinkFederatedStorage; -import org.keycloak.storage.federated.UserConsentFederatedStorage; import org.keycloak.storage.federated.UserFederatedStorageProvider; -import org.keycloak.storage.federated.UserGroupMembershipFederatedStorage; -import org.keycloak.storage.federated.UserRequiredActionsFederatedStorage; -import org.keycloak.storage.federated.UserRoleMappingsFederatedStorage; import org.keycloak.storage.jpa.entity.BrokerLinkEntity; import org.keycloak.storage.jpa.entity.FederatedUser; import org.keycloak.storage.jpa.entity.FederatedUserAttributeEntity; @@ -794,38 +787,6 @@ public class JpaUserFederatedStorageProvider implements .setParameter("realmId", realm.getId()).executeUpdate(); } - @Override - public void preRemove(RealmModel realm, UserFederationProviderModel link) { - int num = em.createNamedQuery("deleteFederatedUserRoleMappingsByRealmAndLink") - .setParameter("realmId", realm.getId()) - .setParameter("link", link.getId()) - .executeUpdate(); - num = em.createNamedQuery("deleteFederatedUserRequiredActionsByRealmAndLink") - .setParameter("realmId", realm.getId()) - .setParameter("link", link.getId()) - .executeUpdate(); - num = em.createNamedQuery("deleteBrokerLinkByRealmAndLink") - .setParameter("realmId", realm.getId()) - .setParameter("link", link.getId()) - .executeUpdate(); - num = em.createNamedQuery("deleteFederatedCredentialAttributeByRealmAndLink") - .setParameter("realmId", realm.getId()) - .setParameter("link", link.getId()) - .executeUpdate(); - num = em.createNamedQuery("deleteFederatedUserCredentialsByRealmAndLink") - .setParameter("realmId", realm.getId()) - .setParameter("link", link.getId()) - .executeUpdate(); - num = em.createNamedQuery("deleteUserFederatedAttributesByRealmAndLink") - .setParameter("realmId", realm.getId()) - .setParameter("link", link.getId()) - .executeUpdate(); - num = em.createNamedQuery("deleteFederatedUsersByRealmAndLink") - .setParameter("realmId", realm.getId()) - .setParameter("link", link.getId()) - .executeUpdate(); - } - @Override public void preRemove(RealmModel realm, RoleModel role) { em.createNamedQuery("deleteFederatedUserRoleMappingsByRole").setParameter("roleId", role.getId()).executeUpdate(); 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 6ef597e662..dd4d7a6d82 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 @@ -28,7 +28,6 @@ import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext; import org.keycloak.credential.CredentialModel; import org.keycloak.credential.UserCredentialStore; import org.keycloak.models.ClientModel; -import org.keycloak.models.CredentialValidationOutput; import org.keycloak.models.FederatedIdentityModel; import org.keycloak.models.GroupModel; import org.keycloak.models.KeycloakSession; @@ -39,8 +38,6 @@ import org.keycloak.models.RealmModel; import org.keycloak.models.RequiredActionProviderModel; import org.keycloak.models.RoleModel; import org.keycloak.models.UserConsentModel; -import org.keycloak.models.UserCredentialModel; -import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserManager; import org.keycloak.models.UserModel; import org.keycloak.models.UserProvider; @@ -457,17 +454,6 @@ public class MongoUserProvider implements UserProvider, UserCredentialStore { getMongoStore().removeEntities(MongoUserEntity.class, query, true, invocationContext); } - @Override - public void preRemove(RealmModel realm, UserFederationProviderModel link) { - // Remove all users linked with federationProvider and their consents - DBObject query = new QueryBuilder() - .and("realmId").is(realm.getId()) - .and("federationLink").is(link.getId()) - .get(); - getMongoStore().removeEntities(MongoUserEntity.class, query, true, invocationContext); - - } - @Override public void preRemove(RealmModel realm, ClientModel client) { // Remove all role mappings and consents mapped to all roles of this client 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 f92482fcdf..d581710fbc 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 @@ -32,7 +32,6 @@ import org.keycloak.models.GroupModel; import org.keycloak.models.IdentityProviderMapperModel; import org.keycloak.models.IdentityProviderModel; import org.keycloak.models.KeycloakSession; -import org.keycloak.models.ModelDuplicateException; import org.keycloak.models.ModelException; import org.keycloak.models.OTPPolicy; import org.keycloak.models.PasswordPolicy; @@ -41,9 +40,6 @@ import org.keycloak.models.RealmProvider; import org.keycloak.models.RequiredActionProviderModel; import org.keycloak.models.RequiredCredentialModel; import org.keycloak.models.RoleModel; -import org.keycloak.models.UserFederationMapperModel; -import org.keycloak.models.UserFederationProviderCreationEventImpl; -import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.mongo.keycloak.entities.AuthenticationExecutionEntity; import org.keycloak.models.mongo.keycloak.entities.AuthenticationFlowEntity; import org.keycloak.models.mongo.keycloak.entities.AuthenticatorConfigEntity; @@ -56,15 +52,12 @@ import org.keycloak.models.mongo.keycloak.entities.MongoRealmEntity; import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity; import org.keycloak.models.mongo.keycloak.entities.RequiredActionProviderEntity; import org.keycloak.models.mongo.keycloak.entities.RequiredCredentialEntity; -import org.keycloak.models.mongo.keycloak.entities.UserFederationMapperEntity; -import org.keycloak.models.mongo.keycloak.entities.UserFederationProviderEntity; import org.keycloak.models.utils.ComponentUtil; import org.keycloak.models.utils.KeycloakModelUtils; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; diff --git a/model/mongo/src/main/java/org/keycloak/storage/mongo/MongoUserFederatedStorageProvider.java b/model/mongo/src/main/java/org/keycloak/storage/mongo/MongoUserFederatedStorageProvider.java index adc681e51c..a5f66ef577 100644 --- a/model/mongo/src/main/java/org/keycloak/storage/mongo/MongoUserFederatedStorageProvider.java +++ b/model/mongo/src/main/java/org/keycloak/storage/mongo/MongoUserFederatedStorageProvider.java @@ -33,27 +33,18 @@ import org.keycloak.models.ProtocolMapperModel; import org.keycloak.models.RealmModel; import org.keycloak.models.RoleModel; import org.keycloak.models.UserConsentModel; -import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserModel; import org.keycloak.models.mongo.keycloak.entities.CredentialEntity; import org.keycloak.models.mongo.keycloak.entities.FederatedIdentityEntity; -import org.keycloak.models.mongo.keycloak.entities.MongoUserEntity; import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.storage.StorageId; import org.keycloak.storage.UserStorageProvider; -import org.keycloak.storage.federated.UserAttributeFederatedStorage; -import org.keycloak.storage.federated.UserBrokerLinkFederatedStorage; -import org.keycloak.storage.federated.UserConsentFederatedStorage; import org.keycloak.storage.federated.UserFederatedStorageProvider; -import org.keycloak.storage.federated.UserGroupMembershipFederatedStorage; -import org.keycloak.storage.federated.UserRequiredActionsFederatedStorage; -import org.keycloak.storage.federated.UserRoleMappingsFederatedStorage; import org.keycloak.storage.mongo.entity.FederatedUser; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Set; @@ -220,11 +211,6 @@ public class MongoUserFederatedStorageProvider implements getMongoStore().removeEntities(FederatedUser.class, query, true, invocationContext); } - @Override - public void preRemove(RealmModel realm, UserFederationProviderModel link) { - - } - @Override public void preRemove(RealmModel realm, GroupModel group) { DBObject query = new QueryBuilder() diff --git a/server-spi-private/src/main/java/org/keycloak/mappers/FederationConfigValidationException.java b/server-spi-private/src/main/java/org/keycloak/mappers/FederationConfigValidationException.java deleted file mode 100644 index cf58b0bdd3..0000000000 --- a/server-spi-private/src/main/java/org/keycloak/mappers/FederationConfigValidationException.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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.mappers; - -/** - * @author Marek Posolda - */ -public class FederationConfigValidationException extends Exception { - - private Object[] parameters; - - public FederationConfigValidationException(String message) { - super(message); - } - - public FederationConfigValidationException(String message, Throwable cause) { - super(message, cause); - } - - public FederationConfigValidationException(String message, Object ... parameters) { - super(message); - this.parameters = parameters; - } - - public Object[] getParameters() { - return parameters; - } - - public void setParameters(Object[] parameters) { - this.parameters = parameters; - } -} diff --git a/server-spi-private/src/main/java/org/keycloak/mappers/UserFederationMapper.java b/server-spi-private/src/main/java/org/keycloak/mappers/UserFederationMapper.java deleted file mode 100644 index 9e4be6f822..0000000000 --- a/server-spi-private/src/main/java/org/keycloak/mappers/UserFederationMapper.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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.mappers; - -import org.keycloak.models.GroupModel; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserFederationMapperModel; -import org.keycloak.models.UserFederationProvider; -import org.keycloak.models.UserFederationSyncResult; -import org.keycloak.models.UserModel; -import org.keycloak.provider.Provider; - -import java.util.List; - -/** - * @author Marek Posolda - */ -public interface UserFederationMapper extends Provider { - - /** - * Sync data from federated storage to Keycloak. It's useful just if mapper needs some data preloaded from federated storage (For example - * load roles from federated provider and sync them to Keycloak database) - * - * Applicable just if sync is supported (see UserFederationMapperFactory.getSyncConfig() ) - * - * @see UserFederationMapperFactory#getSyncConfig() - * @param mapperModel - * @param federationProvider - * @param session - * @param realm - */ - UserFederationSyncResult syncDataFromFederationProviderToKeycloak(UserFederationMapperModel mapperModel, UserFederationProvider federationProvider, KeycloakSession session, RealmModel realm); - - /** - * Sync data from Keycloak back to federated storage - * - * @see UserFederationMapperFactory#getSyncConfig() - * @param mapperModel - * @param federationProvider - * @param session - * @param realm - */ - UserFederationSyncResult syncDataFromKeycloakToFederationProvider(UserFederationMapperModel mapperModel, UserFederationProvider federationProvider, KeycloakSession session, RealmModel realm); - - /** - * Return empty list if doesn't support storing of groups - */ - List getGroupMembers(UserFederationMapperModel mapperModel, UserFederationProvider federationProvider, RealmModel realm, GroupModel group, int firstResult, int maxResults); -} diff --git a/server-spi-private/src/main/java/org/keycloak/mappers/UserFederationMapperFactory.java b/server-spi-private/src/main/java/org/keycloak/mappers/UserFederationMapperFactory.java deleted file mode 100644 index 023d1819eb..0000000000 --- a/server-spi-private/src/main/java/org/keycloak/mappers/UserFederationMapperFactory.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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.mappers; - -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserFederationMapperModel; -import org.keycloak.models.UserFederationProviderModel; -import org.keycloak.provider.ConfiguredProvider; -import org.keycloak.provider.ProviderFactory; -import org.keycloak.representations.idm.UserFederationMapperSyncConfigRepresentation; - -import java.util.Map; - -/** - * @author Marek Posolda - */ -public interface UserFederationMapperFactory extends ProviderFactory, ConfiguredProvider { - - /** - * Refers to providerName (type) of the federated provider, which this mapper can be used for. For example "ldap" or "kerberos" - * - * @return providerName - */ - String getFederationProviderType(); - - String getDisplayCategory(); - String getDisplayType(); - - /** - * Specifies if mapper supports sync data from federated storage to keycloak and viceversa. - * Also specifies messages to be displayed in admin console UI (For example "Sync roles from LDAP" etc) - * - * @return syncConfig representation - */ - UserFederationMapperSyncConfigRepresentation getSyncConfig(); - - /** - * Called when instance of mapperModel is created for this factory through admin endpoint - * - * @param realm - * @param fedProviderModel - * @param mapperModel - * @throws FederationConfigValidationException if configuration provided in mapperModel is not valid - */ - void validateConfig(RealmModel realm, UserFederationProviderModel fedProviderModel, UserFederationMapperModel mapperModel) throws FederationConfigValidationException; - - /** - * Used to detect what are default values for ProviderConfigProperties specified during mapper creation - * - * @return - */ - Map getDefaultConfig(UserFederationProviderModel providerModel); - -} diff --git a/server-spi-private/src/main/java/org/keycloak/mappers/UserFederationMapperSpi.java b/server-spi-private/src/main/java/org/keycloak/mappers/UserFederationMapperSpi.java deleted file mode 100644 index bea07f8012..0000000000 --- a/server-spi-private/src/main/java/org/keycloak/mappers/UserFederationMapperSpi.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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.mappers; - -import org.keycloak.provider.Provider; -import org.keycloak.provider.ProviderFactory; -import org.keycloak.provider.Spi; - -/** - * @author Marek Posolda - */ -public class UserFederationMapperSpi implements Spi { - - @Override - public String getName() { - return "userFederationMapper"; - } - - @Override - public Class getProviderClass() { - return UserFederationMapper.class; - } - - @Override - public Class getProviderFactoryClass() { - return UserFederationMapperFactory.class; - } - - @Override - public boolean isInternal() { - return true; - } -} diff --git a/server-spi-private/src/main/java/org/keycloak/models/UserFederationEventAwareProviderFactory.java b/server-spi-private/src/main/java/org/keycloak/models/UserFederationEventAwareProviderFactory.java deleted file mode 100644 index 05e5929316..0000000000 --- a/server-spi-private/src/main/java/org/keycloak/models/UserFederationEventAwareProviderFactory.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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.models; - -import org.keycloak.provider.ProviderEvent; -import org.keycloak.provider.ProviderEventListener; - -/** - * Provides "onProviderModelCreated" callback invoked when UserFederationProviderModel for this factory implementation is created in realm - * - * @author Marek Posolda - */ -public abstract class UserFederationEventAwareProviderFactory implements UserFederationProviderFactory { - - @Override - public void postInit(KeycloakSessionFactory factory) { - factory.register(new ProviderEventListener() { - - @Override - public void onEvent(ProviderEvent event) { - if (event instanceof RealmModel.UserFederationProviderCreationEvent) { - RealmModel.UserFederationProviderCreationEvent fedCreationEvent = (RealmModel.UserFederationProviderCreationEvent)event; - UserFederationProviderModel providerModel = fedCreationEvent.getCreatedFederationProvider(); - - if (providerModel.getProviderName().equals(getId())) { - onProviderModelCreated(fedCreationEvent.getRealm(), providerModel); - } - } - } - - }); - } - - public abstract void onProviderModelCreated(RealmModel realm, UserFederationProviderModel createdProviderModel); -} diff --git a/server-spi-private/src/main/java/org/keycloak/models/UserFederationProviderCreationEventImpl.java b/server-spi-private/src/main/java/org/keycloak/models/UserFederationProviderCreationEventImpl.java deleted file mode 100644 index c5468a73db..0000000000 --- a/server-spi-private/src/main/java/org/keycloak/models/UserFederationProviderCreationEventImpl.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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.models; - -/** - * @author Marek Posolda - */ -public class UserFederationProviderCreationEventImpl implements RealmModel.UserFederationProviderCreationEvent { - - private final UserFederationProviderModel createdFederationProvider; - private final RealmModel realm; - - public UserFederationProviderCreationEventImpl(RealmModel realm, UserFederationProviderModel createdFederationProvider) { - this.realm = realm; - this.createdFederationProvider = createdFederationProvider; - } - - @Override - public UserFederationProviderModel getCreatedFederationProvider() { - return createdFederationProvider; - } - - @Override - public RealmModel getRealm() { - return realm; - } -} diff --git a/server-spi-private/src/main/java/org/keycloak/models/UserFederationSpi.java b/server-spi-private/src/main/java/org/keycloak/models/UserFederationSpi.java deleted file mode 100755 index 11ef8a8eaf..0000000000 --- a/server-spi-private/src/main/java/org/keycloak/models/UserFederationSpi.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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.models; - -import org.keycloak.provider.Provider; -import org.keycloak.provider.ProviderFactory; -import org.keycloak.provider.Spi; - -/** - * @author Stian Thorgersen - */ -public class UserFederationSpi implements Spi { - - @Override - public boolean isInternal() { - return true; - } - - @Override - public String getName() { - return "userFederation"; - } - - @Override - public Class getProviderClass() { - return UserFederationProvider.class; - } - - @Override - public Class getProviderFactoryClass() { - return UserFederationProviderFactory.class; - } - -} diff --git a/server-spi-private/src/main/java/org/keycloak/models/UserFederationValidatingProviderFactory.java b/server-spi-private/src/main/java/org/keycloak/models/UserFederationValidatingProviderFactory.java deleted file mode 100644 index 9624690236..0000000000 --- a/server-spi-private/src/main/java/org/keycloak/models/UserFederationValidatingProviderFactory.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.models; - -import org.keycloak.mappers.FederationConfigValidationException; - -/** - * TODO: Merge with UserFederationProviderFactory and add "default" method validateConfig with empty body once we move to source level 1.8 - * - * @author Marek Posolda - */ -public interface UserFederationValidatingProviderFactory extends UserFederationProviderFactory { - - /** - * Called when instance of mapperModel is created for this factory through admin endpoint - * - * @param realm - * @param providerModel - * @throws FederationConfigValidationException if configuration provided in mapperModel is not valid - */ - void validateConfig(RealmModel realm, UserFederationProviderModel providerModel) throws FederationConfigValidationException; -} diff --git a/server-spi-private/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java b/server-spi-private/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java index 80e45e4fad..c0f28db92b 100755 --- a/server-spi-private/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java +++ b/server-spi-private/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java @@ -22,11 +22,8 @@ import org.keycloak.broker.social.SocialIdentityProviderFactory; import org.keycloak.common.util.Base64Url; import org.keycloak.common.util.CertificateUtils; import org.keycloak.common.util.KeyUtils; -import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.common.util.PemUtils; -import org.keycloak.component.ComponentFactory; import org.keycloak.component.ComponentModel; -import org.keycloak.keys.KeyProvider; import org.keycloak.models.AuthenticationExecutionModel; import org.keycloak.models.AuthenticationFlowModel; import org.keycloak.models.ClientModel; @@ -38,19 +35,12 @@ import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.models.KeycloakSessionTask; import org.keycloak.models.KeycloakTransaction; -import org.keycloak.models.ModelDuplicateException; import org.keycloak.models.RealmModel; import org.keycloak.models.RoleContainerModel; import org.keycloak.models.RoleModel; import org.keycloak.models.ScopeContainerModel; import org.keycloak.models.UserCredentialModel; -import org.keycloak.models.UserFederationMapperModel; -import org.keycloak.models.UserFederationProvider; -import org.keycloak.models.UserFederationProviderFactory; -import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserModel; -import org.keycloak.provider.Provider; -import org.keycloak.provider.ProviderFactory; import org.keycloak.representations.idm.CertificateRepresentation; import org.keycloak.storage.UserStorageProviderModel; import org.keycloak.transaction.JtaTransactionManagerLookup; @@ -61,20 +51,15 @@ import javax.transaction.SystemException; import javax.transaction.Transaction; import java.security.Key; import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.X509Certificate; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Set; import java.util.UUID; -import java.util.stream.StreamSupport; /** * Set of helper methods, which are useful in various model implementations. @@ -259,29 +244,6 @@ public final class KeycloakModelUtils { // USER FEDERATION RELATED STUFF - /** - * Ensure that displayName of myProvider (if not null) is unique and there is no other provider with same displayName in the list. - * - * @param displayName to check for duplications - * @param myProvider provider, which is excluded from the list (if present) - * @param federationProviders - * @throws ModelDuplicateException if there is other provider with same displayName - */ - public static void ensureUniqueDisplayName(String displayName, UserFederationProviderModel myProvider, List federationProviders) throws ModelDuplicateException { - if (displayName != null) { - - for (UserFederationProviderModel federationProvider : federationProviders) { - if (myProvider != null && (myProvider.equals(federationProvider) || (myProvider.getId() != null && myProvider.getId().equals(federationProvider.getId())))) { - continue; - } - - if (displayName.equals(federationProvider.getDisplayName())) { - throw new ModelDuplicateException("There is already existing federation provider with display name: " + displayName); - } - } - } - } - public static UserStorageProviderModel findUserStorageProviderByName(String displayName, RealmModel realm) { if (displayName == null) { @@ -329,41 +291,6 @@ public final class KeycloakModelUtils { } - - public static UserFederationMapperModel createUserFederationMapperModel(String name, String federationProviderId, String mapperType, String... config) { - UserFederationMapperModel mapperModel = new UserFederationMapperModel(); - mapperModel.setName(name); - mapperModel.setFederationProviderId(federationProviderId); - mapperModel.setFederationMapperType(mapperType); - - Map configMap = new HashMap<>(); - String key = null; - for (String configEntry : config) { - if (key == null) { - key = configEntry; - } else { - configMap.put(key, configEntry); - key = null; - } - } - if (key != null) { - throw new IllegalStateException("Invalid count of arguments for config. Maybe mistake?"); - } - mapperModel.setConfig(configMap); - - return mapperModel; - } - - public static UserFederationProviderFactory getFederationProviderFactory(KeycloakSession session, UserFederationProviderModel model) { - return (UserFederationProviderFactory)session.getKeycloakSessionFactory().getProviderFactory(UserFederationProvider.class, model.getProviderName()); - } - - public static UserFederationProvider getFederationProviderInstance(KeycloakSession session, UserFederationProviderModel model) { - UserFederationProviderFactory factory = getFederationProviderFactory(session, model); - return factory.getInstance(session, model); - - } - // END USER FEDERATION RELATED STUFF public static String toLowerCaseSafe(String str) { diff --git a/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java b/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java index a8255c1197..26a30b487a 100755 --- a/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java +++ b/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java @@ -52,8 +52,6 @@ import org.keycloak.models.RequiredCredentialModel; import org.keycloak.models.RoleModel; import org.keycloak.models.UserConsentModel; import org.keycloak.models.UserCredentialModel; -import org.keycloak.models.UserFederationMapperModel; -import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserModel; import org.keycloak.models.UserSessionModel; import org.keycloak.provider.ProviderConfigProperty; @@ -78,8 +76,6 @@ import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RequiredActionProviderRepresentation; import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.representations.idm.UserConsentRepresentation; -import org.keycloak.representations.idm.UserFederationMapperRepresentation; -import org.keycloak.representations.idm.UserFederationProviderRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserSessionRepresentation; import org.keycloak.representations.idm.authorization.PolicyRepresentation; @@ -574,19 +570,6 @@ public class ModelToRepresentation { return rep; } - public static UserFederationProviderRepresentation toRepresentation(UserFederationProviderModel model) { - UserFederationProviderRepresentation rep = new UserFederationProviderRepresentation(); - rep.setId(model.getId()); - rep.setConfig(model.getConfig()); - rep.setProviderName(model.getProviderName()); - rep.setPriority(model.getPriority()); - rep.setDisplayName(model.getDisplayName()); - rep.setFullSyncPeriod(model.getFullSyncPeriod()); - rep.setChangedSyncPeriod(model.getChangedSyncPeriod()); - rep.setLastSync(model.getLastSync()); - return rep; - } - public static IdentityProviderRepresentation toRepresentation(RealmModel realm, IdentityProviderModel identityProviderModel) { IdentityProviderRepresentation providerRep = new IdentityProviderRepresentation(); diff --git a/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java index 44fed9c7e2..75f46f5d8a 100755 --- a/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java +++ b/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java @@ -62,8 +62,6 @@ import org.keycloak.models.RoleModel; import org.keycloak.models.ScopeContainerModel; import org.keycloak.models.UserConsentModel; import org.keycloak.models.UserCredentialModel; -import org.keycloak.models.UserFederationMapperModel; -import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserModel; import org.keycloak.provider.ProviderConfigProperty; import org.keycloak.representations.idm.ApplicationRepresentation; @@ -113,7 +111,6 @@ import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.Set; -import java.util.TreeSet; import java.util.function.Function; import java.util.stream.Collectors; @@ -367,11 +364,9 @@ public class RepresentationToModel { mapperConvertSet.put(LDAPConstants.LDAP_PROVIDER, "org.keycloak.storage.ldap.mappers.LDAPStorageMapper"); - List providerModels = null; Map userStorageModels = new HashMap<>(); if (rep.getUserFederationProviders() != null) { - providerModels = new LinkedList<>(); for (UserFederationProviderRepresentation fedRep : rep.getUserFederationProviders()) { if (convertSet.contains(fedRep.getProviderName())) { ComponentModel component = convertFedProviderToComponent(newRealm.getId(), fedRep); @@ -869,22 +864,6 @@ public class RepresentationToModel { // Basic realm stuff - private static List convertFederationProviders(List providers) { - List result = new ArrayList(); - - for (UserFederationProviderRepresentation representation : providers) { - UserFederationProviderModel model = convertFederationProvider(representation); - result.add(model); - } - return result; - } - - private static UserFederationProviderModel convertFederationProvider(UserFederationProviderRepresentation representation) { - return new UserFederationProviderModel(representation.getId(), representation.getProviderName(), - representation.getConfig(), representation.getPriority(), representation.getDisplayName(), - representation.getFullSyncPeriod(), representation.getChangedSyncPeriod(), representation.getLastSync()); - } - public static ComponentModel convertFedProviderToComponent(String realmId, UserFederationProviderRepresentation fedModel) { UserStorageProviderModel model = new UserStorageProviderModel(); model.setId(fedModel.getId()); @@ -1368,7 +1347,7 @@ public class RepresentationToModel { convertDeprecatedSocialProviders(userRep); // Import users just to user storage. Don't federate - UserModel user = session.userStorage().addUser(newRealm, userRep.getId(), userRep.getUsername(), false, false); + UserModel user = session.userLocalStorage().addUser(newRealm, userRep.getId(), userRep.getUsername(), false, false); user.setEnabled(userRep.isEnabled() != null && userRep.isEnabled()); user.setCreatedTimestamp(userRep.getCreatedTimestamp()); user.setEmail(userRep.getEmail()); @@ -1400,7 +1379,7 @@ public class RepresentationToModel { if (userRep.getClientConsents() != null) { for (UserConsentRepresentation consentRep : userRep.getClientConsents()) { UserConsentModel consentModel = toModel(newRealm, consentRep); - session.userStorage().addConsent(newRealm, user.getId(), consentModel); + session.users().addConsent(newRealm, user.getId(), consentModel); } } if (userRep.getServiceAccountClientId() != null) { diff --git a/server-spi-private/src/main/resources/META-INF/services/org.keycloak.provider.Spi b/server-spi-private/src/main/resources/META-INF/services/org.keycloak.provider.Spi index bbd588ea50..0ddc9da6c9 100755 --- a/server-spi-private/src/main/resources/META-INF/services/org.keycloak.provider.Spi +++ b/server-spi-private/src/main/resources/META-INF/services/org.keycloak.provider.Spi @@ -15,10 +15,8 @@ # limitations under the License. # -org.keycloak.models.UserFederationSpi org.keycloak.storage.UserStorageProviderSpi org.keycloak.storage.federated.UserFederatedStorageProviderSpi -org.keycloak.mappers.UserFederationMapperSpi org.keycloak.models.RealmSpi org.keycloak.models.UserSessionSpi org.keycloak.models.UserSpi diff --git a/server-spi/src/main/java/org/keycloak/models/KeycloakSession.java b/server-spi/src/main/java/org/keycloak/models/KeycloakSession.java index c91331a74e..766078d769 100755 --- a/server-spi/src/main/java/org/keycloak/models/KeycloakSession.java +++ b/server-spi/src/main/java/org/keycloak/models/KeycloakSession.java @@ -110,10 +110,10 @@ public interface KeycloakSession { * * @return may be null if cache is disabled */ - UserCache getUserCache(); + UserCache userCache(); /** - * A cached view of all users in system including deprecated UserFederationProvider SPI + * A cached view of all users in system including users loaded by UserStorageProviders * * @return */ @@ -121,18 +121,18 @@ public interface KeycloakSession { /** - * Un-cached view of all users in system that does NOT include users available from the deprecated UserFederationProvider SPI. + * Un-cached view of all users in system including users loaded by UserStorageProviders * * @return */ UserProvider userStorageManager(); - UserCredentialManager userCredentialManager(); - /** - * A cached view of all users in system that does NOT include users available from the deprecated UserFederationProvider SPI. + * Service that allows you to valid and update credentials for a user + * + * @return */ - UserProvider userStorage(); + UserCredentialManager userCredentialManager(); /** * Keycloak specific local storage for users. No cache in front, this api talks directly to database configured for Keycloak diff --git a/server-spi/src/main/java/org/keycloak/models/RealmModel.java b/server-spi/src/main/java/org/keycloak/models/RealmModel.java index d65452b579..4409b9d88d 100755 --- a/server-spi/src/main/java/org/keycloak/models/RealmModel.java +++ b/server-spi/src/main/java/org/keycloak/models/RealmModel.java @@ -67,11 +67,6 @@ public interface RealmModel extends RoleContainerModel { KeycloakSession getKeycloakSession(); } - interface UserFederationProviderCreationEvent extends ProviderEvent { - UserFederationProviderModel getCreatedFederationProvider(); - RealmModel getRealm(); - } - String getId(); String getName(); diff --git a/server-spi/src/main/java/org/keycloak/models/UserFederationManager.java b/server-spi/src/main/java/org/keycloak/models/UserFederationManager.java deleted file mode 100755 index 0ff7f5cd89..0000000000 --- a/server-spi/src/main/java/org/keycloak/models/UserFederationManager.java +++ /dev/null @@ -1,314 +0,0 @@ -/* - * 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.models; - -import org.jboss.logging.Logger; -import org.keycloak.component.ComponentModel; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public class UserFederationManager implements UserProvider { - - private static final Logger logger = Logger.getLogger(UserFederationManager.class); - - protected KeycloakSession session; - - // Set of already validated/proxied federation users during this session. Key is user ID - private Map managedUsers = new HashMap<>(); - - public UserFederationManager(KeycloakSession session) { - this.session = session; - } - - @Override - public UserModel addUser(RealmModel realm, String id, String username, boolean addDefaultRoles, boolean addDefaultRequiredActions) { - UserModel user = session.userStorage().addUser(realm, id, username.toLowerCase(), addDefaultRoles, addDefaultRequiredActions); - return user; - } - - @Override - public UserModel addUser(RealmModel realm, String username) { - UserModel user = session.userStorage().addUser(realm, username.toLowerCase()); - return user; - } - - @Override - public boolean removeUser(RealmModel realm, UserModel user) { - return session.userStorage().removeUser(realm, user); - - } - - @Override - public void addFederatedIdentity(RealmModel realm, UserModel user, FederatedIdentityModel socialLink) { - session.userStorage().addFederatedIdentity(realm, user, socialLink); - } - - public void updateFederatedIdentity(RealmModel realm, UserModel federatedUser, FederatedIdentityModel federatedIdentityModel) { - session.userStorage().updateFederatedIdentity(realm, federatedUser, federatedIdentityModel); - } - - @Override - public boolean removeFederatedIdentity(RealmModel realm, UserModel user, String socialProvider) { - if (user == null) throw new IllegalStateException("Federated user no longer valid"); - return session.userStorage().removeFederatedIdentity(realm, user, socialProvider); - } - - @Override - public void addConsent(RealmModel realm, String userId, UserConsentModel consent) { - session.userStorage().addConsent(realm, userId, consent); - - } - - @Override - public UserConsentModel getConsentByClient(RealmModel realm, String userId, String clientInternalId) { - return session.userStorage().getConsentByClient(realm, userId, clientInternalId); - } - - @Override - public List getConsents(RealmModel realm, String userId) { - return session.userStorage().getConsents(realm, userId); - } - - @Override - public void updateConsent(RealmModel realm, String userId, UserConsentModel consent) { - session.userStorage().updateConsent(realm, userId, consent); - - } - - @Override - public boolean revokeConsentForClient(RealmModel realm, String userId, String clientInternalId) { - return session.userStorage().revokeConsentForClient(realm, userId, clientInternalId); - } - - @Override - public UserModel getUserById(String id, RealmModel realm) { - UserModel user = session.userStorage().getUserById(id, realm); - return user; - } - - @Override - public List getGroupMembers(RealmModel realm, final GroupModel group, int firstResult, int maxResults) { - // Not very effective. For the page X, it is loading also all previous pages 0..X-1 . Improve if needed... - int maxTotal = firstResult + maxResults; - List localMembers = query(new PaginatedQuery() { - - @Override - public List query(RealmModel realm, int first, int max) { - return session.userStorage().getGroupMembers(realm, group, first, max); - } - - }, realm, 0, maxTotal); - - Set result = new LinkedHashSet<>(localMembers); - - if (result.size() <= firstResult) { - return Collections.emptyList(); - } - - int max = Math.min(maxTotal, result.size()); - return new ArrayList<>(result).subList(firstResult, max); - } - - @Override - public List getGroupMembers(RealmModel realm, GroupModel group) { - return getGroupMembers(realm, group, -1, -1); - } - - @Override - public UserModel getUserByUsername(String username, RealmModel realm) { - UserModel user = session.userStorage().getUserByUsername(username.toLowerCase(), realm); - return user; - } - - @Override - public UserModel getUserByEmail(String email, RealmModel realm) { - UserModel user = session.userStorage().getUserByEmail(email.toLowerCase(), realm); - return user; - } - - @Override - public UserModel getUserByFederatedIdentity(FederatedIdentityModel socialLink, RealmModel realm) { - UserModel user = session.userStorage().getUserByFederatedIdentity(socialLink, realm); - return user; - } - - @Override - public UserModel getServiceAccount(ClientModel client) { - UserModel user = session.userStorage().getServiceAccount(client); - return user; - } - - @Override - public List getUsers(RealmModel realm, boolean includeServiceAccounts) { - return getUsers(realm, 0, Integer.MAX_VALUE - 1, includeServiceAccounts); - - } - - @Override - public List getUsers(RealmModel realm) { - return getUsers(realm, false); - } - - @Override - public List getUsers(RealmModel realm, int firstResult, int maxResults) { - return getUsers(realm, firstResult, maxResults, false); - } - - @Override - public int getUsersCount(RealmModel realm) { - return session.userStorage().getUsersCount(realm); - } - - interface PaginatedQuery { - List query(RealmModel realm, int first, int max); - } - - protected List query(PaginatedQuery pagedQuery, RealmModel realm, int firstResult, int maxResults) { - List results = new LinkedList(); - if (maxResults == 0) return results; - int first = firstResult; - int max = maxResults; - do { - List query = pagedQuery.query(realm, first, max); - if (query == null || query.size() == 0) return results; - int added = 0; - for (UserModel user : query) { - results.add(user); - added++; - } - if (results.size() == maxResults) return results; - if (query.size() < max) return results; - first = query.size(); - max -= added; - if (max <= 0) return results; - } while (true); - } - - @Override - public List getUsers(RealmModel realm, int firstResult, int maxResults, final boolean includeServiceAccounts) { - return query(new PaginatedQuery() { - @Override - public List query(RealmModel realm, int first, int max) { - return session.userStorage().getUsers(realm, first, max, includeServiceAccounts); - } - }, realm, firstResult, maxResults); - } - - @Override - public List searchForUser(String search, RealmModel realm) { - return searchForUser(search, realm, 0, Integer.MAX_VALUE - 1); - } - - @Override - public List searchForUser(final String search, RealmModel realm, int firstResult, int maxResults) { - return query(new PaginatedQuery() { - @Override - public List query(RealmModel realm, int first, int max) { - return session.userStorage().searchForUser(search, realm, first, max); - } - }, realm, firstResult, maxResults); - } - - @Override - public List searchForUser(Map attributes, RealmModel realm) { - return searchForUser(attributes, realm, 0, Integer.MAX_VALUE - 1); - } - - @Override - public List searchForUser(final Map attributes, RealmModel realm, int firstResult, int maxResults) { - return query(new PaginatedQuery() { - @Override - public List query(RealmModel realm, int first, int max) { - return session.userStorage().searchForUser(attributes, realm, first, max); - } - }, realm, firstResult, maxResults); - } - - @Override - public List searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm) { - return session.userStorage().searchForUserByUserAttribute(attrName, attrValue, realm); - } - - @Override - public Set getFederatedIdentities(UserModel user, RealmModel realm) { - return session.userStorage().getFederatedIdentities(user, realm); - } - - @Override - public FederatedIdentityModel getFederatedIdentity(UserModel user, String socialProvider, RealmModel realm) { - return session.userStorage().getFederatedIdentity(user, socialProvider, realm); - } - - @Override - public void grantToAllUsers(RealmModel realm, RoleModel role) { - // not federation-aware for now - session.userStorage().grantToAllUsers(realm, role); - } - - @Override - public void preRemove(RealmModel realm) { - session.userStorage().preRemove(realm); - } - - @Override - public void preRemove(RealmModel realm, UserFederationProviderModel model) { - session.userStorage().preRemove(realm, model); - } - - @Override - public void preRemove(RealmModel realm, GroupModel group) { - session.userStorage().preRemove(realm, group); - - } - - @Override - public void preRemove(RealmModel realm, RoleModel role) { - session.userStorage().preRemove(realm, role); - } - - @Override - public void preRemove(RealmModel realm, ClientModel client) { - session.userStorage().preRemove(realm, client); - } - - @Override - public void preRemove(ProtocolMapperModel protocolMapper) { - session.userStorage().preRemove(protocolMapper); - } - - @Override - public void preRemove(RealmModel realm, ComponentModel component) { - session.userStorage().preRemove(realm, component); - - } - - @Override - public void close() { - } -} diff --git a/server-spi/src/main/java/org/keycloak/models/UserFederationMapperModel.java b/server-spi/src/main/java/org/keycloak/models/UserFederationMapperModel.java deleted file mode 100644 index 3e05d3240e..0000000000 --- a/server-spi/src/main/java/org/keycloak/models/UserFederationMapperModel.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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.models; - -import java.io.Serializable; -import java.util.Map; - -/** - * @author Marek Posolda - */ -public class UserFederationMapperModel implements Serializable { - - protected String id; - protected String name; - - // Refers to DB ID of federation provider - protected String federationProviderId; - - // Refers to ID of UserFederationMapper implementation ( UserFederationMapperFactory.getId ) - protected String federationMapperType; - - protected Map config; - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getFederationProviderId() { - return federationProviderId; - } - - public void setFederationProviderId(String federationProviderId) { - this.federationProviderId = federationProviderId; - } - - public String getFederationMapperType() { - return federationMapperType; - } - - public void setFederationMapperType(String federationMapperType) { - this.federationMapperType = federationMapperType; - } - - public Map getConfig() { - return config; - } - - public void setConfig(Map config) { - this.config = config; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - UserFederationMapperModel that = (UserFederationMapperModel) o; - - if (!id.equals(that.id)) return false; - - return true; - } - - @Override - public int hashCode() { - return id.hashCode(); - } - - @Override - public String toString() { - return new StringBuilder(" { name=" + name) - .append(", federationMapperType=" + federationMapperType) - .append(", config=" + config) - .append(" } ").toString(); - } -} diff --git a/server-spi/src/main/java/org/keycloak/models/UserFederationProvider.java b/server-spi/src/main/java/org/keycloak/models/UserFederationProvider.java deleted file mode 100755 index 69d17ec174..0000000000 --- a/server-spi/src/main/java/org/keycloak/models/UserFederationProvider.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * 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.models; - -import org.keycloak.credential.CredentialInputUpdater; -import org.keycloak.credential.CredentialInputValidator; -import org.keycloak.provider.Provider; - -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * SPI for plugging in federation storage. This class is instantiated once per session/request and is closed after - * the session/request is finished. - * - * @author Bill Burke - * @version $Revision: 1 $ - */ -@Deprecated -public interface UserFederationProvider extends Provider, CredentialInputValidator, CredentialInputUpdater { - - public static final String USERNAME = UserModel.USERNAME; - public static final String EMAIL = UserModel.EMAIL; - public static final String FIRST_NAME = UserModel.FIRST_NAME; - public static final String LAST_NAME = UserModel.LAST_NAME; - - /** - * Optional type that can be by implementations to describe edit mode of federation storage - * - */ - enum EditMode { - /** - * federation storage is read-only - */ - READ_ONLY, - /** - * federation storage is writable - * - */ - WRITABLE, - /** - * updates to user are stored locally and not synced with federation storage. - * - */ - UNSYNCED - } - - - /** - * Gives the provider an option to validate if user still exists in federation backend and then proxy UserModel loaded from local storage. - * This method is called whenever a UserModel is pulled from Keycloak local storage. - * For example, the LDAP provider proxies the UserModel and does on-demand synchronization with - * LDAP whenever UserModel update methods are invoked. It also overrides UserModel.updateCredential for the - * credential types it supports - * - * @param realm - * @param local - * @return null if user is no longer valid or proxy object otherwise - */ - UserModel validateAndProxy(RealmModel realm, UserModel local); - - /** - * Should user registrations be synchronized with this provider? - * FYI, only one provider will be chosen (by priority) to have this synchronization - * - * @return - */ - boolean synchronizeRegistrations(); - - /** - * Called if this federation provider has priority and supports synchronized registrations. - * - * @param realm - * @param user - * @return - */ - UserModel register(RealmModel realm, UserModel user); - boolean removeUser(RealmModel realm, UserModel user); - - /** - * Keycloak will search for user in local storage first. If it can't find the UserModel is local storage, - * it will call this method. You are required to import the returned UserModel into local storage. - * - * @param realm - * @param username - * @return - */ - UserModel getUserByUsername(RealmModel realm, String username); - - /** - * Keycloak will search for user in local storage first. If it can't find the UserModel is local storage, - * it will call this method. You are required to import the returned UserModel into local storage. - * - * @param realm - * @param email - * @return - */ - UserModel getUserByEmail(RealmModel realm, String email); - - /** - * Keycloak does not search in local storage first before calling this method. The implementation must check - * to see if user is already in local storage (KeycloakSession.userStorage()) before doing an import. - * Currently only attributes USERNAME, EMAIL, FIRST_NAME and LAST_NAME will be used. - * - * @param attributes - * @param realm - * @return - */ - List searchByAttributes(Map attributes, RealmModel realm, int maxResults); - - /** - * Return group members from federation storage. Useful if info about group memberships is stored in the federation storage. - * Return empty list if your federation provider doesn't support storing user-group memberships - * - * @param realm - * @param group - * @param firstResult - * @param maxResults - * @return - */ - List getGroupMembers(RealmModel realm, GroupModel group, int firstResult, int maxResults); - - /** - * called whenever a Realm is removed - * - * @param realm - */ - void preRemove(RealmModel realm); - - /** - * called before a role is removed. - * - * @param realm - * @param role - */ - void preRemove(RealmModel realm, RoleModel role); - - /** - * called before a role is removed. - * - * @param realm - * @param group - */ - void preRemove(RealmModel realm, GroupModel group); - - /** - * Is the Keycloak UserModel still valid and/or existing in federated storage? Keycloak may call this method - * in various user operations. The local storage may be deleted if this method returns false. - * - * @param realm - * @param local - * @return - */ - boolean isValid(RealmModel realm, UserModel local); - - /** - * What UserCredentialModel types should be handled by this provider? This is called in scenarios when we don't know user, - * who is going to authenticate (For example Kerberos authentication). - * - * @return - */ - Set getSupportedCredentialTypes(); - - /** - * Validate credentials of unknown user. The authenticated user is recognized based on provided credentials and returned back in CredentialValidationOutput - * @param realm - * @param credential - * @return - */ - CredentialValidationOutput validCredentials(RealmModel realm, UserCredentialModel credential); - - /** - * This method is called at the end of requests. - * - */ - void close(); - - - -} diff --git a/server-spi/src/main/java/org/keycloak/models/UserFederationProviderFactory.java b/server-spi/src/main/java/org/keycloak/models/UserFederationProviderFactory.java deleted file mode 100755 index 5d1ab36e99..0000000000 --- a/server-spi/src/main/java/org/keycloak/models/UserFederationProviderFactory.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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.models; - -import org.keycloak.provider.ProviderFactory; - -import java.util.Date; -import java.util.Set; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public interface UserFederationProviderFactory extends ProviderFactory { - /** - * called per Keycloak transaction. - * - * @param session - * @param model - * @return - */ - UserFederationProvider getInstance(KeycloakSession session, UserFederationProviderModel model); - - /** - * Config options to display in generic admin console page for federation - * - * @return - */ - Set getConfigurationOptions(); - - /** - * This is the name of the provider and will be showed in the admin console as an option. - * - * @return - */ - @Override - String getId(); - - /** - * Sync all users from the provider storage to Keycloak storage. Alternatively can update existing users or remove keycloak users, which are no longer - * available in federation storage (depends on the implementation) - * - * @param sessionFactory - * @param realmId - * @param model - * @return result with count of added/updated/removed users - */ - UserFederationSyncResult syncAllUsers(KeycloakSessionFactory sessionFactory, String realmId, UserFederationProviderModel model); - - /** - * Sync just changed (added / updated / removed) users from the provider storage to Keycloak storage. This is useful in case - * that your storage supports "changelogs" (Tracking what users changed since specified date). It's implementation specific to - * decide what exactly will be changed - * - * @param sessionFactory - * @param realmId - * @param model - * @param lastSync - */ - UserFederationSyncResult syncChangedUsers(KeycloakSessionFactory sessionFactory, String realmId, UserFederationProviderModel model, Date lastSync); - - /** - * This method is never called and is only an artifact of ProviderFactory. Returning null with no implementation is recommended. - * @param session - * @return - */ - @Override - UserFederationProvider create(KeycloakSession session); -} diff --git a/server-spi/src/main/java/org/keycloak/models/UserFederationProviderModel.java b/server-spi/src/main/java/org/keycloak/models/UserFederationProviderModel.java deleted file mode 100755 index 68e7733c9d..0000000000 --- a/server-spi/src/main/java/org/keycloak/models/UserFederationProviderModel.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * 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.models; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; - -/** - * Stored configuration of a User Federation provider instance. - * - * @author Marek Posolda - * @author Bill Burke - */ -public class UserFederationProviderModel implements Serializable { - - private String id; - private String providerName; - private Map config = new HashMap(); - private int priority; - private String displayName; - private int fullSyncPeriod = -1; // In seconds. -1 means that periodic full sync is disabled - private int changedSyncPeriod = -1; // In seconds. -1 means that periodic changed sync is disabled - private int lastSync; // Date when last sync was done for this provider - - public UserFederationProviderModel() {} - - public UserFederationProviderModel(String id, String providerName, Map config, int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync) { - this.id = id; - this.providerName = providerName; - if (config != null) { - this.config.putAll(config); - } - this.priority = priority; - this.displayName = displayName; - this.fullSyncPeriod = fullSyncPeriod; - this.changedSyncPeriod = changedSyncPeriod; - this.lastSync = lastSync; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getProviderName() { - return providerName; - } - - public void setProviderName(String providerName) { - this.providerName = providerName; - } - - public Map getConfig() { - return config; - } - - public void setConfig(Map config) { - this.config = config; - } - - public int getPriority() { - return priority; - } - - public void setPriority(int priority) { - this.priority = priority; - } - - public String getDisplayName() { - return displayName; - } - - public void setDisplayName(String displayName) { - this.displayName = displayName; - } - - public int getFullSyncPeriod() { - return fullSyncPeriod; - } - - public void setFullSyncPeriod(int fullSyncPeriod) { - this.fullSyncPeriod = fullSyncPeriod; - } - - public int getChangedSyncPeriod() { - return changedSyncPeriod; - } - - public void setChangedSyncPeriod(int changedSyncPeriod) { - this.changedSyncPeriod = changedSyncPeriod; - } - - public int getLastSync() { - return lastSync; - } - - public void setLastSync(int lastSync) { - this.lastSync = lastSync; - } -} diff --git a/server-spi/src/main/java/org/keycloak/models/UserFederationSyncResult.java b/server-spi/src/main/java/org/keycloak/models/UserFederationSyncResult.java deleted file mode 100644 index 380c654659..0000000000 --- a/server-spi/src/main/java/org/keycloak/models/UserFederationSyncResult.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * 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.models; - -/** - * @author Marek Posolda - */ -public class UserFederationSyncResult { - - private boolean ignored; - - private int added; - private int updated; - private int removed; - private int failed; - - public boolean isIgnored() { - return ignored; - } - - public void setIgnored(boolean ignored) { - this.ignored = ignored; - } - - public int getAdded() { - return added; - } - - public void setAdded(int added) { - this.added = added; - } - - public int getUpdated() { - return updated; - } - - public void setUpdated(int updated) { - this.updated = updated; - } - - public int getRemoved() { - return removed; - } - - public void setRemoved(int removed) { - this.removed = removed; - } - - public int getFailed() { - return failed; - } - - public void setFailed(int failed) { - this.failed = failed; - } - - public void increaseAdded() { - added++; - } - - public void increaseUpdated() { - updated++; - } - - public void increaseRemoved() { - removed++; - } - - public void increaseFailed() { - failed++; - } - - public void add(UserFederationSyncResult other) { - added += other.added; - updated += other.updated; - removed += other.removed; - failed += other.failed; - } - - public String getStatus() { - if (ignored) { - return "Synchronization ignored as it's already in progress"; - } else { - String status = String.format("%d imported users, %d updated users", added, updated); - if (removed > 0) { - status += String.format(", %d removed users", removed); - } - if (failed != 0) { - status += String.format(", %d users failed sync! See server log for more details", failed); - } - return status; - } - } - - @Override - public String toString() { - return String.format("UserFederationSyncResult [ %s ]", getStatus()); - } - - public static UserFederationSyncResult empty() { - return new UserFederationSyncResult(); - } - - public static UserFederationSyncResult ignored() { - UserFederationSyncResult result = new UserFederationSyncResult(); - result.setIgnored(true); - return 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 b8b240e07d..924470d83b 100755 --- a/server-spi/src/main/java/org/keycloak/models/UserProvider.java +++ b/server-spi/src/main/java/org/keycloak/models/UserProvider.java @@ -67,8 +67,6 @@ public interface UserProvider extends Provider, UserModel addUser(RealmModel realm, String id, String username, boolean addDefaultRoles, boolean addDefaultRequiredActions); void preRemove(RealmModel realm); - void preRemove(RealmModel realm, UserFederationProviderModel link); - void preRemove(RealmModel realm, RoleModel role); void preRemove(RealmModel realm, GroupModel group); diff --git a/examples/providers/federation-provider/src/main/java/org/keycloak/examples/federation/properties/ReadonlyUserModelProxy.java b/server-spi/src/main/java/org/keycloak/storage/ReadOnlyException.java old mode 100755 new mode 100644 similarity index 61% rename from examples/providers/federation-provider/src/main/java/org/keycloak/examples/federation/properties/ReadonlyUserModelProxy.java rename to server-spi/src/main/java/org/keycloak/storage/ReadOnlyException.java index 453c5aefeb..340437010d --- a/examples/providers/federation-provider/src/main/java/org/keycloak/examples/federation/properties/ReadonlyUserModelProxy.java +++ b/server-spi/src/main/java/org/keycloak/storage/ReadOnlyException.java @@ -14,27 +14,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -package org.keycloak.examples.federation.properties; - -import org.keycloak.models.UserModel; -import org.keycloak.models.utils.UserModelDelegate; +package org.keycloak.storage; /** - * Readonly proxy for a UserModel that prevents passwords from being updated. + * Thrown when UserStorageProvider UserModel adapter is read-only * * @author Bill Burke * @version $Revision: 1 $ */ -public class ReadonlyUserModelProxy extends UserModelDelegate { - - public ReadonlyUserModelProxy(UserModel delegate) { - super(delegate); +public class ReadOnlyException extends RuntimeException { + public ReadOnlyException(String message) { + super(message); } - - @Override - public void setUsername(String username) { - throw new IllegalStateException("Username is readonly"); - } - } diff --git a/server-spi/src/main/java/org/keycloak/storage/adapter/AbstractUserAdapter.java b/server-spi/src/main/java/org/keycloak/storage/adapter/AbstractUserAdapter.java index c15902090e..b0d7ca3772 100644 --- a/server-spi/src/main/java/org/keycloak/storage/adapter/AbstractUserAdapter.java +++ b/server-spi/src/main/java/org/keycloak/storage/adapter/AbstractUserAdapter.java @@ -27,6 +27,7 @@ import org.keycloak.models.RoleModel; import org.keycloak.models.UserModel; import org.keycloak.models.utils.DefaultRoles; import org.keycloak.models.utils.RoleUtils; +import org.keycloak.storage.ReadOnlyException; import org.keycloak.storage.StorageId; import java.util.Collections; @@ -49,11 +50,6 @@ import java.util.Set; * @version $Revision: 1 $ */ public abstract class AbstractUserAdapter implements UserModel { - public static class ReadOnlyException extends RuntimeException { - public ReadOnlyException(String message) { - super(message); - } - } protected KeycloakSession session; protected RealmModel realm; protected ComponentModel storageProviderModel; diff --git a/server-spi/src/main/java/org/keycloak/storage/federated/UserFederatedStorageProvider.java b/server-spi/src/main/java/org/keycloak/storage/federated/UserFederatedStorageProvider.java index 12847bc77f..1d12d3626f 100755 --- a/server-spi/src/main/java/org/keycloak/storage/federated/UserFederatedStorageProvider.java +++ b/server-spi/src/main/java/org/keycloak/storage/federated/UserFederatedStorageProvider.java @@ -23,7 +23,6 @@ import org.keycloak.models.GroupModel; import org.keycloak.models.ProtocolMapperModel; import org.keycloak.models.RealmModel; import org.keycloak.models.RoleModel; -import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserModel; import org.keycloak.provider.Provider; @@ -47,8 +46,6 @@ public interface UserFederatedStorageProvider extends Provider, void preRemove(RealmModel realm); - void preRemove(RealmModel realm, UserFederationProviderModel link); - void preRemove(RealmModel realm, GroupModel group); void preRemove(RealmModel realm, RoleModel role); diff --git a/services/src/main/java/org/keycloak/authorization/admin/ResourceSetService.java b/services/src/main/java/org/keycloak/authorization/admin/ResourceSetService.java index 796d189ddb..c1cb821f33 100644 --- a/services/src/main/java/org/keycloak/authorization/admin/ResourceSetService.java +++ b/services/src/main/java/org/keycloak/authorization/admin/ResourceSetService.java @@ -30,7 +30,6 @@ import org.keycloak.models.ClientModel; import org.keycloak.models.Constants; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; -import org.keycloak.models.UserFederationManager; import org.keycloak.models.UserModel; import org.keycloak.models.UserProvider; import org.keycloak.representations.idm.authorization.ResourceOwnerRepresentation; diff --git a/services/src/main/java/org/keycloak/credential/OTPCredentialProvider.java b/services/src/main/java/org/keycloak/credential/OTPCredentialProvider.java index 96351467e6..4bae7ee906 100644 --- a/services/src/main/java/org/keycloak/credential/OTPCredentialProvider.java +++ b/services/src/main/java/org/keycloak/credential/OTPCredentialProvider.java @@ -102,7 +102,7 @@ public class OTPCredentialProvider implements CredentialProvider, CredentialInpu } else { getCredentialStore().updateCredential(realm, user, model); } - session.getUserCache().evict(realm, user); + session.userCache().evict(realm, user); return true; @@ -138,7 +138,7 @@ public class OTPCredentialProvider implements CredentialProvider, CredentialInpu } if (disableTOTP || disableHOTP) { - session.getUserCache().evict(realm, user); + session.userCache().evict(realm, user); } } diff --git a/services/src/main/java/org/keycloak/credential/PasswordCredentialProvider.java b/services/src/main/java/org/keycloak/credential/PasswordCredentialProvider.java index bdc32e70b3..0a6fe8c3f6 100644 --- a/services/src/main/java/org/keycloak/credential/PasswordCredentialProvider.java +++ b/services/src/main/java/org/keycloak/credential/PasswordCredentialProvider.java @@ -27,7 +27,6 @@ import org.keycloak.models.UserCredentialModel; import org.keycloak.models.UserModel; import org.keycloak.models.cache.CachedUserModel; import org.keycloak.models.cache.OnUserCache; -import org.keycloak.policy.HashAlgorithmPasswordPolicyProviderFactory; import org.keycloak.policy.PasswordPolicyManagerProvider; import org.keycloak.policy.PolicyError; @@ -99,7 +98,7 @@ public class PasswordCredentialProvider implements CredentialProvider, Credentia newPassword.setCreatedDate(createdDate); hash.encode(cred.getValue(), policy, newPassword); getCredentialStore().createCredential(realm, user, newPassword); - session.getUserCache().evict(realm, user); + session.userCache().evict(realm, user); return true; } @@ -213,7 +212,7 @@ public class PasswordCredentialProvider implements CredentialProvider, Credentia hash.encode(cred.getValue(), policy, password); getCredentialStore().updateCredential(realm, user, password); - session.getUserCache().evict(realm, user); + session.userCache().evict(realm, user); return true; } diff --git a/services/src/main/java/org/keycloak/credential/UserCredentialStoreManager.java b/services/src/main/java/org/keycloak/credential/UserCredentialStoreManager.java index 0661317dbc..0fabb1fe21 100644 --- a/services/src/main/java/org/keycloak/credential/UserCredentialStoreManager.java +++ b/services/src/main/java/org/keycloak/credential/UserCredentialStoreManager.java @@ -21,19 +21,14 @@ import org.keycloak.models.CredentialValidationOutput; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.UserCredentialManager; -import org.keycloak.models.UserCredentialModel; -import org.keycloak.models.UserFederationProvider; -import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserModel; import org.keycloak.models.cache.CachedUserModel; import org.keycloak.models.cache.OnUserCache; -import org.keycloak.models.utils.CredentialValidation; import org.keycloak.provider.ProviderFactory; import org.keycloak.storage.StorageId; import org.keycloak.storage.UserStorageManager; import org.keycloak.storage.UserStorageProvider; -import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; diff --git a/services/src/main/java/org/keycloak/exportimport/util/ExportUtils.java b/services/src/main/java/org/keycloak/exportimport/util/ExportUtils.java index 7ae30e7b6b..df7f8d352f 100755 --- a/services/src/main/java/org/keycloak/exportimport/util/ExportUtils.java +++ b/services/src/main/java/org/keycloak/exportimport/util/ExportUtils.java @@ -44,7 +44,6 @@ import org.keycloak.models.RealmModel; import org.keycloak.models.RoleContainerModel; import org.keycloak.models.RoleModel; import org.keycloak.models.UserConsentModel; -import org.keycloak.models.UserFederationManager; import org.keycloak.models.UserModel; import org.keycloak.models.UserProvider; import org.keycloak.models.utils.ModelToRepresentation; diff --git a/services/src/main/java/org/keycloak/services/DefaultKeycloakSession.java b/services/src/main/java/org/keycloak/services/DefaultKeycloakSession.java index 4cc77a269e..13b3bdae82 100644 --- a/services/src/main/java/org/keycloak/services/DefaultKeycloakSession.java +++ b/services/src/main/java/org/keycloak/services/DefaultKeycloakSession.java @@ -27,14 +27,12 @@ import org.keycloak.models.KeycloakTransactionManager; import org.keycloak.models.KeyManager; import org.keycloak.models.RealmProvider; import org.keycloak.models.UserCredentialManager; -import org.keycloak.models.UserFederationManager; import org.keycloak.models.UserProvider; import org.keycloak.models.UserSessionProvider; import org.keycloak.models.cache.CacheRealmProvider; import org.keycloak.models.cache.UserCache; import org.keycloak.provider.Provider; import org.keycloak.provider.ProviderFactory; -import org.keycloak.scripting.ScriptingProvider; import org.keycloak.storage.UserStorageManager; import org.keycloak.storage.federated.UserFederatedStorageProvider; @@ -60,7 +58,6 @@ public class DefaultKeycloakSession implements KeycloakSession { private UserStorageManager userStorageManager; private UserCredentialStoreManager userCredentialStorageManager; private UserSessionProvider sessionProvider; - private UserFederationManager federationManager; private UserFederatedStorageProvider userFederatedStorageProvider; private KeycloakContext context; private KeyManager keyManager; @@ -68,7 +65,6 @@ public class DefaultKeycloakSession implements KeycloakSession { public DefaultKeycloakSession(DefaultKeycloakSessionFactory factory) { this.factory = factory; this.transactionManager = new DefaultKeycloakTransactionManager(this); - federationManager = new UserFederationManager(this); context = new DefaultKeycloakContext(this); } @@ -86,17 +82,8 @@ public class DefaultKeycloakSession implements KeycloakSession { } } - private UserProvider getUserProvider() { - UserCache cache = getProvider(UserCache.class); - if (cache != null) { - return cache; - } else { - return getProvider(UserProvider.class); - } - } - @Override - public UserCache getUserCache() { + public UserCache userCache() { return getProvider(UserCache.class); } @@ -151,17 +138,19 @@ public class DefaultKeycloakSession implements KeycloakSession { } @Override - public UserCredentialManager userCredentialManager() { - if (userCredentialStorageManager == null) userCredentialStorageManager = new UserCredentialStoreManager(this); - return userCredentialStorageManager; + public UserProvider users() { + UserCache cache = getProvider(UserCache.class); + if (cache != null) { + return cache; + } else { + return userStorageManager(); + } } @Override - public UserProvider userStorage() { - if (userModel == null) { - userModel = getUserProvider(); - } - return userModel; + public UserCredentialManager userCredentialManager() { + if (userCredentialStorageManager == null) userCredentialStorageManager = new UserCredentialStoreManager(this); + return userCredentialStorageManager; } public T getProvider(Class clazz) { @@ -239,11 +228,6 @@ public class DefaultKeycloakSession implements KeycloakSession { return model; } - @Override - public UserFederationManager users() { - return federationManager; - } - @Override public UserSessionProvider sessions() { if (sessionProvider == null) { diff --git a/services/src/main/java/org/keycloak/services/managers/ClientManager.java b/services/src/main/java/org/keycloak/services/managers/ClientManager.java index eb6fba623c..1aa9b7f0f3 100644 --- a/services/src/main/java/org/keycloak/services/managers/ClientManager.java +++ b/services/src/main/java/org/keycloak/services/managers/ClientManager.java @@ -156,7 +156,7 @@ public class ClientManager { logger.debugf("Creating service account user '%s'", username); // Don't use federation for service account user - UserModel user = realmManager.getSession().userStorage().addUser(client.getRealm(), username); + UserModel user = realmManager.getSession().userLocalStorage().addUser(client.getRealm(), username); user.setEnabled(true); user.setEmail(username + "@placeholder.org"); user.setServiceAccountClientLink(client.getId()); diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java index 9d30df9aa3..93aafd67f1 100755 --- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java +++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java @@ -31,7 +31,6 @@ import org.keycloak.models.ProtocolMapperModel; import org.keycloak.models.RealmModel; import org.keycloak.models.RealmProvider; import org.keycloak.models.RoleModel; -import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserModel; import org.keycloak.models.UserSessionProvider; import org.keycloak.models.session.UserSessionPersisterProvider; diff --git a/services/src/main/java/org/keycloak/storage/UserStorageManager.java b/services/src/main/java/org/keycloak/storage/UserStorageManager.java index 9c8b4ce9fb..256247039e 100755 --- a/services/src/main/java/org/keycloak/storage/UserStorageManager.java +++ b/services/src/main/java/org/keycloak/storage/UserStorageManager.java @@ -21,7 +21,6 @@ import org.jboss.logging.Logger; import org.keycloak.common.util.reflections.Types; import org.keycloak.component.ComponentModel; import org.keycloak.models.ClientModel; -import org.keycloak.models.CredentialValidationOutput; import org.keycloak.models.FederatedIdentityModel; import org.keycloak.models.GroupModel; import org.keycloak.models.KeycloakSession; @@ -31,16 +30,12 @@ import org.keycloak.models.ProtocolMapperModel; import org.keycloak.models.RealmModel; import org.keycloak.models.RoleModel; import org.keycloak.models.UserConsentModel; -import org.keycloak.models.UserCredentialModel; -import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserManager; import org.keycloak.models.UserModel; import org.keycloak.models.UserProvider; import org.keycloak.models.cache.CachedUserModel; import org.keycloak.models.cache.OnUserCache; import org.keycloak.storage.federated.UserFederatedStorageProvider; -import org.keycloak.credential.CredentialAuthentication; -import org.keycloak.storage.user.ImportSynchronization; import org.keycloak.storage.user.ImportedUserValidation; import org.keycloak.storage.user.UserLookupProvider; import org.keycloak.storage.user.UserQueryProvider; @@ -248,7 +243,7 @@ public class UserStorageManager implements UserProvider, OnUserCache { if (user == null || user.getFederationLink() == null) return user; UserStorageProvider provider = getStorageProvider(session, realm, user.getFederationLink()); if (provider != null && provider instanceof ImportedUserValidation) { - UserModel validated = ((ImportedUserValidation)provider).validate(realm, user); + UserModel validated = ((ImportedUserValidation) provider).validate(realm, user); if (validated == null) { deleteInvalidUser(realm, user); return null; @@ -256,6 +251,11 @@ public class UserStorageManager implements UserProvider, OnUserCache { return validated; } + } else if (provider == null) { + // remove linked user with unknown storage provider. + logger.debugf("Removed user with federation link of unknown storage provider '%s'", user.getUsername()); + deleteInvalidUser(realm, user); + return null; } else { return user; } @@ -265,7 +265,7 @@ public class UserStorageManager implements UserProvider, OnUserCache { protected void deleteInvalidUser(final RealmModel realm, final UserModel user) { String userId = user.getId(); String userName = user.getUsername(); - session.getUserCache().evict(realm, user); + session.userCache().evict(realm, user); runJobInTransaction(session.getKeycloakSessionFactory(), new KeycloakSessionTask() { @Override @@ -321,11 +321,13 @@ public class UserStorageManager implements UserProvider, OnUserCache { @Override public UserModel getUserByEmail(String email, RealmModel realm) { UserModel user = localStorage().getUserByEmail(email, realm); - if (user != null) return user; + if (user != null) { + return importValidation(realm, user); + } for (UserLookupProvider provider : getStorageProviders(session, realm, UserLookupProvider.class)) { user = provider.getUserByEmail(email, realm); if (user != null) { - return importValidation(realm, user); + return user; } } return null; @@ -562,12 +564,6 @@ public class UserStorageManager implements UserProvider, OnUserCache { } } - @Override - public void preRemove(RealmModel realm, UserFederationProviderModel model) { - if (getFederatedStorage() != null) getFederatedStorage().preRemove(realm, model); - localStorage().preRemove(realm, model); - } - @Override public void preRemove(RealmModel realm, GroupModel group) { localStorage().preRemove(realm, group); diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyUserFederationProvider.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyUserFederationProvider.java index dbb5ed3d3a..ad6d16f688 100644 --- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyUserFederationProvider.java +++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyUserFederationProvider.java @@ -19,24 +19,19 @@ package org.keycloak.testsuite.federation; import org.keycloak.component.ComponentModel; import org.keycloak.credential.CredentialInput; -import org.keycloak.credential.CredentialInputUpdater; import org.keycloak.credential.CredentialInputValidator; import org.keycloak.credential.CredentialModel; -import org.keycloak.models.CredentialValidationOutput; 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.UserFederationProvider; import org.keycloak.models.UserModel; import org.keycloak.storage.UserStorageProvider; import org.keycloak.storage.user.UserLookupProvider; -import org.keycloak.storage.user.UserQueryProvider; import org.keycloak.storage.user.UserRegistrationProvider; import java.util.Collections; -import java.util.List; import java.util.Map; import java.util.Set; diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyUserFederationProviderFactory.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyUserFederationProviderFactory.java index 489e0ee525..0a672c1216 100644 --- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyUserFederationProviderFactory.java +++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyUserFederationProviderFactory.java @@ -22,11 +22,6 @@ import org.keycloak.Config; import org.keycloak.component.ComponentModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; -import org.keycloak.models.LDAPConstants; -import org.keycloak.models.UserFederationProvider; -import org.keycloak.models.UserFederationProviderFactory; -import org.keycloak.models.UserFederationProviderModel; -import org.keycloak.models.UserFederationSyncResult; import org.keycloak.models.UserModel; import org.keycloak.provider.ProviderConfigProperty; import org.keycloak.provider.ProviderConfigurationBuilder; @@ -37,10 +32,8 @@ import org.keycloak.storage.user.SynchronizationResult; import java.util.Date; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; /** diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestingResourceProvider.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestingResourceProvider.java index 77094f4577..f2b530a139 100644 --- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestingResourceProvider.java +++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestingResourceProvider.java @@ -32,18 +32,13 @@ import org.keycloak.events.admin.AdminEventQuery; import org.keycloak.events.admin.AuthDetails; import org.keycloak.events.admin.OperationType; import org.keycloak.events.admin.ResourceType; -import org.keycloak.keys.KeyProvider; -import org.keycloak.keys.KeyProviderFactory; import org.keycloak.models.AuthenticationFlowModel; import org.keycloak.models.ClientModel; import org.keycloak.models.FederatedIdentityModel; -import org.keycloak.models.IdentityProviderModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.RealmProvider; import org.keycloak.models.UserCredentialModel; -import org.keycloak.models.UserFederationProvider; -import org.keycloak.models.UserFederationProviderFactory; import org.keycloak.models.UserModel; import org.keycloak.models.UserProvider; import org.keycloak.models.UserSessionModel; @@ -54,7 +49,6 @@ import org.keycloak.representations.idm.AuthDetailsRepresentation; import org.keycloak.representations.idm.AuthenticationFlowRepresentation; import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.UserRepresentation; -import org.keycloak.services.managers.ClientSessionCode; import org.keycloak.services.managers.RealmManager; import org.keycloak.services.resource.RealmResourceProvider; import org.keycloak.storage.UserStorageProvider; diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/LDAPTestConfiguration.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/LDAPTestConfiguration.java index b8b7940398..772ae2dcd5 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/LDAPTestConfiguration.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/LDAPTestConfiguration.java @@ -22,7 +22,7 @@ import org.jboss.logging.Logger; import org.keycloak.common.constants.GenericConstants; import org.keycloak.common.constants.KerberosConstants; import org.keycloak.models.LDAPConstants; -import org.keycloak.models.UserFederationProvider; +import org.keycloak.storage.UserStorageProvider; import java.io.File; import java.io.FileInputStream; @@ -83,7 +83,7 @@ public class LDAPTestConfiguration { DEFAULT_VALUES.put(LDAPConstants.BATCH_SIZE_FOR_SYNC, String.valueOf(LDAPConstants.DEFAULT_BATCH_SIZE_FOR_SYNC)); DEFAULT_VALUES.put(LDAPConstants.USERNAME_LDAP_ATTRIBUTE, null); DEFAULT_VALUES.put(LDAPConstants.USER_OBJECT_CLASSES, null); - DEFAULT_VALUES.put(LDAPConstants.EDIT_MODE, UserFederationProvider.EditMode.READ_ONLY.toString()); + DEFAULT_VALUES.put(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.READ_ONLY.toString()); DEFAULT_VALUES.put(KerberosConstants.ALLOW_KERBEROS_AUTHENTICATION, "false"); DEFAULT_VALUES.put(KerberosConstants.KERBEROS_REALM, "KEYCLOAK.ORG"); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/federation/AbstractKerberosAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/federation/AbstractKerberosAdapterTest.java deleted file mode 100755 index 962795ee1b..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/federation/AbstractKerberosAdapterTest.java +++ /dev/null @@ -1,373 +0,0 @@ -/* - * 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.adapter.federation; - -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.Credentials; -import org.apache.http.client.params.AuthPolicy; -import org.apache.http.impl.client.DefaultHttpClient; -import org.jboss.arquillian.container.test.api.Deployment; -import org.jboss.arquillian.graphene.page.Page; -import org.jboss.resteasy.client.jaxrs.ResteasyClient; -import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; -import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine; -import org.jboss.shrinkwrap.api.spec.WebArchive; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.keycloak.adapters.HttpClientBuilder; -import org.keycloak.admin.client.resource.RealmResource; -import org.keycloak.common.constants.KerberosConstants; -import org.keycloak.events.Details; -import org.keycloak.federation.kerberos.CommonKerberosConfig; -import org.keycloak.models.LDAPConstants; -import org.keycloak.models.UserFederationProvider; -import org.keycloak.models.UserFederationProviderModel; -import org.keycloak.models.UserModel; -import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.representations.idm.UserFederationProviderRepresentation; -import org.keycloak.representations.idm.UserRepresentation; -import org.keycloak.storage.UserStorageProviderModel; -import org.keycloak.testsuite.AssertEvents; -import org.keycloak.testsuite.adapter.AbstractServletsAdapterTest; -import org.keycloak.testsuite.adapter.page.KerberosPortal; -import org.keycloak.testsuite.adapter.servlet.KerberosCredDelegServlet; -import org.keycloak.testsuite.admin.ApiUtil; -import org.keycloak.testsuite.auth.page.AuthRealm; -import org.keycloak.testsuite.auth.page.account.ChangePassword; -import org.keycloak.testsuite.util.LDAPTestConfiguration; -import org.keycloak.util.ldap.KerberosEmbeddedServer; -import org.keycloak.util.ldap.LDAPEmbeddedServer; - -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.Response; -import java.security.Principal; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -import static org.keycloak.testsuite.util.IOUtil.loadRealm; - -/** - * @author Marek Posolda - */ -public abstract class AbstractKerberosAdapterTest extends AbstractServletsAdapterTest { - - protected static LDAPTestConfiguration ldapTestConfiguration; - - protected KeycloakSPNegoSchemeFactory spnegoSchemeFactory; - - protected ResteasyClient client; - - protected static LDAPEmbeddedServer ldapEmbeddedServer; - - @Rule - public AssertEvents events = new AssertEvents(this); - - @Page - protected ChangePassword changePasswordPage; - - @Page - protected KerberosPortal kerberosPortal; - - protected abstract String getConnectionPropertiesLocation(); - - protected abstract CommonKerberosConfig getKerberosConfig(UserStorageProviderModel model); - - @Deployment(name = KerberosPortal.DEPLOYMENT_NAME) - protected static WebArchive kerberosPortal() { - return servletDeployment(KerberosPortal.DEPLOYMENT_NAME, "keycloak.json", KerberosCredDelegServlet.class); - } - - @Override - public void addAdapterTestRealms(List testRealms) { - testRealms.add(loadRealm("/adapter-test/kerberosrealm.json")); - } - - - @Before - public void before() throws Exception { - testRealmPage.setAuthRealm(AuthRealm.TEST); - changePasswordPage.setAuthRealm(testRealmPage); - // Global kerberos configuration - ldapTestConfiguration = LDAPTestConfiguration.readConfiguration(getConnectionPropertiesLocation()); - String krb5ConfPath = LDAPTestConfiguration.getResource("test-krb5.conf"); - log.info("Krb5.conf file location is: " + krb5ConfPath); - System.setProperty("java.security.krb5.conf", krb5ConfPath); - if (ldapTestConfiguration.isStartEmbeddedLdapServer() && ldapEmbeddedServer == null) { - ldapEmbeddedServer = createServer(); - ldapEmbeddedServer.init(); - ldapEmbeddedServer.start(); - } - UserStorageProviderModel model = new UserStorageProviderModel(); - model.setConfig(AbstractKerberosStandaloneAdapterTest.toComponentConfig(ldapTestConfiguration.getLDAPConfig())); - spnegoSchemeFactory = new KeycloakSPNegoSchemeFactory(getKerberosConfig(model)); - initHttpClient(true); - removeAllUsers(); - } - - @After - public void after() { - client.close(); - client = null; - } - - @AfterClass - public static void afterClass() { - try { - if (ldapEmbeddedServer != null) { - ldapEmbeddedServer.stop(); - ldapEmbeddedServer = null; - } - ldapTestConfiguration = null; - } catch (Exception e) { - throw new RuntimeException("Error tearDown Embedded LDAP server.", e); - } - } - - @Test - public void spnegoNotAvailableTest() throws Exception { - initHttpClient(false); - - String kcLoginPageLocation = client.target(kerberosPortal.getInjectedUrl().toString()).request().get().getLocation().toString(); - - Response response = client.target(kcLoginPageLocation).request().get(); - Assert.assertEquals(401, response.getStatus()); - Assert.assertEquals(KerberosConstants.NEGOTIATE, response.getHeaderString(HttpHeaders.WWW_AUTHENTICATE)); - String responseText = response.readEntity(String.class); - responseText.contains("Log in to test"); - response.close(); - } - - protected void spnegoLoginTestImpl() throws Exception { - Response spnegoResponse = spnegoLogin("hnelson", "secret"); - Assert.assertEquals(302, spnegoResponse.getStatus()); - - List users = testRealmResource().users().search("hnelson", 0, 1); - String userId = users.get(0).getId(); - events.expectLogin() - .client("kerberos-app") - .user(userId) - .detail(Details.REDIRECT_URI, kerberosPortal.toString()) - //.detail(Details.AUTH_METHOD, "spnego") - .detail(Details.USERNAME, "hnelson") - .assertEvent(); - - String location = spnegoResponse.getLocation().toString(); - driver.navigate().to(location); - - String pageSource = driver.getPageSource(); - Assert.assertTrue( - pageSource.contains("Kerberos Test") && pageSource.contains("Kerberos servlet secured content")); - - spnegoResponse.close(); - events.clear(); - } - - // KEYCLOAK-2102 - @Test - public void spnegoCaseInsensitiveTest() throws Exception { - Response spnegoResponse = spnegoLogin(ldapTestConfiguration.isCaseSensitiveLogin() ? "MyDuke" : "myduke", "theduke"); - Assert.assertEquals(302, spnegoResponse.getStatus()); - List users = testRealmResource().users().search("myduke", 0, 1); - String userId = users.get(0).getId(); - events.expectLogin() - .client("kerberos-app") - .user(userId) - .detail(Details.REDIRECT_URI, kerberosPortal.toString()) - //.detail(Details.AUTH_METHOD, "spnego") - .detail(Details.USERNAME, "myduke") - .assertEvent(); - - String location = spnegoResponse.getLocation().toString(); - driver.navigate().to(location); - - String pageSource = driver.getPageSource(); - Assert.assertTrue( - pageSource.contains("Kerberos Test") && pageSource.contains("Kerberos servlet secured content")); - - spnegoResponse.close(); - events.clear(); - } - - @Test - public void usernamePasswordLoginTest() throws Exception { - // Change editMode to READ_ONLY - updateProviderEditMode(UserFederationProvider.EditMode.READ_ONLY); - - // Login with username/password from kerberos - changePasswordPage.navigateTo(); - testRealmLoginPage.isCurrent(); - testRealmLoginPage.form().login("jduke", "theduke"); - changePasswordPage.isCurrent(); - - // Bad existing password - changePasswordPage.changePasswords("theduke-invalid", "newPass", "newPass"); - Assert.assertTrue(driver.getPageSource().contains("Invalid existing password.")); - - // Change password is not possible as editMode is READ_ONLY - changePasswordPage.changePasswords("theduke", "newPass", "newPass"); - Assert.assertTrue( - driver.getPageSource().contains("You can't update your password as your account is read only")); - - // Change editMode to UNSYNCED - updateProviderEditMode(UserFederationProvider.EditMode.UNSYNCED); - - // Successfully change password now - changePasswordPage.changePasswords("theduke", "newPass", "newPass"); - Assert.assertTrue(driver.getPageSource().contains("Your password has been updated.")); - changePasswordPage.logOut(); - - // Login with old password doesn't work, but with new password works - testRealmLoginPage.form().login("jduke", "theduke"); - testRealmLoginPage.isCurrent(); - testRealmLoginPage.form().login("jduke", "newPass"); - changePasswordPage.isCurrent(); - changePasswordPage.logOut(); - - // Assert SPNEGO login still with the old password as mode is unsynced - events.clear(); - Response spnegoResponse = spnegoLogin("jduke", "theduke"); - Assert.assertEquals(302, spnegoResponse.getStatus()); - UserRepresentation user = ApiUtil.findUserByUsername(testRealmResource(), "jduke"); - events.expectLogin() - .client("kerberos-app") - .user(user != null ? user.getId() : null) - .detail(Details.REDIRECT_URI, kerberosPortal.toString()) - //.detail(Details.AUTH_METHOD, "spnego") - .detail(Details.USERNAME, "jduke") - .assertEvent(); - spnegoResponse.close(); - } - - - protected Response spnegoLogin(String username, String password) { - kerberosPortal.navigateTo(); - Response res = client.target(kerberosPortal.getInjectedUrl().toString()).request().get(); - String kcLoginPageLocation = res.getLocation().toString(); - if (driver.manage().getCookieNamed("OAuth_Token_Request_State") != null) { - kcLoginPageLocation = res.getLocation().toString().replaceFirst("state=.*&", "state=" + driver.manage().getCookieNamed("OAuth_Token_Request_State").getValue() + "&"); - } - // Request for SPNEGO login sent with Resteasy client - spnegoSchemeFactory.setCredentials(username, password); - Response response = client.target(kcLoginPageLocation).request().get(); - if (response.getStatus() == 302) { - if (response.getLocation() == null) - return response; - String uri = response.getLocation().toString(); - if (uri.contains("login-actions/required-action")) { - response = client.target(uri).request().get(); - } - } - return response; - - } - - - - protected void initHttpClient(boolean useSpnego) { - if (client != null) { - after(); - } - DefaultHttpClient httpClient = (DefaultHttpClient) new HttpClientBuilder().build(); - httpClient.getAuthSchemes().register(AuthPolicy.SPNEGO, spnegoSchemeFactory); - - if (useSpnego) { - Credentials fake = new Credentials() { - - public String getPassword() { - return null; - } - - public Principal getUserPrincipal() { - return null; - } - - }; - - httpClient.getCredentialsProvider().setCredentials( - new AuthScope(null, -1, null), - fake); - } - ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient); - client = new ResteasyClientBuilder().httpEngine(engine).build(); - } - - protected void removeAllUsers() { - RealmResource realm = testRealmResource(); - List users = realm.users().search("", 0, Integer.MAX_VALUE); - for (UserRepresentation user : users) { - if (!user.getUsername().equals(AssertEvents.DEFAULT_USERNAME)) { - realm.users().get(user.getId()).remove(); - } - } - Assert.assertEquals(1, realm.users().search("", 0, Integer.MAX_VALUE).size()); - } - - protected void assertUser(String expectedUsername, String expectedEmail, String expectedFirstname, - String expectedLastname, boolean updateProfileActionExpected) { - try { - UserRepresentation user = ApiUtil.findUserByUsername(testRealmResource(), expectedUsername); - Assert.assertNotNull(user); - Assert.assertEquals(expectedEmail, user.getEmail()); - Assert.assertEquals(expectedFirstname, user.getFirstName()); - Assert.assertEquals(expectedLastname, user.getLastName()); - - if (updateProfileActionExpected) { - Assert.assertEquals(UserModel.RequiredAction.UPDATE_PROFILE.toString(), - user.getRequiredActions().iterator().next()); - } else { - Assert.assertTrue(user.getRequiredActions().isEmpty()); - } - } finally { - } - } - - protected void updateProviderEditMode(UserFederationProvider.EditMode editMode) { - RealmResource realm = testRealmResource(); - RealmRepresentation realmRepresentation = realm.toRepresentation(); - UserFederationProviderRepresentation kerberosProviderRepresentation = realmRepresentation - .getUserFederationProviders().get(0); - kerberosProviderRepresentation.getConfig().put(LDAPConstants.EDIT_MODE, editMode.toString()); - realm.update(realmRepresentation); - } - - public RealmResource testRealmResource() { - return adminClient.realm("test"); - } - - public Map getConfig() { - return ldapTestConfiguration.getLDAPConfig(); - } - - protected static LDAPEmbeddedServer createServer() { - Properties defaultProperties = new Properties(); - defaultProperties.setProperty(LDAPEmbeddedServer.PROPERTY_DSF, LDAPEmbeddedServer.DSF_INMEMORY); - defaultProperties.setProperty(LDAPEmbeddedServer.PROPERTY_LDIF_FILE, "classpath:kerberos/users-kerberos.ldif"); - return new KerberosEmbeddedServer(defaultProperties); - } - - @Override - public void setDefaultPageUriParameters() { - super.setDefaultPageUriParameters(); - testRealmPage.setAuthRealm(AuthRealm.TEST); - } -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/federation/AbstractKerberosStandaloneAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/federation/AbstractKerberosStandaloneAdapterTest.java deleted file mode 100755 index 77fe41030f..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/federation/AbstractKerberosStandaloneAdapterTest.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * 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.adapter.federation; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.keycloak.common.constants.KerberosConstants; -import org.keycloak.common.util.MultivaluedHashMap; -import org.keycloak.federation.kerberos.CommonKerberosConfig; -import org.keycloak.federation.kerberos.KerberosConfig; -import org.keycloak.federation.kerberos.KerberosFederationProviderFactory; -import org.keycloak.models.UserFederationProviderModel; -import org.keycloak.representations.idm.ComponentRepresentation; -import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.representations.idm.UserFederationProviderRepresentation; -import org.keycloak.storage.UserStorageProvider; -import org.keycloak.storage.UserStorageProviderModel; - -import javax.ws.rs.core.Response; -import java.util.Arrays; -import java.util.Map; - -/** - * Test of KerberosFederationProvider (Kerberos not backed by LDAP) - * - * @author Marek Posolda - */ -public abstract class AbstractKerberosStandaloneAdapterTest extends AbstractKerberosAdapterTest { - - public static MultivaluedHashMap toComponentConfig(Map ldapConfig) { - MultivaluedHashMap config = new MultivaluedHashMap<>(); - for (Map.Entry entry : ldapConfig.entrySet()) { - config.add(entry.getKey(), entry.getValue()); - - } - return config; - } - - protected static final String PROVIDER_CONFIG_LOCATION = "kerberos-standalone-connection.properties"; - - @Before - public void init() throws Exception{ - RealmRepresentation realmRepresentation = testRealmResource().toRepresentation(); - Map ldapConfig = getConfig(); - ComponentRepresentation component = new ComponentRepresentation(); - component.setName("kerberos-standalone"); - component.setParentId(realmRepresentation.getId()); - component.setProviderId(KerberosFederationProviderFactory.PROVIDER_NAME); - component.setProviderType(UserStorageProvider.class.getName()); - component.setConfig(toComponentConfig(ldapConfig)); - component.getConfig().putSingle("priority", "0"); - - testRealmResource().components().add(component); - realmRepresentation.setEventsEnabled(true); - testRealmResource().update(realmRepresentation); - } - - @Override - protected CommonKerberosConfig getKerberosConfig(UserStorageProviderModel model) { - return new KerberosConfig(model); - } - - @Override - protected String getConnectionPropertiesLocation() { - return PROVIDER_CONFIG_LOCATION; - } - - @Test - public void spnegoLoginTest() throws Exception { - spnegoLoginTestImpl(); - // Assert user was imported and hasn't any required action on him - assertUser("hnelson", "hnelson@" + getConfig().get(KerberosConstants.KERBEROS_REALM).toLowerCase(), null, null, false); - } - - @Test - @Override - public void usernamePasswordLoginTest() throws Exception { - super.usernamePasswordLoginTest(); - } - - @Test - public void updateProfileEnabledTest() throws Exception { - // Switch updateProfileOnFirstLogin to on - RealmRepresentation realm = testRealmResource().toRepresentation(); - UserFederationProviderRepresentation kerberosProviderRepresentation = realm.getUserFederationProviders().get(0); - kerberosProviderRepresentation.getConfig().put(KerberosConstants.UPDATE_PROFILE_FIRST_LOGIN, "true"); - testRealmResource().update(realm); - - // Assert update profile page is displayed - Response spnegoResponse = spnegoLogin("hnelson", "secret"); - Assert.assertEquals(200, spnegoResponse.getStatus()); - String responseText = spnegoResponse.readEntity(String.class); - Assert.assertTrue(responseText.contains("You need to update your user profile to activate your account.")); - Assert.assertTrue(responseText.contains("hnelson@" + getConfig().get(KerberosConstants.KERBEROS_REALM).toLowerCase())); - spnegoResponse.close(); - - // Assert user was imported and has required action on him - assertUser("hnelson", "hnelson@" + getConfig().get(KerberosConstants.KERBEROS_REALM).toLowerCase(), null, null, true); - - // Switch updateProfileOnFirstLogin to off - - kerberosProviderRepresentation = realm.getUserFederationProviders().get(0); - kerberosProviderRepresentation.getConfig().put(KerberosConstants.UPDATE_PROFILE_FIRST_LOGIN, "false"); - testRealmResource().update(realm); - } -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportUtil.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportUtil.java index 001ed86b60..3e16c4b0d2 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportUtil.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportUtil.java @@ -25,11 +25,8 @@ import org.keycloak.admin.client.resource.ClientTemplateResource; import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.admin.client.resource.UserResource; import org.keycloak.common.constants.KerberosConstants; -import org.keycloak.component.ComponentModel; import org.keycloak.models.Constants; import org.keycloak.models.LDAPConstants; -import org.keycloak.models.UserFederationMapperModel; -import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.utils.DefaultAuthenticationFlows; import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper; @@ -38,14 +35,12 @@ import org.keycloak.representations.idm.AuthenticationFlowRepresentation; import org.keycloak.representations.idm.ClientMappingsRepresentation; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.ClientTemplateRepresentation; -import org.keycloak.representations.idm.ComponentExportRepresentation; import org.keycloak.representations.idm.ComponentRepresentation; import org.keycloak.representations.idm.FederatedIdentityRepresentation; import org.keycloak.representations.idm.IdentityProviderRepresentation; import org.keycloak.representations.idm.ProtocolMapperRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RoleRepresentation; -import org.keycloak.representations.idm.UserFederationMapperRepresentation; import org.keycloak.representations.idm.UserFederationProviderRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.authorization.PolicyRepresentation; @@ -53,7 +48,6 @@ import org.keycloak.representations.idm.authorization.ResourceRepresentation; import org.keycloak.representations.idm.authorization.ResourceServerRepresentation; import org.keycloak.representations.idm.authorization.ScopeRepresentation; import org.keycloak.storage.UserStorageProvider; -import org.keycloak.storage.UserStorageProviderModel; import org.keycloak.storage.ldap.mappers.FullNameLDAPStorageMapper; import org.keycloak.storage.ldap.mappers.FullNameLDAPStorageMapperFactory; import org.keycloak.storage.ldap.mappers.LDAPStorageMapper; diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractKeycloakIdentityProviderTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractKeycloakIdentityProviderTest.java index 888f954156..0977d2dbc6 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractKeycloakIdentityProviderTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractKeycloakIdentityProviderTest.java @@ -26,7 +26,6 @@ import org.keycloak.models.IdentityProviderModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.RoleModel; -import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserModel; import org.keycloak.representations.idm.IdentityProviderRepresentation; import org.keycloak.services.Urls; @@ -47,7 +46,6 @@ import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.Response; import java.io.IOException; import java.net.URI; -import java.util.HashMap; import java.util.Set; import static org.junit.Assert.assertEquals; diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/AbstractKerberosTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/AbstractKerberosTest.java index 10841b5377..78266b8810 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/AbstractKerberosTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/AbstractKerberosTest.java @@ -39,8 +39,6 @@ import org.keycloak.models.KeycloakSession; import org.keycloak.models.LDAPConstants; import org.keycloak.models.ProtocolMapperModel; import org.keycloak.models.RealmModel; -import org.keycloak.models.UserFederationProvider; -import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserModel; import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.protocol.oidc.mappers.UserSessionNoteMapper; @@ -345,14 +343,14 @@ public abstract class AbstractKerberosTest { RealmManager manager = new RealmManager(session); RealmModel appRealm = manager.getRealm("test"); - List users = session.userStorage().getUsers(appRealm, true); + List users = session.users().getUsers(appRealm, true); for (UserModel user : users) { if (!user.getUsername().equals(AssertEvents.DEFAULT_USERNAME)) { - session.userStorage().removeUser(appRealm, user); + session.users().removeUser(appRealm, user); } } - Assert.assertEquals(1, session.userStorage().getUsers(appRealm, true).size()); + Assert.assertEquals(1, session.users().getUsers(appRealm, true).size()); } finally { keycloakRule.stopSession(session, true); } diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/KerberosStandaloneTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/KerberosStandaloneTest.java index 26b11ccf57..aeb58b20fb 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/KerberosStandaloneTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/KerberosStandaloneTest.java @@ -32,11 +32,9 @@ import org.keycloak.federation.kerberos.KerberosConfig; import org.keycloak.federation.kerberos.KerberosFederationProviderFactory; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; -import org.keycloak.models.UserFederationProviderModel; import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.services.managers.RealmManager; import org.keycloak.storage.UserStorageProviderModel; -import org.keycloak.storage.ldap.LDAPStorageProviderFactory; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.federation.storage.ldap.LDAPTestUtils; import org.keycloak.testsuite.rule.KerberosRule; diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPTestConfiguration.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPTestConfiguration.java index 4a5adb0cbf..b254a1abe5 100644 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPTestConfiguration.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPTestConfiguration.java @@ -20,7 +20,7 @@ package org.keycloak.testsuite.federation.ldap; import org.jboss.logging.Logger; import org.keycloak.common.constants.KerberosConstants; import org.keycloak.models.LDAPConstants; -import org.keycloak.models.UserFederationProvider; +import org.keycloak.storage.UserStorageProvider; import java.io.File; import java.io.InputStream; @@ -79,7 +79,7 @@ public class LDAPTestConfiguration { DEFAULT_VALUES.put(LDAPConstants.BATCH_SIZE_FOR_SYNC, String.valueOf(LDAPConstants.DEFAULT_BATCH_SIZE_FOR_SYNC)); DEFAULT_VALUES.put(LDAPConstants.USERNAME_LDAP_ATTRIBUTE, null); DEFAULT_VALUES.put(LDAPConstants.USER_OBJECT_CLASSES, null); - DEFAULT_VALUES.put(LDAPConstants.EDIT_MODE, UserFederationProvider.EditMode.READ_ONLY.toString()); + DEFAULT_VALUES.put(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.READ_ONLY.toString()); DEFAULT_VALUES.put(KerberosConstants.ALLOW_KERBEROS_AUTHENTICATION, "false"); DEFAULT_VALUES.put(KerberosConstants.KERBEROS_REALM, "KEYCLOAK.ORG"); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/KerberosLdapTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/KerberosLdapTest.java index 1e211924bb..ea48ff7eae 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/KerberosLdapTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/KerberosLdapTest.java @@ -24,12 +24,8 @@ import org.junit.Test; import org.junit.rules.RuleChain; import org.junit.rules.TestRule; import org.keycloak.common.util.MultivaluedHashMap; -import org.keycloak.component.ComponentModel; import org.keycloak.events.Details; import org.keycloak.federation.kerberos.CommonKerberosConfig; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.LDAPConstants; -import org.keycloak.models.UserFederationProvider; import org.keycloak.storage.UserStorageProvider; import org.keycloak.storage.UserStorageProviderModel; import org.keycloak.storage.ldap.LDAPStorageProviderFactory; diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPSyncTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPSyncTest.java index 169d82fc27..41438467b9 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPSyncTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPSyncTest.java @@ -315,7 +315,7 @@ public class LDAPSyncTest { // Remove all users from model for (UserModel user : session.userLocalStorage().getUsers(testRealm, true)) { System.out.println("trying to delete user: " + user.getUsername()); - session.getUserCache().evict(testRealm, user); + session.userCache().evict(testRealm, user); session.userLocalStorage().removeUser(testRealm, user); } diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/sync/SyncDummyUserFederationProviderFactory.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/sync/SyncDummyUserFederationProviderFactory.java index 478d0dd834..e890ddaa59 100644 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/sync/SyncDummyUserFederationProviderFactory.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/sync/SyncDummyUserFederationProviderFactory.java @@ -22,8 +22,6 @@ import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.models.KeycloakSessionTask; import org.keycloak.models.RealmModel; -import org.keycloak.models.UserFederationProviderModel; -import org.keycloak.models.UserFederationSyncResult; import org.keycloak.models.UserModel; import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.provider.ProviderConfigProperty; @@ -34,7 +32,6 @@ import org.keycloak.testsuite.federation.DummyUserFederationProviderFactory; import java.util.Date; import java.util.List; -import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -93,13 +90,13 @@ public class SyncDummyUserFederationProviderFactory extends DummyUserFederationP // KEYCLOAK-2412 : Just remove and add some users for testing purposes for (int i = 0; i < 10; i++) { String username = "dummyuser-" + i; - UserModel user = session.userStorage().getUserByUsername(username, realm); + UserModel user = session.userLocalStorage().getUserByUsername(username, realm); if (user != null) { - session.userStorage().removeUser(realm, user); + session.userLocalStorage().removeUser(realm, user); } - user = session.userStorage().addUser(realm, username); + user = session.userLocalStorage().addUser(realm, username); } logger.infof("Finished sync of changed users. Waiting now for %d seconds", waitTime); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/sync/SyncFederationTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/sync/SyncFederationTest.java index 7eb0d0ea4a..4967bcc6c1 100644 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/sync/SyncFederationTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/sync/SyncFederationTest.java @@ -24,12 +24,9 @@ import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runners.MethodSorters; import org.keycloak.common.util.Time; -import org.keycloak.component.ComponentModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.models.RealmModel; -import org.keycloak.models.UserFederationProviderModel; -import org.keycloak.models.UserFederationSyncResult; import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.UserStorageSyncManager; import org.keycloak.storage.UserStorageProvider; @@ -39,8 +36,6 @@ import org.keycloak.testsuite.federation.DummyUserFederationProviderFactory; import org.keycloak.testsuite.rule.KeycloakRule; import org.keycloak.timer.TimerProvider; -import java.util.HashMap; -import java.util.Map; import java.util.concurrent.TimeUnit; /** 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 b7bd2afef4..2e3f162ee8 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 @@ -36,10 +36,6 @@ import org.keycloak.models.RealmModel; import org.keycloak.models.RequiredCredentialModel; import org.keycloak.models.RoleModel; import org.keycloak.models.UserConsentModel; -import org.keycloak.models.UserFederationMapperModel; -import org.keycloak.models.UserFederationProvider; -import org.keycloak.models.UserFederationProviderFactory; -import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserModel; import org.keycloak.models.utils.DefaultAuthenticationFlows; import org.keycloak.models.utils.KeycloakModelUtils; diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/SyncDummyFederationProviderCommand.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/SyncDummyFederationProviderCommand.java index 4ba0f6765f..fe53b82c69 100644 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/SyncDummyFederationProviderCommand.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/SyncDummyFederationProviderCommand.java @@ -20,16 +20,11 @@ package org.keycloak.testsuite.util.cli; import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; -import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.services.managers.UserStorageSyncManager; import org.keycloak.storage.UserStorageProviderModel; -import org.keycloak.testsuite.federation.DummyUserFederationProviderFactory; import org.keycloak.testsuite.federation.sync.SyncDummyUserFederationProviderFactory; -import java.util.HashMap; -import java.util.Map; - /** * @author Marek Posolda */