Merge pull request #3791 from mposolda/master

KEYCLOAK-4282 Import authorization after users are imported
This commit is contained in:
Marek Posolda 2017-01-25 12:21:21 +01:00 committed by GitHub
commit b24d2e064a
9 changed files with 57 additions and 52 deletions

View file

@ -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);
}

View file

@ -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);

View file

@ -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

View file

@ -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));
}

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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()));

View file

@ -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",