KEYCLOAK-886 Model and representations for UserFederationMappers

This commit is contained in:
mposolda 2015-05-21 17:37:56 +02:00
parent a9f1fda68a
commit 7476ee51e4
32 changed files with 1173 additions and 160 deletions

View file

@ -2,6 +2,7 @@
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd"> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet author="bburke@redhat.com" id="1.3.0.Beta1"> <changeSet author="bburke@redhat.com" id="1.3.0.Beta1">
<delete tableName="CLIENT_SESSION_ROLE"/> <delete tableName="CLIENT_SESSION_ROLE"/>
<delete tableName="CLIENT_SESSION_PROT_MAPPER"/>
<delete tableName="CLIENT_SESSION_NOTE"/> <delete tableName="CLIENT_SESSION_NOTE"/>
<delete tableName="CLIENT_SESSION"/> <delete tableName="CLIENT_SESSION"/>
<delete tableName="USER_SESSION_NOTE"/> <delete tableName="USER_SESSION_NOTE"/>
@ -21,6 +22,33 @@
<column name="REPRESENTATION" type="VARCHAR(25500)"/> <column name="REPRESENTATION" type="VARCHAR(25500)"/>
<column name="ERROR" type="VARCHAR(255)"/> <column name="ERROR" type="VARCHAR(255)"/>
</createTable> </createTable>
<createTable tableName="USER_FEDERATION_MAPPER">
<column name="ID" type="VARCHAR(36)">
<constraints nullable="false"/>
</column>
<column name="NAME" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
<column name="FEDERATION_PROVIDER_ID" type="VARCHAR(36)">
<constraints nullable="false"/>
</column>
<column name="FEDERATION_MAPPER_TYPE" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
<column name="REALM_ID" type="VARCHAR(36)">
<constraints nullable="false"/>
</column>
</createTable>
<createTable tableName="USER_FEDERATION_MAPPER_CONFIG">
<column name="USER_FEDERATION_MAPPER_ID" type="VARCHAR(36)">
<constraints nullable="false"/>
</column>
<column name="VALUE" type="VARCHAR(255)"/>
<column name="NAME" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
</createTable>
<addColumn tableName="REALM"> <addColumn tableName="REALM">
<column name="ADMIN_EVENTS_ENABLED" type="BOOLEAN" defaultValueBoolean="false"> <column name="ADMIN_EVENTS_ENABLED" type="BOOLEAN" defaultValueBoolean="false">
<constraints nullable="false"/> <constraints nullable="false"/>
@ -67,6 +95,11 @@
<dropColumn tableName="USER_REQUIRED_ACTION" columnName="ACTION"/> <dropColumn tableName="USER_REQUIRED_ACTION" columnName="ACTION"/>
<addPrimaryKey columnNames="REQUIRED_ACTION, USER_ID" constraintName="CONSTRAINT_REQUIRED_ACTION" tableName="USER_REQUIRED_ACTION"/> <addPrimaryKey columnNames="REQUIRED_ACTION, USER_ID" constraintName="CONSTRAINT_REQUIRED_ACTION" tableName="USER_REQUIRED_ACTION"/>
<addPrimaryKey columnNames="CLIENT_SESSION, AUTHENTICATOR" constraintName="CONSTRAINT_AUTH_STATUS_PK" tableName="CLIENT_SESSION_AUTH_STATUS"/> <addPrimaryKey columnNames="CLIENT_SESSION, AUTHENTICATOR" constraintName="CONSTRAINT_AUTH_STATUS_PK" tableName="CLIENT_SESSION_AUTH_STATUS"/>
<addPrimaryKey columnNames="ID" constraintName="CONSTRAINT_FEDMAPPERPM" tableName="USER_FEDERATION_MAPPER"/>
<addPrimaryKey columnNames="USER_FEDERATION_MAPPER_ID, NAME" constraintName="CONSTRAINT_FEDMAPPER_CFG_PM" tableName="USER_FEDERATION_MAPPER_CONFIG"/>
<addForeignKeyConstraint baseColumnNames="CLIENT_SESSION" baseTableName="CLIENT_SESSION_AUTH_STATUS" constraintName="AUTH_STATUS_CONSTRAINT" referencedColumnNames="ID" referencedTableName="CLIENT_SESSION"/> <addForeignKeyConstraint baseColumnNames="CLIENT_SESSION" baseTableName="CLIENT_SESSION_AUTH_STATUS" constraintName="AUTH_STATUS_CONSTRAINT" referencedColumnNames="ID" referencedTableName="CLIENT_SESSION"/>
<addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="USER_FEDERATION_MAPPER" constraintName="FK_FEDMAPPERPM_REALM" referencedColumnNames="ID" referencedTableName="REALM"/>
<addForeignKeyConstraint baseColumnNames="FEDERATION_PROVIDER_ID" baseTableName="USER_FEDERATION_MAPPER" constraintName="FK_FEDMAPPERPM_FEDPRV" referencedColumnNames="ID" referencedTableName="USER_FEDERATION_PROVIDER"/>
<addForeignKeyConstraint baseColumnNames="USER_FEDERATION_MAPPER_ID" baseTableName="USER_FEDERATION_MAPPER_CONFIG" constraintName="FK_FEDMAPPER_CFG" referencedColumnNames="ID" referencedTableName="USER_FEDERATION_MAPPER"/>
</changeSet> </changeSet>
</databaseChangeLog> </databaseChangeLog>

View file

@ -9,6 +9,7 @@
<class>org.keycloak.models.jpa.entities.RealmAttributeEntity</class> <class>org.keycloak.models.jpa.entities.RealmAttributeEntity</class>
<class>org.keycloak.models.jpa.entities.RequiredCredentialEntity</class> <class>org.keycloak.models.jpa.entities.RequiredCredentialEntity</class>
<class>org.keycloak.models.jpa.entities.UserFederationProviderEntity</class> <class>org.keycloak.models.jpa.entities.UserFederationProviderEntity</class>
<class>org.keycloak.models.jpa.entities.UserFederationMapperEntity</class>
<class>org.keycloak.models.jpa.entities.RoleEntity</class> <class>org.keycloak.models.jpa.entities.RoleEntity</class>
<class>org.keycloak.models.jpa.entities.FederatedIdentityEntity</class> <class>org.keycloak.models.jpa.entities.FederatedIdentityEntity</class>
<class>org.keycloak.models.jpa.entities.MigrationModelEntity</class> <class>org.keycloak.models.jpa.entities.MigrationModelEntity</class>

View file

@ -39,6 +39,7 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
"org.keycloak.models.sessions.mongo.entities.MongoUserSessionEntity", "org.keycloak.models.sessions.mongo.entities.MongoUserSessionEntity",
"org.keycloak.models.sessions.mongo.entities.MongoClientSessionEntity", "org.keycloak.models.sessions.mongo.entities.MongoClientSessionEntity",
"org.keycloak.models.entities.UserFederationProviderEntity", "org.keycloak.models.entities.UserFederationProviderEntity",
"org.keycloak.models.entities.UserFederationMapperEntity",
"org.keycloak.models.entities.ProtocolMapperEntity", "org.keycloak.models.entities.ProtocolMapperEntity",
"org.keycloak.models.entities.IdentityProviderMapperEntity", "org.keycloak.models.entities.IdentityProviderMapperEntity",
"org.keycloak.models.mongo.keycloak.entities.MongoUserConsentEntity", "org.keycloak.models.mongo.keycloak.entities.MongoUserConsentEntity",

View file

@ -53,6 +53,7 @@ public class RealmRepresentation {
protected Map<String, String> browserSecurityHeaders; protected Map<String, String> browserSecurityHeaders;
protected Map<String, String> smtpServer; protected Map<String, String> smtpServer;
protected List<UserFederationProviderRepresentation> userFederationProviders; protected List<UserFederationProviderRepresentation> userFederationProviders;
protected List<UserFederationMapperRepresentation> userFederationMappers;
protected String loginTheme; protected String loginTheme;
protected String accountTheme; protected String accountTheme;
protected String adminTheme; protected String adminTheme;
@ -536,6 +537,19 @@ public class RealmRepresentation {
this.userFederationProviders = userFederationProviders; this.userFederationProviders = userFederationProviders;
} }
public List<UserFederationMapperRepresentation> getUserFederationMappers() {
return userFederationMappers;
}
public void setUserFederationMappers(List<UserFederationMapperRepresentation> userFederationMappers) {
this.userFederationMappers = userFederationMappers;
}
public void addUserFederationMapper(UserFederationMapperRepresentation userFederationMapper) {
if (userFederationMappers == null) userFederationMappers = new LinkedList<>();
userFederationMappers.add(userFederationMapper);
}
public List<IdentityProviderRepresentation> getIdentityProviders() { public List<IdentityProviderRepresentation> getIdentityProviders() {
return identityProviders; return identityProviders;
} }

View file

@ -0,0 +1,56 @@
package org.keycloak.representations.idm;
import java.util.Map;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class UserFederationMapperRepresentation {
protected String id;
protected String name;
protected String federationProviderDisplayName;
protected String federationMapperType;
protected Map<String, String> 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 getFederationProviderDisplayName() {
return federationProviderDisplayName;
}
public void setFederationProviderDisplayName(String federationProviderDisplayName) {
this.federationProviderDisplayName = federationProviderDisplayName;
}
public String getFederationMapperType() {
return federationMapperType;
}
public void setFederationMapperType(String federationMapperType) {
this.federationMapperType = federationMapperType;
}
public Map<String, String> getConfig() {
return config;
}
public void setConfig(Map<String, String> config) {
this.config = config;
}
}

View file

@ -0,0 +1,55 @@
package org.keycloak.representations.idm;
import java.util.List;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class UserFederationMapperTypeRepresentation {
protected String id;
protected String name;
protected String category;
protected String helpText;
protected List<ConfigPropertyRepresentation> properties;
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 getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getHelpText() {
return helpText;
}
public void setHelpText(String helpText) {
this.helpText = helpText;
}
public List<ConfigPropertyRepresentation> getProperties() {
return properties;
}
public void setProperties(List<ConfigPropertyRepresentation> properties) {
this.properties = properties;
}
}

View file

