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">
<changeSet author="bburke@redhat.com" id="1.3.0.Beta1">
<delete tableName="CLIENT_SESSION_ROLE"/>
<delete tableName="CLIENT_SESSION_PROT_MAPPER"/>
<delete tableName="CLIENT_SESSION_NOTE"/>
<delete tableName="CLIENT_SESSION"/>
<delete tableName="USER_SESSION_NOTE"/>
@ -21,6 +22,33 @@
<column name="REPRESENTATION" type="VARCHAR(25500)"/>
<column name="ERROR" type="VARCHAR(255)"/>
</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">
<column name="ADMIN_EVENTS_ENABLED" type="BOOLEAN" defaultValueBoolean="false">
<constraints nullable="false"/>
@ -67,6 +95,11 @@
<dropColumn tableName="USER_REQUIRED_ACTION" columnName="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="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="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>
</databaseChangeLog>

View file

@ -9,6 +9,7 @@
<class>org.keycloak.models.jpa.entities.RealmAttributeEntity</class>
<class>org.keycloak.models.jpa.entities.RequiredCredentialEntity</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.FederatedIdentityEntity</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.MongoClientSessionEntity",
"org.keycloak.models.entities.UserFederationProviderEntity",
"org.keycloak.models.entities.UserFederationMapperEntity",
"org.keycloak.models.entities.ProtocolMapperEntity",
"org.keycloak.models.entities.IdentityProviderMapperEntity",
"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> smtpServer;
protected List<UserFederationProviderRepresentation> userFederationProviders;
protected List<UserFederationMapperRepresentation> userFederationMappers;
protected String loginTheme;
protected String accountTheme;
protected String adminTheme;
@ -536,6 +537,19 @@ public class RealmRepresentation {
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() {
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);
}
List<UserFederationMapperModel> federationMappers = realm.getUserFederationMappers();
Set<UserFederationMapperModel> federationMappers = realm.getUserFederationMappers();
for (UserFederationMapperModel mapperModel : federationMappers) {
LDAPFederationMapper ldapMapper = getMapper(mapperModel);
proxied = ldapMapper.proxy(mapperModel, this, ldapObject, proxied, realm);
@ -268,7 +268,7 @@ public class LDAPFederationProvider implements UserFederationProvider {
UserModel imported = session.userStorage().addUser(realm, ldapUsername);
imported.setEnabled(true);
List<UserFederationMapperModel> federationMappers = realm.getUserFederationMappers();
Set<UserFederationMapperModel> federationMappers = realm.getUserFederationMappers();
for (UserFederationMapperModel mapperModel : federationMappers) {
LDAPFederationMapper ldapMapper = getMapper(mapperModel);
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)))) {
// Update keycloak user
List<UserFederationMapperModel> federationMappers = realm.getUserFederationMappers();
Set<UserFederationMapperModel> federationMappers = realm.getUserFederationMappers();
for (UserFederationMapperModel mapperModel : federationMappers) {
LDAPFederationMapper ldapMapper = getMapper(mapperModel);
ldapMapper.onImportUserFromLDAP(mapperModel, this, ldapUser, currentUser, realm, false);
@ -477,9 +477,9 @@ public class LDAPFederationProvider implements UserFederationProvider {
}
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) {
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;

View file

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

View file

@ -475,12 +475,12 @@ public class LDAPOperationManager {
String url = this.config.getConnectionUrl();
if (url == null) {
throw new RuntimeException("url");
if (url != null) {
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();
if (connectionPooling != null) {
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 static final String ID = "full-name-ldap-mapper";
@Override
public String getHelpText() {
return "Some help text - full name mapper - TODO";
@ -23,7 +25,7 @@ public class FullNameLDAPFederationMapperFactory extends AbstractLDAPFederationM
@Override
public String getId() {
return "full-name-ldap-mapper";
return ID;
}
@Override

View file

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

View file

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

View file

@ -23,4 +23,9 @@ public class UserFederationMapperSpi implements Spi {
public Class<? extends ProviderFactory> getProviderFactoryClass() {
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 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();

View file

@ -9,7 +9,13 @@ public class UserFederationMapperModel {
protected String id;
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;
public String getId() {
@ -28,12 +34,20 @@ public class UserFederationMapperModel {
this.name = name;
}
public String getFederationMapperId() {
return federationMapperId;
public String getFederationProviderId() {
return federationProviderId;
}
public void setFederationMapperId(String federationMapperId) {
this.federationMapperId = federationMapperId;
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() {

View file

@ -53,6 +53,7 @@ public class RealmEntity extends AbstractIdentifiableEntity {
private List<RequiredCredentialEntity> requiredCredentials = new ArrayList<RequiredCredentialEntity>();
private List<UserFederationProviderEntity> userFederationProviders = new ArrayList<UserFederationProviderEntity>();
private List<UserFederationMapperEntity> userFederationMappers = new ArrayList<UserFederationMapperEntity>();
private List<IdentityProviderEntity> identityProviders = new ArrayList<IdentityProviderEntity>();
private Map<String, String> browserSecurityHeaders = new HashMap<String, String>();
@ -426,6 +427,14 @@ public class RealmEntity extends AbstractIdentifiableEntity {
this.userFederationProviders = userFederationProviders;
}
public List<UserFederationMapperEntity> getUserFederationMappers() {
return userFederationMappers;
}
public void setUserFederationMappers(List<UserFederationMapperEntity> userFederationMappers) {
this.userFederationMappers = userFederationMappers;
}
public List<IdentityProviderEntity> getIdentityProviders() {
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.KeycloakSessionTask;
import org.keycloak.models.KeycloakTransaction;
import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserFederationProvider;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.UserModel;
import org.keycloak.util.CertificateUtils;
import org.keycloak.util.PemUtils;
@ -23,6 +26,8 @@ import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
@ -267,4 +272,49 @@ public final class KeycloakModelUtils {
}
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.IdentityProviderMapperModel;
import org.keycloak.models.IdentityProviderModel;
import org.keycloak.models.ModelException;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RequiredCredentialModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserConsentModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserFederationMapperModel;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
@ -25,6 +27,7 @@ import org.keycloak.representations.idm.RealmEventsConfigRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.UserConsentRepresentation;
import org.keycloak.representations.idm.UserFederationMapperRepresentation;
import org.keycloak.representations.idm.UserFederationProviderRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.representations.idm.UserSessionRepresentation;
@ -162,6 +165,10 @@ public class ModelToRepresentation {
rep.setUserFederationProviders(fedProviderReps);
}
for (UserFederationMapperModel mapper : realm.getUserFederationMappers()) {
rep.addUserFederationMapper(toRepresentation(realm, mapper));
}
for (IdentityProviderModel provider : realm.getIdentityProviders()) {
rep.addIdentityProvider(toRepresentation(provider));
}
@ -291,6 +298,24 @@ public class ModelToRepresentation {
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) {
IdentityProviderRepresentation providerRep = new IdentityProviderRepresentation();

View file

@ -11,6 +11,7 @@ import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.IdentityProviderMapperModel;
import org.keycloak.models.IdentityProviderModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelException;
import org.keycloak.models.PasswordPolicy;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
@ -18,6 +19,7 @@ import org.keycloak.models.RoleModel;
import org.keycloak.models.UserConsentModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserCredentialValueModel;
import org.keycloak.models.UserFederationMapperModel;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.UserModel;
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.SocialLinkRepresentation;
import org.keycloak.representations.idm.UserConsentRepresentation;
import org.keycloak.representations.idm.UserFederationMapperRepresentation;
import org.keycloak.representations.idm.UserFederationProviderRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.util.UriUtils;
@ -240,6 +243,11 @@ public class RepresentationToModel {
List<UserFederationProviderModel> providerModels = convertFederationProviders(rep.getUserFederationProviders());
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
@ -475,6 +483,23 @@ public class RepresentationToModel {
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
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.RequiredCredentialEntity;
import org.keycloak.models.entities.RoleEntity;
import org.keycloak.models.entities.UserFederationMapperEntity;
import org.keycloak.models.entities.UserFederationProviderEntity;
import org.keycloak.models.utils.KeycloakModelUtils;
@ -812,6 +813,8 @@ public class RealmAdapter implements RealmModel {
@Override
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();
entity.setId(KeycloakModelUtils.generateId());
entity.setPriority(priority);
@ -837,6 +840,12 @@ public class RealmAdapter implements RealmModel {
if (entity.getId().equals(provider.getId())) {
session.users().preRemove(this, new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(),
entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync()));
Set<UserFederationMapperEntity> mappers = getUserFederationMapperEntitiesByFederationProvider(provider.getId());
for (UserFederationMapperEntity mapper : mappers) {
realm.getUserFederationMappers().remove(mapper);
}
it.remove();
}
}
@ -844,6 +853,8 @@ public class RealmAdapter implements RealmModel {
@Override
public void updateUserFederationProvider(UserFederationProviderModel model) {
KeycloakModelUtils.ensureUniqueDisplayName(model.getDisplayName(), model, getUserFederationProviders());
Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
while (it.hasNext()) {
UserFederationProviderEntity entity = it.next();
@ -889,6 +900,10 @@ public class RealmAdapter implements RealmModel {
@Override
public void setUserFederationProviders(List<UserFederationProviderModel> providers) {
for (UserFederationProviderModel currentProvider : providers) {
KeycloakModelUtils.ensureUniqueDisplayName(currentProvider.getDisplayName(), currentProvider, providers);
}
List<UserFederationProviderEntity> entities = new LinkedList<UserFederationProviderEntity>();
for (UserFederationProviderModel model : providers) {
UserFederationProviderEntity entity = new UserFederationProviderEntity();
@ -1063,16 +1078,7 @@ public class RealmAdapter implements RealmModel {
public Set<IdentityProviderMapperModel> getIdentityProviderMappers() {
Set<IdentityProviderMapperModel> mappings = new HashSet<>();
for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) {
IdentityProviderMapperModel mapping = new IdentityProviderMapperModel();
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);
IdentityProviderMapperModel mapping = entityToModel(entity);
mappings.add(mapping);
}
return mappings;
@ -1084,16 +1090,7 @@ public class RealmAdapter implements RealmModel {
if (!entity.getIdentityProviderAlias().equals(brokerAlias)) {
continue;
}
IdentityProviderMapperModel mapping = new IdentityProviderMapperModel();
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);
IdentityProviderMapperModel mapping = entityToModel(entity);
mappings.add(mapping);
}
return mappings;
@ -1102,7 +1099,7 @@ public class RealmAdapter implements RealmModel {
@Override
public IdentityProviderMapperModel addIdentityProviderMapper(IdentityProviderMapperModel model) {
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();
IdentityProviderMapperEntity entity = new IdentityProviderMapperEntity();
@ -1186,8 +1183,116 @@ public class RealmAdapter implements RealmModel {
}
@Override
public List<UserFederationMapperModel> getUserFederationMappers() {
throw new IllegalStateException("Not yet implemented");
public Set<UserFederationMapperModel> getUserFederationMappers() {
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;
}
public static String LDAP_MODE = "LDAP_ONLY";
@Override
public List<UserFederationMapperModel> getUserFederationMappers() {
// TODO: Some hardcoded stuff...
List<UserFederationMapperModel> mappers = new ArrayList<UserFederationMapperModel>();
mappers.add(createMapperModel("usn", "usernameMapper", "user-attribute-ldap-mapper",
"user.model.attribute", UserModel.USERNAME,
"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));
public Set<UserFederationMapperModel> getUserFederationMappers() {
if (updated != null) return updated.getUserFederationMappers();
Set<UserFederationMapperModel> mappers = new HashSet<UserFederationMapperModel>();
for (List<UserFederationMapperModel> models : cached.getUserFederationMappers().values()) {
for (UserFederationMapperModel model : models) {
mappers.add(model);
}
}
return mappers;
}
private static UserFederationMapperModel createMapperModel(String id, String name, String mapperId, String... config) {
UserFederationMapperModel mapperModel = new UserFederationMapperModel();
mapperModel.setId(id);
mapperModel.setName(name);
mapperModel.setFederationMapperId(mapperId);
@Override
public Set<UserFederationMapperModel> getUserFederationMappersByFederationProvider(String federationProviderId) {
if (updated != null) return updated.getUserFederationMappersByFederationProvider(federationProviderId);
Set<UserFederationMapperModel> mappers = new HashSet<>();
List<UserFederationMapperModel> list = cached.getUserFederationMappers().getList(federationProviderId);
for (UserFederationMapperModel entity : list) {
mappers.add(entity);
}
return mappers;
}
Map<String, String> configMap = new HashMap<String, String>();
String key = null;
for (String configEntry : config) {
if (key == null) {
key = configEntry;
} else {
configMap.put(key, configEntry);
key = null;
@Override
public UserFederationMapperModel addUserFederationMapper(UserFederationMapperModel mapper) {
getDelegateForUpdate();
return updated.addUserFederationMapper(mapper);
}
@Override
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 mapperModel;
return null;
}
@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.RequiredCredentialModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserFederationMapperModel;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.cache.RealmCache;
import org.keycloak.util.MultivaluedHashMap;
@ -70,6 +71,7 @@ public class CachedRealm {
private List<RequiredCredentialModel> requiredCredentials = new ArrayList<RequiredCredentialModel>();
private List<UserFederationProviderModel> userFederationProviders = new ArrayList<UserFederationProviderModel>();
private MultivaluedHashMap<String, UserFederationMapperModel> userFederationMappers = new MultivaluedHashMap<String, UserFederationMapperModel>();
private List<IdentityProviderModel> identityProviders = new ArrayList<IdentityProviderModel>();
private Map<String, String> browserSecurityHeaders = new HashMap<String, String>();
@ -136,6 +138,9 @@ public class CachedRealm {
requiredCredentials = model.getRequiredCredentials();
userFederationProviders = model.getUserFederationProviders();
for (UserFederationMapperModel mapper : model.getUserFederationMappers()) {
userFederationMappers.add(mapper.getFederationProviderId(), mapper);
}
this.identityProviders = new ArrayList<>();
@ -373,6 +378,10 @@ public class CachedRealm {
return userFederationProviders;
}
public MultivaluedHashMap<String, UserFederationMapperModel> getUserFederationMappers() {
return userFederationMappers;
}
public String getCertificatePem() {
return certificatePem;
}

View file

@ -5,11 +5,14 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.IdentityProviderMapperModel;
import org.keycloak.models.IdentityProviderModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.ModelException;
import org.keycloak.models.PasswordPolicy;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RequiredCredentialModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserFederationMapperModel;
import org.keycloak.models.UserFederationProvider;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.jpa.entities.ClientEntity;
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.RequiredCredentialEntity;
import org.keycloak.models.jpa.entities.RoleEntity;
import org.keycloak.models.jpa.entities.UserFederationMapperEntity;
import org.keycloak.models.jpa.entities.UserFederationProviderEntity;
import org.keycloak.models.utils.KeycloakModelUtils;
@ -760,6 +764,8 @@ public class RealmAdapter implements RealmModel {
@Override
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();
UserFederationProviderEntity entity = new UserFederationProviderEntity();
entity.setId(id);
@ -786,7 +792,14 @@ public class RealmAdapter implements RealmModel {
while (it.hasNext()) {
UserFederationProviderEntity entity = it.next();
if (entity.getId().equals(provider.getId())) {
session.users().preRemove(this, provider);
Set<UserFederationMapperEntity> mappers = getUserFederationMapperEntitiesByFederationProvider(provider.getId());
for (UserFederationMapperEntity mapper : mappers) {
realm.getUserFederationMappers().remove(mapper);
em.remove(mapper);
}
it.remove();
em.remove(entity);
return;
@ -795,6 +808,8 @@ public class RealmAdapter implements RealmModel {
}
@Override
public void updateUserFederationProvider(UserFederationProviderModel model) {
KeycloakModelUtils.ensureUniqueDisplayName(model.getDisplayName(), model, getUserFederationProviders());
Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
while (it.hasNext()) {
UserFederationProviderEntity entity = it.next();
@ -817,6 +832,9 @@ public class RealmAdapter implements RealmModel {
@Override
public void setUserFederationProviders(List<UserFederationProviderModel> providers) {
for (UserFederationProviderModel currentProvider : providers) {
KeycloakModelUtils.ensureUniqueDisplayName(currentProvider.getDisplayName(), currentProvider, providers);
}
Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
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
public RoleModel getRole(String name) {
TypedQuery<RoleEntity> query = em.createNamedQuery("getRealmRoleByName", RoleEntity.class);
@ -1225,16 +1252,7 @@ public class RealmAdapter implements RealmModel {
public Set<IdentityProviderMapperModel> getIdentityProviderMappers() {
Set<IdentityProviderMapperModel> mappings = new HashSet<IdentityProviderMapperModel>();
for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) {
IdentityProviderMapperModel mapping = new IdentityProviderMapperModel();
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);
IdentityProviderMapperModel mapping = entityToModel(entity);
mappings.add(mapping);
}
return mappings;
@ -1247,16 +1265,7 @@ public class RealmAdapter implements RealmModel {
if (!entity.getIdentityProviderAlias().equals(brokerAlias)) {
continue;
}
IdentityProviderMapperModel mapping = new IdentityProviderMapperModel();
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);
IdentityProviderMapperModel mapping = entityToModel(entity);
mappings.add(mapping);
}
return mappings;
@ -1265,7 +1274,7 @@ public class RealmAdapter implements RealmModel {
@Override
public IdentityProviderMapperModel addIdentityProviderMapper(IdentityProviderMapperModel model) {
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();
IdentityProviderMapperEntity entity = new IdentityProviderMapperEntity();
@ -1353,8 +1362,122 @@ public class RealmAdapter implements RealmModel {
}
@Override
public List<UserFederationMapperModel> getUserFederationMappers() {
throw new IllegalStateException("Not yet implemented");
public Set<UserFederationMapperModel> getUserFederationMappers() {
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")
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)
@JoinTable(name="REALM_CLIENT", joinColumns={ @JoinColumn(name="REALM_ID") }, inverseJoinColumns={ @JoinColumn(name="CLIENT_ID") })
Collection<ClientEntity> clients = new ArrayList<>();
@ -475,6 +478,14 @@ public class RealmEntity {
this.userFederationProviders = userFederationProviders;
}
public Collection<UserFederationMapperEntity> getUserFederationMappers() {
return userFederationMappers;
}
public void setUserFederationMappers(Collection<UserFederationMapperEntity> userFederationMappers) {
this.userFederationMappers = userFederationMappers;
}
public Collection<RealmAttributeEntity> getAttributes() {
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.IdentityProviderModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.PasswordPolicy;
import org.keycloak.models.RealmModel;
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.IdentityProviderMapperEntity;
import org.keycloak.models.entities.RequiredCredentialEntity;
import org.keycloak.models.entities.UserFederationMapperEntity;
import org.keycloak.models.entities.UserFederationProviderEntity;
import org.keycloak.models.mongo.keycloak.entities.MongoClientEntity;
import org.keycloak.models.mongo.keycloak.entities.MongoRealmEntity;
@ -833,6 +835,8 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
@Override
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();
entity.setId(KeycloakModelUtils.generateId());
entity.setPriority(priority);
@ -859,6 +863,12 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
if (entity.getId().equals(provider.getId())) {
session.users().preRemove(this, new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(),
entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync()));
Set<UserFederationMapperEntity> mappers = getUserFederationMapperEntitiesByFederationProvider(provider.getId());
for (UserFederationMapperEntity mapper : mappers) {
getMongoEntity().getUserFederationMappers().remove(mapper);
}
it.remove();
}
}
@ -867,6 +877,8 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
@Override
public void updateUserFederationProvider(UserFederationProviderModel model) {
KeycloakModelUtils.ensureUniqueDisplayName(model.getDisplayName(), model, getUserFederationProviders());
Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
while (it.hasNext()) {
UserFederationProviderEntity entity = it.next();
@ -913,6 +925,10 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
@Override
public void setUserFederationProviders(List<UserFederationProviderModel> providers) {
for (UserFederationProviderModel currentProvider : providers) {
KeycloakModelUtils.ensureUniqueDisplayName(currentProvider.getDisplayName(), currentProvider, providers);
}
List<UserFederationProviderEntity> entities = new LinkedList<UserFederationProviderEntity>();
for (UserFederationProviderModel model : providers) {
UserFederationProviderEntity entity = new UserFederationProviderEntity();
@ -923,7 +939,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
entity.setPriority(model.getPriority());
String displayName = model.getDisplayName();
if (displayName == null) {
entity.setDisplayName(entity.getId());
displayName = entity.getId();
}
entity.setDisplayName(displayName);
entity.setFullSyncPeriod(model.getFullSyncPeriod());
@ -1089,16 +1105,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
public Set<IdentityProviderMapperModel> getIdentityProviderMappers() {
Set<IdentityProviderMapperModel> mappings = new HashSet<IdentityProviderMapperModel>();
for (IdentityProviderMapperEntity entity : getMongoEntity().getIdentityProviderMappers()) {
IdentityProviderMapperModel mapping = new IdentityProviderMapperModel();
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);
IdentityProviderMapperModel mapping = entityToModel(entity);
mappings.add(mapping);
}
return mappings;
@ -1111,16 +1118,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
if (!entity.getIdentityProviderAlias().equals(brokerAlias)) {
continue;
}
IdentityProviderMapperModel mapping = new IdentityProviderMapperModel();
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);
IdentityProviderMapperModel mapping = entityToModel(entity);
mappings.add(mapping);
}
return mappings;
@ -1129,7 +1127,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
@Override
public IdentityProviderMapperModel addIdentityProviderMapper(IdentityProviderMapperModel model) {
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();
IdentityProviderMapperEntity entity = new IdentityProviderMapperEntity();
@ -1169,6 +1167,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
IdentityProviderMapperEntity toDelete = getIdentityProviderMapperEntity(mapping.getId());
if (toDelete != null) {
this.realm.getIdentityProviderMappers().remove(toDelete);
updateMongoEntity();
}
}
@ -1215,7 +1214,119 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
}
@Override
public List<UserFederationMapperModel> getUserFederationMappers() {
throw new IllegalStateException("Not yet implemented");
public Set<UserFederationMapperModel> getUserFederationMappers() {
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
public void test01_ldapOnlyRoleMappings() {
// TODO: Remove me!!!
RealmAdapter.LDAP_MODE = "LDAP_ONLY";
//RealmAdapter.LDAP_MODE = "LDAP_ONLY";
KeycloakSession session = keycloakRule.startSession();
try {
@ -231,7 +231,7 @@ public class LDAPRoleMappingsTest {
@Test
public void test02_readOnlyRoleMappings() {
// TODO: Remove me!!!
RealmAdapter.LDAP_MODE = "READ_ONLY";
//RealmAdapter.LDAP_MODE = "READ_ONLY";
KeycloakSession session = keycloakRule.startSession();
try {
@ -293,7 +293,7 @@ public class LDAPRoleMappingsTest {
@Test
public void test03_importRoleMappings() {
// TODO: Remove me!!!
RealmAdapter.LDAP_MODE = "IMPORT";
//RealmAdapter.LDAP_MODE = "IMPORT";
KeycloakSession session = keycloakRule.startSession();
try {
@ -346,7 +346,7 @@ public class LDAPRoleMappingsTest {
}
private static UserFederationMapperModel findRoleMapperModel(RealmModel appRealm) {
List<UserFederationMapperModel> fedMappers = appRealm.getUserFederationMappers();
Set<UserFederationMapperModel> fedMappers = appRealm.getUserFederationMappers();
for (UserFederationMapperModel mapper : fedMappers) {
if ("realmRoleMapper".equals(mapper.getName())) {
return mapper;

View file

@ -13,6 +13,7 @@ import org.keycloak.models.RequiredCredentialModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserCredentialValueModel;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserProvider;
import org.keycloak.representations.idm.CredentialRepresentation;
@ -23,8 +24,11 @@ import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.junit.Assert.assertNotNull;
@ -741,6 +745,59 @@ public class AdapterTest extends AbstractModelTest {
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 {
return KeyPairGenerator.getInstance("RSA").generateKeyPair();
}

View file

@ -5,6 +5,8 @@ import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
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.Constants;
import org.keycloak.models.FederatedIdentityModel;
@ -15,6 +17,7 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.RequiredCredentialModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserConsentModel;
import org.keycloak.models.UserFederationMapperModel;
import org.keycloak.models.UserFederationProvider;
import org.keycloak.models.UserFederationProviderFactory;
import org.keycloak.models.UserFederationProviderModel;
@ -220,6 +223,15 @@ public class ImportTest extends AbstractModelTest {
Assert.assertEquals(1, ldap.getPriority());
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
UserFederationProviderFactory factory = (UserFederationProviderFactory)session.getKeycloakSessionFactory().getProviderFactory(UserFederationProvider.class, "dummy");
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": [
{
"username": "wburke",