Partial import feature does not import Identity Provider mappers in Keycloak #12861
This commit is contained in:
parent
98ac3829d6
commit
adeef6c2a0
5 changed files with 179 additions and 6 deletions
|
@ -36,6 +36,7 @@ public class PartialImportRepresentation {
|
||||||
protected List<GroupRepresentation> groups;
|
protected List<GroupRepresentation> groups;
|
||||||
protected List<ClientRepresentation> clients;
|
protected List<ClientRepresentation> clients;
|
||||||
protected List<IdentityProviderRepresentation> identityProviders;
|
protected List<IdentityProviderRepresentation> identityProviders;
|
||||||
|
protected List<IdentityProviderMapperRepresentation> identityProviderMappers;
|
||||||
protected RolesRepresentation roles;
|
protected RolesRepresentation roles;
|
||||||
|
|
||||||
public boolean hasUsers() {
|
public boolean hasUsers() {
|
||||||
|
@ -107,6 +108,14 @@ public class PartialImportRepresentation {
|
||||||
this.identityProviders = identityProviders;
|
this.identityProviders = identityProviders;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<IdentityProviderMapperRepresentation> getIdentityProviderMappers() {
|
||||||
|
return identityProviderMappers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIdentityProviderMappers(List<IdentityProviderMapperRepresentation> identityProviderMappers) {
|
||||||
|
this.identityProviderMappers = identityProviderMappers;
|
||||||
|
}
|
||||||
|
|
||||||
public RolesRepresentation getRoles() {
|
public RolesRepresentation getRoles() {
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.partialimport;
|
||||||
|
|
||||||
|
import org.keycloak.models.IdentityProviderMapperModel;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
import org.keycloak.models.utils.RepresentationToModel;
|
||||||
|
import org.keycloak.representations.idm.IdentityProviderMapperRepresentation;
|
||||||
|
import org.keycloak.representations.idm.PartialImportRepresentation;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PartialImport handler for Identitiy Provider Mappers.
|
||||||
|
*
|
||||||
|
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
|
||||||
|
*/
|
||||||
|
public class IdentityProviderMappersPartialImport extends AbstractPartialImport<IdentityProviderMapperRepresentation> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<IdentityProviderMapperRepresentation> getRepList(PartialImportRepresentation partialImportRep) {
|
||||||
|
return partialImportRep.getIdentityProviderMappers();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName(IdentityProviderMapperRepresentation idpMapperRep) {
|
||||||
|
return idpMapperRep.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getModelId(RealmModel realm, KeycloakSession session, IdentityProviderMapperRepresentation idpMapperRep) {
|
||||||
|
return realm.getIdentityProviderMapperByName(idpMapperRep.getIdentityProviderAlias(), idpMapperRep.getName()).getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean exists(RealmModel realm, KeycloakSession session, IdentityProviderMapperRepresentation idpMapperRep) {
|
||||||
|
return realm.getIdentityProviderMapperByName(idpMapperRep.getIdentityProviderAlias(), idpMapperRep.getName()) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String existsMessage(RealmModel realm, IdentityProviderMapperRepresentation idpMapperRep) {
|
||||||
|
return "Identity Provider Mapper'" + getName(idpMapperRep) + "' already exists.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResourceType getResourceType() {
|
||||||
|
return ResourceType.IDP_MAPPER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove(RealmModel realm, KeycloakSession session, IdentityProviderMapperRepresentation idpMapperRep) {
|
||||||
|
IdentityProviderMapperModel idpMapper = RepresentationToModel.toModel(idpMapperRep);
|
||||||
|
realm.removeIdentityProviderMapper(idpMapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void create(RealmModel realm, KeycloakSession session, IdentityProviderMapperRepresentation idpMapperRep) {
|
||||||
|
IdentityProviderMapperModel existing = realm.getIdentityProviderMapperByName(idpMapperRep.getIdentityProviderAlias(), idpMapperRep.getName());
|
||||||
|
if(existing != null) {
|
||||||
|
realm.removeIdentityProviderMapper(existing);
|
||||||
|
}
|
||||||
|
idpMapperRep.setId(KeycloakModelUtils.generateId());
|
||||||
|
IdentityProviderMapperModel idpMapper = RepresentationToModel.toModel(idpMapperRep);
|
||||||
|
realm.addIdentityProviderMapper(idpMapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -54,6 +54,7 @@ public class PartialImportManager {
|
||||||
partialImports.add(new ClientsPartialImport());
|
partialImports.add(new ClientsPartialImport());
|
||||||
partialImports.add(new RolesPartialImport());
|
partialImports.add(new RolesPartialImport());
|
||||||
partialImports.add(new IdentityProvidersPartialImport());
|
partialImports.add(new IdentityProvidersPartialImport());
|
||||||
|
partialImports.add(new IdentityProviderMappersPartialImport());
|
||||||
partialImports.add(new GroupsPartialImport());
|
partialImports.add(new GroupsPartialImport());
|
||||||
partialImports.add(new UsersPartialImport());
|
partialImports.add(new UsersPartialImport());
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ package org.keycloak.partialimport;
|
||||||
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
|
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
|
||||||
*/
|
*/
|
||||||
public enum ResourceType {
|
public enum ResourceType {
|
||||||
USER, GROUP, CLIENT, IDP, REALM_ROLE, CLIENT_ROLE;
|
USER, GROUP, CLIENT, IDP, IDP_MAPPER, REALM_ROLE, CLIENT_ROLE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to create the admin path in events.
|
* Used to create the admin path in events.
|
||||||
|
@ -36,6 +36,7 @@ public enum ResourceType {
|
||||||
case GROUP: return "groups";
|
case GROUP: return "groups";
|
||||||
case CLIENT: return "clients";
|
case CLIENT: return "clients";
|
||||||
case IDP: return "identity-provider-settings";
|
case IDP: return "identity-provider-settings";
|
||||||
|
case IDP_MAPPER: return "mappers";
|
||||||
case REALM_ROLE: return "realms";
|
case REALM_ROLE: return "realms";
|
||||||
case CLIENT_ROLE: return "clients";
|
case CLIENT_ROLE: return "clients";
|
||||||
default: return "";
|
default: return "";
|
||||||
|
@ -49,6 +50,7 @@ public enum ResourceType {
|
||||||
case GROUP: return "Group";
|
case GROUP: return "Group";
|
||||||
case CLIENT: return "Client";
|
case CLIENT: return "Client";
|
||||||
case IDP: return "Identity Provider";
|
case IDP: return "Identity Provider";
|
||||||
|
case IDP_MAPPER: return "Identity Provider Mapper";
|
||||||
case REALM_ROLE: return "Realm Role";
|
case REALM_ROLE: return "Realm Role";
|
||||||
case CLIENT_ROLE: return "Client Role";
|
case CLIENT_ROLE: return "Client Role";
|
||||||
default: return super.toString();
|
default: return super.toString();
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.keycloak.partialimport.PartialImportResults;
|
||||||
import org.keycloak.representations.idm.AdminEventRepresentation;
|
import org.keycloak.representations.idm.AdminEventRepresentation;
|
||||||
import org.keycloak.representations.idm.ClientRepresentation;
|
import org.keycloak.representations.idm.ClientRepresentation;
|
||||||
import org.keycloak.representations.idm.GroupRepresentation;
|
import org.keycloak.representations.idm.GroupRepresentation;
|
||||||
|
import org.keycloak.representations.idm.IdentityProviderMapperRepresentation;
|
||||||
import org.keycloak.representations.idm.IdentityProviderRepresentation;
|
import org.keycloak.representations.idm.IdentityProviderRepresentation;
|
||||||
import org.keycloak.representations.idm.PartialImportRepresentation;
|
import org.keycloak.representations.idm.PartialImportRepresentation;
|
||||||
import org.keycloak.representations.idm.PartialImportRepresentation.Policy;
|
import org.keycloak.representations.idm.PartialImportRepresentation.Policy;
|
||||||
|
@ -42,7 +43,6 @@ import org.keycloak.testsuite.AbstractAuthTest;
|
||||||
import org.keycloak.testsuite.Assert;
|
import org.keycloak.testsuite.Assert;
|
||||||
import org.keycloak.testsuite.ProfileAssume;
|
import org.keycloak.testsuite.ProfileAssume;
|
||||||
import org.keycloak.testsuite.admin.ApiUtil;
|
import org.keycloak.testsuite.admin.ApiUtil;
|
||||||
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
|
|
||||||
import org.keycloak.testsuite.util.AssertAdminEvents;
|
import org.keycloak.testsuite.util.AssertAdminEvents;
|
||||||
import org.keycloak.testsuite.util.RealmBuilder;
|
import org.keycloak.testsuite.util.RealmBuilder;
|
||||||
|
|
||||||
|
@ -303,7 +303,12 @@ public class PartialImportTest extends AbstractAuthTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addProviders() {
|
private void addProviders() {
|
||||||
|
addProviders(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addProviders(boolean withMappers) {
|
||||||
List<IdentityProviderRepresentation> providers = new ArrayList<>();
|
List<IdentityProviderRepresentation> providers = new ArrayList<>();
|
||||||
|
List<IdentityProviderMapperRepresentation> mappers = new ArrayList<>();
|
||||||
|
|
||||||
for (String alias : IDP_ALIASES) {
|
for (String alias : IDP_ALIASES) {
|
||||||
IdentityProviderRepresentation idpRep = new IdentityProviderRepresentation();
|
IdentityProviderRepresentation idpRep = new IdentityProviderRepresentation();
|
||||||
|
@ -318,9 +323,31 @@ public class PartialImportTest extends AbstractAuthTest {
|
||||||
config.put("clientId", alias);
|
config.put("clientId", alias);
|
||||||
idpRep.setConfig(config);
|
idpRep.setConfig(config);
|
||||||
providers.add(idpRep);
|
providers.add(idpRep);
|
||||||
|
|
||||||
|
if(withMappers) {
|
||||||
|
Map<String, String> mapConfig = new HashMap<>();
|
||||||
|
mapConfig.put("external.role", "IDP.TEST_ROLE");
|
||||||
|
mapConfig.put("syncMode", "FORCE");
|
||||||
|
mapConfig.put("role", "TEST_ROLE");
|
||||||
|
|
||||||
|
IdentityProviderMapperRepresentation idpMapRep = new IdentityProviderMapperRepresentation();
|
||||||
|
idpMapRep.setName(alias+"_mapper");
|
||||||
|
idpMapRep.setIdentityProviderAlias(alias);
|
||||||
|
idpMapRep.setIdentityProviderMapper("keycloak-oidc-role-to-role-idp-mapper");
|
||||||
|
idpMapRep.setConfig(mapConfig);
|
||||||
|
|
||||||
|
mappers.add(idpMapRep);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
piRep.setIdentityProviders(providers);
|
piRep.setIdentityProviders(providers);
|
||||||
|
if (withMappers) {
|
||||||
|
piRep.setIdentityProviderMappers(mappers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addProviderMappers() {
|
||||||
|
addProviders(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<RoleRepresentation> makeRoles(String prefix) {
|
private List<RoleRepresentation> makeRoles(String prefix) {
|
||||||
|
@ -517,6 +544,30 @@ public class PartialImportTest extends AbstractAuthTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddProviderMappers() {
|
||||||
|
setFail();
|
||||||
|
addProviderMappers();
|
||||||
|
|
||||||
|
PartialImportResults results = doImport();
|
||||||
|
assertEquals(IDP_ALIASES.length*2, results.getAdded());
|
||||||
|
|
||||||
|
for (PartialImportResult result : results.getResults()) {
|
||||||
|
if (ResourceType.IDP.equals(result.getResourceType())) {
|
||||||
|
String id = result.getId();
|
||||||
|
IdentityProviderResource idpRsc = testRealmResource().identityProviders().get(id);
|
||||||
|
IdentityProviderMapperRepresentation idpMap = idpRsc.getMappers().get(0);
|
||||||
|
String alias = idpMap.getIdentityProviderAlias();
|
||||||
|
assertTrue(Arrays.asList(IDP_ALIASES).contains(alias));
|
||||||
|
assertEquals(alias + "_mapper", idpMap.getName());
|
||||||
|
assertEquals("keycloak-oidc-role-to-role-idp-mapper", idpMap.getIdentityProviderMapper());
|
||||||
|
assertEquals("IDP.TEST_ROLE", idpMap.getConfig().get("external.role"));
|
||||||
|
assertEquals("FORCE", idpMap.getConfig().get("syncMode"));
|
||||||
|
assertEquals("TEST_ROLE", idpMap.getConfig().get("role"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddRealmRoles() {
|
public void testAddRealmRoles() {
|
||||||
setFail();
|
setFail();
|
||||||
|
@ -581,6 +632,12 @@ public class PartialImportTest extends AbstractAuthTest {
|
||||||
testFail();
|
testFail();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddProviderMappersFail() {
|
||||||
|
addProviderMappers();
|
||||||
|
testFail();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddRealmRolesFail() {
|
public void testAddRealmRolesFail() {
|
||||||
addRealmRoles();
|
addRealmRoles();
|
||||||
|
@ -594,12 +651,16 @@ public class PartialImportTest extends AbstractAuthTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testSkip() {
|
private void testSkip() {
|
||||||
|
testSkip(NUM_ENTITIES);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testSkip(int numberEntities) {
|
||||||
setSkip();
|
setSkip();
|
||||||
PartialImportResults results = doImport();
|
PartialImportResults results = doImport();
|
||||||
assertEquals(NUM_ENTITIES, results.getAdded());
|
assertEquals(numberEntities, results.getAdded());
|
||||||
|
|
||||||
results = doImport();
|
results = doImport();
|
||||||
assertEquals(NUM_ENTITIES, results.getSkipped());
|
assertEquals(numberEntities, results.getSkipped());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -637,6 +698,12 @@ public class PartialImportTest extends AbstractAuthTest {
|
||||||
testSkip();
|
testSkip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddProviderMappersSkip() {
|
||||||
|
addProviderMappers();
|
||||||
|
testSkip(NUM_ENTITIES*2);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddRealmRolesSkip() {
|
public void testAddRealmRolesSkip() {
|
||||||
addRealmRoles();
|
addRealmRoles();
|
||||||
|
@ -650,12 +717,16 @@ public class PartialImportTest extends AbstractAuthTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testOverwrite() {
|
private void testOverwrite() {
|
||||||
|
testOverwrite(NUM_ENTITIES);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testOverwrite(int numberEntities) {
|
||||||
setOverwrite();
|
setOverwrite();
|
||||||
PartialImportResults results = doImport();
|
PartialImportResults results = doImport();
|
||||||
assertEquals(NUM_ENTITIES, results.getAdded());
|
assertEquals(numberEntities, results.getAdded());
|
||||||
|
|
||||||
results = doImport();
|
results = doImport();
|
||||||
assertEquals(NUM_ENTITIES, results.getOverwritten());
|
assertEquals(numberEntities, results.getOverwritten());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -717,6 +788,12 @@ public class PartialImportTest extends AbstractAuthTest {
|
||||||
testOverwrite();
|
testOverwrite();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddProviderMappersOverwrite() {
|
||||||
|
addProviderMappers();
|
||||||
|
testOverwrite(NUM_ENTITIES*2);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddRealmRolesOverwrite() {
|
public void testAddRealmRolesOverwrite() {
|
||||||
addRealmRoles();
|
addRealmRoles();
|
||||||
|
|
Loading…
Reference in a new issue