diff --git a/model/build-processor/src/main/java/org/keycloak/models/map/processor/AbstractGenerateEntityImplementationsProcessor.java b/model/build-processor/src/main/java/org/keycloak/models/map/processor/AbstractGenerateEntityImplementationsProcessor.java index 1e9f24fb6d..d04057e52e 100644 --- a/model/build-processor/src/main/java/org/keycloak/models/map/processor/AbstractGenerateEntityImplementationsProcessor.java +++ b/model/build-processor/src/main/java/org/keycloak/models/map/processor/AbstractGenerateEntityImplementationsProcessor.java @@ -165,7 +165,10 @@ public abstract class AbstractGenerateEntityImplementationsProcessor extends Abs } protected boolean isImmutableFinalType(TypeMirror fieldType) { - return isPrimitiveType(fieldType) || isBoxedPrimitiveType(fieldType) || Objects.equals("java.lang.String", fieldType.toString()); + return isPrimitiveType(fieldType) + || isBoxedPrimitiveType(fieldType) + || isEnumType(fieldType) + || Objects.equals("java.lang.String", fieldType.toString()); } protected boolean isKnownCollectionOfImmutableFinalTypes(TypeMirror fieldType) { @@ -208,6 +211,10 @@ public abstract class AbstractGenerateEntityImplementationsProcessor extends Abs return "deepClone(" + parameterName + ")"; } + protected boolean isEnumType(TypeMirror fieldType) { + return types.asElement(fieldType).getKind() == ElementKind.ENUM; + } + protected boolean isPrimitiveType(TypeMirror fieldType) { try { types.getPrimitiveType(fieldType.getKind()); diff --git a/model/map/src/main/java/org/keycloak/models/map/authorization/MapPermissionTicketStore.java b/model/map/src/main/java/org/keycloak/models/map/authorization/MapPermissionTicketStore.java index 0c2898f7ef..a50878aca5 100644 --- a/model/map/src/main/java/org/keycloak/models/map/authorization/MapPermissionTicketStore.java +++ b/model/map/src/main/java/org/keycloak/models/map/authorization/MapPermissionTicketStore.java @@ -29,6 +29,7 @@ import org.keycloak.models.KeycloakSession; import org.keycloak.models.ModelDuplicateException; import org.keycloak.models.map.authorization.adapter.MapPermissionTicketAdapter; import org.keycloak.models.map.authorization.entity.MapPermissionTicketEntity; +import org.keycloak.models.map.authorization.entity.MapPermissionTicketEntityImpl; import org.keycloak.models.map.storage.MapKeycloakTransaction; import org.keycloak.models.map.storage.MapStorage; @@ -108,7 +109,7 @@ public class MapPermissionTicketStore implements PermissionTicketStore { + ", Resource: " + resourceId + ", owner: " + owner + ", scopeId: " + scopeId + " already exists."); } - MapPermissionTicketEntity entity = new MapPermissionTicketEntity(); + MapPermissionTicketEntity entity = new MapPermissionTicketEntityImpl(); entity.setResourceId(resourceId); entity.setRequester(requester); entity.setCreatedTimestamp(System.currentTimeMillis()); diff --git a/model/map/src/main/java/org/keycloak/models/map/authorization/MapPolicyStore.java b/model/map/src/main/java/org/keycloak/models/map/authorization/MapPolicyStore.java index 358290e102..2975de81fd 100644 --- a/model/map/src/main/java/org/keycloak/models/map/authorization/MapPolicyStore.java +++ b/model/map/src/main/java/org/keycloak/models/map/authorization/MapPolicyStore.java @@ -27,6 +27,7 @@ import org.keycloak.models.KeycloakSession; import org.keycloak.models.ModelDuplicateException; import org.keycloak.models.map.authorization.adapter.MapPolicyAdapter; import org.keycloak.models.map.authorization.entity.MapPolicyEntity; +import org.keycloak.models.map.authorization.entity.MapPolicyEntityImpl; import org.keycloak.models.map.storage.MapKeycloakTransaction; import org.keycloak.models.map.storage.MapStorage; import org.keycloak.models.map.storage.ModelCriteriaBuilder.Operator; @@ -84,7 +85,8 @@ public class MapPolicyStore implements PolicyStore { } String uid = representation.getId(); - MapPolicyEntity entity = new MapPolicyEntity(uid); + MapPolicyEntity entity = new MapPolicyEntityImpl(); + entity.setId(uid); entity.setType(representation.getType()); entity.setName(representation.getName()); entity.setResourceServerId(resourceServer.getId()); diff --git a/model/map/src/main/java/org/keycloak/models/map/authorization/MapResourceServerStore.java b/model/map/src/main/java/org/keycloak/models/map/authorization/MapResourceServerStore.java index a0da21e330..5085efd659 100644 --- a/model/map/src/main/java/org/keycloak/models/map/authorization/MapResourceServerStore.java +++ b/model/map/src/main/java/org/keycloak/models/map/authorization/MapResourceServerStore.java @@ -34,6 +34,7 @@ import org.keycloak.models.ModelDuplicateException; import org.keycloak.models.ModelException; import org.keycloak.models.map.authorization.adapter.MapResourceServerAdapter; import org.keycloak.models.map.authorization.entity.MapResourceServerEntity; +import org.keycloak.models.map.authorization.entity.MapResourceServerEntityImpl; import org.keycloak.models.map.storage.MapKeycloakTransaction; import org.keycloak.models.map.storage.MapStorage; import org.keycloak.storage.StorageId; @@ -74,7 +75,8 @@ public class MapResourceServerStore implements ResourceServerStore { throw new ModelDuplicateException("Resource server already exists: " + clientId); } - MapResourceServerEntity entity = new MapResourceServerEntity(clientId); + MapResourceServerEntity entity = new MapResourceServerEntityImpl(); + entity.setId(clientId); return entityToAdapter(tx.create(entity)); } diff --git a/model/map/src/main/java/org/keycloak/models/map/authorization/MapResourceStore.java b/model/map/src/main/java/org/keycloak/models/map/authorization/MapResourceStore.java index 54dfe974c7..113d819dc4 100644 --- a/model/map/src/main/java/org/keycloak/models/map/authorization/MapResourceStore.java +++ b/model/map/src/main/java/org/keycloak/models/map/authorization/MapResourceStore.java @@ -27,6 +27,7 @@ import org.keycloak.models.KeycloakSession; import org.keycloak.models.ModelDuplicateException; import org.keycloak.models.map.authorization.adapter.MapResourceAdapter; import org.keycloak.models.map.authorization.entity.MapResourceEntity; +import org.keycloak.models.map.authorization.entity.MapResourceEntityImpl; import org.keycloak.models.map.storage.MapKeycloakTransaction; import org.keycloak.models.map.storage.MapStorage; @@ -82,8 +83,8 @@ public class MapResourceStore implements ResourceStore { throw new ModelDuplicateException("Resource with name '" + name + "' for " + resourceServer.getId() + " already exists for request owner " + owner); } - MapResourceEntity entity = new MapResourceEntity(id); - + MapResourceEntity entity = new MapResourceEntityImpl(); + entity.setId(id); entity.setName(name); entity.setResourceServerId(resourceServer.getId()); entity.setOwner(owner); diff --git a/model/map/src/main/java/org/keycloak/models/map/authorization/MapScopeStore.java b/model/map/src/main/java/org/keycloak/models/map/authorization/MapScopeStore.java index 3cb5731a38..1f706481d0 100644 --- a/model/map/src/main/java/org/keycloak/models/map/authorization/MapScopeStore.java +++ b/model/map/src/main/java/org/keycloak/models/map/authorization/MapScopeStore.java @@ -27,6 +27,7 @@ import org.keycloak.models.KeycloakSession; import org.keycloak.models.ModelDuplicateException; import org.keycloak.models.map.authorization.adapter.MapScopeAdapter; import org.keycloak.models.map.authorization.entity.MapScopeEntity; +import org.keycloak.models.map.authorization.entity.MapScopeEntityImpl; import org.keycloak.models.map.storage.MapKeycloakTransaction; import org.keycloak.models.map.storage.MapStorage; @@ -81,8 +82,8 @@ public class MapScopeStore implements ScopeStore { throw new ModelDuplicateException("Scope with name '" + name + "' for " + resourceServer.getId() + " already exists"); } - MapScopeEntity entity = new MapScopeEntity(id); - + MapScopeEntity entity = new MapScopeEntityImpl(); + entity.setId(id); entity.setName(name); entity.setResourceServerId(resourceServer.getId()); diff --git a/model/map/src/main/java/org/keycloak/models/map/authorization/adapter/MapPolicyAdapter.java b/model/map/src/main/java/org/keycloak/models/map/authorization/adapter/MapPolicyAdapter.java index 7b65bd40a3..4acfb0bc3a 100644 --- a/model/map/src/main/java/org/keycloak/models/map/authorization/adapter/MapPolicyAdapter.java +++ b/model/map/src/main/java/org/keycloak/models/map/authorization/adapter/MapPolicyAdapter.java @@ -26,6 +26,7 @@ import org.keycloak.models.map.authorization.entity.MapPolicyEntity; import org.keycloak.representations.idm.authorization.DecisionStrategy; import org.keycloak.representations.idm.authorization.Logic; +import java.util.Collections; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; @@ -48,7 +49,8 @@ public class MapPolicyAdapter extends AbstractPolicyModel { @Override public DecisionStrategy getDecisionStrategy() { - return entity.getDecisionStrategy(); + DecisionStrategy ds = entity.getDecisionStrategy(); + return ds == null ? DecisionStrategy.UNANIMOUS : ds; } @Override @@ -59,7 +61,8 @@ public class MapPolicyAdapter extends AbstractPolicyModel { @Override public Logic getLogic() { - return entity.getLogic(); + Logic l = entity.getLogic(); + return l == null ? Logic.POSITIVE : l; } @Override @@ -70,13 +73,14 @@ public class MapPolicyAdapter extends AbstractPolicyModel { @Override public Map getConfig() { - return entity.getConfig(); + Map c = entity.getConfigs(); + return c == null ? Collections.emptyMap() : c; } @Override public void setConfig(Map config) { throwExceptionIfReadonly(); - entity.setConfig(config); + entity.setConfigs(config); } @Override @@ -88,7 +92,7 @@ public class MapPolicyAdapter extends AbstractPolicyModel { @Override public void putConfig(String name, String value) { throwExceptionIfReadonly(); - entity.putConfig(name, value); + entity.setConfig(name, value); } @Override @@ -121,7 +125,8 @@ public class MapPolicyAdapter extends AbstractPolicyModel { @Override public Set getAssociatedPolicies() { String resourceServerId = entity.getResourceServerId(); - return entity.getAssociatedPoliciesIds().stream() + Set ids = entity.getAssociatedPolicyIds(); + return ids == null ? Collections.emptySet() : ids.stream() .map(policyId -> storeFactory.getPolicyStore().findById(policyId, resourceServerId)) .collect(Collectors.toSet()); } @@ -129,7 +134,8 @@ public class MapPolicyAdapter extends AbstractPolicyModel { @Override public Set getResources() { String resourceServerId = entity.getResourceServerId(); - return entity.getResourceIds().stream() + Set ids = entity.getResourceIds(); + return ids == null ? Collections.emptySet() : ids.stream() .map(resourceId -> storeFactory.getResourceStore().findById(resourceId, resourceServerId)) .collect(Collectors.toSet()); } @@ -137,7 +143,8 @@ public class MapPolicyAdapter extends AbstractPolicyModel { @Override public Set getScopes() { String resourceServerId = entity.getResourceServerId(); - return entity.getScopeIds().stream() + Set ids = entity.getScopeIds(); + return ids == null ? Collections.emptySet() : ids.stream() .map(scopeId -> storeFactory.getScopeStore().findById(scopeId, resourceServerId)) .collect(Collectors.toSet()); } @@ -156,37 +163,37 @@ public class MapPolicyAdapter extends AbstractPolicyModel { @Override public void addScope(Scope scope) { throwExceptionIfReadonly(); - entity.addScope(scope.getId()); + entity.addScopeId(scope.getId()); } @Override public void removeScope(Scope scope) { throwExceptionIfReadonly(); - entity.removeScope(scope.getId()); + entity.removeScopeId(scope.getId()); } @Override public void addAssociatedPolicy(Policy associatedPolicy) { throwExceptionIfReadonly(); - entity.addAssociatedPolicy(associatedPolicy.getId()); + entity.addAssociatedPolicyId(associatedPolicy.getId()); } @Override public void removeAssociatedPolicy(Policy associatedPolicy) { throwExceptionIfReadonly(); - entity.removeAssociatedPolicy(associatedPolicy.getId()); + entity.removeAssociatedPolicyId(associatedPolicy.getId()); } @Override public void addResource(Resource resource) { throwExceptionIfReadonly(); - entity.addResource(resource.getId()); + entity.addResourceId(resource.getId()); } @Override public void removeResource(Resource resource) { throwExceptionIfReadonly(); - entity.removeResource(resource.getId()); + entity.removeResourceId(resource.getId()); } @Override diff --git a/model/map/src/main/java/org/keycloak/models/map/authorization/adapter/MapResourceAdapter.java b/model/map/src/main/java/org/keycloak/models/map/authorization/adapter/MapResourceAdapter.java index 73e2c3eed8..1a2db083a9 100644 --- a/model/map/src/main/java/org/keycloak/models/map/authorization/adapter/MapResourceAdapter.java +++ b/model/map/src/main/java/org/keycloak/models/map/authorization/adapter/MapResourceAdapter.java @@ -63,7 +63,8 @@ public class MapResourceAdapter extends AbstractResourceModel @Override public Set getUris() { - return entity.getUris(); + Set uris = entity.getUris(); + return uris == null ? Collections.emptySet() : entity.getUris(); } @Override @@ -85,7 +86,8 @@ public class MapResourceAdapter extends AbstractResourceModel @Override public List getScopes() { - return entity.getScopeIds().stream() + Set ids = entity.getScopeIds(); + return ids == null ? Collections.emptyList() : ids.stream() .map(id -> storeFactory .getScopeStore().findById(id, entity.getResourceServerId())) .collect(Collectors.toList()); @@ -114,7 +116,8 @@ public class MapResourceAdapter extends AbstractResourceModel @Override public boolean isOwnerManagedAccess() { - return entity.isOwnerManagedAccess(); + Boolean isOMA = entity.isOwnerManagedAccess(); + return isOMA == null ? false : isOMA; } @Override @@ -131,7 +134,8 @@ public class MapResourceAdapter extends AbstractResourceModel @Override public Map> getAttributes() { - return Collections.unmodifiableMap(new HashMap<>(entity.getAttributes())); + Map> attrs = entity.getAttributes(); + return attrs == null ? Collections.emptyMap() : Collections.unmodifiableMap(new HashMap<>(attrs)); } @Override diff --git a/model/map/src/main/java/org/keycloak/models/map/authorization/adapter/MapResourceServerAdapter.java b/model/map/src/main/java/org/keycloak/models/map/authorization/adapter/MapResourceServerAdapter.java index 7aa5b8932c..72c90e03d1 100644 --- a/model/map/src/main/java/org/keycloak/models/map/authorization/adapter/MapResourceServerAdapter.java +++ b/model/map/src/main/java/org/keycloak/models/map/authorization/adapter/MapResourceServerAdapter.java @@ -36,7 +36,8 @@ public class MapResourceServerAdapter extends AbstractResourceServerModel config = new HashMap<>(); - private String resourceServerId; - private final Set associatedPoliciesIds = new HashSet<>(); - private final Set resourceIds = new HashSet<>(); - private final Set scopeIds = new HashSet<>(); - private String owner; +@GenerateEntityImplementations( + inherits = "org.keycloak.models.map.authorization.entity.MapPolicyEntity.AbstractMapPolicyEntity" +) +@DeepCloner.Root +public interface MapPolicyEntity extends UpdatableEntity, AbstractEntity { - public MapPolicyEntity(String id) { - this.id = id; - } + public abstract class AbstractMapPolicyEntity extends UpdatableEntity.Impl implements MapPolicyEntity { - public MapPolicyEntity() {} + private String id; - public String getName() { - return name; - } + @Override + public String getId() { + return this.id; + } - public void setName(String name) { - this.updated |= !Objects.equals(this.name, name); - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.updated |= !Objects.equals(this.description, description); - this.description = description; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.updated |= !Objects.equals(this.type, type); - this.type = type; - } - - public DecisionStrategy getDecisionStrategy() { - return decisionStrategy; - } - - public void setDecisionStrategy(DecisionStrategy decisionStrategy) { - this.updated |= !Objects.equals(this.decisionStrategy, decisionStrategy); - this.decisionStrategy = decisionStrategy; - } - - public Logic getLogic() { - return logic; - } - - public void setLogic(Logic logic) { - this.updated |= !Objects.equals(this.logic, logic); - this.logic = logic; - } - - public Map getConfig() { - return config; - } - - public String getConfigValue(String name) { - return config.get(name); - } - - public void setConfig(Map config) { - if (Objects.equals(this.config, config)) return; - - this.updated = true; - this.config.clear(); - if (config != null) { - this.config.putAll(config); + @Override + public void setId(String id) { + if (this.id != null) throw new IllegalStateException("Id cannot be changed"); + this.id = id; + this.updated |= id != null; } } - - public void removeConfig(String name) { - this.updated |= this.config.remove(name) != null; - } - public void putConfig(String name, String value) { - this.updated |= !Objects.equals(value, this.config.put(name, value)); - } + String getName(); + void setName(String name); - public String getResourceServerId() { - return resourceServerId; - } + String getDescription(); + void setDescription(String description); - public void setResourceServerId(String resourceServerId) { - this.updated |= !Objects.equals(this.resourceServerId, resourceServerId); - this.resourceServerId = resourceServerId; - } + String getType(); + void setType(String type); - public Set getAssociatedPoliciesIds() { - return associatedPoliciesIds; - } + DecisionStrategy getDecisionStrategy(); + void setDecisionStrategy(DecisionStrategy decisionStrategy); - public void addAssociatedPolicy(String policyId) { - this.updated |= this.associatedPoliciesIds.add(policyId); - } + Logic getLogic(); + void setLogic(Logic logic); - public void removeAssociatedPolicy(String policyId) { - this.updated |= this.associatedPoliciesIds.remove(policyId); - } + Map getConfigs(); + void setConfigs(Map config); + String getConfig(String name); + void setConfig(String name, String value); + void removeConfig(String name); - public Set getResourceIds() { - return resourceIds; - } + String getResourceServerId(); + void setResourceServerId(String resourceServerId); - public void addResource(String resourceId) { - this.updated |= this.resourceIds.add(resourceId); - } + Set getAssociatedPolicyIds(); + void addAssociatedPolicyId(String policyId); + void removeAssociatedPolicyId(String policyId); - public void removeResource(String resourceId) { - this.updated |= this.resourceIds.remove(resourceId); - } + Set getResourceIds(); + void addResourceId(String resourceId); + void removeResourceId(String resourceId); - public Set getScopeIds() { - return scopeIds; - } - - public void addScope(String scopeId) { - this.updated |= this.scopeIds.add(scopeId); - } - - public void removeScope(String scopeId) { - this.updated |= this.scopeIds.remove(scopeId); - } + Set getScopeIds(); + void addScopeId(String scopeId); + void removeScopeId(String scopeId); - public String getOwner() { - return owner; - } - - public void setOwner(String owner) { - this.updated |= !Objects.equals(this.owner, owner); - this.owner = owner; - } - - @Override - public String getId() { - return id; - } - - @Override - public void setId(String id) { - if (this.id != null) throw new IllegalStateException("Id cannot be changed"); - this.id = id; - this.updated |= id != null; - } - - @Override - public String toString() { - return String.format("%s@%08x", getId(), System.identityHashCode(this)); - } + String getOwner(); + void setOwner(String owner); } diff --git a/model/map/src/main/java/org/keycloak/models/map/authorization/entity/MapResourceEntity.java b/model/map/src/main/java/org/keycloak/models/map/authorization/entity/MapResourceEntity.java index 6c9d449dd3..12161996f4 100644 --- a/model/map/src/main/java/org/keycloak/models/map/authorization/entity/MapResourceEntity.java +++ b/model/map/src/main/java/org/keycloak/models/map/authorization/entity/MapResourceEntity.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Red Hat, Inc. and/or its affiliates + * Copyright 2022 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"); @@ -17,175 +17,61 @@ package org.keycloak.models.map.authorization.entity; +import org.keycloak.models.map.annotations.GenerateEntityImplementations; import org.keycloak.models.map.common.AbstractEntity; - +import org.keycloak.models.map.common.DeepCloner; import org.keycloak.models.map.common.EntityWithAttributes; import org.keycloak.models.map.common.UpdatableEntity; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; + import java.util.Set; -public class MapResourceEntity extends UpdatableEntity.Impl implements AbstractEntity, EntityWithAttributes { - - private String id; - private String name; - private String displayName; - private final Set uris = new HashSet<>(); - private String type; - private String iconUri; - private String owner; - private boolean ownerManagedAccess; - private String resourceServerId; - private final Set scopeIds = new HashSet<>(); - private final Set policyIds = new HashSet<>(); - private final Map> attributes = new HashMap<>(); +@GenerateEntityImplementations( + inherits = "org.keycloak.models.map.authorization.entity.MapResourceEntity.AbstractMapResourceEntity" +) +@DeepCloner.Root +public interface MapResourceEntity extends UpdatableEntity, AbstractEntity, EntityWithAttributes { - public MapResourceEntity(String id) { - this.id = id; - } + public abstract class AbstractMapResourceEntity extends UpdatableEntity.Impl implements MapResourceEntity { - public MapResourceEntity() {} + private String id; - @Override - public String getId() { - return id; - } + @Override + public String getId() { + return this.id; + } - @Override - public void setId(String id) { - if (this.id != null) throw new IllegalStateException("Id cannot be changed"); - this.id = id; - this.updated |= id != null; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.updated |= !Objects.equals(this.name, name); - this.name = name; - } - - public String getDisplayName() { - return displayName; - } - - public void setDisplayName(String displayName) { - this.updated |= !Objects.equals(this.displayName, displayName); - this.displayName = displayName; - } - - public Set getUris() { - return uris; - } - - public void setUris(Set uris) { - if (Objects.equals(this.uris, uris)) return; - - this.updated = true; - this.uris.clear(); - - if (uris != null) { - this.uris.addAll(uris); + @Override + public void setId(String id) { + if (this.id != null) throw new IllegalStateException("Id cannot be changed"); + this.id = id; + this.updated |= id != null; } } - public String getType() { - return type; - } + String getName(); + void setName(String name); - public void setType(String type) { - this.updated |= !Objects.equals(this.type, type); - this.type = type; - } + String getDisplayName(); + void setDisplayName(String displayName); - public String getIconUri() { - return iconUri; - } + Set getUris(); + void setUris(Set uris); - public void setIconUri(String iconUri) { - this.updated |= !Objects.equals(this.iconUri, iconUri); - this.iconUri = iconUri; - } + String getType(); + void setType(String type); - public String getOwner() { - return owner; - } + String getIconUri(); + void setIconUri(String iconUri); - public void setOwner(String owner) { - this.updated |= !Objects.equals(this.owner, owner); - this.owner = owner; - } + String getOwner(); + void setOwner(String owner); - public boolean isOwnerManagedAccess() { - return ownerManagedAccess; - } + Boolean isOwnerManagedAccess(); + void setOwnerManagedAccess(Boolean ownerManagedAccess); - public void setOwnerManagedAccess(boolean ownerManagedAccess) { - this.updated |= this.ownerManagedAccess != ownerManagedAccess; - this.ownerManagedAccess = ownerManagedAccess; - } + void setResourceServerId(String resourceServerId); + String getResourceServerId(); - public String getResourceServerId() { - return resourceServerId; - } - - public void setResourceServerId(String resourceServerId) { - this.updated |= !Objects.equals(this.resourceServerId, resourceServerId); - this.resourceServerId = resourceServerId; - } - - public Set getScopeIds() { - return scopeIds; - } - - public void setScopeIds(Set scopeIds) { - if (Objects.equals(this.scopeIds, scopeIds)) return; - - this.updated = true; - this.scopeIds.clear(); - if (scopeIds != null) { - this.scopeIds.addAll(scopeIds); - } - } - - public Set getPolicyIds() { - return policyIds; - } - - @Override - public Map> getAttributes() { - return attributes; - } - - @Override - public void setAttributes(Map> attributes) { - this.updated |= ! Objects.equals(this.attributes, attributes); - this.attributes.clear(); - this.attributes.putAll(attributes); - } - - @Override - public List getAttribute(String name) { - return attributes.get(name); - } - - @Override - public void setAttribute(String name, List value) { - this.updated |= !Objects.equals(this.attributes.put(name, value), value); - } - - @Override - public void removeAttribute(String name) { - this.updated |= this.attributes.remove(name) != null; - } - - @Override - public String toString() { - return String.format("%s@%08x", getId(), System.identityHashCode(this)); - } + Set getScopeIds(); + void setScopeIds(Set scopeIds); } diff --git a/model/map/src/main/java/org/keycloak/models/map/authorization/entity/MapResourceServerEntity.java b/model/map/src/main/java/org/keycloak/models/map/authorization/entity/MapResourceServerEntity.java index 76dc83ae55..6a762c28c8 100644 --- a/model/map/src/main/java/org/keycloak/models/map/authorization/entity/MapResourceServerEntity.java +++ b/model/map/src/main/java/org/keycloak/models/map/authorization/entity/MapResourceServerEntity.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Red Hat, Inc. and/or its affiliates + * Copyright 2022 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"); @@ -17,68 +17,42 @@ package org.keycloak.models.map.authorization.entity; +import org.keycloak.models.map.annotations.GenerateEntityImplementations; import org.keycloak.models.map.common.AbstractEntity; +import org.keycloak.models.map.common.DeepCloner; import org.keycloak.models.map.common.UpdatableEntity; import org.keycloak.representations.idm.authorization.DecisionStrategy; import org.keycloak.representations.idm.authorization.PolicyEnforcementMode; -import java.util.Objects; +@GenerateEntityImplementations( + inherits = "org.keycloak.models.map.authorization.entity.MapResourceServerEntity.AbstractMapResourceServerEntity" +) +@DeepCloner.Root +public interface MapResourceServerEntity extends UpdatableEntity, AbstractEntity { -public class MapResourceServerEntity extends UpdatableEntity.Impl implements AbstractEntity { + public abstract class AbstractMapResourceServerEntity extends UpdatableEntity.Impl implements MapResourceServerEntity { - private String id; + private String id; - private boolean allowRemoteResourceManagement; - private PolicyEnforcementMode policyEnforcementMode = PolicyEnforcementMode.ENFORCING; - private DecisionStrategy decisionStrategy = DecisionStrategy.UNANIMOUS; + @Override + public String getId() { + return this.id; + } - public MapResourceServerEntity(String id) { - this.id = id; + @Override + public void setId(String id) { + if (this.id != null) throw new IllegalStateException("Id cannot be changed"); + this.id = id; + this.updated |= id != null; + } } - public MapResourceServerEntity() {} + Boolean isAllowRemoteResourceManagement(); + void setAllowRemoteResourceManagement(Boolean allowRemoteResourceManagement); - @Override - public String getId() { - return id; - } + PolicyEnforcementMode getPolicyEnforcementMode(); + void setPolicyEnforcementMode(PolicyEnforcementMode policyEnforcementMode); - @Override - public void setId(String id) { - if (this.id != null) throw new IllegalStateException("Id cannot be changed"); - this.id = id; - this.updated |= id != null; - } - - public boolean isAllowRemoteResourceManagement() { - return allowRemoteResourceManagement; - } - - public void setAllowRemoteResourceManagement(boolean allowRemoteResourceManagement) { - this.updated |= this.allowRemoteResourceManagement != allowRemoteResourceManagement; - this.allowRemoteResourceManagement = allowRemoteResourceManagement; - } - - public PolicyEnforcementMode getPolicyEnforcementMode() { - return policyEnforcementMode; - } - - public void setPolicyEnforcementMode(PolicyEnforcementMode policyEnforcementMode) { - this.updated |= !Objects.equals(this.policyEnforcementMode, policyEnforcementMode); - this.policyEnforcementMode = policyEnforcementMode; - } - - public DecisionStrategy getDecisionStrategy() { - return decisionStrategy; - } - - public void setDecisionStrategy(DecisionStrategy decisionStrategy) { - this.updated |= !Objects.equals(this.decisionStrategy, decisionStrategy); - this.decisionStrategy = decisionStrategy; - } - - @Override - public String toString() { - return String.format("%s@%08x", getId(), System.identityHashCode(this)); - } + DecisionStrategy getDecisionStrategy(); + void setDecisionStrategy(DecisionStrategy decisionStrategy); } diff --git a/model/map/src/main/java/org/keycloak/models/map/authorization/entity/MapScopeEntity.java b/model/map/src/main/java/org/keycloak/models/map/authorization/entity/MapScopeEntity.java index 96aff466d5..2f3eb70035 100644 --- a/model/map/src/main/java/org/keycloak/models/map/authorization/entity/MapScopeEntity.java +++ b/model/map/src/main/java/org/keycloak/models/map/authorization/entity/MapScopeEntity.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Red Hat, Inc. and/or its affiliates + * Copyright 2022 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"); @@ -17,75 +17,43 @@ package org.keycloak.models.map.authorization.entity; +import org.keycloak.models.map.annotations.GenerateEntityImplementations; import org.keycloak.models.map.common.AbstractEntity; - +import org.keycloak.models.map.common.DeepCloner; import org.keycloak.models.map.common.UpdatableEntity; -import java.util.Objects; -public class MapScopeEntity extends UpdatableEntity.Impl implements AbstractEntity { +@GenerateEntityImplementations( + inherits = "org.keycloak.models.map.authorization.entity.MapScopeEntity.AbstractMapScopeEntity" +) +@DeepCloner.Root +public interface MapScopeEntity extends UpdatableEntity, AbstractEntity { - private String id; - private String name; - private String displayName; - private String iconUri; - private String resourceServerId; + public abstract class AbstractMapScopeEntity extends UpdatableEntity.Impl implements MapScopeEntity { - public MapScopeEntity(String id) { - this.id = id; + private String id; + + @Override + public String getId() { + return this.id; + } + + @Override + public void setId(String id) { + if (this.id != null) throw new IllegalStateException("Id cannot be changed"); + this.id = id; + this.updated |= id != null; + } } - public MapScopeEntity() {} + String getName(); + void setName(String name); - @Override - public String getId() { - return id; - } + String getDisplayName(); + void setDisplayName(String displayName); - @Override - public void setId(String id) { - if (this.id != null) throw new IllegalStateException("Id cannot be changed"); - this.id = id; - this.updated |= id != null; - } + String getIconUri(); + void setIconUri(String iconUri); - public String getName() { - return name; - } - - public void setName(String name) { - this.updated |= !Objects.equals(this.name, name); - this.name = name; - } - - public String getDisplayName() { - return displayName; - } - - public void setDisplayName(String displayName) { - this.updated |= !Objects.equals(this.displayName, displayName); - this.displayName = displayName; - } - - public String getIconUri() { - return iconUri; - } - - public void setIconUri(String iconUri) { - this.updated |= !Objects.equals(this.iconUri, iconUri); - this.iconUri = iconUri; - } - - public String getResourceServerId() { - return resourceServerId; - } - - public void setResourceServerId(String resourceServerId) { - this.updated |= !Objects.equals(this.resourceServerId, resourceServerId); - this.resourceServerId = resourceServerId; - } - - @Override - public String toString() { - return String.format("%s@%08x", getId(), System.identityHashCode(this)); - } + String getResourceServerId(); + void setResourceServerId(String resourceServerId); } diff --git a/model/map/src/main/java/org/keycloak/models/map/storage/chm/ConcurrentHashMapStorageProviderFactory.java b/model/map/src/main/java/org/keycloak/models/map/storage/chm/ConcurrentHashMapStorageProviderFactory.java index 495155ad05..f8275e913f 100644 --- a/model/map/src/main/java/org/keycloak/models/map/storage/chm/ConcurrentHashMapStorageProviderFactory.java +++ b/model/map/src/main/java/org/keycloak/models/map/storage/chm/ConcurrentHashMapStorageProviderFactory.java @@ -16,6 +16,14 @@ */ package org.keycloak.models.map.storage.chm; +import org.keycloak.models.map.authorization.entity.MapPermissionTicketEntity; +import org.keycloak.models.map.authorization.entity.MapPermissionTicketEntityImpl; +import org.keycloak.models.map.authorization.entity.MapPolicyEntity; +import org.keycloak.models.map.authorization.entity.MapPolicyEntityImpl; +import org.keycloak.models.map.authorization.entity.MapResourceEntityImpl; +import org.keycloak.models.map.authorization.entity.MapResourceServerEntityImpl; +import org.keycloak.models.map.authorization.entity.MapScopeEntity; +import org.keycloak.models.map.authorization.entity.MapScopeEntityImpl; import org.keycloak.models.map.common.StringKeyConvertor; import org.keycloak.component.AmphibianProviderFactory; import org.keycloak.Config.Scope; @@ -94,6 +102,11 @@ public class ConcurrentHashMapStorageProviderFactory implements AmphibianProvide .constructor(MapUserFederatedIdentityEntityImpl.class, MapUserFederatedIdentityEntityImpl::new) .constructor(MapUserConsentEntityImpl.class, MapUserConsentEntityImpl::new) .constructor(MapClientScopeEntityImpl.class, MapClientScopeEntityImpl::new) + .constructor(MapResourceServerEntityImpl.class, MapResourceServerEntityImpl::new) + .constructor(MapResourceEntityImpl.class, MapResourceEntityImpl::new) + .constructor(MapScopeEntity.class, MapScopeEntityImpl::new) + .constructor(MapPolicyEntity.class, MapPolicyEntityImpl::new) + .constructor(MapPermissionTicketEntity.class, MapPermissionTicketEntityImpl::new) .build(); private static final Map KEY_CONVERTORS = new HashMap<>(); diff --git a/model/map/src/main/java/org/keycloak/models/map/storage/chm/MapFieldPredicates.java b/model/map/src/main/java/org/keycloak/models/map/storage/chm/MapFieldPredicates.java index eda1098678..3cc7165643 100644 --- a/model/map/src/main/java/org/keycloak/models/map/storage/chm/MapFieldPredicates.java +++ b/model/map/src/main/java/org/keycloak/models/map/storage/chm/MapFieldPredicates.java @@ -341,10 +341,10 @@ public class MapFieldPredicates { getter = re -> re.getUris() != null && !re.getUris().isEmpty(); } else if (op == Operator.IN && values != null && values.length == 1 && (values[0] instanceof Collection)) { Collection c = (Collection) values[0]; - getter = re -> re.getUris().stream().anyMatch(c::contains); + getter = re -> Optional.ofNullable(re.getUris()).orElseGet(Collections::emptySet).stream().anyMatch(c::contains); } else { String uri = ensureEqSingleValue(Resource.SearchableFields.URI, "uri", op, values); - getter = re -> re.getUris().contains(uri); + getter = re -> Optional.ofNullable(re.getUris()).orElseGet(Collections::emptySet).contains(uri); } return mcb.fieldCompare(Boolean.TRUE::equals, getter); @@ -355,10 +355,10 @@ public class MapFieldPredicates { if (op == Operator.IN && values != null && values.length == 1 && (values[0] instanceof Collection)) { Collection c = (Collection) values[0]; - getter = re -> re.getScopeIds().stream().map(Object::toString).anyMatch(c::contains); + getter = re -> Optional.ofNullable(re.getScopeIds()).orElseGet(Collections::emptySet).stream().map(Object::toString).anyMatch(c::contains); } else { String scope = ensureEqSingleValue(Resource.SearchableFields.URI, "scope_id", op, values); - getter = re -> re.getScopeIds().stream().map(Object::toString).anyMatch(scope::equals); + getter = re -> Optional.ofNullable(re.getScopeIds()).orElseGet(Collections::emptySet).stream().map(Object::toString).anyMatch(scope::equals); } return mcb.fieldCompare(Boolean.TRUE::equals, getter); @@ -368,13 +368,13 @@ public class MapFieldPredicates { Function getter; if (op == Operator.NOT_EXISTS) { - getter = re -> re.getResourceIds().isEmpty(); + getter = re -> re.getResourceIds() == null || re.getResourceIds().isEmpty(); } else if (op == Operator.IN && values != null && values.length == 1 && (values[0] instanceof Collection)) { Collection c = (Collection) values[0]; - getter = re -> re.getResourceIds().stream().map(Object::toString).anyMatch(c::contains); + getter = re -> Optional.ofNullable(re.getResourceIds()).orElseGet(Collections::emptySet).stream().map(Object::toString).anyMatch(c::contains); } else { String scope = ensureEqSingleValue(Policy.SearchableFields.RESOURCE_ID, "resource_id", op, values, String.class); - getter = re -> re.getResourceIds().stream().map(Object::toString).anyMatch(scope::equals); + getter = re -> Optional.ofNullable(re.getResourceIds()).orElseGet(Collections::emptySet).stream().map(Object::toString).anyMatch(scope::equals); } return mcb.fieldCompare(Boolean.TRUE::equals, getter); @@ -385,10 +385,10 @@ public class MapFieldPredicates { if (op == Operator.IN && values != null && values.length == 1 && (values[0] instanceof Collection)) { Collection c = (Collection) values[0]; - getter = re -> re.getScopeIds().stream().map(Object::toString).anyMatch(c::contains); // TODO: Use KeyConverter + getter = re -> Optional.ofNullable(re.getScopeIds()).orElseGet(Collections::emptySet).stream().map(Object::toString).anyMatch(c::contains); // TODO: Use KeyConverter } else { String scope = ensureEqSingleValue(Policy.SearchableFields.CONFIG, "scope_id", op, values); - getter = re -> re.getScopeIds().stream().map(Object::toString).anyMatch(scope::equals); + getter = re -> Optional.ofNullable(re.getScopeIds()).orElseGet(Collections::emptySet).stream().map(Object::toString).anyMatch(scope::equals); } return mcb.fieldCompare(Boolean.TRUE::equals, getter); @@ -407,7 +407,7 @@ public class MapFieldPredicates { System.arraycopy(values, 1, realValues, 0, values.length - 1); Predicate valueComparator = CriteriaOperator.predicateFor(op, realValues); getter = pe -> { - final String configValue = pe.getConfigValue(attrNameS); + final String configValue = pe.getConfig(attrNameS); return valueComparator.test(configValue); }; @@ -419,10 +419,10 @@ public class MapFieldPredicates { if (op == Operator.IN && values != null && values.length == 1 && (values[0] instanceof Collection)) { Collection c = (Collection) values[0]; - getter = re -> re.getAssociatedPoliciesIds().stream().map(Object::toString).anyMatch(c::contains); + getter = re -> Optional.ofNullable(re.getAssociatedPolicyIds()).orElseGet(Collections::emptySet).stream().map(Object::toString).anyMatch(c::contains); } else { String policyId = ensureEqSingleValue(Policy.SearchableFields.ASSOCIATED_POLICY_ID, "associated_policy_id", op, values); - getter = re -> re.getAssociatedPoliciesIds().stream().map(Object::toString).anyMatch(policyId::equals); + getter = re -> Optional.ofNullable(re.getAssociatedPolicyIds()).orElseGet(Collections::emptySet).stream().map(Object::toString).anyMatch(policyId::equals); } return mcb.fieldCompare(Boolean.TRUE::equals, getter);