Skip to content

Commit

Permalink
[KEYCLOAK-3554] - Properly handle dependencies between policies when …
Browse files Browse the repository at this point in the history
…importing settings
  • Loading branch information
pedroigor committed Nov 14, 2016
1 parent 6c64494 commit fb1cd9d
Show file tree
Hide file tree
Showing 3 changed files with 314 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,7 @@
import org.keycloak.authorization.store.StoreFactory;
import org.keycloak.common.enums.SslRequired;
import org.keycloak.common.util.Base64;
import org.keycloak.common.util.CertificateUtils;
import org.keycloak.common.util.KeyUtils;
import org.keycloak.common.util.MultivaluedHashMap;
import org.keycloak.common.util.PemUtils;
import org.keycloak.common.util.UriUtils;
import org.keycloak.component.ComponentModel;
import org.keycloak.credential.CredentialModel;
Expand Down Expand Up @@ -105,11 +102,7 @@
import org.keycloak.util.JsonSerialization;

import java.io.IOException;
import java.security.KeyPair;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
Expand Down Expand Up @@ -1866,7 +1859,18 @@ public static void toModel(ResourceServerRepresentation rep, AuthorizationProvid
toModel(resourceRepresentation, resourceServer, authorization);
});

rep.getPolicies().forEach(policyRepresentation -> {
importPolicies(authorization, resourceServer, rep.getPolicies(), null);
}

private static Policy importPolicies(AuthorizationProvider authorization, ResourceServer resourceServer, List<PolicyRepresentation> policiesToImport, String parentPolicyName) {
StoreFactory storeFactory = authorization.getStoreFactory();
KeycloakSession session = authorization.getKeycloakSession();
RealmModel realm = authorization.getRealm();
for (PolicyRepresentation policyRepresentation : policiesToImport) {
if (parentPolicyName != null && !parentPolicyName.equals(policyRepresentation.getName())) {
continue;
}

Map<String, String> config = policyRepresentation.getConfig();

String roles = config.get("roles");
Expand Down Expand Up @@ -1899,6 +1903,16 @@ public static void toModel(ResourceServerRepresentation rep, AuthorizationProvid
.findFirst().orElse(null);
}

if (role == null) {
role = realm.getRoleById(roleName);

if (role == null) {
String finalRoleName1 = roleName;
role = realm.getClients().stream().map(clientModel -> clientModel.getRole(finalRoleName1)).filter(roleModel -> roleModel != null)
.findFirst().orElse(null);
}
}

if (role == null) {
throw new RuntimeException("Error while importing configuration. Role [" + roleName + "] could not be found.");
}
Expand All @@ -1916,7 +1930,19 @@ public static void toModel(ResourceServerRepresentation rep, AuthorizationProvid
if (users != null && !users.isEmpty()) {
try {
List<String> usersMap = JsonSerialization.readValue(users, List.class);
config.put("users", JsonSerialization.writeValueAsString(usersMap.stream().map(userName -> session.users().getUserByUsername(userName, realm).getId()).collect(Collectors.toList())));
config.put("users", JsonSerialization.writeValueAsString(usersMap.stream().map(userId -> {
UserModel user = session.users().getUserByUsername(userId, realm);

if (user == null) {
user = session.users().getUserById(userId, realm);
}

if (user == null) {
throw new RuntimeException("Error while importing configuration. User [" + userId + "] could not be found.");
}

return user.getId();
}).collect(Collectors.toList())));
} catch (Exception e) {
throw new RuntimeException("Error while exporting policy [" + policyRepresentation.getName() + "].", e);
}
Expand All @@ -1926,10 +1952,15 @@ public static void toModel(ResourceServerRepresentation rep, AuthorizationProvid

if (scopes != null && !scopes.isEmpty()) {
try {
ScopeStore scopeStore = storeFactory.getScopeStore();
List<String> scopesMap = JsonSerialization.readValue(scopes, List.class);
config.put("scopes", JsonSerialization.writeValueAsString(scopesMap.stream().map(scopeName -> {
Scope newScope = scopeStore.findByName(scopeName, resourceServer.getId());

if (newScope == null) {
newScope = scopeStore.findById(scopeName);
}

if (newScope == null) {
throw new RuntimeException("Scope with name [" + scopeName + "] not defined.");
}
Expand All @@ -1947,8 +1978,21 @@ public static void toModel(ResourceServerRepresentation rep, AuthorizationProvid
ResourceStore resourceStore = storeFactory.getResourceStore();
try {
List<String> resources = JsonSerialization.readValue(policyResources, List.class);
config.put("resources", JsonSerialization.writeValueAsString(resources.stream().map(resourceName -> {
return resourceStore.findByName(resourceName, resourceServer.getId()).getId();
config.put("resources", JsonSerialization.writeValueAsString(resources.stream().map(new Function<String, String>() {
@Override
public String apply(String resourceName) {
Resource resource = resourceStore.findByName(resourceName, resourceServer.getId());

if (resource == null) {
resource = resourceStore.findById(resourceName);
}

if (resource == null) {
throw new RuntimeException("Resource with name [" + resourceName + "] not defined.");
}

return resource.getId();
}
}).collect(Collectors.toList())));
} catch (Exception e) {
throw new RuntimeException("Error while exporting policy [" + policyRepresentation.getName() + "].", e);
Expand All @@ -1965,7 +2009,14 @@ public static void toModel(ResourceServerRepresentation rep, AuthorizationProvid
Policy policy = policyStore.findByName(policyName, resourceServer.getId());

if (policy == null) {
throw new RuntimeException("Policy with name [" + policyName + "] not defined.");
policy = policyStore.findById(policyName);
}

if (policy == null) {
policy = importPolicies(authorization, resourceServer, policiesToImport, policyName);
if (policy == null) {
throw new RuntimeException("Policy with name [" + policyName + "] not defined.");
}
}

return policy.getId();
Expand All @@ -1975,8 +2026,14 @@ public static void toModel(ResourceServerRepresentation rep, AuthorizationProvid
}
}

toModel(policyRepresentation, resourceServer, authorization);
});
if (parentPolicyName == null) {
toModel(policyRepresentation, resourceServer, authorization);
} else if (parentPolicyName.equals(policyRepresentation.getName())) {
return toModel(policyRepresentation, resourceServer, authorization);
}
}

return null;
}

public static Policy toModel(PolicyRepresentation policy, ResourceServer resourceServer, AuthorizationProvider authorization) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* 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.testsuite.admin.client.authorization;

import static com.sun.corba.se.impl.oa.poa.Policies.defaultPolicies;
import static org.junit.Assert.assertEquals;

import java.util.List;

import org.junit.Test;
import org.keycloak.admin.client.resource.AuthorizationResource;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
import org.keycloak.util.JsonSerialization;

/**
*
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
public class ImportAuthorizationSettingsTest extends AbstractAuthorizationTest {

@Test
public void testImportUnorderedSettings() throws Exception {
ClientResource clientResource = getClientResource();

enableAuthorizationServices();

ResourceServerRepresentation toImport = JsonSerialization.readValue(getClass().getResourceAsStream("/authorization-test/import-authorization-unordered-settings.json"), ResourceServerRepresentation.class);

realmsResouce().realm(getRealmId()).roles().create(new RoleRepresentation("user", null, false));
clientResource.roles().create(new RoleRepresentation("manage-albums", null, false));

AuthorizationResource authorizationResource = clientResource.authorization();

authorizationResource.importSettings(toImport);

assertEquals(13, authorizationResource.policies().policies().size());
}
}
Loading

0 comments on commit fb1cd9d

Please sign in to comment.