keycloak-aplcache
Changes
authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/group/GroupPolicyProviderFactory.java 31(+26 -5)
Details
diff --git a/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/group/GroupPolicyProviderFactory.java b/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/group/GroupPolicyProviderFactory.java
index d101c79..f558449 100644
--- a/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/group/GroupPolicyProviderFactory.java
+++ b/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/group/GroupPolicyProviderFactory.java
@@ -30,9 +30,12 @@ import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.policy.provider.PolicyProvider;
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
+import org.keycloak.models.ClientModel;
import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.representations.idm.authorization.GroupPolicyRepresentation;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;
@@ -74,7 +77,7 @@ public class GroupPolicyProviderFactory implements PolicyProviderFactory<GroupPo
public GroupPolicyRepresentation toRepresentation(Policy policy, GroupPolicyRepresentation representation) {
representation.setGroupsClaim(policy.getConfig().get("groupsClaim"));
try {
- representation.setGroups(new HashSet<>(Arrays.asList(JsonSerialization.readValue(policy.getConfig().get("groups"), GroupPolicyRepresentation.GroupDefinition[].class))));
+ representation.setGroups(getGroupsDefinition(policy.getConfig()));
} catch (IOException cause) {
throw new RuntimeException("Failed to deserialize groups", cause);
}
@@ -99,7 +102,7 @@ public class GroupPolicyProviderFactory implements PolicyProviderFactory<GroupPo
@Override
public void onImport(Policy policy, PolicyRepresentation representation, AuthorizationProvider authorization) {
try {
- updatePolicy(policy, representation.getConfig().get("groupsClaim"), JsonSerialization.readValue(representation.getConfig().get("groups"), Set.class), authorization);
+ updatePolicy(policy, representation.getConfig().get("groupsClaim"), getGroupsDefinition(representation.getConfig()), authorization);
} catch (IOException cause) {
throw new RuntimeException("Failed to deserialize groups", cause);
}
@@ -107,7 +110,24 @@ public class GroupPolicyProviderFactory implements PolicyProviderFactory<GroupPo
@Override
public void onExport(Policy policy, PolicyRepresentation representation, AuthorizationProvider authorizationProvider) {
+ Map<String, String> config = new HashMap<>();
+ GroupPolicyRepresentation groupPolicy = toRepresentation(policy, new GroupPolicyRepresentation());
+ Set<GroupPolicyRepresentation.GroupDefinition> groups = groupPolicy.getGroups();
+
+ for (GroupPolicyRepresentation.GroupDefinition definition: groups) {
+ GroupModel group = authorizationProvider.getRealm().getGroupById(definition.getId());
+ definition.setId(null);
+ definition.setPath(ModelToRepresentation.buildGroupPath(group));
+ }
+ try {
+ config.put("groupsClaim", groupPolicy.getGroupsClaim());
+ config.put("groups", JsonSerialization.writeValueAsString(groups));
+ } catch (IOException cause) {
+ throw new RuntimeException("Failed to export group policy [" + policy.getName() + "]", cause);
+ }
+
+ representation.setConfig(config);
}
@Override
@@ -157,9 +177,6 @@ public class GroupPolicyProviderFactory implements PolicyProviderFactory<GroupPo
GroupModel parent = null;
for (String part : parts) {
- if ("".trim().equals(part)) {
- continue;
- }
if (parent == null) {
parent = topLevelGroups.stream().filter(groupModel -> groupModel.getName().equals(part)).findFirst().orElseThrow(() -> new RuntimeException("Top level group with name [" + part + "] not found"));
} else {
@@ -190,4 +207,8 @@ public class GroupPolicyProviderFactory implements PolicyProviderFactory<GroupPo
policy.setConfig(config);
}
+
+ private HashSet<GroupPolicyRepresentation.GroupDefinition> getGroupsDefinition(Map<String, String> config) throws IOException {
+ return new HashSet<>(Arrays.asList(JsonSerialization.readValue(config.get("groups"), GroupPolicyRepresentation.GroupDefinition[].class)));
+ }
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportUtil.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportUtil.java
index b29abc1..677430d 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportUtil.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportUtil.java
@@ -627,12 +627,13 @@ public class ExportImportUtil {
assertPredicate(scopes, scopePredicates);
List<PolicyRepresentation> policies = authzResource.policies().policies();
- Assert.assertEquals(13, policies.size());
+ Assert.assertEquals(14, 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(representation -> "Client and Realm Role Policy".equals(representation.getName()));
policyPredicates.add(representation -> "Client Test Policy".equals(representation.getName()));
+ policyPredicates.add(representation -> "Group Policy Test".equals(representation.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()));
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/model/testrealm.json b/testsuite/integration-arquillian/tests/base/src/test/resources/model/testrealm.json
index 5f84e38..fb1a7e0 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/model/testrealm.json
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/model/testrealm.json
@@ -71,6 +71,50 @@
}
}
],
+ "groups": [
+ {
+ "name": "Group A",
+ "path": "/Group A",
+ "attributes": {
+ "topAttribute": [
+ "true"
+ ]
+ },
+ "subGroups": [
+ {
+ "name": "Group B",
+ "path": "/Group A/Group B",
+ "attributes": {
+ "level2Attribute": [
+ "true"
+ ]
+ },
+ "subGroups": []
+ }
+ ]
+ },
+ {
+ "name": "Group C",
+ "path": "/Group C",
+ "attributes": {
+ "topAttribute": [
+ "true"
+ ]
+ },
+ "subGroups": [
+ {
+ "name": "Group D",
+ "path": "/Group C/Group D",
+ "attributes": {
+ "level2Attribute": [
+ "true"
+ ]
+ },
+ "subGroups": []
+ }
+ ]
+ }
+ ],
"users": [
{
"username": "wburke",
@@ -299,6 +343,14 @@
}
},
{
+ "name": "Group Policy Test",
+ "type": "group",
+ "config": {
+ "groupsClaim": "groups",
+ "groups": "[{\"path\":\"/Group A\",\"extendChildren\":true},{\"path\":\"/Group A/Group B\",\"extendChildren\":false},{\"path\":\"/Group C/Group D\",\"extendChildren\":true}]"
+ }
+ },
+ {
"name": "Only Premium User Policy",
"description": "Defines that only premium users can do something",
"type": "role",