forked from keycloak/keycloak
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request keycloak#3144 from pedroigor/KEYCLOAK-3144
[KEYCLOAK-3144] - Add authorization settings when exporting/importing a realm
- Loading branch information
Showing
24 changed files
with
1,377 additions
and
850 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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; | ||
|
@@ -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; | ||
|
@@ -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> | ||
|
@@ -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; | ||
} | ||
} |
Oops, something went wrong.