http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/common/lib/src/main/java/org/apache/syncope/common/lib/types/AbstractPolicySpec.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AbstractPolicySpec.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AbstractPolicySpec.java new file mode 100644 index 0000000..5f2fd1e --- /dev/null +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AbstractPolicySpec.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.common.lib.types; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.XmlType; +import org.apache.syncope.common.lib.annotation.SchemaList; + +@XmlType +public abstract class AbstractPolicySpec implements PolicySpec { + + private static final long serialVersionUID = -6210646284287392063L; + + /** + * Substrings not permitted. + */ + private final List<String> wordsNotPermitted = new ArrayList<>(); + + /** + * User attribute values not permitted. + */ + @SchemaList + protected final List<String> schemasNotPermitted = new ArrayList<>(); + + /** + * Substrings not permitted as prefix. + */ + protected final List<String> prefixesNotPermitted = new ArrayList<>(); + + /** + * Substrings not permitted as suffix. + */ + protected final List<String> suffixesNotPermitted = new ArrayList<>(); + + @XmlElementWrapper(name = "wordsNotPermitted") + @XmlElement(name = "word") + @JsonProperty("wordsNotPermitted") + public List<String> getWordsNotPermitted() { + return wordsNotPermitted; + } + + @XmlElementWrapper(name = "prefixesNotPermitted") + @XmlElement(name = "prefix") + @JsonProperty("prefixesNotPermitted") + public List<String> getPrefixesNotPermitted() { + return prefixesNotPermitted; + } + + @XmlElementWrapper(name = "schemasNotPermitted") + @XmlElement(name = "schema") + @JsonProperty("schemasNotPermitted") + public List<String> getSchemasNotPermitted() { + return schemasNotPermitted; + } + + @XmlElementWrapper(name = "suffixesNotPermitted") + @XmlElement(name = "suffix") + @JsonProperty("suffixesNotPermitted") + public List<String> getSuffixesNotPermitted() { + return suffixesNotPermitted; + } + +}
http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/common/lib/src/main/java/org/apache/syncope/common/lib/types/AccountPolicySpec.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AccountPolicySpec.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AccountPolicySpec.java index 8d5a792..cada048 100644 --- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AccountPolicySpec.java +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AccountPolicySpec.java @@ -18,16 +18,10 @@ */ package org.apache.syncope.common.lib.types; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlType; -import org.apache.syncope.common.lib.annotation.SchemaList; @XmlType -public class AccountPolicySpec implements PolicySpec { +public class AccountPolicySpec extends AbstractPolicySpec { private static final long serialVersionUID = 3259256974414758406L; @@ -47,27 +41,6 @@ public class AccountPolicySpec implements PolicySpec { private String pattern; /** - * Substrings not permitted. - */ - private List<String> wordsNotPermitted; - - /** - * User attribute values not permitted. - */ - @SchemaList - private List<String> schemasNotPermitted; - - /** - * Substrings not permitted as prefix. - */ - private List<String> prefixesNotPermitted; - - /** - * Substrings not permitted as suffix. - */ - private List<String> suffixesNotPermitted; - - /** * Specify if one or more lowercase characters are permitted. */ private boolean allUpperCase; @@ -130,46 +103,6 @@ public class AccountPolicySpec implements PolicySpec { this.pattern = pattern; } - @XmlElementWrapper(name = "prefixesNotPermitted") - @XmlElement(name = "prefix") - @JsonProperty("prefixesNotPermitted") - public List<String> getPrefixesNotPermitted() { - if (prefixesNotPermitted == null) { - prefixesNotPermitted = new ArrayList<String>(); - } - return prefixesNotPermitted; - } - - @XmlElementWrapper(name = "schemasNotPermitted") - @XmlElement(name = "schema") - @JsonProperty("schemasNotPermitted") - public List<String> getSchemasNotPermitted() { - if (schemasNotPermitted == null) { - schemasNotPermitted = new ArrayList<String>(); - } - return schemasNotPermitted; - } - - @XmlElementWrapper(name = "suffixesNotPermitted") - @XmlElement(name = "suffix") - @JsonProperty("suffixesNotPermitted") - public List<String> getSuffixesNotPermitted() { - if (suffixesNotPermitted == null) { - suffixesNotPermitted = new ArrayList<String>(); - } - return suffixesNotPermitted; - } - - @XmlElementWrapper(name = "wordsNotPermitted") - @XmlElement(name = "word") - @JsonProperty("wordsNotPermitted") - public List<String> getWordsNotPermitted() { - if (wordsNotPermitted == null) { - wordsNotPermitted = new ArrayList<String>(); - } - return wordsNotPermitted; - } - public boolean isPropagateSuspension() { return propagateSuspension; } http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/common/lib/src/main/java/org/apache/syncope/common/lib/types/AttrSchemaType.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AttrSchemaType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AttrSchemaType.java index 2fc937b..be78979 100644 --- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AttrSchemaType.java +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AttrSchemaType.java @@ -33,7 +33,7 @@ public enum AttrSchemaType { Encrypted(byte[].class), Binary(byte[].class); - final private Class<?> type; + private final Class<?> type; AttrSchemaType(final Class<?> type) { this.type = type; http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/common/lib/src/main/java/org/apache/syncope/common/lib/types/AttributableType.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AttributableType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AttributableType.java index 6b989df..fab34f0 100644 --- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AttributableType.java +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AttributableType.java @@ -24,7 +24,7 @@ import javax.xml.bind.annotation.XmlEnum; public enum AttributableType { USER, - ROLE, + GROUP, MEMBERSHIP, CONFIGURATION; http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditElements.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditElements.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditElements.java index 40ff86a..323ea09 100644 --- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditElements.java +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditElements.java @@ -26,9 +26,6 @@ public final class AuditElements implements Serializable { private static final long serialVersionUID = -4385059255522273254L; - private AuditElements() { - } - @XmlEnum public enum EventCategoryType { http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditLoggerName.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditLoggerName.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditLoggerName.java index d491037..de0ec90 100644 --- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditLoggerName.java +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditLoggerName.java @@ -49,8 +49,9 @@ public class AuditLoggerName extends AbstractBaseBean { @JsonProperty("category") final String category, @JsonProperty("subcategory") final String subcategory, @JsonProperty("event") final String event, - @JsonProperty("result") final Result result) - throws IllegalArgumentException { + @JsonProperty("result") final Result result) { + + super(); this.type = type == null ? AuditElements.EventCategoryType.CUSTOM : type; this.category = category; @@ -86,7 +87,7 @@ public class AuditLoggerName extends AbstractBaseBean { @SuppressWarnings("unchecked") public static AuditLoggerName fromLoggerName(final String loggerName) - throws IllegalArgumentException, ParseException { + throws ParseException { if (StringUtils.isBlank(loggerName)) { throw new IllegalArgumentException("Null value not permitted"); @@ -153,7 +154,7 @@ public class AuditLoggerName extends AbstractBaseBean { } } - return new AbstractMap.SimpleEntry< EventCategoryTO, Result>(eventCategoryTO, condition); + return new AbstractMap.SimpleEntry<>(eventCategoryTO, condition); } /** @@ -183,38 +184,24 @@ public class AuditLoggerName extends AbstractBaseBean { eventBuilder.append(type.name()); } } - eventBuilder.append(']'); - - eventBuilder.append(":"); - - eventBuilder.append('['); + eventBuilder.append("]:["); if (StringUtils.isNotBlank(category)) { eventBuilder.append(category); } - eventBuilder.append(']'); - - eventBuilder.append(":"); - - eventBuilder.append('['); + eventBuilder.append("]:["); if (StringUtils.isNotBlank(subcategory)) { eventBuilder.append(subcategory); } - eventBuilder.append(']'); - - eventBuilder.append(":"); - - eventBuilder.append('['); + eventBuilder.append("]:["); if (StringUtils.isNotBlank(event)) { eventBuilder.append(event); } eventBuilder.append(']'); if (resultValueCondition != null) { - eventBuilder.append(":"); - - eventBuilder.append('['); - eventBuilder.append(resultValueCondition); - eventBuilder.append(']'); + eventBuilder.append(":["). + append(resultValueCondition). + append(']'); } return eventBuilder.toString(); http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/common/lib/src/main/java/org/apache/syncope/common/lib/types/CipherAlgorithm.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/CipherAlgorithm.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/CipherAlgorithm.java index af5592e..d7be1bc 100644 --- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/CipherAlgorithm.java +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/CipherAlgorithm.java @@ -35,9 +35,9 @@ public enum CipherAlgorithm { SSHA512("S-SHA-512", false), BCRYPT("BCRYPT", false); - final private String algorithm; + private final String algorithm; - final private boolean invertible; + private final boolean invertible; CipherAlgorithm(final String algorithm, final boolean invertible) { this.algorithm = algorithm; http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java index c55cebd..f67c3d4 100644 --- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java @@ -35,10 +35,10 @@ public enum ClientExceptionType { InvalidConnIdConf(Response.Status.BAD_REQUEST), InvalidPolicy(Response.Status.BAD_REQUEST), InvalidConf(Response.Status.BAD_REQUEST), - InvalidRole(Response.Status.BAD_REQUEST), + InvalidGroup(Response.Status.BAD_REQUEST), InvalidReport(Response.Status.BAD_REQUEST), InvalidReportExec(Response.Status.BAD_REQUEST), - InvalidRoles(Response.Status.BAD_REQUEST), + InvalidGroups(Response.Status.BAD_REQUEST), InvalidSchemaDefinition(Response.Status.BAD_REQUEST), InvalidSearchExpression(Response.Status.BAD_REQUEST), InvalidPageOrSize(Response.Status.BAD_REQUEST), @@ -59,9 +59,9 @@ public enum ClientExceptionType { RejectedUserCreate(Response.Status.BAD_REQUEST), RequiredValuesMissing(Response.Status.BAD_REQUEST), RESTValidation(Response.Status.BAD_REQUEST), - RoleOwnership(Response.Status.BAD_REQUEST), + GroupOwnership(Response.Status.BAD_REQUEST), Scheduling(Response.Status.BAD_REQUEST), - UnauthorizedRole(Response.Status.UNAUTHORIZED), + UnauthorizedGroup(Response.Status.UNAUTHORIZED), Unauthorized(Response.Status.UNAUTHORIZED), Unknown(Response.Status.BAD_REQUEST), Workflow(Response.Status.BAD_REQUEST); http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java index 5a92daa..30193f6 100644 --- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java @@ -38,12 +38,12 @@ public enum EntityViolationType { InvalidPasswordPolicy("org.apache.syncope.core.persistence.validation.passwordpolicy"), InvalidPolicy("org.apache.syncope.core.persistence.validation.policy"), InvalidPropagationTask("org.apache.syncope.core.persistence.validation.propagationtask"), - InvalidRPlainSchema("org.apache.syncope.core.persistence.validation.attrvalue.rPlainSchema"), - InvalidRDerSchema("org.apache.syncope.core.persistence.validation.attrvalue.rDerSchema"), - InvalidRVirSchema("org.apache.syncope.core.persistence.validation.attrvalue.rVirSchema"), + InvalidGPlainSchema("org.apache.syncope.core.persistence.validation.attrvalue.gPlainSchema"), + InvalidGDerSchema("org.apache.syncope.core.persistence.validation.attrvalue.gDerSchema"), + InvalidGVirSchema("org.apache.syncope.core.persistence.validation.attrvalue.gVirSchema"), InvalidReport("org.apache.syncope.core.persistence.validation.report"), InvalidResource("org.apache.syncope.core.persistence.validation.externalresource"), - InvalidRoleOwner("org.apache.syncope.core.persistence.validation.role.owner"), + InvalidGroupOwner("org.apache.syncope.core.persistence.validation.group.owner"), InvalidSchemaEncrypted("org.apache.syncope.core.persistence.validation.schema.encrypted"), InvalidSchemaEnum("org.apache.syncope.core.persistence.validation.schema.enum"), InvalidSchemaMultivalueUnique("org.apache.syncope.core.persistence.validation.schema.multivalueUnique"), http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/common/lib/src/main/java/org/apache/syncope/common/lib/types/IntMappingType.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/IntMappingType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/IntMappingType.java index 7dd60d6..c329d72 100644 --- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/IntMappingType.java +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/IntMappingType.java @@ -42,14 +42,14 @@ public enum IntMappingType { Username(AttributableType.USER), Password(AttributableType.USER), // ------------------------- - // Role attribute types (the same in RoleMappingType) + // Group attribute types (the same in GroupMappingType) // ------------------------- - RolePlainSchema(AttributableType.ROLE), - RoleDerivedSchema(AttributableType.ROLE), - RoleVirtualSchema(AttributableType.ROLE), - RoleId(AttributableType.ROLE), - RoleName(AttributableType.ROLE), - RoleOwnerSchema(AttributableType.ROLE), + GroupPlainSchema(AttributableType.GROUP), + GroupDerivedSchema(AttributableType.GROUP), + GroupVirtualSchema(AttributableType.GROUP), + GroupId(AttributableType.GROUP), + GroupName(AttributableType.GROUP), + GroupOwnerSchema(AttributableType.GROUP), // ------------------------- // Membership attribute types (the same in MembershipMappingType) // ------------------------- @@ -58,7 +58,7 @@ public enum IntMappingType { MembershipVirtualSchema(AttributableType.MEMBERSHIP), MembershipId(AttributableType.MEMBERSHIP); - private AttributableType attributableType; + private final AttributableType attributableType; private IntMappingType(final AttributableType attributableType) { this.attributableType = attributableType; @@ -91,11 +91,11 @@ public enum IntMappingType { * @return set of attribute types. */ public static Set<IntMappingType> getAttributeTypes(final AttributableType attributableType) { - final EnumSet<?> enumset; + EnumSet<?> enumset; switch (attributableType) { - case ROLE: - enumset = EnumSet.allOf(RoleMappingType.class); + case GROUP: + enumset = EnumSet.allOf(GroupMappingType.class); break; case MEMBERSHIP: @@ -105,9 +105,10 @@ public enum IntMappingType { case USER: default: enumset = EnumSet.allOf(UserMappingType.class); + break; } - final Set<IntMappingType> result = new HashSet<IntMappingType>(enumset.size()); + final Set<IntMappingType> result = new HashSet<>(enumset.size()); for (Object obj : enumset) { result.add(IntMappingType.valueOf(obj.toString())); } @@ -116,9 +117,8 @@ public enum IntMappingType { } public static Set<IntMappingType> getEmbedded() { - return EnumSet.of( - IntMappingType.UserId, IntMappingType.Username, IntMappingType.Password, - IntMappingType.RoleId, IntMappingType.RoleName, IntMappingType.RoleOwnerSchema, + return EnumSet.of(IntMappingType.UserId, IntMappingType.Username, IntMappingType.Password, + IntMappingType.GroupId, IntMappingType.GroupName, IntMappingType.GroupOwnerSchema, IntMappingType.MembershipId); } @@ -131,8 +131,8 @@ public enum IntMappingType { */ public static boolean contains(final AttributableType attributableType, final String type) { switch (attributableType) { - case ROLE: - for (RoleMappingType c : RoleMappingType.values()) { + case GROUP: + for (GroupMappingType c : GroupMappingType.values()) { if (c.name().equals(type)) { return true; } @@ -174,16 +174,16 @@ public enum IntMappingType { } /** - * Role attribute types. + * Group attribute types. */ - private enum RoleMappingType { - - RolePlainSchema, - RoleDerivedSchema, - RoleVirtualSchema, - RoleId, - RoleName, - RoleOwnerSchema; + private enum GroupMappingType { + + GroupPlainSchema, + GroupDerivedSchema, + GroupVirtualSchema, + GroupId, + GroupName, + GroupOwnerSchema; } http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/common/lib/src/main/java/org/apache/syncope/common/lib/types/PasswordPolicySpec.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/PasswordPolicySpec.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/PasswordPolicySpec.java index 448fceb..175a1ef 100644 --- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/PasswordPolicySpec.java +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/PasswordPolicySpec.java @@ -18,16 +18,10 @@ */ package org.apache.syncope.common.lib.types; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlType; -import org.apache.syncope.common.lib.annotation.SchemaList; @XmlType -public class PasswordPolicySpec implements PolicySpec { +public class PasswordPolicySpec extends AbstractPolicySpec { private static final long serialVersionUID = -7988778083915548547L; @@ -47,17 +41,6 @@ public class PasswordPolicySpec implements PolicySpec { private int minLength; /** - * Substrings not permitted. - */ - private List<String> wordsNotPermitted; - - /** - * User attribute values not permitted. - */ - @SchemaList - private List<String> schemasNotPermitted; - - /** * Specify if one or more non alphanumeric characters are required. */ private boolean nonAlphanumericRequired; @@ -147,16 +130,6 @@ public class PasswordPolicySpec implements PolicySpec { */ private boolean allowNullPassword; - /** - * Substrings not permitted as prefix. - */ - private List<String> prefixesNotPermitted; - - /** - * Substrings not permitted as suffix. - */ - private List<String> suffixesNotPermitted; - public boolean isDigitRequired() { return digitRequired; } @@ -261,36 +234,6 @@ public class PasswordPolicySpec implements PolicySpec { this.nonAlphanumericRequired = nonAlphanumericRequired; } - @XmlElementWrapper(name = "prefixesNotPermitted") - @XmlElement(name = "prefix") - @JsonProperty("prefixesNotPermitted") - public List<String> getPrefixesNotPermitted() { - if (prefixesNotPermitted == null) { - prefixesNotPermitted = new ArrayList<String>(); - } - return prefixesNotPermitted; - } - - @XmlElementWrapper(name = "schemasNotPermitted") - @XmlElement(name = "schema") - @JsonProperty("schemasNotPermitted") - public List<String> getSchemasNotPermitted() { - if (schemasNotPermitted == null) { - schemasNotPermitted = new ArrayList<String>(); - } - return schemasNotPermitted; - } - - @XmlElementWrapper(name = "suffixesNotPermitted") - @XmlElement(name = "suffix") - @JsonProperty("suffixesNotPermitted") - public List<String> getSuffixesNotPermitted() { - if (suffixesNotPermitted == null) { - suffixesNotPermitted = new ArrayList<String>(); - } - return suffixesNotPermitted; - } - public boolean isUppercaseRequired() { return uppercaseRequired; } @@ -299,16 +242,6 @@ public class PasswordPolicySpec implements PolicySpec { this.uppercaseRequired = uppercaseRequired; } - @XmlElementWrapper(name = "wordsNotPermitted") - @XmlElement(name = "word") - @JsonProperty("wordsNotPermitted") - public List<String> getWordsNotPermitted() { - if (wordsNotPermitted == null) { - wordsNotPermitted = new ArrayList<String>(); - } - return wordsNotPermitted; - } - public boolean isAlphanumericRequired() { return alphanumericRequired; } http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceAssociationActionType.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceAssociationActionType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceAssociationActionType.java index 7693ca3..3d7955d 100644 --- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceAssociationActionType.java +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceAssociationActionType.java @@ -24,15 +24,15 @@ import javax.xml.bind.annotation.XmlEnum; public enum ResourceAssociationActionType { /** - * Add association between user/role on Syncope and external resource(s) without any propagation. + * Add association between user/group on Syncope and external resource(s) without any propagation. */ LINK, /** - * Add user/role into external resource(s). + * Add user/group into external resource(s). */ PROVISION, /** - * Assign (link + provision) external resource(s) with user/role. + * Assign (link + provision) external resource(s) with user/group. */ ASSIGN http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceDeassociationActionType.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceDeassociationActionType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceDeassociationActionType.java index c88f453..aea4fa3 100644 --- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceDeassociationActionType.java +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceDeassociationActionType.java @@ -24,15 +24,15 @@ import javax.xml.bind.annotation.XmlEnum; public enum ResourceDeassociationActionType { /** - * Remove association between user/role on Syncope and external resource(s) without any propagation. + * Remove association between user/group on Syncope and external resource(s) without any propagation. */ UNLINK, /** - * Remove user/role from external resource(s). + * Remove user/group from external resource(s). */ DEPROVISION, /** - * Unassign (unlink + de-provision) external resource(s) from user/role. + * Unassign (unlink + de-provision) external resource(s) from user/group. */ UNASSIGN http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/common/lib/src/main/java/org/apache/syncope/common/lib/types/SubjectType.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/SubjectType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/SubjectType.java index 0acd314..538f19a 100644 --- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/SubjectType.java +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/SubjectType.java @@ -24,11 +24,11 @@ import javax.xml.bind.annotation.XmlEnum; public enum SubjectType { USER, - ROLE; + GROUP; public AttributableType asAttributableType() { return this == USER ? AttributableType.USER - : AttributableType.ROLE; + : AttributableType.GROUP; } } http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncPolicySpec.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncPolicySpec.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncPolicySpec.java index e0040de..a904209 100644 --- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncPolicySpec.java +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncPolicySpec.java @@ -36,19 +36,19 @@ public class SyncPolicySpec implements PolicySpec { * User attributes and fields for matching during synchronization. */ @SchemaList(extended = true) - private final List<String> uAltSearchSchemas = new ArrayList<String>(); + private final List<String> uAltSearchSchemas = new ArrayList<>(); @ClassList private String userJavaRule; /** - * Role attributes and fields for matching during synchronization. + * Group attributes and fields for matching during synchronization. */ @SchemaList(extended = true) - private final List<String> rAltSearchSchemas = new ArrayList<String>(); + private final List<String> gAltSearchSchemas = new ArrayList<>(); @ClassList - private String roleJavaRule; + private String groupJavaRule; /** * Conflict resolution action. @@ -72,19 +72,19 @@ public class SyncPolicySpec implements PolicySpec { return uAltSearchSchemas; } - @XmlElementWrapper(name = "roleAltSearchSchemas") - @XmlElement(name = "roleAltSearchSchema") - @JsonProperty("roleAltSearchSchemas") + @XmlElementWrapper(name = "groupAltSearchSchemas") + @XmlElement(name = "groupAltSearchSchema") + @JsonProperty("groupAltSearchSchemas") public List<String> getrAltSearchSchemas() { - return rAltSearchSchemas; + return gAltSearchSchemas; } - public String getRoleJavaRule() { - return roleJavaRule; + public String getGroupJavaRule() { + return groupJavaRule; } - public void setRoleJavaRule(final String roleJavaRule) { - this.roleJavaRule = roleJavaRule; + public void setGroupJavaRule(final String groupJavaRule) { + this.groupJavaRule = groupJavaRule; } public String getUserJavaRule() { http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/common/pom.xml ---------------------------------------------------------------------- diff --git a/common/pom.xml b/common/pom.xml index a137eb5..db8b41c 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -33,6 +33,10 @@ under the License. <artifactId>syncope-common</artifactId> <packaging>pom</packaging> + <properties> + <rootpom.basedir>${basedir}/..</rootpom.basedir> + </properties> + <modules> <module>lib</module> <module>rest-api</module> http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/GroupService.java ---------------------------------------------------------------------- diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/GroupService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/GroupService.java new file mode 100644 index 0000000..2bbe9b7 --- /dev/null +++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/GroupService.java @@ -0,0 +1,312 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.common.rest.api.service; + +import java.util.List; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.apache.cxf.jaxrs.model.wadl.Description; +import org.apache.cxf.jaxrs.model.wadl.Descriptions; +import org.apache.cxf.jaxrs.model.wadl.DocTarget; +import org.apache.syncope.common.lib.mod.GroupMod; +import org.apache.syncope.common.lib.to.BulkAction; +import org.apache.syncope.common.lib.to.BulkActionResult; +import org.apache.syncope.common.lib.to.PagedResult; +import org.apache.syncope.common.lib.to.GroupTO; +import org.apache.syncope.common.lib.types.ResourceAssociationActionType; +import org.apache.syncope.common.lib.types.ResourceDeassociationActionType; +import org.apache.syncope.common.lib.wrap.ResourceName; + +/** + * REST operations for groups. + */ +@Path("groups") +public interface GroupService extends JAXRSService { + + /** + * Returns children groups of given group. + * + * @param groupKey key of group to get children from + * @return children groups of given group + */ + @GET + @Path("{groupKey}/children") + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + List<GroupTO> children(@NotNull @PathParam("groupKey") Long groupKey); + + /** + * Returns parent group of the given group (or null if no parent exists). + * + * @param groupKey key of group to get parent group from + * @return parent group of the given group (or null if no parent exists) + */ + @GET + @Path("{groupKey}/parent") + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + GroupTO parent(@NotNull @PathParam("groupKey") Long groupKey); + + /** + * Reads the group matching the provided groupKey. + * + * @param groupKey key of group to be read + * @return group with matching id + */ + @GET + @Path("{groupKey}") + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + GroupTO read(@NotNull @PathParam("groupKey") Long groupKey); + + /** + * This method is similar to {@link #read(Long)}, but uses different authentication handling to ensure that a user + * can read his own groups. + * + * @param groupKey key of group to be read + * @return group with matching id + */ + @Descriptions({ + @Description(target = DocTarget.METHOD, + value = "This method is similar to <tt>read()</tt>, but uses different authentication handling to " + + "ensure that a user can read his own groups.") + }) + @GET + @Path("{groupKey}/own") + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + GroupTO readSelf(@NotNull @PathParam("groupKey") Long groupKey); + + /** + * Returns a paged list of existing groups. + * + * @return paged list of all existing groups + */ + @GET + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + PagedResult<GroupTO> list(); + + /** + * Returns a paged list of existing groups. + * + * @param orderBy list of ordering clauses, separated by comma + * @return paged list of all existing groups + */ + @GET + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + PagedResult<GroupTO> list(@QueryParam(PARAM_ORDERBY) String orderBy); + + /** + * Returns a paged list of existing groups matching page/size conditions. + * + * @param page result page number + * @param size number of entries per page + * @return paged list of existing groups matching page/size conditions + */ + @GET + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + PagedResult<GroupTO> list( + @NotNull @Min(1) @QueryParam(PARAM_PAGE) @DefaultValue(DEFAULT_PARAM_PAGE) Integer page, + @NotNull @Min(1) @QueryParam(PARAM_SIZE) @DefaultValue(DEFAULT_PARAM_SIZE) Integer size); + + /** + * Returns a paged list of existing groups matching page/size conditions. + * + * @param page result page number + * @param size number of entries per page + * @param orderBy list of ordering clauses, separated by comma + * @return paged list of existing groups matching page/size conditions + */ + @GET + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + PagedResult<GroupTO> list( + @NotNull @Min(1) @QueryParam(PARAM_PAGE) @DefaultValue(DEFAULT_PARAM_PAGE) Integer page, + @NotNull @Min(1) @QueryParam(PARAM_SIZE) @DefaultValue(DEFAULT_PARAM_SIZE) Integer size, + @QueryParam(PARAM_ORDERBY) String orderBy); + + /** + * Returns a paged list of groups matching the provided FIQL search condition. + * + * @param fiql FIQL search expression + * @return paged list of groups matching the provided FIQL search condition + */ + @GET + @Path("search") + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + PagedResult<GroupTO> search(@NotNull @QueryParam(PARAM_FIQL) String fiql); + + /** + * Returns a paged list of groups matching the provided FIQL search condition. + * + * @param fiql FIQL search expression + * @param orderBy list of ordering clauses, separated by comma + * @return paged list of groups matching the provided FIQL search condition + */ + @GET + @Path("search") + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + PagedResult<GroupTO> search( + @NotNull @QueryParam(PARAM_FIQL) String fiql, @QueryParam(PARAM_ORDERBY) String orderBy); + + /** + * Returns a paged list of groups matching the provided FIQL search condition. + * + * @param fiql FIQL search expression + * @param page result page number + * @param size number of entries per page + * @return paged list of groups matching the provided FIQL search condition + */ + @GET + @Path("search") + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + PagedResult<GroupTO> search(@QueryParam(PARAM_FIQL) String fiql, + @NotNull @Min(1) @QueryParam(PARAM_PAGE) @DefaultValue(DEFAULT_PARAM_PAGE) Integer page, + @NotNull @Min(1) @QueryParam(PARAM_SIZE) @DefaultValue(DEFAULT_PARAM_SIZE) Integer size); + + /** + * Returns a paged list of groups matching the provided FIQL search condition. + * + * @param fiql FIQL search expression + * @param page result page number + * @param size number of entries per page + * @param orderBy list of ordering clauses, separated by comma + * @return paged list of groups matching the provided FIQL search condition + */ + @GET + @Path("search") + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + PagedResult<GroupTO> search(@QueryParam(PARAM_FIQL) String fiql, + @NotNull @Min(1) @QueryParam(PARAM_PAGE) @DefaultValue(DEFAULT_PARAM_PAGE) Integer page, + @NotNull @Min(1) @QueryParam(PARAM_SIZE) @DefaultValue(DEFAULT_PARAM_SIZE) Integer size, + @QueryParam(PARAM_ORDERBY) String orderBy); + + /** + * Creates a new group. + * + * @param groupTO group to be created + * @return <tt>Response</tt> object featuring <tt>Location</tt> header of created group as well as the group itself + * enriched with propagation status information - {@link GroupTO} as <tt>Entity</tt> + */ + @Descriptions({ + @Description(target = DocTarget.RESPONSE, + value = "Featuring <tt>Location</tt> header of created group as well as the " + + "group itself enriched with propagation status information - <tt>GroupTO</tt> as <tt>Entity</tt>") + }) + @POST + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + Response create(@NotNull GroupTO groupTO); + + /** + * Updates group matching the provided groupKey. + * + * @param groupKey key of group to be updated + * @param groupMod modification to be applied to group matching the provided groupKey + * @return <tt>Response</tt> object featuring the updated group enriched with propagation status information + * - {@link GroupTO} as <tt>Entity</tt> + */ + @Descriptions({ + @Description(target = DocTarget.RESPONSE, + value = "Featuring the updated group enriched with propagation status information - " + + "<tt>GroupTO</tt> as <tt>Entity</tt>") + }) + @POST + @Path("{groupKey}") + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + Response update(@NotNull @PathParam("groupKey") Long groupKey, @NotNull GroupMod groupMod); + + /** + * Deletes group matching provided groupKey. + * + * @param groupKey key of group to be deleted + * @return <tt>Response</tt> object featuring the deleted group enriched with propagation status information + * - {@link GroupTO} as <tt>Entity</tt> + */ + @Descriptions({ + @Description(target = DocTarget.RESPONSE, + value = "Featuring the deleted group enriched with propagation status information - " + + "<tt>GroupTO</tt> as <tt>Entity</tt>") + }) + @DELETE + @Path("{groupKey}") + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + Response delete(@NotNull @PathParam("groupKey") Long groupKey); + + /** + * Executes resource-related operations on given group. + * + * @param groupKey group id. + * @param type resource association action type + * @param resourceNames external resources to be used for propagation-related operations + * @return <tt>Response</tt> object featuring + * {@link BulkActionResult} as <tt>Entity</tt> + */ + @Descriptions({ + @Description(target = DocTarget.RESPONSE, + value = "Featuring <tt>BulkActionResult</tt> as <tt>Entity</tt>") + }) + @POST + @Path("{groupKey}/deassociate/{type}") + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + Response bulkDeassociation(@NotNull @PathParam("groupKey") Long groupKey, + @NotNull @PathParam("type") ResourceDeassociationActionType type, + @NotNull List<ResourceName> resourceNames); + + /** + * Executes resource-related operations on given group. + * + * @param groupKey group id. + * @param type resource association action type + * @param resourceNames external resources to be used for propagation-related operations + * @return <tt>Response</tt> object featuring {@link BulkActionResult} as <tt>Entity</tt> + */ + @Descriptions({ + @Description(target = DocTarget.RESPONSE, + value = "Featuring <tt>BulkActionResult</tt> as <tt>Entity</tt>") + }) + @POST + @Path("{groupKey}/associate/{type}") + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + Response bulkAssociation(@NotNull @PathParam("groupKey") Long groupKey, + @NotNull @PathParam("type") ResourceAssociationActionType type, + @NotNull List<ResourceName> resourceNames); + + /** + * Executes the provided bulk action. + * + * @param bulkAction list of group ids against which the bulk action will be performed. + * @return Bulk action result + */ + @POST + @Path("bulk") + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + BulkActionResult bulk(@NotNull BulkAction bulkAction); +} http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/JAXRSService.java ---------------------------------------------------------------------- diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/JAXRSService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/JAXRSService.java index 7108b49..cd5c473 100644 --- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/JAXRSService.java +++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/JAXRSService.java @@ -20,20 +20,20 @@ package org.apache.syncope.common.rest.api.service; public interface JAXRSService { - final String PARAM_FIQL = "fiql"; + String PARAM_FIQL = "fiql"; - final String PARAM_PAGE = "page"; + String PARAM_PAGE = "page"; - final String DEFAULT_PARAM_PAGE = "1"; + String DEFAULT_PARAM_PAGE = "1"; - final int DEFAULT_PARAM_PAGE_VALUE = Integer.valueOf(DEFAULT_PARAM_PAGE); + int DEFAULT_PARAM_PAGE_VALUE = Integer.valueOf(DEFAULT_PARAM_PAGE); - final String PARAM_SIZE = "size"; + String PARAM_SIZE = "size"; - final String DEFAULT_PARAM_SIZE = "25"; + String DEFAULT_PARAM_SIZE = "25"; - final int DEFAULT_PARAM_SIZE_VALUE = Integer.valueOf(DEFAULT_PARAM_SIZE); + int DEFAULT_PARAM_SIZE_VALUE = Integer.valueOf(DEFAULT_PARAM_SIZE); - final String PARAM_ORDERBY = "orderby"; + String PARAM_ORDERBY = "orderby"; } http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ResourceService.java ---------------------------------------------------------------------- diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ResourceService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ResourceService.java index 9199d37..06b6b32 100644 --- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ResourceService.java +++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ResourceService.java @@ -51,8 +51,8 @@ public interface ResourceService extends JAXRSService { * Returns connector object from the external resource, for the given type and key. * * @param resourceKey Name of resource to read connector object from - * @param type user / role - * @param key user key / role key + * @param type user /group + * @param key user key / group key * @return connector object from the external resource, for the given type and key */ @GET @@ -128,12 +128,12 @@ public interface ResourceService extends JAXRSService { boolean check(@NotNull ResourceTO resourceTO); /** - * De-associate users or roles (depending on the provided subject type) from the given resource. + * De-associate users or groups (depending on the provided subject type) from the given resource. * * @param resourceKey name of resource - * @param subjectType subject type (user or role) + * @param subjectType subject type (user or group) * @param type resource de-association action type - * @param subjectKeys users or roles against which the bulk action will be performed + * @param subjectKeys users or groups against which the bulk action will be performed * @return <tt>Response</tt> object featuring {@link BulkActionResult} as <tt>Entity</tt> */ @Descriptions({ http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RoleService.java ---------------------------------------------------------------------- diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RoleService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RoleService.java deleted file mode 100644 index 5d1b737..0000000 --- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RoleService.java +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.common.rest.api.service; - -import java.util.List; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.DefaultValue; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import org.apache.cxf.jaxrs.model.wadl.Description; -import org.apache.cxf.jaxrs.model.wadl.Descriptions; -import org.apache.cxf.jaxrs.model.wadl.DocTarget; -import org.apache.syncope.common.lib.mod.RoleMod; -import org.apache.syncope.common.lib.to.BulkAction; -import org.apache.syncope.common.lib.to.BulkActionResult; -import org.apache.syncope.common.lib.to.PagedResult; -import org.apache.syncope.common.lib.to.RoleTO; -import org.apache.syncope.common.lib.types.ResourceAssociationActionType; -import org.apache.syncope.common.lib.types.ResourceDeassociationActionType; -import org.apache.syncope.common.lib.wrap.ResourceName; - -/** - * REST operations for roles. - */ -@Path("roles") -public interface RoleService extends JAXRSService { - - /** - * Returns children roles of given role. - * - * @param roleKey key of role to get children from - * @return children roles of given role - */ - @GET - @Path("{roleKey}/children") - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - List<RoleTO> children(@NotNull @PathParam("roleKey") Long roleKey); - - /** - * Returns parent role of the given role (or null if no parent exists). - * - * @param roleKey key of role to get parent role from - * @return parent role of the given role (or null if no parent exists) - */ - @GET - @Path("{roleKey}/parent") - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - RoleTO parent(@NotNull @PathParam("roleKey") Long roleKey); - - /** - * Reads the role matching the provided roleKey. - * - * @param roleKey key of role to be read - * @return role with matching id - */ - @GET - @Path("{roleKey}") - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - RoleTO read(@NotNull @PathParam("roleKey") Long roleKey); - - /** - * This method is similar to {@link #read(Long)}, but uses different authentication handling to ensure that a user - * can read his own roles. - * - * @param roleKey key of role to be read - * @return role with matching id - */ - @Descriptions({ - @Description(target = DocTarget.METHOD, - value = "This method is similar to <tt>read()</tt>, but uses different authentication handling to " - + "ensure that a user can read his own roles.") - }) - @GET - @Path("{roleKey}/own") - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - RoleTO readSelf(@NotNull @PathParam("roleKey") Long roleKey); - - /** - * Returns a paged list of existing roles. - * - * @return paged list of all existing roles - */ - @GET - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - PagedResult<RoleTO> list(); - - /** - * Returns a paged list of existing roles. - * - * @param orderBy list of ordering clauses, separated by comma - * @return paged list of all existing roles - */ - @GET - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - PagedResult<RoleTO> list(@QueryParam(PARAM_ORDERBY) String orderBy); - - /** - * Returns a paged list of existing roles matching page/size conditions. - * - * @param page result page number - * @param size number of entries per page - * @return paged list of existing roles matching page/size conditions - */ - @GET - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - PagedResult<RoleTO> list( - @NotNull @Min(1) @QueryParam(PARAM_PAGE) @DefaultValue(DEFAULT_PARAM_PAGE) Integer page, - @NotNull @Min(1) @QueryParam(PARAM_SIZE) @DefaultValue(DEFAULT_PARAM_SIZE) Integer size); - - /** - * Returns a paged list of existing roles matching page/size conditions. - * - * @param page result page number - * @param size number of entries per page - * @param orderBy list of ordering clauses, separated by comma - * @return paged list of existing roles matching page/size conditions - */ - @GET - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - PagedResult<RoleTO> list( - @NotNull @Min(1) @QueryParam(PARAM_PAGE) @DefaultValue(DEFAULT_PARAM_PAGE) Integer page, - @NotNull @Min(1) @QueryParam(PARAM_SIZE) @DefaultValue(DEFAULT_PARAM_SIZE) Integer size, - @QueryParam(PARAM_ORDERBY) String orderBy); - - /** - * Returns a paged list of roles matching the provided FIQL search condition. - * - * @param fiql FIQL search expression - * @return paged list of roles matching the provided FIQL search condition - */ - @GET - @Path("search") - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - PagedResult<RoleTO> search(@NotNull @QueryParam(PARAM_FIQL) String fiql); - - /** - * Returns a paged list of roles matching the provided FIQL search condition. - * - * @param fiql FIQL search expression - * @param orderBy list of ordering clauses, separated by comma - * @return paged list of roles matching the provided FIQL search condition - */ - @GET - @Path("search") - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - PagedResult<RoleTO> search( - @NotNull @QueryParam(PARAM_FIQL) String fiql, @QueryParam(PARAM_ORDERBY) String orderBy); - - /** - * Returns a paged list of roles matching the provided FIQL search condition. - * - * @param fiql FIQL search expression - * @param page result page number - * @param size number of entries per page - * @return paged list of roles matching the provided FIQL search condition - */ - @GET - @Path("search") - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - PagedResult<RoleTO> search(@QueryParam(PARAM_FIQL) String fiql, - @NotNull @Min(1) @QueryParam(PARAM_PAGE) @DefaultValue(DEFAULT_PARAM_PAGE) Integer page, - @NotNull @Min(1) @QueryParam(PARAM_SIZE) @DefaultValue(DEFAULT_PARAM_SIZE) Integer size); - - /** - * Returns a paged list of roles matching the provided FIQL search condition. - * - * @param fiql FIQL search expression - * @param page result page number - * @param size number of entries per page - * @param orderBy list of ordering clauses, separated by comma - * @return paged list of roles matching the provided FIQL search condition - */ - @GET - @Path("search") - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - PagedResult<RoleTO> search(@QueryParam(PARAM_FIQL) String fiql, - @NotNull @Min(1) @QueryParam(PARAM_PAGE) @DefaultValue(DEFAULT_PARAM_PAGE) Integer page, - @NotNull @Min(1) @QueryParam(PARAM_SIZE) @DefaultValue(DEFAULT_PARAM_SIZE) Integer size, - @QueryParam(PARAM_ORDERBY) String orderBy); - - /** - * Creates a new role. - * - * @param roleTO role to be created - * @return <tt>Response</tt> object featuring <tt>Location</tt> header of created role as well as the role itself - * enriched with propagation status information - {@link RoleTO} as <tt>Entity</tt> - */ - @Descriptions({ - @Description(target = DocTarget.RESPONSE, - value = "Featuring <tt>Location</tt> header of created role as well as the " - + "role itself enriched with propagation status information - <tt>RoleTO</tt> as <tt>Entity</tt>") - }) - @POST - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - Response create(@NotNull RoleTO roleTO); - - /** - * Updates role matching the provided roleKey. - * - * @param roleKey key of role to be updated - * @param roleMod modification to be applied to role matching the provided roleKey - * @return <tt>Response</tt> object featuring the updated role enriched with propagation status information - * - {@link RoleTO} as <tt>Entity</tt> - */ - @Descriptions({ - @Description(target = DocTarget.RESPONSE, - value = "Featuring the updated role enriched with propagation status information - " - + "<tt>RoleTO</tt> as <tt>Entity</tt>") - }) - @POST - @Path("{roleKey}") - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - Response update(@NotNull @PathParam("roleKey") Long roleKey, @NotNull RoleMod roleMod); - - /** - * Deletes role matching provided roleKey. - * - * @param roleKey key of role to be deleted - * @return <tt>Response</tt> object featuring the deleted role enriched with propagation status information - * - {@link RoleTO} as <tt>Entity</tt> - */ - @Descriptions({ - @Description(target = DocTarget.RESPONSE, - value = "Featuring the deleted role enriched with propagation status information - " - + "<tt>RoleTO</tt> as <tt>Entity</tt>") - }) - @DELETE - @Path("{roleKey}") - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - Response delete(@NotNull @PathParam("roleKey") Long roleKey); - - /** - * Executes resource-related operations on given role. - * - * @param roleKey role id. - * @param type resource association action type - * @param resourceNames external resources to be used for propagation-related operations - * @return <tt>Response</tt> object featuring - * {@link BulkActionResult} as <tt>Entity</tt> - */ - @Descriptions({ - @Description(target = DocTarget.RESPONSE, - value = "Featuring <tt>BulkActionResult</tt> as <tt>Entity</tt>") - }) - @POST - @Path("{roleKey}/deassociate/{type}") - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - Response bulkDeassociation(@NotNull @PathParam("roleKey") Long roleKey, - @NotNull @PathParam("type") ResourceDeassociationActionType type, - @NotNull List<ResourceName> resourceNames); - - /** - * Executes resource-related operations on given role. - * - * @param roleKey role id. - * @param type resource association action type - * @param resourceNames external resources to be used for propagation-related operations - * @return <tt>Response</tt> object featuring {@link BulkActionResult} as <tt>Entity</tt> - */ - @Descriptions({ - @Description(target = DocTarget.RESPONSE, - value = "Featuring <tt>BulkActionResult</tt> as <tt>Entity</tt>") - }) - @POST - @Path("{roleKey}/associate/{type}") - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - Response bulkAssociation(@NotNull @PathParam("roleKey") Long roleKey, - @NotNull @PathParam("type") ResourceAssociationActionType type, - @NotNull List<ResourceName> resourceNames); - - /** - * Executes the provided bulk action. - * - * @param bulkAction list of role ids against which the bulk action will be performed. - * @return Bulk action result - */ - @POST - @Path("bulk") - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - BulkActionResult bulk(@NotNull BulkAction bulkAction); -} http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/WorkflowService.java ---------------------------------------------------------------------- diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/WorkflowService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/WorkflowService.java index 92aa86b..b74ec2b 100644 --- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/WorkflowService.java +++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/WorkflowService.java @@ -39,7 +39,7 @@ public interface WorkflowService extends JAXRSService { /** * Exports workflow definition for matching kind. * - * @param kind user or role + * @param kind user or group * @return workflow definition for matching kind */ @GET @@ -49,7 +49,7 @@ public interface WorkflowService extends JAXRSService { /** * Exports workflow diagram representation. * - * @param kind user or role + * @param kind user or group * @return workflow diagram representation */ @GET @@ -60,7 +60,7 @@ public interface WorkflowService extends JAXRSService { /** * Imports workflow definition for matching kind. * - * @param kind user or role + * @param kind user or group * @param definition workflow definition for matching kind */ @PUT http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java ---------------------------------------------------------------------- diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java index 9874e4d..17e1a7e 100644 --- a/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java +++ b/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java @@ -29,7 +29,7 @@ import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr; import org.apache.syncope.core.persistence.api.entity.conf.CPlainSchema; import org.apache.syncope.core.provisioning.api.data.ConfigurationDataBinder; -import org.apache.syncope.core.workflow.api.RoleWorkflowAdapter; +import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter; import org.apache.syncope.core.workflow.api.UserWorkflowAdapter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; @@ -55,7 +55,7 @@ public class ConfigurationLogic extends AbstractTransactionalLogic<ConfTO> { private UserWorkflowAdapter uwfAdapter; @Autowired - private RoleWorkflowAdapter rwfAdapter; + private GroupWorkflowAdapter gwfAdapter; @PreAuthorize("hasRole('CONFIGURATION_DELETE')") public void delete(final String key) { @@ -96,7 +96,7 @@ public class ConfigurationLogic extends AbstractTransactionalLogic<ConfTO> { @Transactional(readOnly = true) public void export(final OutputStream os) { try { - exporter.export(os, uwfAdapter.getPrefix(), rwfAdapter.getPrefix()); + exporter.export(os, uwfAdapter.getPrefix(), gwfAdapter.getPrefix()); LOG.debug("Database content successfully exported"); } catch (Exception e) { LOG.error("While exporting database content", e); http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java ---------------------------------------------------------------------- diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java new file mode 100644 index 0000000..a3fd17a --- /dev/null +++ b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java @@ -0,0 +1,405 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.logic; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import javax.annotation.Resource; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.syncope.common.lib.SyncopeClientException; +import org.apache.syncope.common.lib.mod.GroupMod; +import org.apache.syncope.common.lib.to.BulkAction; +import org.apache.syncope.common.lib.to.BulkActionResult; +import org.apache.syncope.common.lib.to.PropagationStatus; +import org.apache.syncope.common.lib.to.GroupTO; +import org.apache.syncope.common.lib.types.ClientExceptionType; +import org.apache.syncope.common.lib.types.SubjectType; +import org.apache.syncope.core.persistence.api.GroupEntitlementUtil; +import org.apache.syncope.core.persistence.api.dao.NotFoundException; +import org.apache.syncope.core.persistence.api.dao.GroupDAO; +import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO; +import org.apache.syncope.core.persistence.api.dao.UserDAO; +import org.apache.syncope.core.persistence.api.dao.search.OrderByClause; +import org.apache.syncope.core.persistence.api.dao.search.SearchCond; +import org.apache.syncope.core.persistence.api.entity.group.Group; +import org.apache.syncope.core.persistence.api.entity.user.User; +import org.apache.syncope.core.provisioning.api.AttributableTransformer; +import org.apache.syncope.core.provisioning.api.GroupProvisioningManager; +import org.apache.syncope.core.provisioning.api.data.GroupDataBinder; +import org.apache.syncope.core.provisioning.api.propagation.PropagationManager; +import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor; +import org.apache.syncope.core.misc.security.AuthContextUtil; +import org.apache.syncope.core.misc.security.UnauthorizedGroupException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.interceptor.TransactionInterceptor; + +/** + * Note that this controller does not extend {@link AbstractTransactionalLogic}, hence does not provide any + * Spring's Transactional logic at class level. + */ +@Component +public class GroupLogic extends AbstractSubjectLogic<GroupTO, GroupMod> { + + @Autowired + protected GroupDAO groupDAO; + + @Autowired + protected UserDAO userDAO; + + @Autowired + protected SubjectSearchDAO searchDAO; + + @Autowired + protected GroupDataBinder binder; + + @Autowired + protected PropagationManager propagationManager; + + @Autowired + protected PropagationTaskExecutor taskExecutor; + + @Autowired + protected AttributableTransformer attrTransformer; + + @Resource(name = "anonymousUser") + protected String anonymousUser; + + @Autowired + protected GroupProvisioningManager provisioningManager; + + @PreAuthorize("hasAnyRole('GROUP_READ', T(org.apache.syncope.common.lib.SyncopeConstants).ANONYMOUS_ENTITLEMENT)") + @Transactional(readOnly = true) + @Override + public GroupTO read(final Long groupKey) { + Group group; + // bypass group entitlements check + if (anonymousUser.equals(AuthContextUtil.getAuthenticatedUsername())) { + group = groupDAO.find(groupKey); + } else { + group = groupDAO.authFetch(groupKey); + } + + if (group == null) { + throw new NotFoundException("Group " + groupKey); + } + + return binder.getGroupTO(group); + } + + @PreAuthorize("isAuthenticated() " + + "and not(hasRole(T(org.apache.syncope.common.lib.SyncopeConstants).ANONYMOUS_ENTITLEMENT))") + @Transactional(readOnly = true) + public GroupTO readSelf(final Long groupKey) { + // Explicit search instead of using binder.getGroupFromId() in order to bypass auth checks - will do here + Group group = groupDAO.find(groupKey); + if (group == null) { + throw new NotFoundException("Group " + groupKey); + } + + Set<Long> ownedGroupIds; + User authUser = userDAO.find(AuthContextUtil.getAuthenticatedUsername()); + if (authUser == null) { + ownedGroupIds = Collections.<Long>emptySet(); + } else { + ownedGroupIds = authUser.getGroupKeys(); + } + + Set<Long> allowedGroupIds = GroupEntitlementUtil.getGroupKeys(AuthContextUtil.getOwnedEntitlementNames()); + allowedGroupIds.addAll(ownedGroupIds); + if (!allowedGroupIds.contains(group.getKey())) { + throw new UnauthorizedGroupException(group.getKey()); + } + + return binder.getGroupTO(group); + } + + @PreAuthorize("hasRole('GROUP_READ')") + @Transactional(readOnly = true) + public GroupTO parent(final Long groupKey) { + Group group = groupDAO.authFetch(groupKey); + + Set<Long> allowedGroupIds = GroupEntitlementUtil.getGroupKeys(AuthContextUtil.getOwnedEntitlementNames()); + if (group.getParent() != null && !allowedGroupIds.contains(group.getParent().getKey())) { + throw new UnauthorizedGroupException(group.getParent().getKey()); + } + + GroupTO result = group.getParent() == null + ? null + : binder.getGroupTO(group.getParent()); + + return result; + } + + @PreAuthorize("hasRole('GROUP_READ')") + @Transactional(readOnly = true) + public List<GroupTO> children(final Long groupKey) { + Group group = groupDAO.authFetch(groupKey); + + Set<Long> allowedGroupIds = GroupEntitlementUtil.getGroupKeys(AuthContextUtil.getOwnedEntitlementNames()); + + List<Group> children = groupDAO.findChildren(group); + List<GroupTO> childrenTOs = new ArrayList<>(children.size()); + for (Group child : children) { + if (allowedGroupIds.contains(child.getKey())) { + childrenTOs.add(binder.getGroupTO(child)); + } + } + + return childrenTOs; + } + + @PreAuthorize("isAuthenticated()") + @Transactional(readOnly = true, rollbackFor = { Throwable.class }) + @Override + public int count() { + return groupDAO.count(); + } + + @PreAuthorize("isAuthenticated()") + @Transactional(readOnly = true) + @Override + public List<GroupTO> list(final int page, final int size, final List<OrderByClause> orderBy) { + List<Group> groups = groupDAO.findAll(page, size, orderBy); + + List<GroupTO> groupTOs = new ArrayList<>(groups.size()); + for (Group group : groups) { + groupTOs.add(binder.getGroupTO(group)); + } + + return groupTOs; + } + + @PreAuthorize("isAuthenticated()") + @Transactional(readOnly = true, rollbackFor = { Throwable.class }) + @Override + public int searchCount(final SearchCond searchCondition) { + final Set<Long> adminGroupIds = GroupEntitlementUtil.getGroupKeys(AuthContextUtil.getOwnedEntitlementNames()); + return searchDAO.count(adminGroupIds, searchCondition, SubjectType.GROUP); + } + + @PreAuthorize("isAuthenticated()") + @Transactional(readOnly = true, rollbackFor = { Throwable.class }) + @Override + public List<GroupTO> search(final SearchCond searchCondition, final int page, final int size, + final List<OrderByClause> orderBy) { + + final List<Group> matchingGroups = searchDAO.search(GroupEntitlementUtil.getGroupKeys(AuthContextUtil. + getOwnedEntitlementNames()), + searchCondition, page, size, orderBy, SubjectType.GROUP); + + final List<GroupTO> result = new ArrayList<>(matchingGroups.size()); + for (Group group : matchingGroups) { + result.add(binder.getGroupTO(group)); + } + + return result; + } + + @PreAuthorize("hasRole('GROUP_CREATE')") + public GroupTO create(final GroupTO groupTO) { + // Check that this operation is allowed to be performed by caller + Set<Long> allowedGroupIds = GroupEntitlementUtil.getGroupKeys(AuthContextUtil.getOwnedEntitlementNames()); + if (groupTO.getParent() != 0 && !allowedGroupIds.contains(groupTO.getParent())) { + throw new UnauthorizedGroupException(groupTO.getParent()); + } + + // Attributable transformation (if configured) + GroupTO actual = attrTransformer.transform(groupTO); + LOG.debug("Transformed: {}", actual); + + /* + * Actual operations: workflow, propagation + */ + Map.Entry<Long, List<PropagationStatus>> created = provisioningManager.create(groupTO); + final GroupTO savedTO = binder.getGroupTO(created.getKey()); + savedTO.getPropagationStatusTOs().addAll(created.getValue()); + return savedTO; + } + + @PreAuthorize("hasRole('GROUP_UPDATE')") + @Override + public GroupTO update(final GroupMod groupMod) { + // Check that this operation is allowed to be performed by caller + groupDAO.authFetch(groupMod.getKey()); + + // Attribute value transformation (if configured) + GroupMod actual = attrTransformer.transform(groupMod); + LOG.debug("Transformed: {}", actual); + + Map.Entry<Long, List<PropagationStatus>> updated = provisioningManager.update(groupMod); + + final GroupTO updatedTO = binder.getGroupTO(updated.getKey()); + updatedTO.getPropagationStatusTOs().addAll(updated.getValue()); + return updatedTO; + } + + @PreAuthorize("hasRole('GROUP_DELETE')") + @Override + public GroupTO delete(final Long groupKey) { + List<Group> ownedGroups = groupDAO.findOwnedByGroup(groupKey); + if (!ownedGroups.isEmpty()) { + List<String> owned = new ArrayList<>(ownedGroups.size()); + for (Group group : ownedGroups) { + owned.add(group.getKey() + " " + group.getName()); + } + + SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.GroupOwnership); + sce.getElements().addAll(owned); + throw sce; + } + + List<PropagationStatus> statuses = provisioningManager.delete(groupKey); + + GroupTO groupTO = new GroupTO(); + groupTO.setKey(groupKey); + + groupTO.getPropagationStatusTOs().addAll(statuses); + + return groupTO; + } + + @PreAuthorize("(hasRole('GROUP_DELETE') and #bulkAction.operation == #bulkAction.operation.DELETE)") + public BulkActionResult bulk(final BulkAction bulkAction) { + BulkActionResult res = new BulkActionResult(); + + if (bulkAction.getOperation() == BulkAction.Type.DELETE) { + for (String groupKey : bulkAction.getTargets()) { + try { + res.add(delete(Long.valueOf(groupKey)).getKey(), BulkActionResult.Status.SUCCESS); + } catch (Exception e) { + LOG.error("Error performing delete for group {}", groupKey, e); + res.add(groupKey, BulkActionResult.Status.FAILURE); + } + } + } else { + LOG.warn("Unsupported bulk action: {}", bulkAction.getOperation()); + } + + return res; + } + + @PreAuthorize("hasRole('GROUP_UPDATE')") + @Transactional(rollbackFor = { Throwable.class }) + @Override + public GroupTO unlink(final Long groupKey, final Collection<String> resources) { + final GroupMod groupMod = new GroupMod(); + groupMod.setKey(groupKey); + groupMod.getResourcesToRemove().addAll(resources); + final Long updatedResult = provisioningManager.unlink(groupMod); + + return binder.getGroupTO(updatedResult); + } + + @PreAuthorize("hasRole('GROUP_UPDATE')") + @Transactional(rollbackFor = { Throwable.class }) + @Override + public GroupTO link(final Long groupKey, final Collection<String> resources) { + final GroupMod groupMod = new GroupMod(); + groupMod.setKey(groupKey); + groupMod.getResourcesToAdd().addAll(resources); + return binder.getGroupTO(provisioningManager.link(groupMod)); + } + + @PreAuthorize("hasRole('GROUP_UPDATE')") + @Transactional(rollbackFor = { Throwable.class }) + @Override + public GroupTO unassign(final Long groupKey, final Collection<String> resources) { + final GroupMod groupMod = new GroupMod(); + groupMod.setKey(groupKey); + groupMod.getResourcesToRemove().addAll(resources); + return update(groupMod); + } + + @PreAuthorize("hasRole('GROUP_UPDATE')") + @Transactional(rollbackFor = { Throwable.class }) + @Override + public GroupTO assign( + final Long groupKey, final Collection<String> resources, final boolean changePwd, final String password) { + + final GroupMod userMod = new GroupMod(); + userMod.setKey(groupKey); + userMod.getResourcesToAdd().addAll(resources); + return update(userMod); + } + + @PreAuthorize("hasRole('GROUP_UPDATE')") + @Transactional(rollbackFor = { Throwable.class }) + @Override + public GroupTO deprovision(final Long groupKey, final Collection<String> resources) { + final Group group = groupDAO.authFetch(groupKey); + + List<PropagationStatus> statuses = provisioningManager.deprovision(groupKey, resources); + + final GroupTO updatedTO = binder.getGroupTO(group); + updatedTO.getPropagationStatusTOs().addAll(statuses); + return updatedTO; + } + + @PreAuthorize("hasRole('GROUP_UPDATE')") + @Transactional(rollbackFor = { Throwable.class }) + @Override + public GroupTO provision( + final Long groupKey, final Collection<String> resources, final boolean changePwd, final String password) { + final GroupTO original = binder.getGroupTO(groupKey); + + //trick: assign and retrieve propagation statuses ... + original.getPropagationStatusTOs().addAll( + assign(groupKey, resources, changePwd, password).getPropagationStatusTOs()); + + // .... rollback. + TransactionInterceptor.currentTransactionStatus().setRollbackOnly(); + return original; + } + + @Override + protected GroupTO resolveReference(final Method method, final Object... args) throws UnresolvedReferenceException { + Long key = null; + + if (ArrayUtils.isNotEmpty(args)) { + for (int i = 0; key == null && i < args.length; i++) { + if (args[i] instanceof Long) { + key = (Long) args[i]; + } else if (args[i] instanceof GroupTO) { + key = ((GroupTO) args[i]).getKey(); + } else if (args[i] instanceof GroupMod) { + key = ((GroupMod) args[i]).getKey(); + } + } + } + + if ((key != null) && !key.equals(0l)) { + try { + return binder.getGroupTO(key); + } catch (Throwable ignore) { + LOG.debug("Unresolved reference", ignore); + throw new UnresolvedReferenceException(ignore); + } + } + + throw new UnresolvedReferenceException(); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java ---------------------------------------------------------------------- diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java index b85b74c..baeb1ce 100644 --- a/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java +++ b/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java @@ -34,7 +34,7 @@ import org.apache.syncope.common.lib.types.SubjectType; import org.apache.syncope.core.persistence.api.dao.DuplicateException; import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; import org.apache.syncope.core.persistence.api.dao.NotFoundException; -import org.apache.syncope.core.persistence.api.dao.RoleDAO; +import org.apache.syncope.core.persistence.api.dao.GroupDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; import org.apache.syncope.core.persistence.api.entity.AttributableUtil; import org.apache.syncope.core.persistence.api.entity.AttributableUtilFactory; @@ -68,7 +68,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> { private UserDAO userDAO; @Autowired - private RoleDAO roleDAO; + private GroupDAO groupDAO; @Autowired private ResourceDataBinder binder; @@ -170,7 +170,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> { Subject<?, ?, ?> subject = type == SubjectType.USER ? userDAO.find(id) - : roleDAO.find(id); + : groupDAO.find(id); if (subject == null) { throw new NotFoundException(type + " " + id); }
