Skip to content

Commit

Permalink
Merge pull request keycloak#3144 from pedroigor/KEYCLOAK-3144
Browse files Browse the repository at this point in the history
[KEYCLOAK-3144] - Add authorization settings when exporting/importing a realm
  • Loading branch information
pedroigor authored Aug 15, 2016
2 parents fd98369 + a8d2b81 commit ba076ad
Show file tree
Hide file tree
Showing 24 changed files with 1,377 additions and 850 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

package org.keycloak.representations.idm;

import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;

import java.util.List;
import java.util.Map;

Expand Down Expand Up @@ -62,6 +64,7 @@ public class ClientRepresentation {
private Boolean useTemplateConfig;
private Boolean useTemplateScope;
private Boolean useTemplateMappers;
private ResourceServerRepresentation authorizationSettings;


public String getId() {
Expand Down Expand Up @@ -241,6 +244,9 @@ public void setServiceAccountsEnabled(Boolean serviceAccountsEnabled) {
}

public Boolean getAuthorizationServicesEnabled() {
if (authorizationSettings != null) {
return true;
}
return authorizationServicesEnabled;
}

Expand Down Expand Up @@ -353,4 +359,11 @@ public void setUseTemplateMappers(Boolean useTemplateMappers) {
this.useTemplateMappers = useTemplateMappers;
}

public ResourceServerRepresentation getAuthorizationSettings() {
return authorizationSettings;
}

public void setAuthorizationSettings(ResourceServerRepresentation authorizationSettings) {
this.authorizationSettings = authorizationSettings;
}
}
2 changes: 1 addition & 1 deletion distribution/demo-dist/src/main/xslt/standalone.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
<local-cache name="sessions"/>
<local-cache name="offlineSessions"/>
<local-cache name="loginFailures"/>
<local-cache name="authorization "/>
<local-cache name="authorization"/>
<local-cache name="work"/>
</cache-container>
<xsl:apply-templates select="node()|@*"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
import org.keycloak.authorization.store.StoreFactory;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.provider.Provider;
import org.keycloak.provider.ProviderFactory;

Expand Down Expand Up @@ -64,17 +65,19 @@ public final class AuthorizationProvider implements Provider {
private final StoreFactory storeFactory;
private final List<PolicyProviderFactory> policyProviderFactories;
private final KeycloakSession keycloakSession;
private final RealmModel realm;

public AuthorizationProvider(KeycloakSession session, StoreFactory storeFactory, Executor scheduller) {
public AuthorizationProvider(KeycloakSession session, RealmModel realm, StoreFactory storeFactory, Executor scheduller) {
this.keycloakSession = session;
this.realm = realm;
this.storeFactory = storeFactory;
this.scheduller = scheduller;
this.policyProviderFactories = configurePolicyProviderFactories(session);
this.policyEvaluator = new DefaultPolicyEvaluator(this, this.policyProviderFactories);
}

public AuthorizationProvider(KeycloakSession session, StoreFactory storeFactory) {
this(session, storeFactory, Runnable::run);
public AuthorizationProvider(KeycloakSession session, RealmModel realm, StoreFactory storeFactory) {
this(session, realm, storeFactory, Runnable::run);
}

/**
Expand Down Expand Up @@ -120,6 +123,10 @@ public KeycloakSession getKeycloakSession() {
return this.keycloakSession;
}

public RealmModel getRealm() {
return realm;
}

private List<PolicyProviderFactory> configurePolicyProviderFactories(KeycloakSession session) {
List<ProviderFactory> providerFactories = session.getKeycloakSessionFactory().getProviderFactories(PolicyProvider.class);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,14 @@

package org.keycloak.authorization;

import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.provider.ProviderFactory;

/**
* @author <a href="mailto:[email protected]">Pedro Igor</a>
*/
public interface AuthorizationProviderFactory extends ProviderFactory<AuthorizationProvider> {

AuthorizationProvider create(KeycloakSession session, RealmModel realm);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@

package org.keycloak.models.utils;

import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.Resource;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.model.Scope;
import org.keycloak.authorization.store.PolicyStore;
import org.keycloak.authorization.store.ResourceStore;
import org.keycloak.authorization.store.StoreFactory;
import org.keycloak.component.ComponentModel;
import org.keycloak.events.Event;
import org.keycloak.events.admin.AdminEvent;
Expand All @@ -31,6 +39,7 @@
import org.keycloak.models.GroupModel;
import org.keycloak.models.IdentityProviderMapperModel;
import org.keycloak.models.IdentityProviderModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelException;
import org.keycloak.models.OTPPolicy;
import org.keycloak.models.ProtocolMapperModel;
Expand Down Expand Up @@ -72,8 +81,25 @@
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.representations.idm.UserSessionRepresentation;
import org.keycloak.common.util.Time;

import java.util.*;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourceOwnerRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
import org.keycloak.util.JsonSerialization;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
* @author <a href="mailto:[email protected]">Bill Burke</a>
Expand Down Expand Up @@ -767,4 +793,181 @@ public static ComponentRepresentation toRepresentation(ComponentModel component)
rep.setConfig(component.getConfig());
return rep;
}

public static ScopeRepresentation toRepresentation(Scope model, AuthorizationProvider authorizationProvider) {
ScopeRepresentation scope = new ScopeRepresentation();

scope.setId(model.getId());
scope.setName(model.getName());
scope.setIconUri(model.getIconUri());

StoreFactory storeFactory = authorizationProvider.getStoreFactory();

scope.setResources(new ArrayList<>());

storeFactory.getResourceStore().findByScope(model.getId()).forEach(resource -> scope.getResources().add(toRepresentation(resource, resource.getResourceServer(), authorizationProvider)));

PolicyStore policyStore = storeFactory.getPolicyStore();

scope.setPolicies(new ArrayList<>());

policyStore.findByScopeIds(Arrays.asList(model.getId()), model.getResourceServer().getId()).forEach(policyModel -> {
PolicyRepresentation policy = new PolicyRepresentation();

policy.setId(policyModel.getId());
policy.setName(policyModel.getName());
policy.setType(policyModel.getType());

if (!scope.getPolicies().contains(policy)) {
scope.getPolicies().add(policy);
}
});

return scope;
}

public static ResourceServerRepresentation toRepresentation(ResourceServer model, ClientModel client) {
ResourceServerRepresentation server = new ResourceServerRepresentation();

server.setId(model.getId());
server.setClientId(model.getClientId());
server.setName(client.getClientId());
server.setAllowRemoteResourceManagement(model.isAllowRemoteResourceManagement());
server.setPolicyEnforcementMode(model.getPolicyEnforcementMode());

return server;
}

public static PolicyRepresentation toRepresentation(Policy model, AuthorizationProvider authorization) {
PolicyRepresentation representation = new PolicyRepresentation();

representation.setId(model.getId());
representation.setName(model.getName());
representation.setDescription(model.getDescription());
representation.setType(model.getType());
representation.setDecisionStrategy(model.getDecisionStrategy());
representation.setLogic(model.getLogic());
representation.setConfig(new HashMap<>(model.getConfig()));

List<Policy> policies = authorization.getStoreFactory().getPolicyStore().findDependentPolicies(model.getId());

representation.setDependentPolicies(policies.stream().map(policy -> {
PolicyRepresentation representation1 = new PolicyRepresentation();

representation1.setId(policy.getId());
representation1.setName(policy.getName());

return representation1;
}).collect(Collectors.toList()));

List<PolicyRepresentation> associatedPolicies = new ArrayList<>();

List<String> obj = model.getAssociatedPolicies().stream().map(policy -> {
PolicyRepresentation representation1 = new PolicyRepresentation();

representation1.setId(policy.getId());
representation1.setName(policy.getName());
representation1.setType(policy.getType());

associatedPolicies.add(representation1);

return policy.getId();
}).collect(Collectors.toList());

representation.setAssociatedPolicies(associatedPolicies);

try {
representation.getConfig().put("applyPolicies", JsonSerialization.writeValueAsString(obj));
} catch (IOException e) {
e.printStackTrace();
}

return representation;
}

public static ResourceRepresentation toRepresentation(Resource model, ResourceServer resourceServer, AuthorizationProvider authorization) {
ResourceRepresentation resource = new ResourceRepresentation();

resource.setId(model.getId());
resource.setType(model.getType());
resource.setName(model.getName());
resource.setUri(model.getUri());
resource.setIconUri(model.getIconUri());

ResourceOwnerRepresentation owner = new ResourceOwnerRepresentation();

owner.setId(model.getOwner());

KeycloakSession keycloakSession = authorization.getKeycloakSession();
RealmModel realm = authorization.getRealm();

if (owner.getId().equals(resourceServer.getClientId())) {
ClientModel clientModel = realm.getClientById(resourceServer.getClientId());
owner.setName(clientModel.getClientId());
} else {
UserModel userModel = keycloakSession.users().getUserById(owner.getId(), realm);

if (userModel == null) {
throw new RuntimeException("Could not find the user [" + owner.getId() + "] who owns the Resource [" + resource.getId() + "].");
}

owner.setName(userModel.getUsername());
}

resource.setOwner(owner);

resource.setScopes(model.getScopes().stream().map(model1 -> {
ScopeRepresentation scope = new ScopeRepresentation();
scope.setId(model1.getId());
scope.setName(model1.getName());
String iconUri = model1.getIconUri();
if (iconUri != null) {
scope.setIconUri(iconUri);
}
return scope;
}).collect(Collectors.toSet()));

resource.setTypedScopes(new ArrayList<>());

if (resource.getType() != null) {
ResourceStore resourceStore = authorization.getStoreFactory().getResourceStore();
for (Resource typed : resourceStore.findByType(resource.getType())) {
if (typed.getOwner().equals(resourceServer.getClientId()) && !typed.getId().equals(resource.getId())) {
resource.setTypedScopes(typed.getScopes().stream().map(model1 -> {
ScopeRepresentation scope = new ScopeRepresentation();
scope.setId(model1.getId());
scope.setName(model1.getName());
String iconUri = model1.getIconUri();
if (iconUri != null) {
scope.setIconUri(iconUri);
}
return scope;
}).filter(scopeRepresentation -> !resource.getScopes().contains(scopeRepresentation)).collect(Collectors.toList()));
}
}
}

resource.setPolicies(new ArrayList<>());

Set<Policy> policies = new HashSet<>();
PolicyStore policyStore = authorization.getStoreFactory().getPolicyStore();

policies.addAll(policyStore.findByResource(resource.getId()));
policies.addAll(policyStore.findByResourceType(resource.getType(), resourceServer.getId()));
policies.addAll(policyStore.findByScopeIds(resource.getScopes().stream().map(scope -> scope.getId()).collect(Collectors.toList()), resourceServer.getId()));

for (Policy policyModel : policies) {
PolicyRepresentation policy = new PolicyRepresentation();

policy.setId(policyModel.getId());
policy.setName(policyModel.getName());
policy.setType(policyModel.getType());

if (!resource.getPolicies().contains(policy)) {
resource.getPolicies().add(policy);
}
}

return resource;
}
}
Loading

0 comments on commit ba076ad

Please sign in to comment.