KEYCLOAK-1385 Introduce end-of-line normalization

This commit is contained in:
Stian Thorgersen committed 2015-07-17 13:46:51 +02:00
1 parent be8aa93cca
commit 1642ac2394
888 files changed
+110680 -110660

No files matched your search

@@ -1,135 +1,135 @@
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 <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public abstract class BasePropertiesFederationFactory implements UserFederationProviderFactory {
static final Set<String> configOptions = new HashSet<String>();
protected ConcurrentHashMap<String, Properties> files = new ConcurrentHashMap<String, Properties>();
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<String> getConfigurationOptions() {
return configOptions;
}
@Override
public UserFederationProvider create(KeycloakSession session) {
return null;
}
/**
* You can import additional plugin configuration from keycloak-server.json 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<String> 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);
}
}
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 <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public abstract class BasePropertiesFederationFactory implements UserFederationProviderFactory {
static final Set<String> configOptions = new HashSet<String>();
protected ConcurrentHashMap<String, Properties> files = new ConcurrentHashMap<String, Properties>();
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<String> getConfigurationOptions() {
return configOptions;
}
@Override
public UserFederationProvider create(KeycloakSession session) {
return null;
}
/**
* You can import additional plugin configuration from keycloak-server.json 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<String> 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);
}
}
@@ -1,173 +1,173 @@
package org.keycloak.examples.federation.properties;
import org.keycloak.models.CredentialValidationOutput;
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 <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public abstract class BasePropertiesFederationProvider implements UserFederationProvider {
protected static final Set<String> supportedCredentialTypes = new HashSet<String>();
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<UserModel> searchByAttributes(Map<String, String> 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<UserModel> list = new ArrayList<UserModel>(1);
list.add(user);
return list;
}
}
}
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
}
/**
* 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());
}
/**
* hardcoded to only return PASSWORD
*
* @param user
* @return
*/
@Override
public Set<String> getSupportedCredentialTypes(UserModel user) {
return supportedCredentialTypes;
}
@Override
public Set<String> getSupportedCredentialTypes() {
return supportedCredentialTypes;
}
@Override
public boolean validCredentials(RealmModel realm, UserModel user, List<UserCredentialModel> input) {
for (UserCredentialModel cred : input) {
if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
String password = properties.getProperty(user.getUsername());
if (password == null) return false;
return password.equals(cred.getValue());
} else {
return false; // invalid cred type
}
}
return false;
}
@Override
public boolean validCredentials(RealmModel realm, UserModel user, UserCredentialModel... input) {
for (UserCredentialModel cred : input) {
if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
String password = properties.getProperty(user.getUsername());
if (password == null) return false;
return password.equals(cred.getValue());
} else {
return false; // invalid cred type
}
}
return true;
}
@Override
public CredentialValidationOutput validCredentials(RealmModel realm, UserCredentialModel credential) {
return CredentialValidationOutput.failed();
}
@Override
public void close() {
}
}
package org.keycloak.examples.federation.properties;
import org.keycloak.models.CredentialValidationOutput;
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 <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public abstract class BasePropertiesFederationProvider implements UserFederationProvider {
protected static final Set<String> supportedCredentialTypes = new HashSet<String>();
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<UserModel> searchByAttributes(Map<String, String> 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<UserModel> list = new ArrayList<UserModel>(1);
list.add(user);
return list;
}
}
}
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
}
/**
* 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());
}
/**
* hardcoded to only return PASSWORD
*
* @param user
* @return
*/
@Override
public Set<String> getSupportedCredentialTypes(UserModel user) {
return supportedCredentialTypes;
}
@Override
public Set<String> getSupportedCredentialTypes() {
return supportedCredentialTypes;
}
@Override
public boolean validCredentials(RealmModel realm, UserModel user, List<UserCredentialModel> input) {
for (UserCredentialModel cred : input) {
if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
String password = properties.getProperty(user.getUsername());
if (password == null) return false;
return password.equals(cred.getValue());
} else {
return false; // invalid cred type
}
}
return false;
}
@Override
public boolean validCredentials(RealmModel realm, UserModel user, UserCredentialModel... input) {
for (UserCredentialModel cred : input) {
if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
String password = properties.getProperty(user.getUsername());
if (password == null) return false;
return password.equals(cred.getValue());
} else {
return false; // invalid cred type
}
}
return true;
}
@Override
public CredentialValidationOutput validCredentials(RealmModel realm, UserCredentialModel credential) {
return CredentialValidationOutput.failed();
}
@Override
public void close() {
}
}
@@ -1,37 +1,37 @@
package org.keycloak.examples.federation.properties;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.UserFederationProviderModel;
import java.io.InputStream;
import java.util.Properties;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class ClasspathPropertiesFederationFactory extends BasePropertiesFederationFactory {
public static final String PROVIDER_NAME = "classpath-properties";
@Override
protected BasePropertiesFederationProvider createProvider(KeycloakSession session, UserFederationProviderModel model, Properties props) {
return new ClasspathPropertiesFederationProvider(session, model, props);
}
protected InputStream getPropertiesFileStream(String path) {
InputStream is = getClass().getClassLoader().getResourceAsStream(path);
if (is == null) {
throw new IllegalStateException("Path not found for properties file");
}
return is;
}
@Override
public String getId() {
return PROVIDER_NAME;
}
}
package org.keycloak.examples.federation.properties;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.UserFederationProviderModel;
import java.io.InputStream;
import java.util.Properties;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class ClasspathPropertiesFederationFactory extends BasePropertiesFederationFactory {
public static final String PROVIDER_NAME = "classpath-properties";
@Override
protected BasePropertiesFederationProvider createProvider(KeycloakSession session, UserFederationProviderModel model, Properties props) {
return new ClasspathPropertiesFederationProvider(session, model, props);
}
protected InputStream getPropertiesFileStream(String path) {
InputStream is = getClass().getClassLoader().getResourceAsStream(path);
if (is == null) {
throw new IllegalStateException("Path not found for properties file");
}
return is;
}
@Override
public String getId() {
return PROVIDER_NAME;
}
}
@@ -1,66 +1,66 @@
package org.keycloak.examples.federation.properties;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.UserModel;
import java.util.Properties;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class ClasspathPropertiesFederationProvider extends BasePropertiesFederationProvider {
public ClasspathPropertiesFederationProvider(KeycloakSession session, UserFederationProviderModel 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");
}
}
package org.keycloak.examples.federation.properties;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.UserModel;
import java.util.Properties;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class ClasspathPropertiesFederationProvider extends BasePropertiesFederationProvider {
public ClasspathPropertiesFederationProvider(KeycloakSession session, UserFederationProviderModel 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");
}
}
@@ -1,42 +1,42 @@
package org.keycloak.examples.federation.properties;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.UserFederationProviderModel;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Properties;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class FilePropertiesFederationFactory extends BasePropertiesFederationFactory {
public static final String PROVIDER_NAME = "file-properties";
@Override
protected BasePropertiesFederationProvider createProvider(KeycloakSession session, UserFederationProviderModel model, Properties props) {
return new FilePropertiesFederationProvider(session, props, model);
}
protected InputStream getPropertiesFileStream(String path) {
try {
return new FileInputStream(path);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
/**
* Name of the provider. This will show up under the "Add Provider" select box on the Federation page in the
* admin console
*
* @return
*/
@Override
public String getId() {
return PROVIDER_NAME;
}
}
package org.keycloak.examples.federation.properties;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.UserFederationProviderModel;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Properties;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class FilePropertiesFederationFactory extends BasePropertiesFederationFactory {
public static final String PROVIDER_NAME = "file-properties";
@Override
protected BasePropertiesFederationProvider createProvider(KeycloakSession session, UserFederationProviderModel model, Properties props) {
return new FilePropertiesFederationProvider(session, props, model);
}
protected InputStream getPropertiesFileStream(String path) {
try {
return new FileInputStream(path);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
/**
* Name of the provider. This will show up under the "Add Provider" select box on the Federation page in the
* admin console
*
* @return
*/
@Override
public String getId() {
return PROVIDER_NAME;
}
}
@@ -1,86 +1,86 @@
package org.keycloak.examples.federation.properties;
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.Properties;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @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;
}
}
}
package org.keycloak.examples.federation.properties;
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.Properties;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @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;
}
}
}
@@ -1,40 +1,40 @@
package org.keycloak.examples.federation.properties;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserCredentialValueModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.UserModelDelegate;
/**
* Readonly proxy for a UserModel that prevents passwords from being updated.
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class ReadonlyUserModelProxy extends UserModelDelegate {
public ReadonlyUserModelProxy(UserModel delegate) {
super(delegate);
}
@Override
public void setUsername(String username) {
throw new IllegalStateException("Username is readonly");
}
@Override
public void updateCredentialDirectly(UserCredentialValueModel cred) {
if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
throw new IllegalStateException("Passwords are readonly");
}
super.updateCredentialDirectly(cred);
}
@Override
public void updateCredential(UserCredentialModel cred) {
if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
throw new IllegalStateException("Passwords are readonly");
}
super.updateCredential(cred);
}
}
package org.keycloak.examples.federation.properties;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserCredentialValueModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.UserModelDelegate;
/**
* Readonly proxy for a UserModel that prevents passwords from being updated.
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class ReadonlyUserModelProxy extends UserModelDelegate {
public ReadonlyUserModelProxy(UserModel delegate) {
super(delegate);
}
@Override
public void setUsername(String username) {
throw new IllegalStateException("Username is readonly");
}
@Override
public void updateCredentialDirectly(UserCredentialValueModel cred) {
if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
throw new IllegalStateException("Passwords are readonly");
}
super.updateCredentialDirectly(cred);
}
@Override
public void updateCredential(UserCredentialModel cred) {
if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
throw new IllegalStateException("Passwords are readonly");
}
super.updateCredential(cred);
}
}
@@ -1,72 +1,72 @@
package org.keycloak.examples.federation.properties;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserCredentialValueModel;
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 <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @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();
}
}
@Override
public void updateCredentialDirectly(UserCredentialValueModel cred) {
if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
throw new IllegalStateException("Shouldn't be using this method");
}
super.updateCredentialDirectly(cred);
}
@Override
public void updateCredential(UserCredentialModel cred) {
if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
synchronized (provider.getProperties()) {
if (!provider.getProperties().containsKey(delegate.getUsername())) {
throw new IllegalStateException("no user of that in properties file");
}
provider.getProperties().setProperty(delegate.getUsername(), cred.getValue());
provider.save();
}
} else {
super.updateCredential(cred);
}
}
}
package org.keycloak.examples.federation.properties;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserCredentialValueModel;
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 <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @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();
}
}
@Override
public void updateCredentialDirectly(UserCredentialValueModel cred) {
if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
throw new IllegalStateException("Shouldn't be using this method");
}
super.updateCredentialDirectly(cred);
}
@Override
public void updateCredential(UserCredentialModel cred) {
if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
synchronized (provider.getProperties()) {
if (!provider.getProperties().containsKey(delegate.getUsername())) {
throw new IllegalStateException("no user of that in properties file");
}
provider.getProperties().setProperty(delegate.getUsername(), cred.getValue());
provider.save();
}
} else {
super.updateCredential(cred);
}
}
}
@@ -1,2 +1,2 @@
org.keycloak.examples.federation.properties.ClasspathPropertiesFederationFactory
org.keycloak.examples.federation.properties.ClasspathPropertiesFederationFactory
org.keycloak.examples.federation.properties.FilePropertiesFederationFactory
@@ -1,3 +1,3 @@
#
#Sun Aug 03 10:52:57 EDT 2014
belichick=superbowl
#
#Sun Aug 03 10:52:57 EDT 2014
belichick=superbowl