Merge pull request #3791 from mposolda/master
KEYCLOAK-4282 Import authorization after users are imported
This commit is contained in:
commit
b24d2e064a
9 changed files with 57 additions and 52 deletions
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* 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.models.utils;
|
||||
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
||||
/**
|
||||
* Helper interface used just because RealmManager is in keycloak-services and not accessible for ImportUtils
|
||||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public interface RealmImporter {
|
||||
|
||||
RealmModel importRealm(RealmRepresentation rep);
|
||||
}
|
|
@ -129,7 +129,7 @@ public class RepresentationToModel {
|
|||
return policy;
|
||||
|
||||
}
|
||||
public static void importRealm(KeycloakSession session, RealmRepresentation rep, RealmModel newRealm) {
|
||||
public static void importRealm(KeycloakSession session, RealmRepresentation rep, RealmModel newRealm, boolean skipUserDependent) {
|
||||
convertDeprecatedSocialProviders(rep);
|
||||
convertDeprecatedApplications(session, rep);
|
||||
|
||||
|
@ -279,13 +279,6 @@ public class RepresentationToModel {
|
|||
}
|
||||
}
|
||||
|
||||
if (rep.getClients() != null) {
|
||||
rep.getClients().forEach(clientRepresentation -> {
|
||||
ClientModel client = newRealm.getClientByClientId(clientRepresentation.getClientId());
|
||||
importAuthorizationSettings(clientRepresentation, client, session);
|
||||
});
|
||||
}
|
||||
|
||||
if (rep.getSmtpServer() != null) {
|
||||
newRealm.setSmtpConfig(new HashMap(rep.getSmtpServer()));
|
||||
}
|
||||
|
@ -331,6 +324,10 @@ public class RepresentationToModel {
|
|||
}
|
||||
}
|
||||
|
||||
if (!skipUserDependent) {
|
||||
importRealmAuthorizationSettings(rep, newRealm, session);
|
||||
}
|
||||
|
||||
if(rep.isInternationalizationEnabled() != null){
|
||||
newRealm.setInternationalizationEnabled(rep.isInternationalizationEnabled());
|
||||
}
|
||||
|
@ -1813,6 +1810,15 @@ public class RepresentationToModel {
|
|||
}
|
||||
}
|
||||
|
||||
public static void importRealmAuthorizationSettings(RealmRepresentation rep, RealmModel newRealm, KeycloakSession session) {
|
||||
if (rep.getClients() != null) {
|
||||
rep.getClients().forEach(clientRepresentation -> {
|
||||
ClientModel client = newRealm.getClientByClientId(clientRepresentation.getClientId());
|
||||
importAuthorizationSettings(clientRepresentation, client, session);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static void importAuthorizationSettings(ClientRepresentation clientRepresentation, ClientModel client, KeycloakSession session) {
|
||||
if (Boolean.TRUE.equals(clientRepresentation.getAuthorizationServicesEnabled())) {
|
||||
AuthorizationProviderFactory authorizationFactory = (AuthorizationProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(AuthorizationProvider.class);
|
||||
|
|
|
@ -25,7 +25,9 @@ import org.keycloak.exportimport.util.ExportImportSessionTask;
|
|||
import org.keycloak.exportimport.util.ImportUtils;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.models.utils.RepresentationToModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
|
@ -136,7 +138,7 @@ public class DirImportProvider implements ImportProvider {
|
|||
|
||||
@Override
|
||||
public void runExportImportTask(KeycloakSession session) throws IOException {
|
||||
boolean imported = ImportUtils.importRealm(session, realmRep, strategy);
|
||||
boolean imported = ImportUtils.importRealm(session, realmRep, strategy, true);
|
||||
realmImported.set(imported);
|
||||
}
|
||||
|
||||
|
@ -165,6 +167,17 @@ public class DirImportProvider implements ImportProvider {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Import authorization last, as authzPolicies can require users already in DB
|
||||
KeycloakModelUtils.runJobInTransaction(factory, new ExportImportSessionTask() {
|
||||
|
||||
@Override
|
||||
public void runExportImportTask(KeycloakSession session) throws IOException {
|
||||
RealmModel realm = session.realms().getRealmByName(realmName);
|
||||
RepresentationToModel.importRealmAuthorizationSettings(realmRep, realm, session);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -34,6 +34,9 @@ public class SingleFileImportProviderFactory implements ImportProviderFactory {
|
|||
@Override
|
||||
public ImportProvider create(KeycloakSession session) {
|
||||
String fileName = ExportImportConfig.getFile();
|
||||
if (fileName == null) {
|
||||
throw new IllegalArgumentException("Property " + ExportImportConfig.FILE + " needs to be provided!");
|
||||
}
|
||||
return new SingleFileImportProvider(new File(fileName));
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ import org.keycloak.exportimport.Strategy;
|
|||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RealmProvider;
|
||||
import org.keycloak.models.utils.RealmImporter;
|
||||
import org.keycloak.models.utils.RepresentationToModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
|
@ -55,7 +54,7 @@ public class ImportUtils {
|
|||
// Import admin realm first
|
||||
for (RealmRepresentation realm : realms) {
|
||||
if (Config.getAdminRealm().equals(realm.getRealm())) {
|
||||
if (importRealm(session, realm, strategy)) {
|
||||
if (importRealm(session, realm, strategy, false)) {
|
||||
masterImported = true;
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +62,7 @@ public class ImportUtils {
|
|||
|
||||
for (RealmRepresentation realm : realms) {
|
||||
if (!Config.getAdminRealm().equals(realm.getRealm())) {
|
||||
importRealm(session, realm, strategy);
|
||||
importRealm(session, realm, strategy, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,9 +83,10 @@ public class ImportUtils {
|
|||
* @param session
|
||||
* @param rep
|
||||
* @param strategy specifies whether to overwrite or ignore existing realm or user entries
|
||||
* @param skipUserDependent If true, then import of any models, which needs users already imported in DB, will be skipped. For example authorization
|
||||
* @return newly imported realm (or existing realm if ignoreExisting is true and realm of this name already exists)
|
||||
*/
|
||||
public static boolean importRealm(KeycloakSession session, RealmRepresentation rep, Strategy strategy) {
|
||||
public static boolean importRealm(KeycloakSession session, RealmRepresentation rep, Strategy strategy, boolean skipUserDependent) {
|
||||
String realmName = rep.getRealm();
|
||||
RealmProvider model = session.realms();
|
||||
RealmModel realm = model.getRealmByName(realmName);
|
||||
|
@ -110,7 +110,7 @@ public class ImportUtils {
|
|||
|
||||
RealmManager realmManager = new RealmManager(session);
|
||||
realmManager.setContextPath(session.getContext().getContextPath());
|
||||
realmManager.importRealm(rep);
|
||||
realmManager.importRealm(rep, skipUserDependent);
|
||||
|
||||
if (System.getProperty(ExportImportConfig.ACTION) != null) {
|
||||
logger.infof("Realm '%s' imported", realmName);
|
||||
|
|
|
@ -24,8 +24,6 @@ import org.keycloak.models.KeycloakContext;
|
|||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.utils.RealmImporter;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.resources.KeycloakApplication;
|
||||
import org.keycloak.services.util.LocaleHelper;
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ import org.keycloak.models.session.UserSessionPersisterProvider;
|
|||
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
||||
import org.keycloak.models.utils.DefaultRequiredActions;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.models.utils.RealmImporter;
|
||||
import org.keycloak.models.utils.RepresentationToModel;
|
||||
import org.keycloak.protocol.ProtocolMapperUtils;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||
|
@ -61,7 +60,7 @@ import java.util.List;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class RealmManager implements RealmImporter {
|
||||
public class RealmManager {
|
||||
|
||||
protected KeycloakSession session;
|
||||
protected RealmProvider model;
|
||||
|
@ -420,8 +419,15 @@ public class RealmManager implements RealmImporter {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RealmModel importRealm(RealmRepresentation rep) {
|
||||
return importRealm(rep, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* if "skipUserDependent" is true, then import of any models, which needs users already imported in DB, will be skipped. For example authorization
|
||||
*/
|
||||
public RealmModel importRealm(RealmRepresentation rep, boolean skipUserDependent) {
|
||||
String id = rep.getId();
|
||||
if (id == null) {
|
||||
id = KeycloakModelUtils.generateId();
|
||||
|
@ -463,7 +469,7 @@ public class RealmManager implements RealmImporter {
|
|||
|
||||
if (!hasRealmRole(rep, Constants.OFFLINE_ACCESS_ROLE)) setupOfflineTokens(realm);
|
||||
|
||||
RepresentationToModel.importRealm(session, rep, realm);
|
||||
RepresentationToModel.importRealm(session, rep, realm, skipUserDependent);
|
||||
|
||||
setupAdminConsoleLocaleMapper(realm);
|
||||
|
||||
|
|
|
@ -627,11 +627,12 @@ public class ExportImportUtil {
|
|||
assertPredicate(scopes, scopePredicates);
|
||||
|
||||
List<PolicyRepresentation> policies = authzResource.policies().policies();
|
||||
Assert.assertEquals(10, policies.size());
|
||||
Assert.assertEquals(11, policies.size());
|
||||
List<Predicate<PolicyRepresentation>> policyPredicates = new ArrayList<>();
|
||||
policyPredicates.add(policyRepresentation -> "Any Admin Policy".equals(policyRepresentation.getName()));
|
||||
policyPredicates.add(policyRepresentation -> "Any User Policy".equals(policyRepresentation.getName()));
|
||||
policyPredicates.add(policyRepresentation -> "Only Premium User Policy".equals(policyRepresentation.getName()));
|
||||
policyPredicates.add(policyRepresentation -> "wburke policy".equals(policyRepresentation.getName()));
|
||||
policyPredicates.add(policyRepresentation -> "All Users Policy".equals(policyRepresentation.getName()));
|
||||
policyPredicates.add(policyRepresentation -> "Premium Resource Permission".equals(policyRepresentation.getName()));
|
||||
policyPredicates.add(policyRepresentation -> "Administrative Resource Permission".equals(policyRepresentation.getName()));
|
||||
|
|
|
@ -291,6 +291,15 @@
|
|||
"roles": "[{\"id\":\"customer-user-premium\"}]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "wburke policy",
|
||||
"description": "Defines that only wburke can do something",
|
||||
"type": "user",
|
||||
"logic": "POSITIVE",
|
||||
"config": {
|
||||
"users" : "[\"wburke\"]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "All Users Policy",
|
||||
"description": "Defines that all users can do something",
|
||||
|
|
Loading…
Reference in a new issue