KEYCLOAK-886 Model and representations for UserFederationMappers
This commit is contained in:
parent
a9f1fda68a
commit
7476ee51e4
32 changed files with 1173 additions and 160 deletions
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"));
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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",
|
||||||
|
|
Loading…
Reference in a new issue