@ -111,7 +111,7 @@ public class LDAPFederationProvider implements UserFederationProvider {
proxied = new UnsyncedLDAPUserModelDelegate(local, this); proxied = new UnsyncedLDAPUserModelDelegate(local, this);
} }
List<UserFederationMapperModel> federationMappers = realm.getUserFederationMappers(); Set<UserFederationMapperModel> federationMappers = realm.getUserFederationMappers();
for (UserFederationMapperModel mapperModel : federationMappers) { for (UserFederationMapperModel mapperModel : federationMappers) {
LDAPFederationMapper ldapMapper = getMapper(mapperModel); LDAPFederationMapper ldapMapper = getMapper(mapperModel);
proxied = ldapMapper.proxy(mapperModel, this, ldapObject, proxied, realm); proxied = ldapMapper.proxy(mapperModel, this, ldapObject, proxied, realm);
@ -268,7 +268,7 @@ public class LDAPFederationProvider implements UserFederationProvider {
UserModel imported = session.userStorage().addUser(realm, ldapUsername); UserModel imported = session.userStorage().addUser(realm, ldapUsername);
imported.setEnabled(true); imported.setEnabled(true);
List<UserFederationMapperModel> federationMappers = realm.getUserFederationMappers(); Set<UserFederationMapperModel> federationMappers = realm.getUserFederationMappers();
for (UserFederationMapperModel mapperModel : federationMappers) { for (UserFederationMapperModel mapperModel : federationMappers) {
LDAPFederationMapper ldapMapper = getMapper(mapperModel); LDAPFederationMapper ldapMapper = getMapper(mapperModel);
ldapMapper.onImportUserFromLDAP(mapperModel, this, ldapUser, imported, realm, true); ldapMapper.onImportUserFromLDAP(mapperModel, this, ldapUser, imported, realm, true);
@ -404,7 +404,7 @@ public class LDAPFederationProvider implements UserFederationProvider {
if ((fedModel.getId().equals(currentUser.getFederationLink())) && (ldapUser.getUuid().equals(currentUser.getAttribute(LDAPConstants.LDAP_ID)))) { if ((fedModel.getId().equals(currentUser.getFederationLink())) && (ldapUser.getUuid().equals(currentUser.getAttribute(LDAPConstants.LDAP_ID)))) {
// Update keycloak user // Update keycloak user
List<UserFederationMapperModel> federationMappers = realm.getUserFederationMappers(); Set<UserFederationMapperModel> federationMappers = realm.getUserFederationMappers();
for (UserFederationMapperModel mapperModel : federationMappers) { for (UserFederationMapperModel mapperModel : federationMappers) {
LDAPFederationMapper ldapMapper = getMapper(mapperModel); LDAPFederationMapper ldapMapper = getMapper(mapperModel);
ldapMapper.onImportUserFromLDAP(mapperModel, this, ldapUser, currentUser, realm, false); ldapMapper.onImportUserFromLDAP(mapperModel, this, ldapUser, currentUser, realm, false);
@ -477,9 +477,9 @@ public class LDAPFederationProvider implements UserFederationProvider {
} }
public LDAPFederationMapper getMapper(UserFederationMapperModel mapperModel) { public LDAPFederationMapper getMapper(UserFederationMapperModel mapperModel) {
LDAPFederationMapper ldapMapper = (LDAPFederationMapper) getSession().getProvider(UserFederationMapper.class, mapperModel.getFederationMapperId()); LDAPFederationMapper ldapMapper = (LDAPFederationMapper) getSession().getProvider(UserFederationMapper.class, mapperModel.getFederationMapperType());
if (ldapMapper == null) { if (ldapMapper == null) {
throw new ModelException("Can't find mapper type with ID: " + mapperModel.getFederationMapperId()); throw new ModelException("Can't find mapper type with ID: " + mapperModel.getFederationMapperType());
} }
return ldapMapper; return ldapMapper;

View file

@ -1,6 +1,7 @@
package org.keycloak.federation.ldap; package org.keycloak.federation.ldap;
import java.util.List; import java.util.List;
import java.util.Set;
import org.keycloak.federation.ldap.idm.model.LDAPDn; import org.keycloak.federation.ldap.idm.model.LDAPDn;
import org.keycloak.federation.ldap.idm.model.LDAPObject; import org.keycloak.federation.ldap.idm.model.LDAPObject;
@ -34,7 +35,7 @@ public class LDAPUtils {
ldapObject.setRdnAttributeName(ldapConfig.getRdnLdapAttribute()); ldapObject.setRdnAttributeName(ldapConfig.getRdnLdapAttribute());
ldapObject.setObjectClasses(ldapConfig.getObjectClasses()); ldapObject.setObjectClasses(ldapConfig.getObjectClasses());
List<UserFederationMapperModel> federationMappers = realm.getUserFederationMappers(); Set<UserFederationMapperModel> federationMappers = realm.getUserFederationMappers();
for (UserFederationMapperModel mapperModel : federationMappers) { for (UserFederationMapperModel mapperModel : federationMappers) {
LDAPFederationMapper ldapMapper = ldapProvider.getMapper(mapperModel); LDAPFederationMapper ldapMapper = ldapProvider.getMapper(mapperModel);
ldapMapper.onRegisterUserToLDAP(mapperModel, ldapProvider, ldapObject, user, realm); ldapMapper.onRegisterUserToLDAP(mapperModel, ldapProvider, ldapObject, user, realm);
@ -130,7 +131,7 @@ public class LDAPUtils {
ldapQuery.addSearchDns(config.getUserDns()); ldapQuery.addSearchDns(config.getUserDns());
ldapQuery.addObjectClasses(config.getObjectClasses()); ldapQuery.addObjectClasses(config.getObjectClasses());
List<UserFederationMapperModel> mapperModels = realm.getUserFederationMappers(); Set<UserFederationMapperModel> mapperModels = realm.getUserFederationMappers();
ldapQuery.addMappers(mapperModels); ldapQuery.addMappers(mapperModels);
return ldapQuery; return ldapQuery;

View file

@ -475,12 +475,12 @@ public class LDAPOperationManager {
String url = this.config.getConnectionUrl(); String url = this.config.getConnectionUrl();
if (url == null) { if (url != null) {
throw new RuntimeException("url"); env.put(Context.PROVIDER_URL, url);
} else {
logger.warn("LDAP URL is null. LDAPOperationManager won't work correctly");
} }
env.put(Context.PROVIDER_URL, url);
String connectionPooling = this.config.getConnectionPooling(); String connectionPooling = this.config.getConnectionPooling();
if (connectionPooling != null) { if (connectionPooling != null) {
env.put("com.sun.jndi.ldap.connect.pool", connectionPooling); env.put("com.sun.jndi.ldap.connect.pool", connectionPooling);

View file

@ -11,6 +11,8 @@ import org.keycloak.provider.ProviderConfigProperty;
*/ */
public class FullNameLDAPFederationMapperFactory extends AbstractLDAPFederationMapperFactory { public class FullNameLDAPFederationMapperFactory extends AbstractLDAPFederationMapperFactory {
public static final String ID = "full-name-ldap-mapper";
@Override @Override
public String getHelpText() { public String getHelpText() {
return "Some help text - full name mapper - TODO"; return "Some help text - full name mapper - TODO";
@ -23,7 +25,7 @@ public class FullNameLDAPFederationMapperFactory extends AbstractLDAPFederationM
@Override @Override
public String getId() { public String getId() {
return "full-name-ldap-mapper"; return ID;
} }
@Override @Override

View file

@ -11,6 +11,8 @@ import org.keycloak.provider.ProviderConfigProperty;
*/ */
public class RoleLDAPFederationMapperFactory extends AbstractLDAPFederationMapperFactory { public class RoleLDAPFederationMapperFactory extends AbstractLDAPFederationMapperFactory {
public static final String ID = "role-ldap-mapper";
@Override @Override
public String getHelpText() { public String getHelpText() {
return "Some help text - role mapper - TODO"; return "Some help text - role mapper - TODO";
@ -23,7 +25,7 @@ public class RoleLDAPFederationMapperFactory extends AbstractLDAPFederationMappe
@Override @Override
public String getId() { public String getId() {
return "role-ldap-mapper"; return ID ;
} }
@Override @Override

View file

@ -11,6 +11,8 @@ import org.keycloak.provider.ProviderConfigProperty;
*/ */
public class UserAttributeLDAPFederationMapperFactory extends AbstractLDAPFederationMapperFactory { public class UserAttributeLDAPFederationMapperFactory extends AbstractLDAPFederationMapperFactory {
public static final String ID = "user-attribute-ldap-mapper";
@Override @Override
public String getHelpText() { public String getHelpText() {
return "Some help text TODO"; return "Some help text TODO";
@ -23,7 +25,7 @@ public class UserAttributeLDAPFederationMapperFactory extends AbstractLDAPFedera
@Override @Override
public String getId() { public String getId() {
return "user-attribute-ldap-mapper"; return ID;
} }
@Override @Override

View file

@ -23,4 +23,9 @@ public class UserFederationMapperSpi implements Spi {
public Class<? extends ProviderFactory> getProviderFactoryClass() { public Class<? extends ProviderFactory> getProviderFactoryClass() {
return UserFederationMapperFactory.class; return UserFederationMapperFactory.class;
} }
@Override
public boolean isPrivate() {
return false;
}
} }

View file

@ -189,7 +189,13 @@ public interface RealmModel extends RoleContainerModel {
void removeUserFederationProvider(UserFederationProviderModel provider); void removeUserFederationProvider(UserFederationProviderModel provider);
void setUserFederationProviders(List<UserFederationProviderModel> providers); void setUserFederationProviders(List<UserFederationProviderModel> providers);
List<UserFederationMapperModel> getUserFederationMappers(); Set<UserFederationMapperModel> getUserFederationMappers();
Set<UserFederationMapperModel> getUserFederationMappersByFederationProvider(String federationProviderId);
UserFederationMapperModel addUserFederationMapper(UserFederationMapperModel mapper);
void removeUserFederationMapper(UserFederationMapperModel mapper);
void updateUserFederationMapper(UserFederationMapperModel mapper);
UserFederationMapperModel getUserFederationMapperById(String id);
UserFederationMapperModel getUserFederationMapperByName(String federationProviderId, String name);
String getLoginTheme(); String getLoginTheme();

View file

@ -9,7 +9,13 @@ public class UserFederationMapperModel {
protected String id; protected String id;
protected String name; protected String name;
protected String federationMapperId;
// Refers to DB ID of federation provider
protected String federationProviderId;
// Refers to ID of UserFederationMapper implementation ( UserFederationMapperFactory.getId )
protected String federationMapperType;
protected Map<String, String> config; protected Map<String, String> config;
public String getId() { public String getId() {
@ -28,12 +34,20 @@ public class UserFederationMapperModel {
this.name = name; this.name = name;
} }
public String getFederationMapperId() { public String getFederationProviderId() {
return federationMapperId; return federationProviderId;
} }
public void setFederationMapperId(String federationMapperId) { public void setFederationProviderId(String federationProviderId) {
this.federationMapperId = federationMapperId; this.federationProviderId = federationProviderId;
}
public String getFederationMapperType() {
return federationMapperType;
}
public void setFederationMapperType(String federationMapperType) {
this.federationMapperType = federationMapperType;
} }
public Map<String, String> getConfig() { public Map<String, String> getConfig() {

View file

@ -53,6 +53,7 @@ public class RealmEntity extends AbstractIdentifiableEntity {
private List<RequiredCredentialEntity> requiredCredentials = new ArrayList<RequiredCredentialEntity>(); private List<RequiredCredentialEntity> requiredCredentials = new ArrayList<RequiredCredentialEntity>();
private List<UserFederationProviderEntity> userFederationProviders = new ArrayList<UserFederationProviderEntity>(); private List<UserFederationProviderEntity> userFederationProviders = new ArrayList<UserFederationProviderEntity>();
private List<UserFederationMapperEntity> userFederationMappers = new ArrayList<UserFederationMapperEntity>();
private List<IdentityProviderEntity> identityProviders = new ArrayList<IdentityProviderEntity>(); private List<IdentityProviderEntity> identityProviders = new ArrayList<IdentityProviderEntity>();
private Map<String, String> browserSecurityHeaders = new HashMap<String, String>(); private Map<String, String> browserSecurityHeaders = new HashMap<String, String>();
@ -426,6 +427,14 @@ public class RealmEntity extends AbstractIdentifiableEntity {
this.userFederationProviders = userFederationProviders; this.userFederationProviders = userFederationProviders;
} }
public List<UserFederationMapperEntity> getUserFederationMappers() {
return userFederationMappers;
}
public void setUserFederationMappers(List<UserFederationMapperEntity> userFederationMappers) {
this.userFederationMappers = userFederationMappers;
}
public List<IdentityProviderEntity> getIdentityProviders() { public List<IdentityProviderEntity> getIdentityProviders() {
return identityProviders; return identityProviders;
} }

View file

@ -0,0 +1,55 @@
package org.keycloak.models.entities;
import java.util.Map;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class UserFederationMapperEntity {
protected String id;
protected String name;
protected String federationProviderId;
protected String federationMapperType;
protected Map<String, String> 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<String, String> getConfig() {
return config;
}
public void setConfig(Map<String, String> config) {
this.config = config;
}
}

View file

@ -6,9 +6,12 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.KeycloakSessionTask; import org.keycloak.models.KeycloakSessionTask;
import org.keycloak.models.KeycloakTransaction; import org.keycloak.models.KeycloakTransaction;
import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.UserCredentialModel; import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserFederationProvider;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.util.CertificateUtils; import org.keycloak.util.CertificateUtils;
import org.keycloak.util.PemUtils; import org.keycloak.util.PemUtils;
@ -23,6 +26,8 @@ import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.PublicKey; import java.security.PublicKey;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.LinkedList;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
@ -267,4 +272,49 @@ public final class KeycloakModelUtils {
} }
return false; return false;
} }
/**
* 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<UserFederationProviderModel> 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 UserFederationProviderModel findUserFederationProviderByDisplayName(String displayName, RealmModel realm) {
if (displayName == null) {
return null;
}
for (UserFederationProviderModel fedProvider : realm.getUserFederationProviders()) {
if (displayName.equals(fedProvider.getDisplayName())) {
return fedProvider;
}
}
return null;
}
public static UserFederationProviderModel findUserFederationProviderById(String fedProviderId, RealmModel realm) {
for (UserFederationProviderModel fedProvider : realm.getUserFederationProviders()) {
if (fedProviderId.equals(fedProvider.getId())) {
return fedProvider;
}
}
return null;
}
} }

View file

@ -5,12 +5,14 @@ import org.keycloak.models.ClientSessionModel;
import org.keycloak.models.FederatedIdentityModel; import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.IdentityProviderMapperModel; import org.keycloak.models.IdentityProviderMapperModel;
import org.keycloak.models.IdentityProviderModel; import org.keycloak.models.IdentityProviderModel;
import org.keycloak.models.ModelException;
import org.keycloak.models.ProtocolMapperModel; import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RequiredCredentialModel; import org.keycloak.models.RequiredCredentialModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.UserConsentModel; import org.keycloak.models.UserConsentModel;
import org.keycloak.models.UserCredentialModel; import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserFederationMapperModel;
import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel; import org.keycloak.models.UserSessionModel;
@ -25,6 +27,7 @@ import org.keycloak.representations.idm.RealmEventsConfigRepresentation;
import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.UserConsentRepresentation; import org.keycloak.representations.idm.UserConsentRepresentation;
import org.keycloak.representations.idm.UserFederationMapperRepresentation;
import org.keycloak.representations.idm.UserFederationProviderRepresentation; import org.keycloak.representations.idm.UserFederationProviderRepresentation;
import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.representations.idm.UserSessionRepresentation; import org.keycloak.representations.idm.UserSessionRepresentation;
@ -162,6 +165,10 @@ public class ModelToRepresentation {
rep.setUserFederationProviders(fedProviderReps); rep.setUserFederationProviders(fedProviderReps);
} }
for (UserFederationMapperModel mapper : realm.getUserFederationMappers()) {
rep.addUserFederationMapper(toRepresentation(realm, mapper));
}
for (IdentityProviderModel provider : realm.getIdentityProviders()) { for (IdentityProviderModel provider : realm.getIdentityProviders()) {
rep.addIdentityProvider(toRepresentation(provider)); rep.addIdentityProvider(toRepresentation(provider));
} }
@ -291,6 +298,24 @@ public class ModelToRepresentation {
return rep; return rep;
} }
public static UserFederationMapperRepresentation toRepresentation(RealmModel realm, UserFederationMapperModel model) {
UserFederationMapperRepresentation rep = new UserFederationMapperRepresentation();
rep.setId(model.getId());
rep.setName(model.getName());
rep.setFederationMapperType(model.getFederationMapperType());
Map<String, String> config = new HashMap<String, String>();
config.putAll(model.getConfig());
rep.setConfig(config);
UserFederationProviderModel fedProvider = KeycloakModelUtils.findUserFederationProviderById(model.getId(), realm);
if (fedProvider == null) {
throw new ModelException("Couldn't find federation provider with ID " + model.getId());
}
rep.setFederationProviderDisplayName(fedProvider.getDisplayName());
return rep;
}
public static IdentityProviderRepresentation toRepresentation(IdentityProviderModel identityProviderModel) { public static IdentityProviderRepresentation toRepresentation(IdentityProviderModel identityProviderModel) {
IdentityProviderRepresentation providerRep = new IdentityProviderRepresentation(); IdentityProviderRepresentation providerRep = new IdentityProviderRepresentation();

View file

@ -11,6 +11,7 @@ import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.IdentityProviderMapperModel; import org.keycloak.models.IdentityProviderMapperModel;
import org.keycloak.models.IdentityProviderModel; import org.keycloak.models.IdentityProviderModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelException;
import org.keycloak.models.PasswordPolicy; import org.keycloak.models.PasswordPolicy;
import org.keycloak.models.ProtocolMapperModel; import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
@ -18,6 +19,7 @@ import org.keycloak.models.RoleModel;
import org.keycloak.models.UserConsentModel; import org.keycloak.models.UserConsentModel;
import org.keycloak.models.UserCredentialModel; import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserCredentialValueModel; import org.keycloak.models.UserCredentialValueModel;
import org.keycloak.models.UserFederationMapperModel;
import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.ApplicationRepresentation; import org.keycloak.representations.idm.ApplicationRepresentation;
@ -34,6 +36,7 @@ import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.ScopeMappingRepresentation; import org.keycloak.representations.idm.ScopeMappingRepresentation;
import org.keycloak.representations.idm.SocialLinkRepresentation; import org.keycloak.representations.idm.SocialLinkRepresentation;
import org.keycloak.representations.idm.UserConsentRepresentation; import org.keycloak.representations.idm.UserConsentRepresentation;
import org.keycloak.representations.idm.UserFederationMapperRepresentation;
import org.keycloak.representations.idm.UserFederationProviderRepresentation; import org.keycloak.representations.idm.UserFederationProviderRepresentation;
import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.util.UriUtils; import org.keycloak.util.UriUtils;
@ -240,6 +243,11 @@ public class RepresentationToModel {
List<UserFederationProviderModel> providerModels = convertFederationProviders(rep.getUserFederationProviders()); List<UserFederationProviderModel> providerModels = convertFederationProviders(rep.getUserFederationProviders());
newRealm.setUserFederationProviders(providerModels); newRealm.setUserFederationProviders(providerModels);
} }
if (rep.getUserFederationMappers() != null) {
for (UserFederationMapperRepresentation representation : rep.getUserFederationMappers()) {
newRealm.addUserFederationMapper(toModel(newRealm, representation));
}
}
// create users and their role mappings and social mappings // create users and their role mappings and social mappings
@ -475,6 +483,23 @@ public class RepresentationToModel {
return result; return result;
} }
public static UserFederationMapperModel toModel(RealmModel realm, UserFederationMapperRepresentation rep) {
UserFederationMapperModel model = new UserFederationMapperModel();
model.setId(rep.getId());
model.setName(rep.getName());
model.setFederationMapperType(rep.getFederationMapperType());
model.setConfig(rep.getConfig());
UserFederationProviderModel fedProvider = KeycloakModelUtils.findUserFederationProviderByDisplayName(rep.getFederationProviderDisplayName(), realm);
if (fedProvider == null) {
throw new ModelException("Couldn't find federation provider with display name [" + rep.getFederationProviderDisplayName() + "] referenced from mapper ["
+ rep.getName());
}
model.setFederationProviderId(fedProvider.getId());
return model;
}
// Roles // Roles
public static void createRole(RealmModel newRealm, RoleRepresentation roleRep) { public static void createRole(RealmModel newRealm, RoleRepresentation roleRep) {

View file

@ -35,6 +35,7 @@ import org.keycloak.models.entities.IdentityProviderMapperEntity;
import org.keycloak.models.entities.RealmEntity; import org.keycloak.models.entities.RealmEntity;
import org.keycloak.models.entities.RequiredCredentialEntity; import org.keycloak.models.entities.RequiredCredentialEntity;
import org.keycloak.models.entities.RoleEntity; import org.keycloak.models.entities.RoleEntity;
import org.keycloak.models.entities.UserFederationMapperEntity;
import org.keycloak.models.entities.UserFederationProviderEntity; import org.keycloak.models.entities.UserFederationProviderEntity;
import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.models.utils.KeycloakModelUtils;
@ -812,6 +813,8 @@ public class RealmAdapter implements RealmModel {
@Override @Override
public UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config, int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync) { public UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config, int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync) {
KeycloakModelUtils.ensureUniqueDisplayName(displayName, null, getUserFederationProviders());
UserFederationProviderEntity entity = new UserFederationProviderEntity(); UserFederationProviderEntity entity = new UserFederationProviderEntity();
entity.setId(KeycloakModelUtils.generateId()); entity.setId(KeycloakModelUtils.generateId());
entity.setPriority(priority); entity.setPriority(priority);
@ -837,6 +840,12 @@ public class RealmAdapter implements RealmModel {
if (entity.getId().equals(provider.getId())) { if (entity.getId().equals(provider.getId())) {
session.users().preRemove(this, new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(), session.users().preRemove(this, new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(),
entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync())); entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync()));
Set<UserFederationMapperEntity> mappers = getUserFederationMapperEntitiesByFederationProvider(provider.getId());
for (UserFederationMapperEntity mapper : mappers) {
realm.getUserFederationMappers().remove(mapper);
}
it.remove(); it.remove();
} }
} }
@ -844,6 +853,8 @@ public class RealmAdapter implements RealmModel {
@Override @Override
public void updateUserFederationProvider(UserFederationProviderModel model) { public void updateUserFederationProvider(UserFederationProviderModel model) {
KeycloakModelUtils.ensureUniqueDisplayName(model.getDisplayName(), model, getUserFederationProviders());
Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator(); Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
while (it.hasNext()) { while (it.hasNext()) {
UserFederationProviderEntity entity = it.next(); UserFederationProviderEntity entity = it.next();
@ -889,6 +900,10 @@ public class RealmAdapter implements RealmModel {
@Override @Override
public void setUserFederationProviders(List<UserFederationProviderModel> providers) { public void setUserFederationProviders(List<UserFederationProviderModel> providers) {
for (UserFederationProviderModel currentProvider : providers) {
KeycloakModelUtils.ensureUniqueDisplayName(currentProvider.getDisplayName(), currentProvider, providers);
}
List<UserFederationProviderEntity> entities = new LinkedList<UserFederationProviderEntity>(); List<UserFederationProviderEntity> entities = new LinkedList<UserFederationProviderEntity>();
for (UserFederationProviderModel model : providers) { for (UserFederationProviderModel model : providers) {
UserFederationProviderEntity entity = new UserFederationProviderEntity(); UserFederationProviderEntity entity = new UserFederationProviderEntity();
@ -1063,16 +1078,7 @@ public class RealmAdapter implements RealmModel {
public Set<IdentityProviderMapperModel> getIdentityProviderMappers() { public Set<IdentityProviderMapperModel> getIdentityProviderMappers() {
Set<IdentityProviderMapperModel> mappings = new HashSet<>(); Set<IdentityProviderMapperModel> mappings = new HashSet<>();
for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) { for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) {
IdentityProviderMapperModel mapping = new IdentityProviderMapperModel(); IdentityProviderMapperModel mapping = entityToModel(entity);
mapping.setId(entity.getId());
mapping.setName(entity.getName());
mapping.setIdentityProviderAlias(entity.getIdentityProviderAlias());
mapping.setIdentityProviderMapper(entity.getIdentityProviderMapper());
Map<String, String> config = new HashMap<String, String>();
if (entity.getConfig() != null) {
config.putAll(entity.getConfig());
}
mapping.setConfig(config);
mappings.add(mapping); mappings.add(mapping);
} }
return mappings; return mappings;
@ -1084,16 +1090,7 @@ public class RealmAdapter implements RealmModel {
if (!entity.getIdentityProviderAlias().equals(brokerAlias)) { if (!entity.getIdentityProviderAlias().equals(brokerAlias)) {
continue; continue;
} }
IdentityProviderMapperModel mapping = new IdentityProviderMapperModel(); IdentityProviderMapperModel mapping = entityToModel(entity);
mapping.setId(entity.getId());
mapping.setName(entity.getName());
mapping.setIdentityProviderAlias(entity.getIdentityProviderAlias());
mapping.setIdentityProviderMapper(entity.getIdentityProviderMapper());
Map<String, String> config = new HashMap<String, String>();
if (entity.getConfig() != null) {
config.putAll(entity.getConfig());
}
mapping.setConfig(config);
mappings.add(mapping); mappings.add(mapping);
} }
return mappings; return mappings;
@ -1102,7 +1099,7 @@ public class RealmAdapter implements RealmModel {
@Override @Override
public IdentityProviderMapperModel addIdentityProviderMapper(IdentityProviderMapperModel model) { public IdentityProviderMapperModel addIdentityProviderMapper(IdentityProviderMapperModel model) {
if (getIdentityProviderMapperByName(model.getIdentityProviderAlias(), model.getIdentityProviderMapper()) != null) { if (getIdentityProviderMapperByName(model.getIdentityProviderAlias(), model.getIdentityProviderMapper()) != null) {
throw new RuntimeException("protocol mapper name must be unique per protocol"); throw new RuntimeException("identity provider mapper name must be unique per identity provider");
} }
String id = KeycloakModelUtils.generateId(); String id = KeycloakModelUtils.generateId();
IdentityProviderMapperEntity entity = new IdentityProviderMapperEntity(); IdentityProviderMapperEntity entity = new IdentityProviderMapperEntity();
@ -1186,8 +1183,116 @@ public class RealmAdapter implements RealmModel {
} }
@Override @Override
public List<UserFederationMapperModel> getUserFederationMappers() { public Set<UserFederationMapperModel> getUserFederationMappers() {
throw new IllegalStateException("Not yet implemented"); Set<UserFederationMapperModel> mappers = new HashSet<UserFederationMapperModel>();
for (UserFederationMapperEntity entity : this.realm.getUserFederationMappers()) {
UserFederationMapperModel mapper = entityToModel(entity);
mappers.add(mapper);
}
return mappers;
} }
@Override
public Set<UserFederationMapperModel> getUserFederationMappersByFederationProvider(String federationProviderId) {
Set<UserFederationMapperModel> mappers = new HashSet<UserFederationMapperModel>();
Set<UserFederationMapperEntity> mapperEntities = getUserFederationMapperEntitiesByFederationProvider(federationProviderId);
for (UserFederationMapperEntity entity : mapperEntities) {
mappers.add(entityToModel(entity));
}
return mappers;
}
@Override
public UserFederationMapperModel addUserFederationMapper(UserFederationMapperModel model) {
if (getUserFederationMapperByName(model.getFederationProviderId(), model.getName()) != null) {
throw new ModelDuplicateException("User federation mapper must be unique per federation provider");
}
String id = KeycloakModelUtils.generateId();
UserFederationMapperEntity entity = new UserFederationMapperEntity();
entity.setId(id);
entity.setName(model.getName());
entity.setFederationProviderId(model.getFederationProviderId());
entity.setFederationMapperType(model.getFederationMapperType());
entity.setConfig(model.getConfig());
this.realm.getUserFederationMappers().add(entity);
return entityToModel(entity);
}
protected UserFederationMapperEntity getUserFederationMapperEntity(String id) {
for (UserFederationMapperEntity entity : this.realm.getUserFederationMappers()) {
if (entity.getId().equals(id)) {
return entity;
}
}
return null;
}
protected UserFederationMapperEntity getUserFederationMapperEntityByName(String federationProviderId, String name) {
for (UserFederationMapperEntity entity : this.realm.getUserFederationMappers()) {
if (entity.getFederationProviderId().equals(federationProviderId) && entity.getName().equals(name)) {
return entity;
}
}
return null;
}
protected Set<UserFederationMapperEntity> getUserFederationMapperEntitiesByFederationProvider(String federationProviderId) {
Set<UserFederationMapperEntity> mappers = new HashSet<UserFederationMapperEntity>();
for (UserFederationMapperEntity entity : this.realm.getUserFederationMappers()) {
if (federationProviderId.equals(entity.getFederationProviderId())) {
mappers.add(entity);
}
}
return mappers;
}
@Override
public void removeUserFederationMapper(UserFederationMapperModel mapper) {
UserFederationMapperEntity toDelete = getUserFederationMapperEntity(mapper.getId());
if (toDelete != null) {
this.realm.getUserFederationMappers().remove(toDelete);
}
}
@Override
public void updateUserFederationMapper(UserFederationMapperModel mapper) {
UserFederationMapperEntity entity = getUserFederationMapperEntity(mapper.getId());
entity.setFederationProviderId(mapper.getFederationProviderId());
entity.setFederationMapperType(mapper.getFederationMapperType());
if (entity.getConfig() == null) {
entity.setConfig(mapper.getConfig());
} else {
entity.getConfig().clear();
entity.getConfig().putAll(mapper.getConfig());
}
}
@Override
public UserFederationMapperModel getUserFederationMapperById(String id) {
UserFederationMapperEntity entity = getUserFederationMapperEntity(id);
if (entity == null) return null;
return entityToModel(entity);
}
@Override
public UserFederationMapperModel getUserFederationMapperByName(String federationProviderId, String name) {
UserFederationMapperEntity entity = getUserFederationMapperEntityByName(federationProviderId, name);
if (entity == null) return null;
return entityToModel(entity);
}
protected UserFederationMapperModel entityToModel(UserFederationMapperEntity entity) {
UserFederationMapperModel mapper = new UserFederationMapperModel();
mapper.setId(entity.getId());
mapper.setName(entity.getName());
mapper.setFederationProviderId(entity.getFederationProviderId());
mapper.setFederationMapperType(entity.getFederationMapperType());
Map<String, String> config = new HashMap<String, String>();
if (entity.getConfig() != null) config.putAll(entity.getConfig());
mapper.setConfig(config);
return mapper;
}
} }

View file

@ -952,79 +952,67 @@ public class RealmAdapter implements RealmModel {
return null; return null;
} }
public static String LDAP_MODE = "LDAP_ONLY";
@Override @Override
public List<UserFederationMapperModel> getUserFederationMappers() { public Set<UserFederationMapperModel> getUserFederationMappers() {
// TODO: Some hardcoded stuff... if (updated != null) return updated.getUserFederationMappers();
List<UserFederationMapperModel> mappers = new ArrayList<UserFederationMapperModel>(); Set<UserFederationMapperModel> mappers = new HashSet<UserFederationMapperModel>();
for (List<UserFederationMapperModel> models : cached.getUserFederationMappers().values()) {
mappers.add(createMapperModel("usn", "usernameMapper", "user-attribute-ldap-mapper", for (UserFederationMapperModel model : models) {
"user.model.attribute", UserModel.USERNAME, mappers.add(model);
"ldap.attribute", LDAPConstants.UID)); }
}
// Uncomment this for CN + SN config
/*mappers.add(createMapperModel("fn", "firstNameMapper", "user-attribute-ldap-mapper",
"user.model.attribute", UserModel.FIRST_NAME,
"ldap.attribute", LDAPConstants.CN));*/
// Uncomment this for CN + SN + givenname config
mappers.add(createMapperModel("fn", "firstNameMapper", "user-attribute-ldap-mapper",
"user.model.attribute", UserModel.FIRST_NAME,
"ldap.attribute", LDAPConstants.GIVENNAME));
mappers.add(createMapperModel("fulln", "fullNameMapper", "full-name-ldap-mapper",
"ldap.full.name.attribute", LDAPConstants.CN));
mappers.add(createMapperModel("ln", "lastNameMapper", "user-attribute-ldap-mapper",
"user.model.attribute", UserModel.LAST_NAME,
"ldap.attribute", LDAPConstants.SN));
mappers.add(createMapperModel("emailMpr", "emailMapper", "user-attribute-ldap-mapper",
"user.model.attribute", UserModel.EMAIL,
"ldap.attribute", LDAPConstants.EMAIL));
mappers.add(createMapperModel("postalCodeMpr", "postalCodeMapper", "user-attribute-ldap-mapper",
"user.model.attribute", "postal_code",
"ldap.attribute", LDAPConstants.POSTAL_CODE));
mappers.add(createMapperModel("createdDateMpr", "createTimeStampMapper", "user-attribute-ldap-mapper",
"user.model.attribute", LDAPConstants.CREATE_TIMESTAMP,
"ldap.attribute", LDAPConstants.CREATE_TIMESTAMP,
"read.only", "true"));
mappers.add(createMapperModel("modifyDateMpr", "modifyTimeStampMapper", "user-attribute-ldap-mapper",
"user.model.attribute", LDAPConstants.MODIFY_TIMESTAMP,
"ldap.attribute", LDAPConstants.MODIFY_TIMESTAMP,
"read.only", "true"));
mappers.add(createMapperModel("realmRoleMpr", "realmRoleMapper", "role-ldap-mapper",
"roles.dn", "ou=RealmRoles,dc=keycloak,dc=org",
"use.realm.roles.mapping", "true",
"mode", LDAP_MODE));
mappers.add(createMapperModel("financeRoleMpr", "financeRoleMapper", "role-ldap-mapper",
"roles.dn", "ou=FinanceRoles,dc=keycloak,dc=org",
"use.realm.roles.mapping", "false",
"client.id", "finance",
"mode", LDAP_MODE));
return mappers; return mappers;
} }
private static UserFederationMapperModel createMapperModel(String id, String name, String mapperId, String... config) { @Override
UserFederationMapperModel mapperModel = new UserFederationMapperModel(); public Set<UserFederationMapperModel> getUserFederationMappersByFederationProvider(String federationProviderId) {
mapperModel.setId(id); if (updated != null) return updated.getUserFederationMappersByFederationProvider(federationProviderId);
mapperModel.setName(name); Set<UserFederationMapperModel> mappers = new HashSet<>();
mapperModel.setFederationMapperId(mapperId); List<UserFederationMapperModel> list = cached.getUserFederationMappers().getList(federationProviderId);
for (UserFederationMapperModel entity : list) {
mappers.add(entity);
}
return mappers;
}
Map<String, String> configMap = new HashMap<String, String>(); @Override
String key = null; public UserFederationMapperModel addUserFederationMapper(UserFederationMapperModel mapper) {
for (String configEntry : config) { getDelegateForUpdate();
if (key == null) { return updated.addUserFederationMapper(mapper);
key = configEntry; }
} else {
configMap.put(key, configEntry); @Override
key = null; public void removeUserFederationMapper(UserFederationMapperModel mapper) {
getDelegateForUpdate();
updated.removeUserFederationMapper(mapper);
}
@Override
public void updateUserFederationMapper(UserFederationMapperModel mapper) {
getDelegateForUpdate();
updated.updateUserFederationMapper(mapper);
}
@Override
public UserFederationMapperModel getUserFederationMapperById(String id) {
if (updated != null) return updated.getUserFederationMapperById(id);
for (List<UserFederationMapperModel> models : cached.getUserFederationMappers().values()) {
for (UserFederationMapperModel model : models) {
if (model.getId().equals(id)) return model;
} }
} }
mapperModel.setConfig(configMap); return null;
return mapperModel; }
@Override
public UserFederationMapperModel getUserFederationMapperByName(String federationProviderId, String name) {
if (updated != null) return updated.getUserFederationMapperByName(federationProviderId, name);
List<UserFederationMapperModel> models = cached.getUserFederationMappers().getList(federationProviderId);
if (models == null) return null;
for (UserFederationMapperModel model : models) {
if (model.getName().equals(name)) return model;
}
return null;
} }
} }

View file

@ -9,6 +9,7 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.RealmProvider; import org.keycloak.models.RealmProvider;
import org.keycloak.models.RequiredCredentialModel; import org.keycloak.models.RequiredCredentialModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.UserFederationMapperModel;
import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.cache.RealmCache; import org.keycloak.models.cache.RealmCache;
import org.keycloak.util.MultivaluedHashMap; import org.keycloak.util.MultivaluedHashMap;
@ -70,6 +71,7 @@ public class CachedRealm {
private List<RequiredCredentialModel> requiredCredentials = new ArrayList<RequiredCredentialModel>(); private List<RequiredCredentialModel> requiredCredentials = new ArrayList<RequiredCredentialModel>();
private List<UserFederationProviderModel> userFederationProviders = new ArrayList<UserFederationProviderModel>(); private List<UserFederationProviderModel> userFederationProviders = new ArrayList<UserFederationProviderModel>();
private MultivaluedHashMap<String, UserFederationMapperModel> userFederationMappers = new MultivaluedHashMap<String, UserFederationMapperModel>();
private List<IdentityProviderModel> identityProviders = new ArrayList<IdentityProviderModel>(); private List<IdentityProviderModel> identityProviders = new ArrayList<IdentityProviderModel>();
private Map<String, String> browserSecurityHeaders = new HashMap<String, String>(); private Map<String, String> browserSecurityHeaders = new HashMap<String, String>();
@ -136,6 +138,9 @@ public class CachedRealm {
requiredCredentials = model.getRequiredCredentials(); requiredCredentials = model.getRequiredCredentials();
userFederationProviders = model.getUserFederationProviders(); userFederationProviders = model.getUserFederationProviders();
for (UserFederationMapperModel mapper : model.getUserFederationMappers()) {
userFederationMappers.add(mapper.getFederationProviderId(), mapper);
}
this.identityProviders = new ArrayList<>(); this.identityProviders = new ArrayList<>();
@ -373,6 +378,10 @@ public class CachedRealm {
return userFederationProviders; return userFederationProviders;
} }
public MultivaluedHashMap<String, UserFederationMapperModel> getUserFederationMappers() {
return userFederationMappers;
}
public String getCertificatePem() { public String getCertificatePem() {
return certificatePem; return certificatePem;
} }

View file

@ -5,11 +5,14 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.IdentityProviderMapperModel; import org.keycloak.models.IdentityProviderMapperModel;
import org.keycloak.models.IdentityProviderModel; import org.keycloak.models.IdentityProviderModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.ModelException;
import org.keycloak.models.PasswordPolicy; import org.keycloak.models.PasswordPolicy;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RequiredCredentialModel; import org.keycloak.models.RequiredCredentialModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.UserFederationMapperModel; import org.keycloak.models.UserFederationMapperModel;
import org.keycloak.models.UserFederationProvider;
import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.jpa.entities.ClientEntity; import org.keycloak.models.jpa.entities.ClientEntity;
import org.keycloak.models.jpa.entities.IdentityProviderEntity; import org.keycloak.models.jpa.entities.IdentityProviderEntity;
@ -18,6 +21,7 @@ import org.keycloak.models.jpa.entities.RealmAttributeEntity;
import org.keycloak.models.jpa.entities.RealmEntity; import org.keycloak.models.jpa.entities.RealmEntity;
import org.keycloak.models.jpa.entities.RequiredCredentialEntity; import org.keycloak.models.jpa.entities.RequiredCredentialEntity;
import org.keycloak.models.jpa.entities.RoleEntity; 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.jpa.entities.UserFederationProviderEntity;
import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.models.utils.KeycloakModelUtils;
@ -760,6 +764,8 @@ public class RealmAdapter implements RealmModel {
@Override @Override
public UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config, int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync) { public UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config, int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync) {
KeycloakModelUtils.ensureUniqueDisplayName(displayName, null, getUserFederationProviders());
String id = KeycloakModelUtils.generateId(); String id = KeycloakModelUtils.generateId();
UserFederationProviderEntity entity = new UserFederationProviderEntity(); UserFederationProviderEntity entity = new UserFederationProviderEntity();
entity.setId(id); entity.setId(id);
@ -786,7 +792,14 @@ public class RealmAdapter implements RealmModel {
while (it.hasNext()) { while (it.hasNext()) {
UserFederationProviderEntity entity = it.next(); UserFederationProviderEntity entity = it.next();
if (entity.getId().equals(provider.getId())) { if (entity.getId().equals(provider.getId())) {
session.users().preRemove(this, provider); session.users().preRemove(this, provider);
Set<UserFederationMapperEntity> mappers = getUserFederationMapperEntitiesByFederationProvider(provider.getId());
for (UserFederationMapperEntity mapper : mappers) {
realm.getUserFederationMappers().remove(mapper);
em.remove(mapper);
}
it.remove(); it.remove();
em.remove(entity); em.remove(entity);
return; return;
@ -795,6 +808,8 @@ public class RealmAdapter implements RealmModel {
} }
@Override @Override
public void updateUserFederationProvider(UserFederationProviderModel model) { public void updateUserFederationProvider(UserFederationProviderModel model) {
KeycloakModelUtils.ensureUniqueDisplayName(model.getDisplayName(), model, getUserFederationProviders());
Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator(); Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
while (it.hasNext()) { while (it.hasNext()) {
UserFederationProviderEntity entity = it.next(); UserFederationProviderEntity entity = it.next();
@ -817,6 +832,9 @@ public class RealmAdapter implements RealmModel {
@Override @Override
public void setUserFederationProviders(List<UserFederationProviderModel> providers) { public void setUserFederationProviders(List<UserFederationProviderModel> providers) {
for (UserFederationProviderModel currentProvider : providers) {
KeycloakModelUtils.ensureUniqueDisplayName(currentProvider.getDisplayName(), currentProvider, providers);
}
Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator(); Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
while (it.hasNext()) { while (it.hasNext()) {
@ -881,6 +899,15 @@ public class RealmAdapter implements RealmModel {
} }
} }
protected UserFederationProviderEntity getUserFederationProviderEntityById(String federationProviderId) {
for (UserFederationProviderEntity entity : realm.getUserFederationProviders()) {
if (entity.getId().equals(federationProviderId)) {
return entity;
}
}
return null;
}
@Override @Override
public RoleModel getRole(String name) { public RoleModel getRole(String name) {
TypedQuery<RoleEntity> query = em.createNamedQuery("getRealmRoleByName", RoleEntity.class); TypedQuery<RoleEntity> query = em.createNamedQuery("getRealmRoleByName", RoleEntity.class);
@ -1225,16 +1252,7 @@ public class RealmAdapter implements RealmModel {
public Set<IdentityProviderMapperModel> getIdentityProviderMappers() { public Set<IdentityProviderMapperModel> getIdentityProviderMappers() {
Set<IdentityProviderMapperModel> mappings = new HashSet<IdentityProviderMapperModel>(); Set<IdentityProviderMapperModel> mappings = new HashSet<IdentityProviderMapperModel>();
for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) { for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) {
IdentityProviderMapperModel mapping = new IdentityProviderMapperModel(); IdentityProviderMapperModel mapping = entityToModel(entity);
mapping.setId(entity.getId());
mapping.setName(entity.getName());
mapping.setIdentityProviderAlias(entity.getIdentityProviderAlias());
mapping.setIdentityProviderMapper(entity.getIdentityProviderMapper());
Map<String, String> config = new HashMap<String, String>();
if (entity.getConfig() != null) {
config.putAll(entity.getConfig());
}
mapping.setConfig(config);
mappings.add(mapping); mappings.add(mapping);
} }
return mappings; return mappings;
@ -1247,16 +1265,7 @@ public class RealmAdapter implements RealmModel {
if (!entity.getIdentityProviderAlias().equals(brokerAlias)) { if (!entity.getIdentityProviderAlias().equals(brokerAlias)) {
continue; continue;
} }
IdentityProviderMapperModel mapping = new IdentityProviderMapperModel(); IdentityProviderMapperModel mapping = entityToModel(entity);
mapping.setId(entity.getId());
mapping.setName(entity.getName());
mapping.setIdentityProviderAlias(entity.getIdentityProviderAlias());
mapping.setIdentityProviderMapper(entity.getIdentityProviderMapper());
Map<String, String> config = new HashMap<String, String>();
if (entity.getConfig() != null) {
config.putAll(entity.getConfig());
}
mapping.setConfig(config);
mappings.add(mapping); mappings.add(mapping);
} }
return mappings; return mappings;
@ -1265,7 +1274,7 @@ public class RealmAdapter implements RealmModel {
@Override @Override
public IdentityProviderMapperModel addIdentityProviderMapper(IdentityProviderMapperModel model) { public IdentityProviderMapperModel addIdentityProviderMapper(IdentityProviderMapperModel model) {
if (getIdentityProviderMapperByName(model.getIdentityProviderAlias(), model.getIdentityProviderMapper()) != null) { if (getIdentityProviderMapperByName(model.getIdentityProviderAlias(), model.getIdentityProviderMapper()) != null) {
throw new RuntimeException("protocol mapper name must be unique per protocol"); throw new RuntimeException("identity provider mapper name must be unique per identity provider");
} }
String id = KeycloakModelUtils.generateId(); String id = KeycloakModelUtils.generateId();
IdentityProviderMapperEntity entity = new IdentityProviderMapperEntity(); IdentityProviderMapperEntity entity = new IdentityProviderMapperEntity();
@ -1353,8 +1362,122 @@ public class RealmAdapter implements RealmModel {
} }
@Override @Override
public List<UserFederationMapperModel> getUserFederationMappers() { public Set<UserFederationMapperModel> getUserFederationMappers() {
throw new IllegalStateException("Not yet implemented"); Set<UserFederationMapperModel> mappers = new HashSet<UserFederationMapperModel>();
for (UserFederationMapperEntity entity : this.realm.getUserFederationMappers()) {
UserFederationMapperModel mapper = entityToModel(entity);
mappers.add(mapper);
}
return mappers;
}
@Override
public Set<UserFederationMapperModel> getUserFederationMappersByFederationProvider(String federationProviderId) {
Set<UserFederationMapperModel> mappers = new HashSet<UserFederationMapperModel>();
Set<UserFederationMapperEntity> mapperEntities = getUserFederationMapperEntitiesByFederationProvider(federationProviderId);
for (UserFederationMapperEntity entity : mapperEntities) {
UserFederationMapperModel mapper = entityToModel(entity);
mappers.add(mapper);
}
return mappers;
}
@Override
public UserFederationMapperModel addUserFederationMapper(UserFederationMapperModel model) {
if (getUserFederationMapperByName(model.getFederationProviderId(), model.getName()) != null) {
throw new ModelDuplicateException("User federation mapper must be unique per federation provider");
}
String id = KeycloakModelUtils.generateId();
UserFederationMapperEntity entity = new UserFederationMapperEntity();
entity.setId(id);
entity.setName(model.getName());
entity.setFederationProvider(getUserFederationProviderEntityById(model.getFederationProviderId()));
entity.setFederationMapperType(model.getFederationMapperType());
entity.setRealm(this.realm);
entity.setConfig(model.getConfig());
em.persist(entity);
this.realm.getUserFederationMappers().add(entity);
return entityToModel(entity);
}
@Override
public void removeUserFederationMapper(UserFederationMapperModel mapper) {
UserFederationMapperEntity toDelete = getUserFederationMapperEntity(mapper.getId());
if (toDelete != null) {
this.realm.getUserFederationMappers().remove(toDelete);
em.remove(toDelete);
}
}
protected UserFederationMapperEntity getUserFederationMapperEntity(String id) {
for (UserFederationMapperEntity entity : this.realm.getUserFederationMappers()) {
if (entity.getId().equals(id)) {
return entity;
}
}
return null;
}
protected UserFederationMapperEntity getUserFederationMapperEntityByName(String federationProviderId, String name) {
for (UserFederationMapperEntity entity : this.realm.getUserFederationMappers()) {
if (federationProviderId.equals(entity.getFederationProvider().getId()) && entity.getName().equals(name)) {
return entity;
}
}
return null;
}
protected Set<UserFederationMapperEntity> getUserFederationMapperEntitiesByFederationProvider(String federationProviderId) {
Set<UserFederationMapperEntity> mappers = new HashSet<UserFederationMapperEntity>();
for (UserFederationMapperEntity entity : this.realm.getUserFederationMappers()) {
if (federationProviderId.equals(entity.getFederationProvider().getId())) {
mappers.add(entity);
}
}
return mappers;
}
@Override
public void updateUserFederationMapper(UserFederationMapperModel mapper) {
UserFederationMapperEntity entity = getUserFederationMapperEntity(mapper.getId());
entity.setFederationProvider(getUserFederationProviderEntityById(mapper.getFederationProviderId()));
entity.setFederationMapperType(mapper.getFederationMapperType());
if (entity.getConfig() == null) {
entity.setConfig(mapper.getConfig());
} else {
entity.getConfig().clear();
entity.getConfig().putAll(mapper.getConfig());
}
em.flush();
}
@Override
public UserFederationMapperModel getUserFederationMapperById(String id) {
UserFederationMapperEntity entity = getUserFederationMapperEntity(id);
if (entity == null) return null;
return entityToModel(entity);
}
@Override
public UserFederationMapperModel getUserFederationMapperByName(String federationProviderId, String name) {
UserFederationMapperEntity entity = getUserFederationMapperEntityByName(federationProviderId, name);
if (entity == null) return null;
return entityToModel(entity);
}
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<String, String> config = new HashMap<String, String>();
if (entity.getConfig() != null) config.putAll(entity.getConfig());
mapper.setConfig(config);
return mapper;
} }
} }

View file

@ -103,6 +103,9 @@ public class RealmEntity {
@JoinTable(name="FED_PROVIDERS") @JoinTable(name="FED_PROVIDERS")
List<UserFederationProviderEntity> userFederationProviders = new ArrayList<UserFederationProviderEntity>(); List<UserFederationProviderEntity> userFederationProviders = new ArrayList<UserFederationProviderEntity>();
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
Collection<UserFederationMapperEntity> userFederationMappers = new ArrayList<UserFederationMapperEntity>();
@OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true) @OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true)
@JoinTable(name="REALM_CLIENT", joinColumns={ @JoinColumn(name="REALM_ID") }, inverseJoinColumns={ @JoinColumn(name="CLIENT_ID") }) @JoinTable(name="REALM_CLIENT", joinColumns={ @JoinColumn(name="REALM_ID") }, inverseJoinColumns={ @JoinColumn(name="CLIENT_ID") })
Collection<ClientEntity> clients = new ArrayList<>(); Collection<ClientEntity> clients = new ArrayList<>();
@ -475,6 +478,14 @@ public class RealmEntity {
this.userFederationProviders = userFederationProviders; this.userFederationProviders = userFederationProviders;
} }
public Collection<UserFederationMapperEntity> getUserFederationMappers() {
return userFederationMappers;
}
public void setUserFederationMappers(Collection<UserFederationMapperEntity> userFederationMappers) {
this.userFederationMappers = userFederationMappers;
}
public Collection<RealmAttributeEntity> getAttributes() { public Collection<RealmAttributeEntity> getAttributes() {
return attributes; return attributes;
} }

View file

@ -0,0 +1,113 @@
package org.keycloak.models.jpa.entities;
import java.util.Map;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MapKeyColumn;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@Entity
@Table(name="USER_FEDERATION_MAPPER")
public class UserFederationMapperEntity {
@Id
@Column(name="ID", length = 36)
protected String id;
@Column(name="NAME")
protected String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "FEDERATION_PROVIDER_ID")
protected UserFederationProviderEntity federationProvider;
@Column(name = "FEDERATION_MAPPER_TYPE")
protected String federationMapperType;
@ElementCollection
@MapKeyColumn(name="NAME")
@Column(name="VALUE")
@CollectionTable(name="USER_FEDERATION_MAPPER_CONFIG", joinColumns={ @JoinColumn(name="USER_FEDERATION_MAPPER_ID") })
private Map<String, String> config;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "REALM_ID")
private RealmEntity realm;
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 UserFederationProviderEntity getFederationProvider() {
return federationProvider;
}
public void setFederationProvider(UserFederationProviderEntity federationProvider) {
this.federationProvider = federationProvider;
}
public String getFederationMapperType() {
return federationMapperType;
}
public void setFederationMapperType(String federationMapperType) {
this.federationMapperType = federationMapperType;
}
public Map<String, String> getConfig() {
return config;
}
public void setConfig(Map<String, String> config) {
this.config = config;
}
public RealmEntity getRealm() {
return realm;
}
public void setRealm(RealmEntity realm) {
this.realm = realm;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserFederationMapperEntity that = (UserFederationMapperEntity) o;
if (!id.equals(that.id)) return false;
return true;
}
@Override
public int hashCode() {
return id.hashCode();
}
}

View file

@ -9,6 +9,7 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.IdentityProviderMapperModel; import org.keycloak.models.IdentityProviderMapperModel;
import org.keycloak.models.IdentityProviderModel; import org.keycloak.models.IdentityProviderModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.PasswordPolicy; import org.keycloak.models.PasswordPolicy;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RealmProvider; import org.keycloak.models.RealmProvider;
@ -19,6 +20,7 @@ import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.entities.IdentityProviderEntity; import org.keycloak.models.entities.IdentityProviderEntity;
import org.keycloak.models.entities.IdentityProviderMapperEntity; import org.keycloak.models.entities.IdentityProviderMapperEntity;
import org.keycloak.models.entities.RequiredCredentialEntity; import org.keycloak.models.entities.RequiredCredentialEntity;
import org.keycloak.models.entities.UserFederationMapperEntity;
import org.keycloak.models.entities.UserFederationProviderEntity; import org.keycloak.models.entities.UserFederationProviderEntity;
import org.keycloak.models.mongo.keycloak.entities.MongoClientEntity; import org.keycloak.models.mongo.keycloak.entities.MongoClientEntity;
import org.keycloak.models.mongo.keycloak.entities.MongoRealmEntity; import org.keycloak.models.mongo.keycloak.entities.MongoRealmEntity;
@ -833,6 +835,8 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
@Override @Override
public UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config, int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync) { public UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config, int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync) {
KeycloakModelUtils.ensureUniqueDisplayName(displayName, null, getUserFederationProviders());
UserFederationProviderEntity entity = new UserFederationProviderEntity(); UserFederationProviderEntity entity = new UserFederationProviderEntity();
entity.setId(KeycloakModelUtils.generateId()); entity.setId(KeycloakModelUtils.generateId());
entity.setPriority(priority); entity.setPriority(priority);
@ -859,6 +863,12 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
if (entity.getId().equals(provider.getId())) { if (entity.getId().equals(provider.getId())) {
session.users().preRemove(this, new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(), session.users().preRemove(this, new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(),
entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync())); entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync()));
Set<UserFederationMapperEntity> mappers = getUserFederationMapperEntitiesByFederationProvider(provider.getId());
for (UserFederationMapperEntity mapper : mappers) {
getMongoEntity().getUserFederationMappers().remove(mapper);
}
it.remove(); it.remove();
} }
} }
@ -867,6 +877,8 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
@Override @Override
public void updateUserFederationProvider(UserFederationProviderModel model) { public void updateUserFederationProvider(UserFederationProviderModel model) {
KeycloakModelUtils.ensureUniqueDisplayName(model.getDisplayName(), model, getUserFederationProviders());
Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator(); Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
while (it.hasNext()) { while (it.hasNext()) {
UserFederationProviderEntity entity = it.next(); UserFederationProviderEntity entity = it.next();
@ -913,6 +925,10 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
@Override @Override
public void setUserFederationProviders(List<UserFederationProviderModel> providers) { public void setUserFederationProviders(List<UserFederationProviderModel> providers) {
for (UserFederationProviderModel currentProvider : providers) {
KeycloakModelUtils.ensureUniqueDisplayName(currentProvider.getDisplayName(), currentProvider, providers);
}
List<UserFederationProviderEntity> entities = new LinkedList<UserFederationProviderEntity>(); List<UserFederationProviderEntity> entities = new LinkedList<UserFederationProviderEntity>();
for (UserFederationProviderModel model : providers) { for (UserFederationProviderModel model : providers) {
UserFederationProviderEntity entity = new UserFederationProviderEntity(); UserFederationProviderEntity entity = new UserFederationProviderEntity();
@ -923,7 +939,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
entity.setPriority(model.getPriority()); entity.setPriority(model.getPriority());
String displayName = model.getDisplayName(); String displayName = model.getDisplayName();
if (displayName == null) { if (displayName == null) {
entity.setDisplayName(entity.getId()); displayName = entity.getId();
} }
entity.setDisplayName(displayName); entity.setDisplayName(displayName);
entity.setFullSyncPeriod(model.getFullSyncPeriod()); entity.setFullSyncPeriod(model.getFullSyncPeriod());
@ -1089,16 +1105,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
public Set<IdentityProviderMapperModel> getIdentityProviderMappers() { public Set<IdentityProviderMapperModel> getIdentityProviderMappers() {
Set<IdentityProviderMapperModel> mappings = new HashSet<IdentityProviderMapperModel>(); Set<IdentityProviderMapperModel> mappings = new HashSet<IdentityProviderMapperModel>();
for (IdentityProviderMapperEntity entity : getMongoEntity().getIdentityProviderMappers()) { for (IdentityProviderMapperEntity entity : getMongoEntity().getIdentityProviderMappers()) {
IdentityProviderMapperModel mapping = new IdentityProviderMapperModel(); IdentityProviderMapperModel mapping = entityToModel(entity);
mapping.setId(entity.getId());
mapping.setName(entity.getName());
mapping.setIdentityProviderAlias(entity.getIdentityProviderAlias());
mapping.setIdentityProviderMapper(entity.getIdentityProviderMapper());
Map<String, String> config = new HashMap<String, String>();
if (entity.getConfig() != null) {
config.putAll(entity.getConfig());
}
mapping.setConfig(config);
mappings.add(mapping); mappings.add(mapping);
} }
return mappings; return mappings;
@ -1111,16 +1118,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
if (!entity.getIdentityProviderAlias().equals(brokerAlias)) { if (!entity.getIdentityProviderAlias().equals(brokerAlias)) {
continue; continue;
} }
IdentityProviderMapperModel mapping = new IdentityProviderMapperModel(); IdentityProviderMapperModel mapping = entityToModel(entity);
mapping.setId(entity.getId());
mapping.setName(entity.getName());
mapping.setIdentityProviderAlias(entity.getIdentityProviderAlias());
mapping.setIdentityProviderMapper(entity.getIdentityProviderMapper());
Map<String, String> config = new HashMap<String, String>();
if (entity.getConfig() != null) {
config.putAll(entity.getConfig());
}
mapping.setConfig(config);
mappings.add(mapping); mappings.add(mapping);
} }
return mappings; return mappings;
@ -1129,7 +1127,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
@Override @Override
public IdentityProviderMapperModel addIdentityProviderMapper(IdentityProviderMapperModel model) { public IdentityProviderMapperModel addIdentityProviderMapper(IdentityProviderMapperModel model) {
if (getIdentityProviderMapperByName(model.getIdentityProviderAlias(), model.getIdentityProviderMapper()) != null) { if (getIdentityProviderMapperByName(model.getIdentityProviderAlias(), model.getIdentityProviderMapper()) != null) {
throw new RuntimeException("protocol mapper name must be unique per protocol"); throw new RuntimeException("identity provider mapper name must be unique per identity provider");
} }
String id = KeycloakModelUtils.generateId(); String id = KeycloakModelUtils.generateId();
IdentityProviderMapperEntity entity = new IdentityProviderMapperEntity(); IdentityProviderMapperEntity entity = new IdentityProviderMapperEntity();
@ -1169,6 +1167,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
IdentityProviderMapperEntity toDelete = getIdentityProviderMapperEntity(mapping.getId()); IdentityProviderMapperEntity toDelete = getIdentityProviderMapperEntity(mapping.getId());
if (toDelete != null) { if (toDelete != null) {
this.realm.getIdentityProviderMappers().remove(toDelete); this.realm.getIdentityProviderMappers().remove(toDelete);
updateMongoEntity();
} }
} }
@ -1215,7 +1214,119 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
} }
@Override @Override
public List<UserFederationMapperModel> getUserFederationMappers() { public Set<UserFederationMapperModel> getUserFederationMappers() {
throw new IllegalStateException("Not yet implemented"); Set<UserFederationMapperModel> mappers = new HashSet<UserFederationMapperModel>();
for (UserFederationMapperEntity entity : getMongoEntity().getUserFederationMappers()) {
UserFederationMapperModel mapper = entityToModel(entity);
mappers.add(mapper);
}
return mappers;
}
@Override
public Set<UserFederationMapperModel> getUserFederationMappersByFederationProvider(String federationProviderId) {
Set<UserFederationMapperModel> mappers = new HashSet<UserFederationMapperModel>();
Set<UserFederationMapperEntity> mapperEntities = getUserFederationMapperEntitiesByFederationProvider(federationProviderId);
for (UserFederationMapperEntity entity : mapperEntities) {
mappers.add(entityToModel(entity));
}
return mappers;
}
@Override
public UserFederationMapperModel addUserFederationMapper(UserFederationMapperModel model) {
if (getUserFederationMapperByName(model.getFederationProviderId(), model.getName()) != null) {
throw new ModelDuplicateException("User federation mapper must be unique per federation provider");
}
String id = KeycloakModelUtils.generateId();
UserFederationMapperEntity entity = new UserFederationMapperEntity();
entity.setId(id);
entity.setName(model.getName());
entity.setFederationProviderId(model.getFederationProviderId());
entity.setFederationMapperType(model.getFederationMapperType());
entity.setConfig(model.getConfig());
getMongoEntity().getUserFederationMappers().add(entity);
updateMongoEntity();
return entityToModel(entity);
}
protected UserFederationMapperEntity getUserFederationMapperEntity(String id) {
for (UserFederationMapperEntity entity : getMongoEntity().getUserFederationMappers()) {
if (entity.getId().equals(id)) {
return entity;
}
}
return null;
}
protected UserFederationMapperEntity getUserFederationMapperEntityByName(String federationProviderId, String name) {
for (UserFederationMapperEntity entity : getMongoEntity().getUserFederationMappers()) {
if (entity.getFederationProviderId().equals(federationProviderId) && entity.getName().equals(name)) {
return entity;
}
}
return null;
}
protected Set<UserFederationMapperEntity> getUserFederationMapperEntitiesByFederationProvider(String federationProviderId) {
Set<UserFederationMapperEntity> mappers = new HashSet<UserFederationMapperEntity>();
for (UserFederationMapperEntity entity : getMongoEntity().getUserFederationMappers()) {
if (federationProviderId.equals(entity.getFederationProviderId())) {
mappers.add(entity);
}
}
return mappers;
}
@Override
public void removeUserFederationMapper(UserFederationMapperModel mapper) {
UserFederationMapperEntity toDelete = getUserFederationMapperEntity(mapper.getId());
if (toDelete != null) {
this.realm.getUserFederationMappers().remove(toDelete);
updateMongoEntity();
}
}
@Override
public void updateUserFederationMapper(UserFederationMapperModel mapper) {
UserFederationMapperEntity entity = getUserFederationMapperEntity(mapper.getId());
entity.setFederationProviderId(mapper.getFederationProviderId());
entity.setFederationMapperType(mapper.getFederationMapperType());
if (entity.getConfig() == null) {
entity.setConfig(mapper.getConfig());
} else {
entity.getConfig().clear();
entity.getConfig().putAll(mapper.getConfig());
}
updateMongoEntity();
}
@Override
public UserFederationMapperModel getUserFederationMapperById(String id) {
UserFederationMapperEntity entity = getUserFederationMapperEntity(id);
if (entity == null) return null;
return entityToModel(entity);
}
@Override
public UserFederationMapperModel getUserFederationMapperByName(String federationProviderId, String name) {
UserFederationMapperEntity entity = getUserFederationMapperEntityByName(federationProviderId, name);
if (entity == null) return null;
return entityToModel(entity);
}
protected UserFederationMapperModel entityToModel(UserFederationMapperEntity entity) {
UserFederationMapperModel mapper = new UserFederationMapperModel();
mapper.setId(entity.getId());
mapper.setName(entity.getName());
mapper.setFederationProviderId(entity.getFederationProviderId());
mapper.setFederationMapperType(entity.getFederationMapperType());
Map<String, String> config = new HashMap<String, String>();
if (entity.getConfig() != null) config.putAll(entity.getConfig());
mapper.setConfig(config);
return mapper;
} }
} }

View file

@ -144,7 +144,7 @@ public class LDAPRoleMappingsTest {
@Test @Test
public void test01_ldapOnlyRoleMappings() { public void test01_ldapOnlyRoleMappings() {
// TODO: Remove me!!! // TODO: Remove me!!!
RealmAdapter.LDAP_MODE = "LDAP_ONLY"; //RealmAdapter.LDAP_MODE = "LDAP_ONLY";
KeycloakSession session = keycloakRule.startSession(); KeycloakSession session = keycloakRule.startSession();
try { try {
@ -231,7 +231,7 @@ public class LDAPRoleMappingsTest {
@Test @Test
public void test02_readOnlyRoleMappings() { public void test02_readOnlyRoleMappings() {
// TODO: Remove me!!! // TODO: Remove me!!!
RealmAdapter.LDAP_MODE = "READ_ONLY"; //RealmAdapter.LDAP_MODE = "READ_ONLY";
KeycloakSession session = keycloakRule.startSession(); KeycloakSession session = keycloakRule.startSession();
try { try {
@ -293,7 +293,7 @@ public class LDAPRoleMappingsTest {
@Test @Test
public void test03_importRoleMappings() { public void test03_importRoleMappings() {
// TODO: Remove me!!! // TODO: Remove me!!!
RealmAdapter.LDAP_MODE = "IMPORT"; //RealmAdapter.LDAP_MODE = "IMPORT";
KeycloakSession session = keycloakRule.startSession(); KeycloakSession session = keycloakRule.startSession();
try { try {
@ -346,7 +346,7 @@ public class LDAPRoleMappingsTest {
} }
private static UserFederationMapperModel findRoleMapperModel(RealmModel appRealm) { private static UserFederationMapperModel findRoleMapperModel(RealmModel appRealm) {
List<UserFederationMapperModel> fedMappers = appRealm.getUserFederationMappers(); Set<UserFederationMapperModel> fedMappers = appRealm.getUserFederationMappers();
for (UserFederationMapperModel mapper : fedMappers) { for (UserFederationMapperModel mapper : fedMappers) {
if ("realmRoleMapper".equals(mapper.getName())) { if ("realmRoleMapper".equals(mapper.getName())) {
return mapper; return mapper;

View file

@ -13,6 +13,7 @@ import org.keycloak.models.RequiredCredentialModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.UserCredentialModel; import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserCredentialValueModel; import org.keycloak.models.UserCredentialValueModel;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.models.UserProvider; import org.keycloak.models.UserProvider;
import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.CredentialRepresentation;
@ -23,8 +24,11 @@ import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
@ -741,6 +745,59 @@ public class AdapterTest extends AbstractModelTest {
resetSession(); resetSession();
} }
@Test
public void testUserFederationProviderDisplayNameCollisions() throws Exception {
RealmModel realm = realmManager.createRealm("JUGGLER1");
Map<String, String> cfg = Collections.emptyMap();
realm.addUserFederationProvider("ldap", cfg, 1, "providerName1", -1, -1, 0);
realm.addUserFederationProvider("ldap", cfg, 1, "providerName2", -1, -1, 0);
commit();
// Try to add federation provider with same display name
try {
realmManager.getRealmByName("JUGGLER1").addUserFederationProvider("ldap", cfg, 1, "providerName1", -1, -1, 0);
commit();
Assert.fail("Expected exception");
} catch (ModelDuplicateException e) {
}
commit(true);
// Try to rename federation provider tu duplicate display name
try {
List<UserFederationProviderModel> fedProviders = realmManager.getRealmByName("JUGGLER1").getUserFederationProviders();
for (UserFederationProviderModel fedProvider : fedProviders) {
if ("providerName1".equals(fedProvider.getDisplayName())) {
fedProvider.setDisplayName("providerName2");
realm.updateUserFederationProvider(fedProvider);
break;
}
}
commit();
Assert.fail("Expected exception");
} catch (ModelDuplicateException e) {
}
commit(true);
// Try to rename federation provider tu duplicate display name
try {
List<UserFederationProviderModel> fedProviders = realmManager.getRealmByName("JUGGLER1").getUserFederationProviders();
for (UserFederationProviderModel fedProvider : fedProviders) {
if ("providerName1".equals(fedProvider.getDisplayName())) {
fedProvider.setDisplayName("providerName2");
break;
}
}
realm.setUserFederationProviders(fedProviders);
commit();
Assert.fail("Expected exception");
} catch (ModelDuplicateException e) {
}
commit(true);
}
private KeyPair generateKeypair() throws NoSuchAlgorithmException { private KeyPair generateKeypair() throws NoSuchAlgorithmException {
return KeyPairGenerator.getInstance("RSA").generateKeyPair(); return KeyPairGenerator.getInstance("RSA").generateKeyPair();
} }

View file

@ -5,6 +5,8 @@ import org.junit.FixMethodOrder;
import org.junit.Test; import org.junit.Test;
import org.junit.runners.MethodSorters; import org.junit.runners.MethodSorters;
import org.keycloak.constants.KerberosConstants; import org.keycloak.constants.KerberosConstants;
import org.keycloak.federation.ldap.mappers.FullNameLDAPFederationMapper;
import org.keycloak.federation.ldap.mappers.FullNameLDAPFederationMapperFactory;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
import org.keycloak.models.Constants; import org.keycloak.models.Constants;
import org.keycloak.models.FederatedIdentityModel; import org.keycloak.models.FederatedIdentityModel;
@ -15,6 +17,7 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.RequiredCredentialModel; import org.keycloak.models.RequiredCredentialModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.UserConsentModel; import org.keycloak.models.UserConsentModel;
import org.keycloak.models.UserFederationMapperModel;
import org.keycloak.models.UserFederationProvider; import org.keycloak.models.UserFederationProvider;
import org.keycloak.models.UserFederationProviderFactory; import org.keycloak.models.UserFederationProviderFactory;
import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserFederationProviderModel;
@ -220,6 +223,15 @@ public class ImportTest extends AbstractModelTest {
Assert.assertEquals(1, ldap.getPriority()); Assert.assertEquals(1, ldap.getPriority());
Assert.assertEquals("ldap://foo", ldap.getConfig().get("important.config")); Assert.assertEquals("ldap://foo", ldap.getConfig().get("important.config"));
// Test federation mappers
Set<UserFederationMapperModel> fedMappers = realm.getUserFederationMappers();
Assert.assertTrue(fedMappers.size() == 1);
UserFederationMapperModel fullNameMapper = fedMappers.iterator().next();
Assert.assertEquals("FullNameMapper", fullNameMapper.getName());
Assert.assertEquals(FullNameLDAPFederationMapperFactory.ID, fullNameMapper.getFederationMapperType());
Assert.assertEquals(ldap.getId(), fullNameMapper.getFederationProviderId());
Assert.assertEquals("cn", fullNameMapper.getConfig().get(FullNameLDAPFederationMapper.LDAP_FULL_NAME_ATTRIBUTE));
// Assert that federation link wasn't created during import // Assert that federation link wasn't created during import
UserFederationProviderFactory factory = (UserFederationProviderFactory)session.getKeycloakSessionFactory().getProviderFactory(UserFederationProvider.class, "dummy"); UserFederationProviderFactory factory = (UserFederationProviderFactory)session.getKeycloakSessionFactory().getProviderFactory(UserFederationProvider.class, "dummy");
Assert.assertNull(factory.getInstance(session, null).getUserByUsername(realm, "wburke")); Assert.assertNull(factory.getInstance(session, null).getUserByUsername(realm, "wburke"));

View file

@ -0,0 +1,118 @@
package org.keycloak.testsuite.model;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import org.junit.Assert;
import org.junit.Test;
import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserFederationMapperModel;
import org.keycloak.models.UserFederationProviderModel;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class UserFederationModelTest extends AbstractModelTest {
@Test
public void federationMapperCrudTest() {
RealmModel realm = realmManager.createRealm("test-realm");
UserFederationProviderModel fedProvider = realm.addUserFederationProvider("dummy", new TreeMap<String, String>(), 1, "my-cool-provider", -1, -1, 0);
UserFederationProviderModel fedProvider2 = realm.addUserFederationProvider("dummy", new TreeMap<String, String>(), 1, "my-cool-provider2", -1, -1, 0);
UserFederationMapperModel mapperModel1 = createMapper("name1", fedProvider.getId(), "key1", "value1");
UserFederationMapperModel mapperModel2 = createMapper("name2", fedProvider.getId(), "key2", "value2");
UserFederationMapperModel mapperModel3 = createMapper("name1", fedProvider2.getId(), "key3", "value3");
mapperModel1 = realm.addUserFederationMapper(mapperModel1);
mapperModel2 = realm.addUserFederationMapper(mapperModel2);
mapperModel3 = realm.addUserFederationMapper(mapperModel3);
commit();
try {
UserFederationMapperModel conflictMapper = createMapper("name1", fedProvider.getId(), "key4", "value4");
realmManager.getRealmByName("test-realm").addUserFederationMapper(conflictMapper);
commit();
Assert.fail("Don't expect to end here");
} catch (ModelDuplicateException expected) {
}
realm = realmManager.getRealmByName("test-realm");
Set<UserFederationMapperModel> mappers = realm.getUserFederationMappers();
Assert.assertEquals(3, mappers.size());
Assert.assertTrue(mappers.contains(mapperModel1));
Assert.assertTrue(mappers.contains(mapperModel2));
Assert.assertTrue(mappers.contains(mapperModel3));
mappers = realm.getUserFederationMappersByFederationProvider(fedProvider.getId());
Assert.assertEquals(2, mappers.size());
Assert.assertTrue(mappers.contains(mapperModel1));
Assert.assertTrue(mappers.contains(mapperModel2));
mapperModel3.getConfig().put("otherKey", "otherValue");
realm.updateUserFederationMapper(mapperModel3);
commit();
realm = realmManager.getRealmByName("test-realm");
mapperModel3 = realm.getUserFederationMapperById(mapperModel3.getId());
Assert.assertEquals(2, mapperModel3.getConfig().size());
Assert.assertEquals("value3", mapperModel3.getConfig().get("key3"));
Assert.assertEquals("otherValue", mapperModel3.getConfig().get("otherKey"));
}
@Test
public void federationProviderRemovalTest() {
RealmModel realm = realmManager.createRealm("test-realm");
UserFederationProviderModel fedProvider = realm.addUserFederationProvider("dummy", new TreeMap<String, String>(), 1, "my-cool-provider", -1, -1, 0);
UserFederationProviderModel fedProvider2 = realm.addUserFederationProvider("dummy", new TreeMap<String, String>(), 1, "my-cool-provider2", -1, -1, 0);
UserFederationMapperModel mapperModel1 = createMapper("name1", fedProvider.getId(), "key1", "value1");
UserFederationMapperModel mapperModel2 = createMapper("name2", fedProvider.getId(), "key2", "value2");
UserFederationMapperModel mapperModel3 = createMapper("name1", fedProvider2.getId(), "key3", "value3");
mapperModel1 = realm.addUserFederationMapper(mapperModel1);
mapperModel2 = realm.addUserFederationMapper(mapperModel2);
mapperModel3 = realm.addUserFederationMapper(mapperModel3);
commit();
realmManager.getRealmByName("test-realm").removeUserFederationProvider(fedProvider);
commit();
realm = realmManager.getRealmByName("test-realm");
Set<UserFederationMapperModel> mappers = realm.getUserFederationMappers();
Assert.assertEquals(1, mappers.size());
Assert.assertEquals(mapperModel3, mappers.iterator().next());
realm = realmManager.getRealmByName("test-realm");
realmManager.removeRealm(realm);
commit();
}
private UserFederationMapperModel createMapper(String name, String fedProviderId, String... config) {
UserFederationMapperModel mapperModel = new UserFederationMapperModel();
mapperModel.setName(name);
mapperModel.setFederationMapperType("someType");
mapperModel.setFederationProviderId(fedProviderId);
Map<String, String> configMap = new TreeMap<String, String>();
String key = null;
for (String configEntry : config) {
if (key == null) {
key = configEntry;
} else {
configMap.put(key, configEntry);
key = null;
}
}
mapperModel.setConfig(configMap);
return mapperModel;
}
}

View file

@ -33,6 +33,16 @@
} }
} }
], ],
"userFederationMappers": [
{
"name": "FullNameMapper",
"federationProviderDisplayName": "MyLDAPProvider",
"federationMapperType": "full-name-ldap-mapper",
"config": {
"ldap.full.name.attribute": "cn"
}
}
],
"users": [ "users": [
{ {
"username": "wburke", "username": "wburke",