This is an automated email from the ASF dual-hosted git repository. ilgrosso pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/master by this push: new 126ffd3e2c [SYNCOPE-1908] Cleanup 126ffd3e2c is described below commit 126ffd3e2cc874c26b97251d4c78342defd12a31 Author: Francesco Chicchiriccò <ilgro...@apache.org> AuthorDate: Thu Sep 11 12:59:45 2025 +0200 [SYNCOPE-1908] Cleanup --- .../apache/syncope/common/lib/EntityTOUtils.java | 11 +- .../apache/syncope/common/lib/request/AnyCR.java | 42 +++++++- .../syncope/common/lib/request/AnyObjectCR.java | 35 ------- .../syncope/common/lib/request/AnyObjectUR.java | 27 +---- .../apache/syncope/common/lib/request/AnyUR.java | 31 +++++- .../apache/syncope/common/lib/request/GroupCR.java | 40 +------ .../apache/syncope/common/lib/request/GroupUR.java | 14 +-- .../apache/syncope/common/lib/request/UserCR.java | 35 ------- .../apache/syncope/common/lib/request/UserUR.java | 27 +---- .../apache/syncope/common/lib/to/AnyObjectTO.java | 19 ---- .../org/apache/syncope/common/lib/to/AnyTO.java | 21 +++- .../org/apache/syncope/common/lib/to/GroupTO.java | 21 +--- .../org/apache/syncope/common/lib/to/UserTO.java | 19 ---- .../core/persistence/api/entity/AnyUtils.java | 5 + .../core/persistence/api/entity/Groupable.java | 3 +- .../core/persistence/api/entity/Relatable.java | 3 +- .../api/entity/anyobject/AnyObject.java | 4 +- .../core/persistence/api/entity/group/Group.java | 3 +- .../core/persistence/api/entity/user/User.java | 5 +- .../common/dao/AbstractAnyMatchDAO.java | 8 +- .../persistence/common/entity/DefaultAnyUtils.java | 62 +++++++++++ .../common/validation/AnyValidator.java | 2 +- .../jpa/entity/AbstractGroupableRelatable.java | 6 +- .../persistence/jpa/entity/AbstractRelatable.java | 6 +- .../jpa/entity/anyobject/JPAAnyObject.java | 2 +- .../persistence/jpa/entity/group/JPAGroup.java | 3 +- .../core/persistence/jpa/entity/user/JPAUser.java | 3 +- .../neo4j/entity/AbstractGroupableRelatable.java | 7 +- .../neo4j/entity/AbstractRelatable.java | 6 +- .../neo4j/entity/anyobject/Neo4jAnyObject.java | 2 +- .../persistence/neo4j/entity/group/Neo4jGroup.java | 3 +- .../persistence/neo4j/entity/user/Neo4jUser.java | 3 +- .../core/provisioning/api/DerAttrHandler.java | 2 +- .../provisioning/java/DefaultDerAttrHandler.java | 4 +- .../provisioning/java/DefaultMappingManager.java | 8 +- .../core/provisioning/java/data/AnyDataBinder.java | 103 +++++++++++++++++- .../java/data/AnyObjectDataBinderImpl.java | 116 +-------------------- .../java/data/GroupDataBinderImpl.java | 111 +------------------- .../provisioning/java/data/UserDataBinderImpl.java | 104 +----------------- .../elasticsearch/client/ElasticsearchUtils.java | 2 +- .../ext/openfga/client/OpenFGAStoreManager.java | 4 +- .../ext/opensearch/client/OpenSearchUtils.java | 2 +- 42 files changed, 320 insertions(+), 614 deletions(-) diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/EntityTOUtils.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/EntityTOUtils.java index 9b7d37259d..7f10da1df0 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/EntityTOUtils.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/EntityTOUtils.java @@ -68,19 +68,17 @@ public final class EntityTOUtils { anyCR.getAuxClasses().addAll(anyTO.getAuxClasses()); anyCR.getPlainAttrs().addAll(anyTO.getPlainAttrs()); anyCR.getResources().addAll(anyTO.getResources()); + anyCR.getRelationships().addAll(anyTO.getRelationships()); if (anyCR instanceof final UserCR userCR && anyTO instanceof final UserTO userTO) { - userCR.setUsername(userTO.getUsername()); userCR.setPassword(userTO.getPassword()); userCR.setSecurityQuestion(userTO.getSecurityQuestion()); userCR.setSecurityAnswer(userTO.getSecurityAnswer()); userCR.setMustChangePassword(userTO.isMustChangePassword()); - userCR.getRelationships().addAll(userTO.getRelationships()); userCR.getMemberships().addAll(userTO.getMemberships()); userCR.getRoles().addAll(userTO.getRoles()); } else if (anyCR instanceof final GroupCR groupCR && anyTO instanceof final GroupTO groupTO) { - groupCR.setName(groupTO.getName()); groupCR.setUserOwner(groupTO.getUserOwner()); groupCR.setGroupOwner(groupTO.getGroupOwner()); @@ -88,10 +86,8 @@ public final class EntityTOUtils { groupCR.getADynMembershipConds().putAll(groupTO.getADynMembershipConds()); groupCR.getTypeExtensions().addAll(groupTO.getTypeExtensions()); } else if (anyCR instanceof final AnyObjectCR anyObjectCR && anyTO instanceof final AnyObjectTO anyObjectTO) { - anyObjectCR.setType(anyObjectTO.getType()); anyObjectCR.setName(anyObjectTO.getName()); - anyObjectCR.getRelationships().addAll(anyObjectTO.getRelationships()); anyObjectCR.getMemberships().addAll(anyObjectTO.getMemberships()); } } @@ -101,15 +97,14 @@ public final class EntityTOUtils { anyTO.getAuxClasses().addAll(anyCR.getAuxClasses()); anyTO.getPlainAttrs().addAll(anyCR.getPlainAttrs()); anyTO.getResources().addAll(anyCR.getResources()); + anyTO.getRelationships().addAll(anyCR.getRelationships()); if (anyTO instanceof final UserTO userTO && anyCR instanceof final UserCR userCR) { - userTO.setUsername(userCR.getUsername()); userTO.setPassword(userCR.getPassword()); userTO.setSecurityQuestion(userCR.getSecurityQuestion()); userTO.setSecurityAnswer(userCR.getSecurityAnswer()); userTO.setMustChangePassword(userCR.isMustChangePassword()); - userTO.getRelationships().addAll(userCR.getRelationships()); userTO.getMemberships().addAll(userCR.getMemberships()); userTO.getRoles().addAll(userCR.getRoles()); } else if (anyTO instanceof final GroupTO groupTO && anyCR instanceof final GroupCR groupCR) { @@ -121,10 +116,8 @@ public final class EntityTOUtils { groupTO.getADynMembershipConds().putAll(groupCR.getADynMembershipConds()); groupTO.getTypeExtensions().addAll(groupCR.getTypeExtensions()); } else if (anyTO instanceof final AnyObjectTO anyObjectTO && anyCR instanceof final AnyObjectCR anyObjectCR) { - anyObjectTO.setType(anyObjectCR.getType()); anyObjectTO.setName(anyObjectCR.getName()); - anyObjectTO.getRelationships().addAll(anyObjectCR.getRelationships()); anyObjectTO.getMemberships().addAll(anyObjectCR.getMemberships()); } } diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/AnyCR.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/AnyCR.java index f7d67b90ec..9c2bb11e09 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/AnyCR.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/AnyCR.java @@ -25,6 +25,7 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; import io.swagger.v3.oas.annotations.media.Schema; +import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -35,11 +36,13 @@ import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.syncope.common.lib.Attr; import org.apache.syncope.common.lib.BaseBean; import org.apache.syncope.common.lib.RealmMember; +import org.apache.syncope.common.lib.to.RelatableTO; +import org.apache.syncope.common.lib.to.RelationshipTO; @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "_class") @JsonPropertyOrder(value = { "_class" }) @Schema(subTypes = { UserCR.class, GroupCR.class, AnyObjectCR.class }, discriminatorProperty = "_class") -public abstract class AnyCR implements BaseBean, RealmMember { +public abstract class AnyCR implements BaseBean, RealmMember, RelatableTO { private static final long serialVersionUID = -1180587903919947455L; @@ -114,6 +117,24 @@ public abstract class AnyCR implements BaseBean, RealmMember { return (B) this; } + @SuppressWarnings("unchecked") + public B relationship(final RelationshipTO relationship) { + getInstance().getRelationships().add(relationship); + return (B) this; + } + + @SuppressWarnings("unchecked") + public B relationships(final RelationshipTO... relationships) { + getInstance().getRelationships().addAll(List.of(relationships)); + return (B) this; + } + + @SuppressWarnings("unchecked") + public B relationships(final Collection<RelationshipTO> relationships) { + getInstance().getRelationships().addAll(relationships); + return (B) this; + } + public R build() { return getInstance(); } @@ -131,6 +152,8 @@ public abstract class AnyCR implements BaseBean, RealmMember { private final Set<String> resources = new HashSet<>(); + private final List<RelationshipTO> relationships = new ArrayList<>(); + @Schema(name = "_class", requiredMode = Schema.RequiredMode.REQUIRED) public abstract String getDiscriminator(); @@ -186,6 +209,21 @@ public abstract class AnyCR implements BaseBean, RealmMember { return resources; } + @JsonIgnore + @Override + public Optional<RelationshipTO> getRelationship(final String type, final String otherKey) { + return relationships.stream().filter( + relationship -> type.equals(relationship.getType()) && otherKey.equals(relationship.getOtherEndKey())). + findFirst(); + } + + @JacksonXmlElementWrapper(localName = "relationships") + @JacksonXmlProperty(localName = "relationship") + @Override + public List<RelationshipTO> getRelationships() { + return relationships; + } + @Override public int hashCode() { return new HashCodeBuilder(). @@ -194,6 +232,7 @@ public abstract class AnyCR implements BaseBean, RealmMember { append(auxClasses). append(plainAttrs). append(resources). + append(relationships). build(); } @@ -215,6 +254,7 @@ public abstract class AnyCR implements BaseBean, RealmMember { append(auxClasses, other.auxClasses). append(plainAttrs, other.plainAttrs). append(resources, other.resources). + append(relationships, other.relationships). build(); } } diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/AnyObjectCR.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/AnyObjectCR.java index 701ed11b71..7925d4be76 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/AnyObjectCR.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/AnyObjectCR.java @@ -32,7 +32,6 @@ import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.syncope.common.lib.to.GroupableRelatableTO; import org.apache.syncope.common.lib.to.MembershipTO; -import org.apache.syncope.common.lib.to.RelationshipTO; @JsonPropertyOrder(value = { "_class", "name" }) @Schema(allOf = { AnyCR.class }) @@ -53,21 +52,6 @@ public class AnyObjectCR extends AnyCR implements GroupableRelatableTO { getInstance().setName(name); } - public Builder relationship(final RelationshipTO relationship) { - getInstance().getRelationships().add(relationship); - return this; - } - - public Builder relationships(final RelationshipTO... relationships) { - getInstance().getRelationships().addAll(List.of(relationships)); - return this; - } - - public Builder relationships(final Collection<RelationshipTO> relationships) { - getInstance().getRelationships().addAll(relationships); - return this; - } - public Builder membership(final MembershipTO membership) { getInstance().getMemberships().add(membership); return this; @@ -88,8 +72,6 @@ public class AnyObjectCR extends AnyCR implements GroupableRelatableTO { private String name; - private final List<RelationshipTO> relationships = new ArrayList<>(); - private final List<MembershipTO> memberships = new ArrayList<>(); @JacksonXmlProperty(localName = "_class", isAttribute = true) @@ -119,21 +101,6 @@ public class AnyObjectCR extends AnyCR implements GroupableRelatableTO { this.name = name; } - @JsonIgnore - @Override - public Optional<RelationshipTO> getRelationship(final String type, final String otherKey) { - return relationships.stream().filter( - relationship -> type.equals(relationship.getType()) && otherKey.equals(relationship.getOtherEndKey())). - findFirst(); - } - - @JacksonXmlElementWrapper(localName = "relationships") - @JacksonXmlProperty(localName = "relationship") - @Override - public List<RelationshipTO> getRelationships() { - return relationships; - } - @JsonIgnore @Override public Optional<MembershipTO> getMembership(final String groupKey) { @@ -158,7 +125,6 @@ public class AnyObjectCR extends AnyCR implements GroupableRelatableTO { return new HashCodeBuilder(). appendSuper(super.hashCode()). append(name). - append(relationships). append(memberships). build(); } @@ -178,7 +144,6 @@ public class AnyObjectCR extends AnyCR implements GroupableRelatableTO { return new EqualsBuilder(). appendSuper(super.equals(obj)). append(name, other.name). - append(relationships, other.relationships). append(memberships, other.memberships). build(); } diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/AnyObjectUR.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/AnyObjectUR.java index 6064c85847..156047c642 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/AnyObjectUR.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/AnyObjectUR.java @@ -50,21 +50,6 @@ public class AnyObjectUR extends AnyUR { return this; } - public Builder relationship(final RelationshipUR relationship) { - getInstance().getRelationships().add(relationship); - return this; - } - - public Builder relationships(final RelationshipUR... relationships) { - getInstance().getRelationships().addAll(List.of(relationships)); - return this; - } - - public Builder relationships(final Collection<RelationshipUR> relationships) { - getInstance().getRelationships().addAll(relationships); - return this; - } - public Builder membership(final MembershipUR membership) { getInstance().getMemberships().add(membership); return this; @@ -83,8 +68,6 @@ public class AnyObjectUR extends AnyUR { private StringReplacePatchItem name; - private final Set<RelationshipUR> relationships = new HashSet<>(); - private final Set<MembershipUR> memberships = new HashSet<>(); @JacksonXmlProperty(localName = "_class", isAttribute = true) @@ -104,12 +87,6 @@ public class AnyObjectUR extends AnyUR { this.name = name; } - @JacksonXmlElementWrapper(localName = "relationships") - @JacksonXmlProperty(localName = "relationship") - public Set<RelationshipUR> getRelationships() { - return relationships; - } - @JacksonXmlElementWrapper(localName = "memberships") @JacksonXmlProperty(localName = "membership") public Set<MembershipUR> getMemberships() { @@ -118,7 +95,7 @@ public class AnyObjectUR extends AnyUR { @Override public boolean isEmpty() { - return super.isEmpty() && name == null && relationships.isEmpty() && memberships.isEmpty(); + return super.isEmpty() && name == null && memberships.isEmpty(); } @Override @@ -126,7 +103,6 @@ public class AnyObjectUR extends AnyUR { return new HashCodeBuilder(). appendSuper(super.hashCode()). append(name). - append(relationships). append(memberships). build(); } @@ -146,7 +122,6 @@ public class AnyObjectUR extends AnyUR { return new EqualsBuilder(). appendSuper(super.equals(obj)). append(name, other.name). - append(relationships, other.relationships). append(memberships, other.memberships). build(); } diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/AnyUR.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/AnyUR.java index 7e2f8cbb54..e3f931077d 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/AnyUR.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/AnyUR.java @@ -118,6 +118,24 @@ public abstract class AnyUR implements BaseBean { return (B) this; } + @SuppressWarnings("unchecked") + public B relationship(final RelationshipUR relationship) { + getInstance().getRelationships().add(relationship); + return (B) this; + } + + @SuppressWarnings("unchecked") + public B relationships(final RelationshipUR... relationships) { + getInstance().getRelationships().addAll(List.of(relationships)); + return (B) this; + } + + @SuppressWarnings("unchecked") + public B relationships(final Collection<RelationshipUR> relationships) { + getInstance().getRelationships().addAll(relationships); + return (B) this; + } + public R build() { return getInstance(); } @@ -137,6 +155,8 @@ public abstract class AnyUR implements BaseBean { private final Set<StringPatchItem> resources = new HashSet<>(); + private final Set<RelationshipUR> relationships = new HashSet<>(); + @Schema(name = "_class", requiredMode = Schema.RequiredMode.REQUIRED) public abstract String getDiscriminator(); @@ -180,6 +200,12 @@ public abstract class AnyUR implements BaseBean { return resources; } + @JacksonXmlElementWrapper(localName = "relationships") + @JacksonXmlProperty(localName = "relationship") + public Set<RelationshipUR> getRelationships() { + return relationships; + } + /** * @return true if no actual changes are defined */ @@ -188,7 +214,8 @@ public abstract class AnyUR implements BaseBean { return realm == null && auxClasses.isEmpty() && plainAttrs.isEmpty() - && resources.isEmpty(); + && resources.isEmpty() + && relationships.isEmpty(); } @Override @@ -200,6 +227,7 @@ public abstract class AnyUR implements BaseBean { append(auxClasses). append(plainAttrs). append(resources). + append(relationships). build(); } @@ -222,6 +250,7 @@ public abstract class AnyUR implements BaseBean { append(auxClasses, other.auxClasses). append(plainAttrs, other.plainAttrs). append(resources, other.resources). + append(relationships, other.relationships). build(); } } diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/GroupCR.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/GroupCR.java index 9b5ddac6bb..bcf529504d 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/GroupCR.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/GroupCR.java @@ -18,7 +18,6 @@ */ package org.apache.syncope.common.lib.request; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; @@ -29,16 +28,13 @@ import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; -import org.apache.syncope.common.lib.to.RelatableTO; -import org.apache.syncope.common.lib.to.RelationshipTO; import org.apache.syncope.common.lib.to.TypeExtensionTO; @JsonPropertyOrder(value = { "_class", "name" }) @Schema(allOf = { AnyCR.class }) -public class GroupCR extends AnyCR implements RelatableTO { +public class GroupCR extends AnyCR { private static final long serialVersionUID = -4559772531167385473L; @@ -88,21 +84,6 @@ public class GroupCR extends AnyCR implements RelatableTO { getInstance().getTypeExtensions().addAll(typeExtensions); return this; } - - public Builder relationship(final RelationshipTO relationship) { - getInstance().getRelationships().add(relationship); - return this; - } - - public Builder relationships(final RelationshipTO... relationships) { - getInstance().getRelationships().addAll(List.of(relationships)); - return this; - } - - public Builder relationships(final Collection<RelationshipTO> relationships) { - getInstance().getRelationships().addAll(relationships); - return this; - } } private String name; @@ -117,8 +98,6 @@ public class GroupCR extends AnyCR implements RelatableTO { private final List<TypeExtensionTO> typeExtensions = new ArrayList<>(); - private final List<RelationshipTO> relationships = new ArrayList<>(); - @JacksonXmlProperty(localName = "_class", isAttribute = true) @JsonProperty("_class") @Schema(name = "_class", requiredMode = Schema.RequiredMode.REQUIRED, @@ -171,21 +150,6 @@ public class GroupCR extends AnyCR implements RelatableTO { return typeExtensions; } - @JsonIgnore - @Override - public Optional<RelationshipTO> getRelationship(final String type, final String otherKey) { - return relationships.stream().filter( - relationship -> type.equals(relationship.getType()) && otherKey.equals(relationship.getOtherEndKey())). - findFirst(); - } - - @JacksonXmlElementWrapper(localName = "relationships") - @JacksonXmlProperty(localName = "relationship") - @Override - public List<RelationshipTO> getRelationships() { - return relationships; - } - @Override public int hashCode() { return new HashCodeBuilder(). @@ -196,7 +160,6 @@ public class GroupCR extends AnyCR implements RelatableTO { append(udynMembershipCond). append(adynMembershipConds). append(typeExtensions). - append(relationships). build(); } @@ -220,7 +183,6 @@ public class GroupCR extends AnyCR implements RelatableTO { append(udynMembershipCond, other.udynMembershipCond). append(adynMembershipConds, other.adynMembershipConds). append(typeExtensions, other.typeExtensions). - append(relationships, other.relationships). build(); } } diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/GroupUR.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/GroupUR.java index e932c5143e..d28b933f30 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/GroupUR.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/GroupUR.java @@ -26,11 +26,9 @@ import io.swagger.v3.oas.annotations.media.Schema; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.Set; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.syncope.common.lib.to.TypeExtensionTO; @@ -109,8 +107,6 @@ public class GroupUR extends AnyUR { private final List<TypeExtensionTO> typeExtensions = new ArrayList<>(); - private final Set<RelationshipUR> relationships = new HashSet<>(); - @JacksonXmlProperty(localName = "_class", isAttribute = true) @JsonProperty("_class") @Schema(name = "_class", requiredMode = Schema.RequiredMode.REQUIRED, @@ -168,17 +164,11 @@ public class GroupUR extends AnyUR { return typeExtensions; } - @JacksonXmlElementWrapper(localName = "relationships") - @JacksonXmlProperty(localName = "relationship") - public Set<RelationshipUR> getRelationships() { - return relationships; - } - @Override public boolean isEmpty() { return super.isEmpty() && name == null && userOwner == null && groupOwner == null && udynMembershipCond == null - && adynMembershipConds.isEmpty() && typeExtensions.isEmpty() && relationships.isEmpty(); + && adynMembershipConds.isEmpty() && typeExtensions.isEmpty(); } @Override @@ -191,7 +181,6 @@ public class GroupUR extends AnyUR { append(udynMembershipCond). append(adynMembershipConds). append(typeExtensions). - append(relationships). build(); } @@ -215,7 +204,6 @@ public class GroupUR extends AnyUR { append(udynMembershipCond, other.udynMembershipCond). append(adynMembershipConds, other.adynMembershipConds). append(typeExtensions, other.typeExtensions). - append(relationships, other.relationships). build(); } } diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/UserCR.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/UserCR.java index fb141c16c6..2564fb66b5 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/UserCR.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/UserCR.java @@ -35,7 +35,6 @@ import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.syncope.common.lib.to.GroupableRelatableTO; import org.apache.syncope.common.lib.to.LinkedAccountTO; import org.apache.syncope.common.lib.to.MembershipTO; -import org.apache.syncope.common.lib.to.RelationshipTO; @JsonPropertyOrder(value = { "_class", "username" }) @Schema(allOf = { AnyCR.class }) @@ -80,21 +79,6 @@ public class UserCR extends AnyCR implements GroupableRelatableTO { return this; } - public Builder relationship(final RelationshipTO relationship) { - getInstance().getRelationships().add(relationship); - return this; - } - - public Builder relationships(final RelationshipTO... relationships) { - getInstance().getRelationships().addAll(List.of(relationships)); - return this; - } - - public Builder relationships(final Collection<RelationshipTO> relationships) { - getInstance().getRelationships().addAll(relationships); - return this; - } - public Builder membership(final MembershipTO membership) { getInstance().getMemberships().add(membership); return this; @@ -153,8 +137,6 @@ public class UserCR extends AnyCR implements GroupableRelatableTO { private boolean mustChangePassword; - private final List<RelationshipTO> relationships = new ArrayList<>(); - private final List<MembershipTO> memberships = new ArrayList<>(); private final Set<String> roles = new HashSet<>(); @@ -219,21 +201,6 @@ public class UserCR extends AnyCR implements GroupableRelatableTO { this.mustChangePassword = mustChangePassword; } - @JsonIgnore - @Override - public Optional<RelationshipTO> getRelationship(final String type, final String otherKey) { - return relationships.stream().filter( - relationship -> type.equals(relationship.getType()) && otherKey.equals(relationship.getOtherEndKey())). - findFirst(); - } - - @JacksonXmlElementWrapper(localName = "relationships") - @JacksonXmlProperty(localName = "relationship") - @Override - public List<RelationshipTO> getRelationships() { - return relationships; - } - @JsonIgnore @Override public Optional<MembershipTO> getMembership(final String groupKey) { @@ -274,7 +241,6 @@ public class UserCR extends AnyCR implements GroupableRelatableTO { append(securityQuestion). append(securityAnswer). append(mustChangePassword). - append(relationships). append(memberships). append(linkedAccounts). build(); @@ -299,7 +265,6 @@ public class UserCR extends AnyCR implements GroupableRelatableTO { append(securityQuestion, other.securityQuestion). append(securityAnswer, other.securityAnswer). append(mustChangePassword, other.mustChangePassword). - append(relationships, other.relationships). append(memberships, other.memberships). append(linkedAccounts, other.linkedAccounts). build(); diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/UserUR.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/UserUR.java index c0873e0b92..193495f103 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/UserUR.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/UserUR.java @@ -72,21 +72,6 @@ public class UserUR extends AnyUR { return this; } - public Builder relationship(final RelationshipUR relationship) { - getInstance().getRelationships().add(relationship); - return this; - } - - public Builder relationships(final RelationshipUR... relationships) { - getInstance().getRelationships().addAll(List.of(relationships)); - return this; - } - - public Builder relationships(final Collection<RelationshipUR> relationships) { - getInstance().getRelationships().addAll(relationships); - return this; - } - public Builder membership(final MembershipUR membership) { getInstance().getMemberships().add(membership); return this; @@ -128,8 +113,6 @@ public class UserUR extends AnyUR { private BooleanReplacePatchItem mustChangePassword; - private final Set<RelationshipUR> relationships = new HashSet<>(); - private final Set<MembershipUR> memberships = new HashSet<>(); private final Set<StringPatchItem> roles = new HashSet<>(); @@ -185,12 +168,6 @@ public class UserUR extends AnyUR { this.mustChangePassword = mustChangePassword; } - @JacksonXmlElementWrapper(localName = "relationships") - @JacksonXmlProperty(localName = "relationship") - public Set<RelationshipUR> getRelationships() { - return relationships; - } - @JacksonXmlElementWrapper(localName = "memberships") @JacksonXmlProperty(localName = "membership") public Set<MembershipUR> getMemberships() { @@ -213,7 +190,7 @@ public class UserUR extends AnyUR { protected boolean isEmptyNotConsideringPassword() { return super.isEmpty() && username == null && securityQuestion == null && securityAnswer == null - && mustChangePassword == null && relationships.isEmpty() && memberships.isEmpty() && roles.isEmpty() + && mustChangePassword == null && memberships.isEmpty() && roles.isEmpty() && linkedAccounts.isEmpty(); } @@ -236,7 +213,6 @@ public class UserUR extends AnyUR { append(securityQuestion). append(securityAnswer). append(mustChangePassword). - append(relationships). append(memberships). append(roles). append(linkedAccounts). @@ -261,7 +237,6 @@ public class UserUR extends AnyUR { append(securityQuestion, other.securityQuestion). append(securityAnswer, other.securityAnswer). append(mustChangePassword, other.mustChangePassword). - append(relationships, other.relationships). append(memberships, other.memberships). append(roles, other.roles). append(linkedAccounts, other.linkedAccounts). diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AnyObjectTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AnyObjectTO.java index 4975086601..39d283ebb4 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AnyObjectTO.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AnyObjectTO.java @@ -36,8 +36,6 @@ public class AnyObjectTO extends AnyTO implements GroupableRelatableTO { private String name; - private final List<RelationshipTO> relationships = new ArrayList<>(); - private final List<MembershipTO> memberships = new ArrayList<>(); private final List<MembershipTO> dynMemberships = new ArrayList<>(); @@ -59,21 +57,6 @@ public class AnyObjectTO extends AnyTO implements GroupableRelatableTO { this.name = name; } - @JsonIgnore - @Override - public Optional<RelationshipTO> getRelationship(final String type, final String otherKey) { - return relationships.stream().filter( - relationship -> type.equals(relationship.getType()) && otherKey.equals(relationship.getOtherEndKey())). - findFirst(); - } - - @JacksonXmlElementWrapper(localName = "relationships") - @JacksonXmlProperty(localName = "relationship") - @Override - public List<RelationshipTO> getRelationships() { - return relationships; - } - @JsonIgnore @Override public Optional<MembershipTO> getMembership(final String groupKey) { @@ -99,7 +82,6 @@ public class AnyObjectTO extends AnyTO implements GroupableRelatableTO { return new HashCodeBuilder(). appendSuper(super.hashCode()). append(name). - append(relationships). append(memberships). append(dynMemberships). build(); @@ -120,7 +102,6 @@ public class AnyObjectTO extends AnyTO implements GroupableRelatableTO { return new EqualsBuilder(). appendSuper(super.equals(obj)). append(name, other.name). - append(relationships, other.relationships). append(memberships, other.memberships). append(dynMemberships, other.dynMemberships). build(); diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java index 09665bc5ef..32851b2958 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java @@ -40,7 +40,7 @@ import org.apache.syncope.common.lib.RealmMember; @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "_class") @JsonPropertyOrder(value = { "_class", "key", "type", "realm", "username", "name" }) @Schema(subTypes = { UserTO.class, GroupTO.class, AnyObjectTO.class }, discriminatorProperty = "_class") -public abstract class AnyTO implements EntityTO, RealmMember { +public abstract class AnyTO implements EntityTO, RealmMember, RelatableTO { private static final long serialVersionUID = -754311920679872084L; @@ -90,6 +90,8 @@ public abstract class AnyTO implements EntityTO, RealmMember { private final Set<String> resources = new TreeSet<>(); + private final List<RelationshipTO> relationships = new ArrayList<>(); + @Schema(name = "_class", requiredMode = Schema.RequiredMode.REQUIRED) public abstract String getDiscriminator(); @@ -234,6 +236,21 @@ public abstract class AnyTO implements EntityTO, RealmMember { return resources; } + @JsonIgnore + @Override + public Optional<RelationshipTO> getRelationship(final String type, final String otherKey) { + return relationships.stream().filter( + relationship -> type.equals(relationship.getType()) && otherKey.equals(relationship.getOtherEndKey())). + findFirst(); + } + + @JacksonXmlElementWrapper(localName = "relationships") + @JacksonXmlProperty(localName = "relationship") + @Override + public List<RelationshipTO> getRelationships() { + return relationships; + } + @Override public int hashCode() { return new HashCodeBuilder(). @@ -252,6 +269,7 @@ public abstract class AnyTO implements EntityTO, RealmMember { append(plainAttrs). append(derAttrs). append(resources). + append(relationships). build(); } @@ -283,6 +301,7 @@ public abstract class AnyTO implements EntityTO, RealmMember { append(plainAttrs, other.plainAttrs). append(derAttrs, other.derAttrs). append(resources, other.resources). + append(relationships, other.relationships). build(); } } diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/GroupTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/GroupTO.java index aa33846ae4..575bf45429 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/GroupTO.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/GroupTO.java @@ -33,7 +33,7 @@ import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.syncope.common.lib.types.AnyTypeKind; @Schema(allOf = { AnyTO.class }) -public class GroupTO extends AnyTO implements RelatableTO { +public class GroupTO extends AnyTO { private static final long serialVersionUID = -7785920258290147542L; @@ -57,8 +57,6 @@ public class GroupTO extends AnyTO implements RelatableTO { private final List<TypeExtensionTO> typeExtensions = new ArrayList<>(); - private final List<RelationshipTO> relationships = new ArrayList<>(); - @JacksonXmlProperty(localName = "_class", isAttribute = true) @JsonProperty("_class") @Schema(name = "_class", requiredMode = Schema.RequiredMode.REQUIRED, @@ -159,21 +157,6 @@ public class GroupTO extends AnyTO implements RelatableTO { return typeExtensions; } - @JsonIgnore - @Override - public Optional<RelationshipTO> getRelationship(final String type, final String otherKey) { - return relationships.stream().filter( - relationship -> type.equals(relationship.getType()) && otherKey.equals(relationship.getOtherEndKey())). - findFirst(); - } - - @JacksonXmlElementWrapper(localName = "relationships") - @JacksonXmlProperty(localName = "relationship") - @Override - public List<RelationshipTO> getRelationships() { - return relationships; - } - @Override public int hashCode() { return new HashCodeBuilder(). @@ -184,7 +167,6 @@ public class GroupTO extends AnyTO implements RelatableTO { append(udynMembershipCond). append(adynMembershipConds). append(typeExtensions). - append(relationships). build(); } @@ -208,7 +190,6 @@ public class GroupTO extends AnyTO implements RelatableTO { append(udynMembershipCond, other.udynMembershipCond). append(adynMembershipConds, other.adynMembershipConds). append(typeExtensions, other.typeExtensions). - append(relationships, other.relationships). build(); } } diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java index eeedee8b4f..49460a47d8 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java @@ -58,8 +58,6 @@ public class UserTO extends AnyTO implements GroupableRelatableTO { private boolean mustChangePassword; - private final List<RelationshipTO> relationships = new ArrayList<>(); - private final List<MembershipTO> memberships = new ArrayList<>(); private final List<MembershipTO> dynMemberships = new ArrayList<>(); @@ -182,21 +180,6 @@ public class UserTO extends AnyTO implements GroupableRelatableTO { this.mustChangePassword = mustChangePassword; } - @JsonIgnore - @Override - public Optional<RelationshipTO> getRelationship(final String type, final String otherKey) { - return relationships.stream().filter( - relationship -> type.equals(relationship.getType()) && otherKey.equals(relationship.getOtherEndKey())). - findFirst(); - } - - @JacksonXmlElementWrapper(localName = "relationships") - @JacksonXmlProperty(localName = "relationship") - @Override - public List<RelationshipTO> getRelationships() { - return relationships; - } - @JsonIgnore @Override public Optional<MembershipTO> getMembership(final String groupKey) { @@ -265,7 +248,6 @@ public class UserTO extends AnyTO implements GroupableRelatableTO { append(securityAnswer). append(suspended). append(mustChangePassword). - append(relationships). append(memberships). append(dynMemberships). append(linkedAccounts). @@ -300,7 +282,6 @@ public class UserTO extends AnyTO implements GroupableRelatableTO { append(securityAnswer, other.securityAnswer). append(suspended, other.suspended). append(mustChangePassword, other.mustChangePassword). - append(relationships, other.relationships). append(memberships, other.memberships). append(dynMemberships, other.dynMemberships). append(linkedAccounts, other.linkedAccounts). diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtils.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtils.java index fd4b715b30..48350b0e39 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtils.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtils.java @@ -27,6 +27,7 @@ import org.apache.syncope.common.lib.to.AnyTO; import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.core.persistence.api.attrvalue.PlainAttrValidationManager; import org.apache.syncope.core.persistence.api.dao.AnyDAO; +import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; public interface AnyUtils { @@ -49,4 +50,8 @@ public interface AnyUtils { void addAttr(PlainAttrValidationManager validator, String key, PlainSchema schema, String value); void removeAttr(String key, PlainSchema schema); + + void addRelationship(Relatable<?, ?> relatable, RelationshipType relationshipType, AnyObject otherEnd); + + void removeRelationship(Relatable<?, ?> relatable, RelationshipType relationshipType, String otherEndKey); } diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Groupable.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Groupable.java index adf8004e21..c8f1ca01ba 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Groupable.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Groupable.java @@ -21,8 +21,9 @@ package org.apache.syncope.core.persistence.api.entity; import java.util.Collection; import java.util.List; import java.util.Optional; +import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; -public interface Groupable<L extends Any, M extends Membership<L>, R extends Any, REL extends Relationship<L, R>> +public interface Groupable<L extends Any, M extends Membership<L>, REL extends Relationship<L, AnyObject>> extends Any { /** diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Relatable.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Relatable.java index c53e66a188..d1d352db37 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Relatable.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Relatable.java @@ -21,8 +21,9 @@ package org.apache.syncope.core.persistence.api.entity; import java.util.Collection; import java.util.List; import java.util.Optional; +import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; -public interface Relatable<L extends Any, R extends Any, REL extends Relationship<L, R>> extends Any { +public interface Relatable<L extends Any, REL extends Relationship<L, AnyObject>> extends Any { boolean add(REL relationship); diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java index 44755ef89f..15ac74d51e 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java @@ -22,8 +22,8 @@ import org.apache.syncope.core.persistence.api.entity.Groupable; import org.apache.syncope.core.persistence.api.entity.Relatable; public interface AnyObject extends - Groupable<AnyObject, AMembership, AnyObject, ARelationship>, - Relatable<AnyObject, AnyObject, ARelationship> { + Groupable<AnyObject, AMembership, ARelationship>, + Relatable<AnyObject, ARelationship> { String getName(); diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/Group.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/Group.java index 993d190f5c..8911bbd51e 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/Group.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/Group.java @@ -23,11 +23,10 @@ import java.util.Optional; import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.Relatable; import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership; -import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.api.entity.user.UDynGroupMembership; import org.apache.syncope.core.persistence.api.entity.user.User; -public interface Group extends Relatable<Group, AnyObject, GRelationship> { +public interface Group extends Relatable<Group, GRelationship> { String getName(); diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java index ca74049a7a..4fe4171009 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java @@ -24,12 +24,11 @@ import java.util.Optional; import org.apache.syncope.core.persistence.api.entity.Groupable; import org.apache.syncope.core.persistence.api.entity.Relatable; import org.apache.syncope.core.persistence.api.entity.Role; -import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; public interface User extends Account, - Groupable<User, UMembership, AnyObject, URelationship>, - Relatable<User, AnyObject, URelationship> { + Groupable<User, UMembership, URelationship>, + Relatable<User, URelationship> { String getToken(); diff --git a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/dao/AbstractAnyMatchDAO.java b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/dao/AbstractAnyMatchDAO.java index eadd640bc1..c0471cd262 100644 --- a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/dao/AbstractAnyMatchDAO.java +++ b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/dao/AbstractAnyMatchDAO.java @@ -213,7 +213,7 @@ public abstract class AbstractAnyMatchDAO implements AnyMatchDAO { } protected boolean matches( - final Relatable<?, ?, ?> any, final RelationshipTypeCond cond, final boolean not) { + final Relatable<?, ?> any, final RelationshipTypeCond cond, final boolean not) { boolean found = any.getRelationships().stream(). anyMatch(rel -> rel.getType().getKey().equals(cond.getRelationshipTypeKey())); @@ -221,7 +221,7 @@ public abstract class AbstractAnyMatchDAO implements AnyMatchDAO { } protected boolean matches( - final Relatable<?, ?, ?> any, final RelationshipCond cond, final boolean not) { + final Relatable<?, ?> any, final RelationshipCond cond, final boolean not) { Set<String> candidates = SyncopeConstants.UUID_PATTERN.matcher(cond.getAnyObject()).matches() ? Set.of(cond.getAnyObject()) @@ -237,7 +237,7 @@ public abstract class AbstractAnyMatchDAO implements AnyMatchDAO { } protected boolean matches( - final Groupable<?, ?, ?, ?> any, final MembershipCond cond, final boolean not) { + final Groupable<?, ?, ?> any, final MembershipCond cond, final boolean not) { final String group = SyncopeConstants.UUID_PATTERN.matcher(cond.getGroup()).matches() ? cond.getGroup() @@ -266,7 +266,7 @@ public abstract class AbstractAnyMatchDAO implements AnyMatchDAO { protected boolean matches(final Group group, final MemberCond cond, final boolean not) { boolean found = false; - Groupable<?, ?, ?, ?> any = userDAO.findById(cond.getMember()).orElse(null); + Groupable<?, ?, ?> any = userDAO.findById(cond.getMember()).orElse(null); if (any == null) { any = anyObjectDAO.findById(cond.getMember()).orElse(null); if (any != null) { diff --git a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/entity/DefaultAnyUtils.java b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/entity/DefaultAnyUtils.java index 696980e5d3..f8f8fd53fa 100644 --- a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/entity/DefaultAnyUtils.java +++ b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/entity/DefaultAnyUtils.java @@ -18,6 +18,10 @@ */ package org.apache.syncope.core.persistence.common.entity; +import static org.apache.syncope.common.lib.types.AnyTypeKind.ANY_OBJECT; +import static org.apache.syncope.common.lib.types.AnyTypeKind.GROUP; +import static org.apache.syncope.common.lib.types.AnyTypeKind.USER; + import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.Collection; @@ -56,8 +60,13 @@ import org.apache.syncope.core.persistence.api.entity.EntityFactory; import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainSchema; +import org.apache.syncope.core.persistence.api.entity.Relatable; +import org.apache.syncope.core.persistence.api.entity.RelationshipType; +import org.apache.syncope.core.persistence.api.entity.anyobject.ARelationship; import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; +import org.apache.syncope.core.persistence.api.entity.group.GRelationship; import org.apache.syncope.core.persistence.api.entity.group.Group; +import org.apache.syncope.core.persistence.api.entity.user.URelationship; import org.apache.syncope.core.persistence.api.entity.user.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -337,4 +346,57 @@ public class DefaultAnyUtils implements AnyUtils { }, () -> LOG.warn("Any {} does not contain {} PLAIN attribute", key, schema.getKey())); } + + @Transactional + @Override + public void addRelationship( + final Relatable<?, ?> relatable, + final RelationshipType relationshipType, + final AnyObject otherEnd) { + + switch (anyTypeKind) { + case USER -> { + URelationship urelationship = entityFactory.newEntity(URelationship.class); + urelationship.setType(relationshipType); + urelationship.setRightEnd(otherEnd); + urelationship.setLeftEnd((User) relatable); + + ((User) relatable).add(urelationship); + } + + case GROUP -> { + GRelationship grelationship = entityFactory.newEntity(GRelationship.class); + grelationship.setType(relationshipType); + grelationship.setRightEnd(otherEnd); + grelationship.setLeftEnd((Group) relatable); + + ((Group) relatable).add(grelationship); + } + + case ANY_OBJECT -> { + ARelationship arelationship = entityFactory.newEntity(ARelationship.class); + arelationship.setType(relationshipType); + arelationship.setRightEnd(otherEnd); + arelationship.setLeftEnd((AnyObject) relatable); + + ((AnyObject) relatable).add(arelationship); + } + + default -> { + } + } + } + + @Transactional + @Override + public void removeRelationship( + final Relatable<?, ?> relatable, + final RelationshipType relationshipType, + final String otherEndKey) { + + relatable.getRelationship(relationshipType, otherEndKey).ifPresent(relationship -> { + relatable.getRelationships().remove(relationship); + relationship.setLeftEnd(null); + }); + } } diff --git a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/AnyValidator.java b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/AnyValidator.java index e6a841848f..63ab8b69e6 100644 --- a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/AnyValidator.java +++ b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/AnyValidator.java @@ -66,7 +66,7 @@ public class AnyValidator extends AbstractValidator<AnyCheck, Any> { return raiseNotAllowedViolation(context, plainSchema, null); } } - if (any instanceof Groupable<?, ?, ?, ?> groupableRelatable) { + if (any instanceof Groupable<?, ?, ?> groupableRelatable) { for (Membership<?> membership : groupableRelatable.getMemberships()) { for (PlainAttr attr : groupableRelatable.getPlainAttrs(membership)) { String plainSchema = Optional.ofNullable(attr).map(PlainAttr::getSchema).orElse(null); diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractGroupableRelatable.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractGroupableRelatable.java index 79008fa7eb..c6e3417a44 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractGroupableRelatable.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractGroupableRelatable.java @@ -26,13 +26,13 @@ import org.apache.syncope.core.persistence.api.entity.Groupable; import org.apache.syncope.core.persistence.api.entity.Membership; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.Relationship; +import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; public abstract class AbstractGroupableRelatable< L extends Any, M extends Membership<L>, - R extends Any, - REL extends Relationship<L, R>> - extends AbstractRelatable<L, R, REL> implements Groupable<L, M, R, REL> { + REL extends Relationship<L, AnyObject>> + extends AbstractRelatable<L, REL> implements Groupable<L, M, REL> { private static final long serialVersionUID = -2269285197388729673L; diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractRelatable.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractRelatable.java index 0f19b81a4c..ea66591fa7 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractRelatable.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractRelatable.java @@ -24,12 +24,12 @@ import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.Relatable; import org.apache.syncope.core.persistence.api.entity.Relationship; import org.apache.syncope.core.persistence.api.entity.RelationshipType; +import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; public abstract class AbstractRelatable< L extends Any, - R extends Any, - REL extends Relationship<L, R>> - extends AbstractAny implements Relatable<L, R, REL> { + REL extends Relationship<L, AnyObject>> + extends AbstractAny implements Relatable<L, REL> { private static final long serialVersionUID = -2269285197388729673L; diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java index 0a5d0e6e24..623996dbd9 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java @@ -56,7 +56,7 @@ import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource; @Cacheable @AnyObjectCheck public class JPAAnyObject - extends AbstractGroupableRelatable<AnyObject, AMembership, AnyObject, ARelationship> + extends AbstractGroupableRelatable<AnyObject, AMembership, ARelationship> implements AnyObject { private static final long serialVersionUID = 9063766472970643492L; diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java index 274071e4a1..da5cee7af7 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java @@ -45,7 +45,6 @@ import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership; -import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.api.entity.group.GRelationship; import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.api.entity.group.TypeExtension; @@ -65,7 +64,7 @@ import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser; @Cacheable @GroupCheck public class JPAGroup - extends AbstractRelatable<Group, AnyObject, GRelationship> + extends AbstractRelatable<Group, GRelationship> implements Group { private static final long serialVersionUID = -5281258853142421875L; diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java index 75c3f62868..319abbda38 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java @@ -53,7 +53,6 @@ import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.Role; -import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount; import org.apache.syncope.core.persistence.api.entity.user.SecurityQuestion; import org.apache.syncope.core.persistence.api.entity.user.UMembership; @@ -72,7 +71,7 @@ import org.apache.syncope.core.spring.security.SecureRandomUtils; @EntityListeners({ JSONUserListener.class }) @Cacheable public class JPAUser - extends AbstractGroupableRelatable<User, UMembership, AnyObject, URelationship> + extends AbstractGroupableRelatable<User, UMembership, URelationship> implements User { private static final long serialVersionUID = -3905046855521446823L; diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractGroupableRelatable.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractGroupableRelatable.java index 8fbc5d9c03..7a1f7723c4 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractGroupableRelatable.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractGroupableRelatable.java @@ -27,11 +27,14 @@ import org.apache.syncope.core.persistence.api.entity.Groupable; import org.apache.syncope.core.persistence.api.entity.Membership; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.Relationship; +import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.springframework.data.neo4j.core.schema.PostLoad; public abstract class AbstractGroupableRelatable< - L extends Any, M extends Membership<L>, R extends Any, REL extends Relationship<L, R>> - extends AbstractRelatable<L, R, REL> implements Groupable<L, M, R, REL> { + L extends Any, + M extends Membership<L>, + REL extends Relationship<L, AnyObject>> + extends AbstractRelatable<L, REL> implements Groupable<L, M, REL> { private static final long serialVersionUID = -2269285197388729673L; diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractRelatable.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractRelatable.java index 3ed17ada0b..59d48a7d4c 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractRelatable.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractRelatable.java @@ -24,12 +24,12 @@ import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.Relatable; import org.apache.syncope.core.persistence.api.entity.Relationship; import org.apache.syncope.core.persistence.api.entity.RelationshipType; +import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; public abstract class AbstractRelatable< L extends Any, - R extends Any, - REL extends Relationship<L, R>> - extends AbstractAny implements Relatable<L, R, REL> { + REL extends Relationship<L, AnyObject>> + extends AbstractAny implements Relatable<L, REL> { private static final long serialVersionUID = -2269285197388729673L; diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/Neo4jAnyObject.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/Neo4jAnyObject.java index 6890b864e6..73890ab184 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/Neo4jAnyObject.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/Neo4jAnyObject.java @@ -44,7 +44,7 @@ import org.springframework.data.neo4j.core.schema.Relationship; @AnyObjectCheck @AttributableCheck public class Neo4jAnyObject - extends AbstractGroupableRelatable<AnyObject, AMembership, AnyObject, ARelationship> + extends AbstractGroupableRelatable<AnyObject, AMembership, ARelationship> implements AnyObject { private static final long serialVersionUID = -3905046855521446823L; diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/Neo4jGroup.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/Neo4jGroup.java index 836654b39a..ae89c503c0 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/Neo4jGroup.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/Neo4jGroup.java @@ -31,7 +31,6 @@ import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership; -import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.api.entity.group.GRelationship; import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.api.entity.group.TypeExtension; @@ -53,7 +52,7 @@ import org.springframework.data.neo4j.core.schema.Relationship; @GroupCheck @AttributableCheck public class Neo4jGroup - extends AbstractRelatable<Group, AnyObject, GRelationship> + extends AbstractRelatable<Group, GRelationship> implements Group { private static final long serialVersionUID = -5281258853142421875L; diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jUser.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jUser.java index 390fdb3d62..d1cebb24e2 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jUser.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jUser.java @@ -37,7 +37,6 @@ import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.Role; -import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount; import org.apache.syncope.core.persistence.api.entity.user.SecurityQuestion; import org.apache.syncope.core.persistence.api.entity.user.UMembership; @@ -58,7 +57,7 @@ import org.springframework.data.neo4j.core.schema.Relationship; @Node(Neo4jUser.NODE) @AttributableCheck public class Neo4jUser - extends AbstractGroupableRelatable<User, UMembership, AnyObject, URelationship> + extends AbstractGroupableRelatable<User, UMembership, URelationship> implements User { private static final long serialVersionUID = -3905046855521446823L; diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/DerAttrHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/DerAttrHandler.java index b4a6661993..f9863946a9 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/DerAttrHandler.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/DerAttrHandler.java @@ -79,5 +79,5 @@ public interface DerAttrHandler { * @param membership membership * @return derived attribute values */ - Map<DerSchema, String> getValues(Groupable<?, ?, ?, ?> any, Membership<?> membership); + Map<DerSchema, String> getValues(Groupable<?, ?, ?> any, Membership<?> membership); } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultDerAttrHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultDerAttrHandler.java index 3233e6abe2..3741da47da 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultDerAttrHandler.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultDerAttrHandler.java @@ -116,7 +116,7 @@ public class DefaultDerAttrHandler implements DerAttrHandler { } protected static Map<DerSchema, String> getValues( - final Groupable<?, ?, ?, ?> any, final Membership<?> membership, final Set<DerSchema> schemas) { + final Groupable<?, ?, ?> any, final Membership<?> membership, final Set<DerSchema> schemas) { Map<DerSchema, String> result = new HashMap<>(schemas.size()); @@ -132,7 +132,7 @@ public class DefaultDerAttrHandler implements DerAttrHandler { } @Override - public Map<DerSchema, String> getValues(final Groupable<?, ?, ?, ?> any, final Membership<?> membership) { + public Map<DerSchema, String> getValues(final Groupable<?, ?, ?> any, final Membership<?> membership) { return getValues( any, membership, diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java index ef2649382b..9964916f28 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java @@ -704,7 +704,7 @@ public class DefaultMappingManager implements MappingManager { } else { references.add(user); } - } else if (intAttrName.getRelatedAnyObject() != null && any instanceof Relatable<?, ?, ?> relatable) { + } else if (intAttrName.getRelatedAnyObject() != null && any instanceof Relatable<?, ?> relatable) { AnyObject anyObject = anyObjectDAO.findById(intAttrName.getRelatedAnyObject()).orElse(null); if (anyObject == null || relatable.getRelationships(anyObject.getKey()).isEmpty()) { LOG.warn("No relationship for {} in {}, ignoring", intAttrName.getRelatedAnyObject(), relatable); @@ -712,7 +712,7 @@ public class DefaultMappingManager implements MappingManager { references.add(anyObject); } } else if (intAttrName.getRelationshipAnyType() != null && intAttrName.getRelationshipType() != null - && any instanceof Relatable<?, ?, ?> relatable) { + && any instanceof Relatable<?, ?> relatable) { RelationshipType relationshipType = relationshipTypeDAO.findById( intAttrName.getRelationshipType()).orElse(null); @@ -727,7 +727,7 @@ public class DefaultMappingManager implements MappingManager { map(Relationship::getRightEnd). toList()); } - } else if (intAttrName.getMembershipOfGroup() != null && any instanceof Groupable<?, ?, ?, ?> groupable) { + } else if (intAttrName.getMembershipOfGroup() != null && any instanceof Groupable<?, ?, ?> groupable) { membership = groupDAO.findByName(intAttrName.getMembershipOfGroup()). flatMap(group -> groupable.getMembership(group.getKey())). orElse(null); @@ -829,7 +829,7 @@ public class DefaultMappingManager implements MappingManager { case PLAIN -> { PlainAttr attr = membership == null ? plainAttrGetter.apply(ref, intAttrName.getSchema().getKey()) - : ((Groupable<?, ?, ?, ?>) ref).getPlainAttr( + : ((Groupable<?, ?, ?>) ref).getPlainAttr( intAttrName.getSchema().getKey(), membership).orElse(null); if (attr != null) { if (attr.getUniqueValue() != null) { diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyDataBinder.java index 1ddf57dcef..cc3df75852 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyDataBinder.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyDataBinder.java @@ -22,6 +22,7 @@ import java.text.ParseException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; @@ -35,12 +36,14 @@ import org.apache.syncope.common.lib.SyncopeClientException; import org.apache.syncope.common.lib.request.AnyCR; import org.apache.syncope.common.lib.request.AnyUR; import org.apache.syncope.common.lib.request.AttrPatch; +import org.apache.syncope.common.lib.request.RelationshipUR; import org.apache.syncope.common.lib.request.StringPatchItem; import org.apache.syncope.common.lib.to.AnyTO; import org.apache.syncope.common.lib.to.ConnObject; import org.apache.syncope.common.lib.to.MembershipTO; import org.apache.syncope.common.lib.to.Provision; import org.apache.syncope.common.lib.to.RelationshipTO; +import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.lib.types.AttrSchemaType; import org.apache.syncope.common.lib.types.ClientExceptionType; import org.apache.syncope.common.lib.types.PatchOperation; @@ -57,6 +60,7 @@ import org.apache.syncope.core.persistence.api.dao.RealmSearchDAO; import org.apache.syncope.core.persistence.api.dao.RelationshipTypeDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; import org.apache.syncope.core.persistence.api.entity.Any; +import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.AnyUtils; import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; @@ -68,6 +72,8 @@ import org.apache.syncope.core.persistence.api.entity.Membership; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; import org.apache.syncope.core.persistence.api.entity.PlainSchema; +import org.apache.syncope.core.persistence.api.entity.Relatable; +import org.apache.syncope.core.persistence.api.entity.RelationshipType; import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.api.entity.user.User; @@ -305,7 +311,7 @@ abstract class AnyDataBinder extends AttributableDataBinder { AllowedSchemas<PlainSchema> allowedPlainSchemas = anyUtils.dao().findAllowedSchemas(any, PlainSchema.class); allowedPlainSchemas.getForSelf().forEach(schema -> checkMandatory( schema, any.getPlainAttr(schema.getKey()).orElse(null), any, reqValMissing)); - if (any instanceof Groupable<?, ?, ?, ?> groupable) { + if (any instanceof Groupable<?, ?, ?> groupable) { allowedPlainSchemas.getForMemberships().forEach((group, schemas) -> { Membership<?> membership = groupable.getMembership(group.getKey()).orElse(null); schemas.forEach(schema -> checkMandatory( @@ -443,6 +449,61 @@ abstract class AnyDataBinder extends AttributableDataBinder { if (!reqValMissing.isEmpty()) { scce.addException(reqValMissing); } + + // relationships + Set<Pair<String, String>> relationships = new HashSet<>(); + for (RelationshipUR patch : anyUR.getRelationships().stream(). + filter(patch -> patch.getRelationshipTO() != null).toList()) { + + RelationshipType relationshipType = relationshipTypeDAO.findById(patch.getRelationshipTO().getType()). + orElse(null); + if (relationshipType == null) { + LOG.debug("Ignoring invalid relationship type {}", patch.getRelationshipTO().getType()); + } else { + anyUtils.removeRelationship( + (Relatable<?, ?>) any, + relationshipType, + patch.getRelationshipTO().getOtherEndKey()); + + if (patch.getOperation() == PatchOperation.ADD_REPLACE) { + if (StringUtils.isBlank(patch.getRelationshipTO().getOtherEndType()) + || AnyTypeKind.USER.name().equals(patch.getRelationshipTO().getOtherEndType()) + || AnyTypeKind.GROUP.name().equals(patch.getRelationshipTO().getOtherEndType())) { + + SyncopeClientException invalidAnyType = + SyncopeClientException.build(ClientExceptionType.InvalidAnyType); + invalidAnyType.getElements().add(AnyType.class.getSimpleName() + + " not allowed for relationship: " + patch.getRelationshipTO().getOtherEndType()); + scce.addException(invalidAnyType); + } else { + AnyObject otherEnd = anyObjectDAO.findById(patch.getRelationshipTO().getOtherEndKey()). + orElse(null); + if (otherEnd == null) { + LOG.debug("Ignoring invalid any object {}", patch.getRelationshipTO().getOtherEndKey()); + } else if (relationships.contains( + Pair.of(otherEnd.getKey(), patch.getRelationshipTO().getType()))) { + + SyncopeClientException assigned = + SyncopeClientException.build(ClientExceptionType.InvalidRelationship); + assigned.getElements().add("Group was already in relationship " + + patch.getRelationshipTO().getType() + " with " + + otherEnd.getType().getKey() + " " + otherEnd.getName()); + scce.addException(assigned); + } else if (patch.getRelationshipTO().getEnd() == RelationshipTO.End.RIGHT) { + SyncopeClientException noRight = + SyncopeClientException.build(ClientExceptionType.InvalidRelationship); + noRight.getElements().add( + "Relationships shall be created or updated only from their left end"); + scce.addException(noRight); + } else { + relationships.add(Pair.of(otherEnd.getKey(), patch.getRelationshipTO().getType())); + + anyUtils.addRelationship((Relatable<?, ?>) any, relationshipType, otherEnd); + } + } + } + } + } } protected PropagationByResource<String> propByRes( @@ -528,6 +589,44 @@ abstract class AnyDataBinder extends AttributableDataBinder { if (!requiredValuesMissing.isEmpty()) { scce.addException(requiredValuesMissing); } + + // 3. relationships + Set<Pair<String, String>> relationships = new HashSet<>(); + anyCR.getRelationships().forEach(relationshipTO -> { + if (StringUtils.isBlank(relationshipTO.getOtherEndType()) + || AnyTypeKind.USER.name().equals(relationshipTO.getOtherEndType()) + || AnyTypeKind.GROUP.name().equals(relationshipTO.getOtherEndType())) { + + SyncopeClientException invalidAnyType = + SyncopeClientException.build(ClientExceptionType.InvalidAnyType); + invalidAnyType.getElements().add(AnyType.class.getSimpleName() + + " not allowed for relationship: " + relationshipTO.getOtherEndType()); + scce.addException(invalidAnyType); + } else { + AnyObject otherEnd = anyObjectDAO.findById(relationshipTO.getOtherEndKey()).orElse(null); + if (otherEnd == null) { + LOG.debug("Ignoring invalid anyObject {}", relationshipTO.getOtherEndKey()); + } else if (relationshipTO.getEnd() == RelationshipTO.End.RIGHT) { + SyncopeClientException noRight = + SyncopeClientException.build(ClientExceptionType.InvalidRelationship); + noRight.getElements().add( + "Relationships shall be created or updated only from their left end"); + scce.addException(noRight); + } else if (relationships.contains(Pair.of(otherEnd.getKey(), relationshipTO.getType()))) { + SyncopeClientException assigned = + SyncopeClientException.build(ClientExceptionType.InvalidRelationship); + assigned.getElements().add(otherEnd.getType().getKey() + " " + otherEnd.getName() + + " in relationship " + relationshipTO.getType()); + scce.addException(assigned); + } else { + relationships.add(Pair.of(otherEnd.getKey(), relationshipTO.getType())); + + relationshipTypeDAO.findById(relationshipTO.getType()).ifPresentOrElse( + rt -> anyUtils.addRelationship((Relatable<?, ?>) any, rt, otherEnd), + () -> LOG.debug("Ignoring invalid relationship type {}", relationshipTO.getType())); + } + } + }); } protected void fill( @@ -543,7 +642,7 @@ abstract class AnyDataBinder extends AttributableDataBinder { filter(attrTO -> !attrTO.getValues().isEmpty()). forEach(attrTO -> getPlainSchema(attrTO.getSchema()).ifPresent(schema -> { - PlainAttr attr = ((Groupable<?, ?, ?, ?>) any).getPlainAttr(schema.getKey(), membership).orElseGet(() -> { + PlainAttr attr = ((Groupable<?, ?, ?>) any).getPlainAttr(schema.getKey(), membership).orElseGet(() -> { PlainAttr gpa = new PlainAttr(); gpa.setMembership(membership.getKey()); gpa.setPlainSchema(schema); diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java index d9e0056209..bec1013f37 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java @@ -22,7 +22,6 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.Pair; import org.apache.syncope.common.lib.AnyOperations; import org.apache.syncope.common.lib.EntityTOUtils; import org.apache.syncope.common.lib.SyncopeClientCompositeException; @@ -55,9 +54,7 @@ import org.apache.syncope.core.persistence.api.entity.EntityFactory; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.Realm; -import org.apache.syncope.core.persistence.api.entity.RelationshipType; import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership; -import org.apache.syncope.core.persistence.api.entity.anyobject.ARelationship; import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.provisioning.api.DerAttrHandler; @@ -205,51 +202,8 @@ public class AnyObjectDataBinderImpl extends AnyDataBinder implements AnyObjectD } anyObject.setRealm(realm); - // relationships - Set<Pair<String, String>> relationships = new HashSet<>(); - anyObjectCR.getRelationships().forEach(relationshipTO -> { - if (StringUtils.isBlank(relationshipTO.getOtherEndType()) - || AnyTypeKind.USER.name().equals(relationshipTO.getOtherEndType()) - || AnyTypeKind.GROUP.name().equals(relationshipTO.getOtherEndType())) { - - SyncopeClientException invalidAnyType = - SyncopeClientException.build(ClientExceptionType.InvalidAnyType); - invalidAnyType.getElements().add(AnyType.class.getSimpleName() - + " not allowed for relationship: " + relationshipTO.getOtherEndType()); - scce.addException(invalidAnyType); - } else { - AnyObject otherEnd = anyObjectDAO.findById(relationshipTO.getOtherEndKey()).orElse(null); - if (otherEnd == null) { - LOG.debug("Ignoring invalid anyObject {}", relationshipTO.getOtherEndKey()); - } else if (relationshipTO.getEnd() == RelationshipTO.End.RIGHT) { - SyncopeClientException noRight = - SyncopeClientException.build(ClientExceptionType.InvalidRelationship); - noRight.getElements().add( - "Relationships shall be created or updated only from their left end"); - scce.addException(noRight); - } else if (relationships.contains(Pair.of(otherEnd.getKey(), relationshipTO.getType()))) { - SyncopeClientException assigned = - SyncopeClientException.build(ClientExceptionType.InvalidRelationship); - assigned.getElements().add("AnyObject was already in relationship " - + relationshipTO.getType() + " with " - + otherEnd.getType().getKey() + " " + otherEnd.getName()); - scce.addException(assigned); - } else { - relationships.add(Pair.of(otherEnd.getKey(), relationshipTO.getType())); - - relationshipTypeDAO.findById(relationshipTO.getType()).ifPresentOrElse( - relationshipType -> { - ARelationship relationship = entityFactory.newEntity(ARelationship.class); - relationship.setType(relationshipType); - relationship.setRightEnd(otherEnd); - relationship.setLeftEnd(anyObject); - - anyObject.add(relationship); - }, - () -> LOG.debug("Ignoring invalid relationship type {}", relationshipTO.getType())); - } - } - }); + // attributes, resources and relationships + fill(anyTO, anyObject, anyObjectCR, anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT), scce); // memberships Set<String> groups = new HashSet<>(); @@ -280,9 +234,6 @@ public class AnyObjectDataBinderImpl extends AnyDataBinder implements AnyObjectD } }); - // attributes and resources - fill(anyTO, anyObject, anyObjectCR, anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT), scce); - // Throw composite exception if there is at least one element set in the composing exceptions if (scce.hasExceptions()) { throw scce; @@ -314,70 +265,9 @@ public class AnyObjectDataBinderImpl extends AnyDataBinder implements AnyObjectD anyObject.setName(anyObjectUR.getName().getValue()); } - // attributes and resources + // attributes, resources and relationships fill(anyTO, anyObject, anyObjectUR, anyUtils, scce); - // relationships - Set<Pair<String, String>> relationships = new HashSet<>(); - anyObjectUR.getRelationships().stream(). - filter(patch -> patch.getRelationshipTO() != null).forEach(patch -> { - - RelationshipType relationshipType = relationshipTypeDAO.findById( - patch.getRelationshipTO().getType()).orElse(null); - if (relationshipType == null) { - LOG.debug("Ignoring invalid relationship type {}", patch.getRelationshipTO().getType()); - } else { - anyObject.getRelationship(relationshipType, patch.getRelationshipTO().getOtherEndKey()). - ifPresent(relationship -> { - anyObject.getRelationships().remove(relationship); - relationship.setLeftEnd(null); - }); - - if (patch.getOperation() == PatchOperation.ADD_REPLACE) { - if (StringUtils.isBlank(patch.getRelationshipTO().getOtherEndType()) - || AnyTypeKind.USER.name().equals(patch.getRelationshipTO().getOtherEndType()) - || AnyTypeKind.GROUP.name().equals(patch.getRelationshipTO().getOtherEndType())) { - - SyncopeClientException invalidAnyType = - SyncopeClientException.build(ClientExceptionType.InvalidAnyType); - invalidAnyType.getElements().add(AnyType.class.getSimpleName() - + " not allowed for relationship: " + patch.getRelationshipTO().getOtherEndType()); - scce.addException(invalidAnyType); - } else { - AnyObject otherEnd = anyObjectDAO.findById(patch.getRelationshipTO().getOtherEndKey()). - orElse(null); - if (otherEnd == null) { - LOG.debug("Ignoring invalid any object {}", patch.getRelationshipTO().getOtherEndKey()); - } else if (patch.getRelationshipTO().getEnd() == RelationshipTO.End.RIGHT) { - SyncopeClientException noRight = - SyncopeClientException.build(ClientExceptionType.InvalidRelationship); - noRight.getElements().add( - "Relationships shall be created or updated only from their left end"); - scce.addException(noRight); - } else if (relationships.contains( - Pair.of(otherEnd.getKey(), patch.getRelationshipTO().getType()))) { - - SyncopeClientException assigned = - SyncopeClientException.build(ClientExceptionType.InvalidRelationship); - assigned.getElements().add("AnyObject was already in relationship " - + patch.getRelationshipTO().getType() + " with " - + otherEnd.getType().getKey() + " " + otherEnd.getName()); - scce.addException(assigned); - } else { - relationships.add(Pair.of(otherEnd.getKey(), patch.getRelationshipTO().getType())); - - ARelationship newRelationship = entityFactory.newEntity(ARelationship.class); - newRelationship.setType(relationshipType); - newRelationship.setRightEnd(otherEnd); - newRelationship.setLeftEnd(anyObject); - - anyObject.add(newRelationship); - } - } - } - } - }); - SyncopeClientException invalidValues = SyncopeClientException.build(ClientExceptionType.InvalidValues); // memberships diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java index 9ede39b550..e8508c4e6e 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java @@ -19,27 +19,23 @@ package org.apache.syncope.core.provisioning.java.data; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Optional; import java.util.Set; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.Pair; import org.apache.syncope.common.lib.AnyOperations; import org.apache.syncope.common.lib.EntityTOUtils; import org.apache.syncope.common.lib.SyncopeClientCompositeException; import org.apache.syncope.common.lib.SyncopeClientException; import org.apache.syncope.common.lib.request.GroupCR; import org.apache.syncope.common.lib.request.GroupUR; -import org.apache.syncope.common.lib.request.RelationshipUR; import org.apache.syncope.common.lib.to.ConnObject; import org.apache.syncope.common.lib.to.GroupTO; import org.apache.syncope.common.lib.to.RelationshipTO; import org.apache.syncope.common.lib.to.TypeExtensionTO; import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.lib.types.ClientExceptionType; -import org.apache.syncope.common.lib.types.PatchOperation; import org.apache.syncope.common.lib.types.ResourceOperation; import org.apache.syncope.core.persistence.api.attrvalue.PlainAttrValidationManager; import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; @@ -59,10 +55,7 @@ import org.apache.syncope.core.persistence.api.entity.DynGroupMembership; import org.apache.syncope.core.persistence.api.entity.EntityFactory; import org.apache.syncope.core.persistence.api.entity.Groupable; import org.apache.syncope.core.persistence.api.entity.Realm; -import org.apache.syncope.core.persistence.api.entity.RelationshipType; import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership; -import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; -import org.apache.syncope.core.persistence.api.entity.group.GRelationship; import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.api.entity.group.TypeExtension; import org.apache.syncope.core.persistence.api.entity.user.UDynGroupMembership; @@ -179,7 +172,7 @@ public class GroupDataBinderImpl extends AnyDataBinder implements GroupDataBinde } group.setRealm(realm); - // attributes and resources + // attributes, resources and relationships fill(anyTO, group, groupCR, anyUtilsFactory.getInstance(AnyTypeKind.GROUP), scce); // owner @@ -221,46 +214,6 @@ public class GroupDataBinderImpl extends AnyDataBinder implements GroupDataBinde }, () -> LOG.warn("Ignoring invalid {}: {}", AnyType.class.getSimpleName(), typeExtTO.getAnyType()))); - // relationships - Set<Pair<String, String>> relationships = new HashSet<>(); - groupCR.getRelationships().forEach(relationshipTO -> { - AnyObject otherEnd = anyObjectDAO.findById(relationshipTO.getOtherEndKey()).orElse(null); - if (otherEnd == null) { - LOG.debug("Ignoring invalid anyObject {}", relationshipTO.getOtherEndKey()); - } else if (relationshipTO.getEnd() == RelationshipTO.End.RIGHT) { - SyncopeClientException noRight = - SyncopeClientException.build(ClientExceptionType.InvalidRelationship); - noRight.getElements().add( - "Relationships shall be created or updated only from their left end"); - scce.addException(noRight); - } else if (relationships.contains(Pair.of(otherEnd.getKey(), relationshipTO.getType()))) { - SyncopeClientException assigned = - SyncopeClientException.build(ClientExceptionType.InvalidRelationship); - assigned.getElements().add(otherEnd.getType().getKey() + " " + otherEnd.getName() - + " in relationship " + relationshipTO.getType()); - scce.addException(assigned); - } else if (group.getRealm().getFullPath().startsWith(otherEnd.getRealm().getFullPath())) { - relationships.add(Pair.of(otherEnd.getKey(), relationshipTO.getType())); - - relationshipTypeDAO.findById(relationshipTO.getType()).ifPresentOrElse( - relationshipType -> { - GRelationship relationship = entityFactory.newEntity(GRelationship.class); - relationship.setType(relationshipType); - relationship.setRightEnd(otherEnd); - relationship.setLeftEnd(group); - - group.add(relationship); - }, - () -> LOG.debug("Ignoring invalid relationship type {}", relationshipTO.getType())); - } else { - SyncopeClientException unrelatable = - SyncopeClientException.build(ClientExceptionType.InvalidRelationship); - unrelatable.getElements().add(otherEnd.getType().getKey() + " " + otherEnd.getName() - + " cannot be related"); - scce.addException(unrelatable); - } - }); - // Throw composite exception if there is at least one element set in the composing exceptions if (scce.hasExceptions()) { throw scce; @@ -327,7 +280,7 @@ public class GroupDataBinderImpl extends AnyDataBinder implements GroupDataBinde } } - // attributes and resources + // attributes, resources and relationships fill(anyTO, group, groupUR, anyUtilsFactory.getInstance(AnyTypeKind.GROUP), scce); group = groupDAO.save(group); @@ -397,64 +350,6 @@ public class GroupDataBinderImpl extends AnyDataBinder implements GroupDataBinde group.getTypeExtensions(). removeIf(typeExt -> groupUR.getTypeExtension(typeExt.getAnyType().getKey()).isEmpty()); - // relationships - Set<Pair<String, String>> relationships = new HashSet<>(); - for (RelationshipUR patch : groupUR.getRelationships().stream(). - filter(patch -> patch.getRelationshipTO() != null).toList()) { - - RelationshipType relationshipType = relationshipTypeDAO.findById(patch.getRelationshipTO().getType()). - orElse(null); - if (relationshipType == null) { - LOG.debug("Ignoring invalid relationship type {}", patch.getRelationshipTO().getType()); - } else { - GRelationship relationship = group.getRelationship( - relationshipType, patch.getRelationshipTO().getOtherEndKey()).orElse(null); - if (relationship != null) { - group.getRelationships().remove(relationship); - relationship.setLeftEnd(null); - } - - if (patch.getOperation() == PatchOperation.ADD_REPLACE) { - AnyObject otherEnd = anyObjectDAO.findById(patch.getRelationshipTO().getOtherEndKey()).orElse(null); - if (otherEnd == null) { - LOG.debug("Ignoring invalid any object {}", patch.getRelationshipTO().getOtherEndKey()); - } else if (relationships.contains( - Pair.of(otherEnd.getKey(), patch.getRelationshipTO().getType()))) { - - SyncopeClientException assigned = - SyncopeClientException.build(ClientExceptionType.InvalidRelationship); - assigned.getElements().add("Group was already in relationship " - + patch.getRelationshipTO().getType() + " with " - + otherEnd.getType().getKey() + " " + otherEnd.getName()); - scce.addException(assigned); - } else if (patch.getRelationshipTO().getEnd() == RelationshipTO.End.RIGHT) { - SyncopeClientException noRight = - SyncopeClientException.build(ClientExceptionType.InvalidRelationship); - noRight.getElements().add( - "Relationships shall be created or updated only from their left end"); - scce.addException(noRight); - } else if (group.getRealm().getFullPath().startsWith(otherEnd.getRealm().getFullPath())) { - relationships.add(Pair.of(otherEnd.getKey(), patch.getRelationshipTO().getType())); - - GRelationship newRelationship = entityFactory.newEntity(GRelationship.class); - newRelationship.setType(relationshipType); - newRelationship.setRightEnd(otherEnd); - newRelationship.setLeftEnd(group); - - group.add(newRelationship); - } else { - LOG.error("{} cannot be related to {}", otherEnd, group); - - SyncopeClientException unrelatable = - SyncopeClientException.build(ClientExceptionType.InvalidRelationship); - unrelatable.getElements().add(otherEnd.getType().getKey() + " " + otherEnd.getName() - + " cannot be related"); - scce.addException(unrelatable); - } - } - } - } - // Throw composite exception if there is at least one element set in the composing exceptions if (scce.hasExceptions()) { throw scce; @@ -541,7 +436,7 @@ public class GroupDataBinderImpl extends AnyDataBinder implements GroupDataBinde protected static void populateTransitiveResources( final Group group, - final Groupable<?, ?, ?, ?> any, + final Groupable<?, ?, ?> any, final Map<String, PropagationByResource<String>> result) { PropagationByResource<String> propByRes = new PropagationByResource<>(); diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java index f182ab4c39..c44800dd06 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java @@ -72,14 +72,11 @@ import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.Realm; -import org.apache.syncope.core.persistence.api.entity.RelationshipType; import org.apache.syncope.core.persistence.api.entity.Role; -import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount; import org.apache.syncope.core.persistence.api.entity.user.SecurityQuestion; import org.apache.syncope.core.persistence.api.entity.user.UMembership; -import org.apache.syncope.core.persistence.api.entity.user.URelationship; import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.provisioning.api.DerAttrHandler; import org.apache.syncope.core.provisioning.api.IntAttrNameParser; @@ -313,45 +310,8 @@ public class UserDataBinderImpl extends AnyDataBinder implements UserDataBinder } user.setRealm(realm); - // relationships - Set<Pair<String, String>> relationships = new HashSet<>(); - userCR.getRelationships().forEach(relationshipTO -> { - AnyObject otherEnd = anyObjectDAO.findById(relationshipTO.getOtherEndKey()).orElse(null); - if (otherEnd == null) { - LOG.debug("Ignoring invalid anyObject {}", relationshipTO.getOtherEndKey()); - } else if (relationshipTO.getEnd() == RelationshipTO.End.RIGHT) { - SyncopeClientException noRight = - SyncopeClientException.build(ClientExceptionType.InvalidRelationship); - noRight.getElements().add( - "Relationships shall be created or updated only from their left end"); - scce.addException(noRight); - } else if (relationships.contains(Pair.of(otherEnd.getKey(), relationshipTO.getType()))) { - SyncopeClientException assigned = - SyncopeClientException.build(ClientExceptionType.InvalidRelationship); - assigned.getElements().add(otherEnd.getType().getKey() + " " + otherEnd.getName() - + " in relationship " + relationshipTO.getType()); - scce.addException(assigned); - } else if (user.getRealm().getFullPath().startsWith(otherEnd.getRealm().getFullPath())) { - relationships.add(Pair.of(otherEnd.getKey(), relationshipTO.getType())); - - relationshipTypeDAO.findById(relationshipTO.getType()).ifPresentOrElse( - relationshipType -> { - URelationship relationship = entityFactory.newEntity(URelationship.class); - relationship.setType(relationshipType); - relationship.setRightEnd(otherEnd); - relationship.setLeftEnd(user); - - user.add(relationship); - }, - () -> LOG.debug("Ignoring invalid relationship type {}", relationshipTO.getType())); - } else { - SyncopeClientException unrelatable = - SyncopeClientException.build(ClientExceptionType.InvalidRelationship); - unrelatable.getElements().add(otherEnd.getType().getKey() + " " + otherEnd.getName() - + " cannot be related"); - scce.addException(unrelatable); - } - }); + // attributes, resources and relationships + fill(anyTO, user, userCR, anyUtilsFactory.getInstance(AnyTypeKind.USER), scce); // memberships Set<String> groups = new HashSet<>(); @@ -390,9 +350,6 @@ public class UserDataBinderImpl extends AnyDataBinder implements UserDataBinder scce.addException(invalidValues); } - // attributes and resources - fill(anyTO, user, userCR, anyUtilsFactory.getInstance(AnyTypeKind.USER), scce); - // Throw composite exception if there is at least one element set in the composing exceptions if (scce.hasExceptions()) { throw scce; @@ -498,64 +455,9 @@ public class UserDataBinderImpl extends AnyDataBinder implements UserDataBinder () -> LOG.warn("Ignoring unknown role with key {}", patch.getValue())); } - // attributes and resources + // attributes, resources and relationships fill(anyTO, user, userUR, anyUtils, scce); - // relationships - Set<Pair<String, String>> relationships = new HashSet<>(); - userUR.getRelationships().stream().filter(patch -> patch.getRelationshipTO() != null).forEach(patch -> { - RelationshipType relationshipType = relationshipTypeDAO.findById(patch.getRelationshipTO().getType()). - orElse(null); - if (relationshipType == null) { - LOG.debug("Ignoring invalid relationship type {}", patch.getRelationshipTO().getType()); - } else { - user.getRelationship(relationshipType, patch.getRelationshipTO().getOtherEndKey()). - ifPresent(relationship -> { - user.getRelationships().remove(relationship); - relationship.setLeftEnd(null); - }); - - if (patch.getOperation() == PatchOperation.ADD_REPLACE) { - AnyObject otherEnd = anyObjectDAO.findById(patch.getRelationshipTO().getOtherEndKey()).orElse(null); - if (otherEnd == null) { - LOG.debug("Ignoring invalid any object {}", patch.getRelationshipTO().getOtherEndKey()); - } else if (relationships.contains( - Pair.of(otherEnd.getKey(), patch.getRelationshipTO().getType()))) { - - SyncopeClientException assigned = - SyncopeClientException.build(ClientExceptionType.InvalidRelationship); - assigned.getElements().add("User was already in relationship " - + patch.getRelationshipTO().getType() + " with " - + otherEnd.getType().getKey() + " " + otherEnd.getName()); - scce.addException(assigned); - } else if (patch.getRelationshipTO().getEnd() == RelationshipTO.End.RIGHT) { - SyncopeClientException noRight = - SyncopeClientException.build(ClientExceptionType.InvalidRelationship); - noRight.getElements().add( - "Relationships shall be created or updated only from their left end"); - scce.addException(noRight); - } else if (user.getRealm().getFullPath().startsWith(otherEnd.getRealm().getFullPath())) { - relationships.add(Pair.of(otherEnd.getKey(), patch.getRelationshipTO().getType())); - - URelationship newRelationship = entityFactory.newEntity(URelationship.class); - newRelationship.setType(relationshipType); - newRelationship.setRightEnd(otherEnd); - newRelationship.setLeftEnd(user); - - user.add(newRelationship); - } else { - LOG.error("{} cannot be related to {}", otherEnd, user); - - SyncopeClientException unrelatable = - SyncopeClientException.build(ClientExceptionType.InvalidRelationship); - unrelatable.getElements().add(otherEnd.getType().getKey() + " " + otherEnd.getName() - + " cannot be related"); - scce.addException(unrelatable); - } - } - } - }); - SyncopeClientException invalidValues = SyncopeClientException.build(ClientExceptionType.InvalidValues); // memberships diff --git a/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchUtils.java b/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchUtils.java index 68ad03f96e..ac667c3875 100644 --- a/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchUtils.java +++ b/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchUtils.java @@ -196,7 +196,7 @@ public class ElasticsearchUtils { } // add also flattened membership attributes - if (any instanceof Groupable<?, ?, ?, ?> groupable) { + if (any instanceof Groupable<?, ?, ?> groupable) { groupable.getMemberships().forEach(m -> groupable.getPlainAttrs(m).forEach(mAttr -> { List<Object> values = mAttr.getValues().stream(). map(PlainAttrValue::getValue).collect(Collectors.toList()); diff --git a/ext/openfga/client-openfga/src/main/java/org/apache/syncope/ext/openfga/client/OpenFGAStoreManager.java b/ext/openfga/client-openfga/src/main/java/org/apache/syncope/ext/openfga/client/OpenFGAStoreManager.java index c856624fd9..7c3319ad0b 100644 --- a/ext/openfga/client-openfga/src/main/java/org/apache/syncope/ext/openfga/client/OpenFGAStoreManager.java +++ b/ext/openfga/client-openfga/src/main/java/org/apache/syncope/ext/openfga/client/OpenFGAStoreManager.java @@ -240,14 +240,14 @@ public class OpenFGAStoreManager { next = List.of(); } else { next = new ArrayList<>(); - if (any instanceof Groupable<?, ?, ?, ?> groupable) { + if (any instanceof Groupable<?, ?, ?> groupable) { next.addAll(groupable.getMemberships().stream().map(m -> new TupleKey(). user(id(groupable)). relation(OpenFGAClientFactory.MEMBERSHIP_RELATION). _object(id(m.getRightEnd()))). toList()); } - if (any instanceof Relatable<?, ?, ?> relatable) { + if (any instanceof Relatable<?, ?> relatable) { next.addAll(relatable.getRelationships().stream(). filter(r -> !r.getType().getRightEndAnyType().equals(any.getType())). map(r -> new TupleKey(). diff --git a/ext/opensearch/client-opensearch/src/main/java/org/apache/syncope/ext/opensearch/client/OpenSearchUtils.java b/ext/opensearch/client-opensearch/src/main/java/org/apache/syncope/ext/opensearch/client/OpenSearchUtils.java index 28f2f65eb8..10650a7ca3 100644 --- a/ext/opensearch/client-opensearch/src/main/java/org/apache/syncope/ext/opensearch/client/OpenSearchUtils.java +++ b/ext/opensearch/client-opensearch/src/main/java/org/apache/syncope/ext/opensearch/client/OpenSearchUtils.java @@ -196,7 +196,7 @@ public class OpenSearchUtils { } // add also flattened membership attributes - if (any instanceof Groupable<?, ?, ?, ?> groupable) { + if (any instanceof Groupable<?, ?, ?> groupable) { groupable.getMemberships().forEach(m -> groupable.getPlainAttrs(m).forEach(mAttr -> { List<Object> values = mAttr.getValues().stream(). map(PlainAttrValue::getValue).collect(Collectors.toList());