diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/OfflineSerializationTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/OfflineSerializationTest.java index f92ccd7ea39..0832e7ad6d5 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/OfflineSerializationTest.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/OfflineSerializationTest.java @@ -47,7 +47,6 @@ import com.sap.sse.common.Color; import com.sap.sse.common.Duration; import com.sap.sse.common.Util; import com.sap.sse.common.impl.MillisecondsTimePoint; -import com.sap.sse.security.UserImpl; import com.sap.sse.security.UserStore; import com.sap.sse.security.shared.UserGroupManagementException; import com.sap.sse.security.shared.UserManagementException; @@ -110,7 +109,7 @@ public class OfflineSerializationTest extends AbstractSerializationTest { UserStore userStore = new UserStoreImpl("defaultTenant"); userStore.clear(); UserGroup defaultTenant = userStore.createUserGroup(UUID.randomUUID(), "admin-tenant"); - UserImpl user = userStore.createUser("admin", "", defaultTenant); + User user = userStore.createUser("admin", "", defaultTenant); defaultTenant.add(user); userStore.updateUserGroup(defaultTenant); user.getDefaultTenantMap().put("testserver", defaultTenant); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/MigrateGroupOwnershipDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/MigrateGroupOwnershipDialog.java index 60b8c99a6f8..bbea0b6de6c 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/MigrateGroupOwnershipDialog.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/MigrateGroupOwnershipDialog.java @@ -18,6 +18,7 @@ import com.sap.sse.gwt.client.Notification.NotificationType; import com.sap.sse.gwt.client.dialog.DataEntryDialog; import com.sap.sse.security.shared.dto.OwnershipDTO; import com.sap.sse.security.shared.dto.SecuredDTO; +import com.sap.sse.security.shared.dto.StrippedUserGroupDTO; import com.sap.sse.security.shared.dto.UserGroupDTO; import com.sap.sse.security.ui.client.UserManagementServiceAsync; @@ -79,13 +80,13 @@ public class MigrateGroupOwnershipDialog extends DataEntryDialog callback) { super(stringMessages.ownership(), stringMessages.migrateHierarchyToGroupOwner(), stringMessages.ok(), stringMessages.cancel(), new Validator(stringMessages), callback); this.userManagementService = userManagementService; - this.currentGroupLabel = new Label(currentGroupOwner == null ? "n/a" : currentGroupOwner.getName()); - this.groupnameBox = createTextBox(currentGroupOwner == null ? "" : currentGroupOwner.getName(), + this.currentGroupLabel = new Label(tenant == null ? "n/a" : tenant.getName()); + this.groupnameBox = createTextBox(tenant == null ? "" : tenant.getName(), /* visibileLength */ 20); this.groupnameBox.addChangeHandler(e -> resolveUserGroup()); @@ -173,7 +174,7 @@ public class MigrateGroupOwnershipDialog extends DataEntryDialog, U extends SecurityUser> +public abstract class AbstractOwnership> implements Serializable { private static final long serialVersionUID = 1L; diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractRole.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractRole.java index c64922eb1e4..5e19800f876 100755 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractRole.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractRole.java @@ -12,7 +12,7 @@ import com.sap.sse.common.Util.Triple; * * @author Axel Uhl (D043530) */ -public abstract class AbstractRole, U extends SecurityUser> +public abstract class AbstractRole> implements Named { private static final String QUALIFIER_SEPARATOR = WildcardPermission.PART_DIVIDER_TOKEN; private static final long serialVersionUID = 1243342091492822614L; diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractUserGroupImpl.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractUserGroupImpl.java new file mode 100644 index 00000000000..76896bfcf72 --- /dev/null +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractUserGroupImpl.java @@ -0,0 +1,38 @@ +package com.sap.sse.security.shared; + +import java.util.Set; +import java.util.UUID; + +/** + * A group of users; equality and hash code are based solely on the {@link #getId() ID}. + * + * @author Axel Uhl (d043530) + * + */ +public abstract class AbstractUserGroupImpl> + extends SecurityUserGroupImpl { + private static final long serialVersionUID = 1L; + + private Set users; + + public AbstractUserGroupImpl(Set users, UUID id, String name) { + super(id, name); + this.users = users; + } + + public Iterable getUsers() { + return users; + } + + public void add(U user) { + users.add(user); + } + + public void remove(U user) { + users.remove(user); + } + + public boolean contains(U user) { + return users.contains(user); + } +} diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/PermissionChecker.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/PermissionChecker.java index a8e6a20ed65..fb04c222953 100644 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/PermissionChecker.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/PermissionChecker.java @@ -61,7 +61,7 @@ public class PermissionChecker { * @param acl * may be {@code null} in which case no ACL-specific checks are performed */ - public static , O extends AbstractOwnership, U extends SecurityUser, G extends AbstractUserGroup, A extends SecurityAccessControlList> boolean isPermitted( + public static , O extends AbstractOwnership, U extends SecurityUser, G extends SecurityUserGroup, A extends SecurityAccessControlList> boolean isPermitted( WildcardPermission permission, U user, U allUser, O ownership, A acl) { return isPermitted(permission, user, (Iterable) (user == null ? null : user.getUserGroups()), allUser, @@ -80,7 +80,7 @@ public class PermissionChecker { * @param acl * may be {@code null} in which case no ACL-specific checks are performed */ - public static , O extends AbstractOwnership, U extends SecurityUser, G extends AbstractUserGroup, A extends SecurityAccessControlList> boolean isPermitted( + public static , O extends AbstractOwnership, U extends SecurityUser, G extends SecurityUserGroup, A extends SecurityAccessControlList> boolean isPermitted( WildcardPermission permission, U user, Iterable groupsOfWhichUserIsMember, U allUser, Iterable allUserGroupsOfWhichUserIsMember, O ownership, A acl) { @@ -126,7 +126,7 @@ public class PermissionChecker { /** * Checks if a user has a specific role either for a given ownership or globally if no ownership exists. */ - public static , O extends AbstractOwnership, U extends SecurityUser, G extends AbstractUserGroup, A extends SecurityAccessControlList> boolean ownsUserASpecificRole( + public static , O extends AbstractOwnership, U extends SecurityUser, G extends SecurityUserGroup, A extends SecurityAccessControlList> boolean ownsUserASpecificRole( U user, U allUser, O ownership, String requiredRoleName) { assert requiredRoleName != null; @@ -135,7 +135,7 @@ public class PermissionChecker { } - private static , O extends AbstractOwnership, U extends SecurityUser, G extends AbstractUserGroup, A extends SecurityAccessControlList> boolean ownsUserASpecificRole( + private static , O extends AbstractOwnership, U extends SecurityUser, G extends SecurityUserGroup, A extends SecurityAccessControlList> boolean ownsUserASpecificRole( U user, O ownership, String requiredRoleName) { if (user == null) { return false; @@ -180,7 +180,7 @@ public class PermissionChecker { * complete list for the running system. Otherwise we potentially do not check for all required types if the given * {@link WildcardPermission} has a wildcard as type part. */ - public static , O extends AbstractOwnership, U extends SecurityUser, G extends AbstractUserGroup, A extends SecurityAccessControlList> boolean checkMetaPermission( + public static , O extends AbstractOwnership, U extends SecurityUser, G extends SecurityUserGroup, A extends SecurityAccessControlList> boolean checkMetaPermission( WildcardPermission permission, Iterable allPermissionTypes, U user, U allUser, O ownership) { assert permission != null; @@ -275,7 +275,7 @@ public class PermissionChecker { * because only users that have an unqualified version of a permission would pass that permission check. This means * we need to check the permission for any possibly existing object ID. */ - public static , O extends AbstractOwnership, U extends SecurityUser, G extends AbstractUserGroup, A extends SecurityAccessControlList> boolean hasUserAnyPermission( + public static , O extends AbstractOwnership, U extends SecurityUser, G extends SecurityUserGroup, A extends SecurityAccessControlList> boolean hasUserAnyPermission( WildcardPermission permission, Iterable allPermissionTypes, U user, U allUser, O ownership) { assert permission != null; @@ -293,7 +293,7 @@ public class PermissionChecker { return false; } - private static , O extends AbstractOwnership, U extends SecurityUser, G extends AbstractUserGroup, A extends SecurityAccessControlList> PermissionState checkUserPermissions( + private static , O extends AbstractOwnership, U extends SecurityUser, G extends SecurityUserGroup, A extends SecurityAccessControlList> PermissionState checkUserPermissions( WildcardPermission permission, U user, O ownership, WildcardPermissionChecker permissionChecker, boolean matchOnlyNonQualifiedRolesIfNoOwnershipIsGiven) { @@ -336,7 +336,7 @@ public class PermissionChecker { * @param ownership * Ownership of the data object for which the {@code permission} is requested */ - private static , O extends AbstractOwnership, U extends SecurityUser, G extends AbstractUserGroup, A extends SecurityAccessControlList> boolean implies( + private static , O extends AbstractOwnership, U extends SecurityUser, G extends SecurityUserGroup, A extends SecurityAccessControlList> boolean implies( R role, WildcardPermission permission, O ownership, WildcardPermissionChecker permissionChecker, boolean matchOnlyNonQualifiedRolesIfNoOwnershipIsGiven) { @@ -373,7 +373,7 @@ public class PermissionChecker { /** * There are cases where need to check instances of different implementations if they represent the same user. */ - public static , O extends AbstractOwnership, U extends SecurityUser, G extends AbstractUserGroup, A extends SecurityAccessControlList> boolean isSameUser( + public static , O extends AbstractOwnership, U extends SecurityUser, G extends SecurityUserGroup, A extends SecurityAccessControlList> boolean isSameUser( U user1, U user2) { if (user1 == user2) { return true; diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/SecurityAccessControlList.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/SecurityAccessControlList.java index 0f8468f7252..dd04d752389 100644 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/SecurityAccessControlList.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/SecurityAccessControlList.java @@ -4,12 +4,12 @@ import java.io.Serializable; import java.util.Map; import java.util.Set; -import com.sap.sse.security.shared.impl.UserGroup; +import com.sap.sse.security.shared.impl.UserGroupImpl; /** - * Grants and revokes permissions to a set of actions for an object on a per-{@link UserGroup} basis. This way, there + * Grants and revokes permissions to a set of actions for an object on a per-{@link UserGroupImpl} basis. This way, there * should usually be at most one instance of this type defined for one object to which access is controlled. The sets of - * actions are keyed by the {@link UserGroup} to which they are granted/revoked. An action would, e.g., be something + * actions are keyed by the {@link UserGroupImpl} to which they are granted/revoked. An action would, e.g., be something * like "UPDATE" in the permission EVENT:UPDATE:84730-74837-47384-ab987f9. Note that nothing but the action is required * for each group because the ACL pertains to a single object such that the type (e.g., "EVENT") as well as the object * ID are known and don't need to and make no sense to be specified. @@ -31,7 +31,7 @@ import com.sap.sse.security.shared.impl.UserGroup; * @author Axel Uhl (d043530) * */ -public interface SecurityAccessControlList> extends Serializable { +public interface SecurityAccessControlList extends Serializable { /** * Checks whether this access control list grants the {@code user} the permission to execute {@code action} on the * object to which this ACL pertains. @@ -57,7 +57,7 @@ public interface SecurityAccessControlList> exten * {@code '!'} denies the action that follows. Multiple leading exclamation marks toggle accordingly. * @return {@code true} if the permission was added; {@code false} if the permission was already in this ACL and * therefore didn't need to be added - * @see #denyPermission(UserGroup, String) + * @see #denyPermission(UserGroupImpl, String) */ boolean addPermission(G userGroup, String actionToAllow); @@ -69,13 +69,13 @@ public interface SecurityAccessControlList> exten * accordingly. * @return {@code true} if the denial was added; {@code false} if the denial was already in this ACL and therefore * didn't need to be added - * @see #addPermission(UserGroup, String) + * @see #addPermission(UserGroupImpl, String) */ boolean denyPermission(G userGroup, String actionToDeny); /** * Removes a permission denial from those permissions denied for the user group. If the action starts with an - * {@code "!"} exclamation mark, the exclamation mark is stripped, and {@link #removePermission(UserGroup, String)} + * {@code "!"} exclamation mark, the exclamation mark is stripped, and {@link #removePermission(UserGroupImpl, String)} * is invoked with the remaining string. * * @return {@code true} if the permission was removed; {@code false} if the permission was not in this ACL and @@ -85,7 +85,7 @@ public interface SecurityAccessControlList> exten /** * Removes a permission from those permissions granted to the user group. If the action starts with an {@code "!"} - * exclamation mark, the exclamation mark is stripped, and {@link #removeDenial(UserGroup, String)} is invoked with + * exclamation mark, the exclamation mark is stripped, and {@link #removeDenial(UserGroupImpl, String)} is invoked with * the remaining string. * * @return {@code true} if the permission was removed; {@code false} if the permission was not in this ACL and diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/SecurityUser.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/SecurityUser.java index 3c699a57c99..81ce75282d1 100755 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/SecurityUser.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/SecurityUser.java @@ -12,7 +12,7 @@ import com.sap.sse.common.WithID; * @author Axel Uhl (d043530) * */ -public interface SecurityUser, G extends AbstractUserGroup> +public interface SecurityUser, G extends SecurityUserGroup> extends NamedWithID { /** * Returns the "raw" permissions explicitly set for this user. This does not include permissions diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/SecurityUserGroup.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/SecurityUserGroup.java new file mode 100644 index 00000000000..b25b8a867fa --- /dev/null +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/SecurityUserGroup.java @@ -0,0 +1,11 @@ +package com.sap.sse.security.shared; + +import java.util.UUID; + +public interface SecurityUserGroup { + + String getName(); + + UUID getId(); + +} \ No newline at end of file diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractUserGroup.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/SecurityUserGroupImpl.java similarity index 60% rename from java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractUserGroup.java rename to java/com.sap.sse.security.common/src/com/sap/sse/security/shared/SecurityUserGroupImpl.java index d4df198cf9a..1e157e10197 100644 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractUserGroup.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/SecurityUserGroupImpl.java @@ -1,6 +1,5 @@ package com.sap.sse.security.shared; -import java.util.Set; import java.util.UUID; import com.sap.sse.common.NamedWithID; @@ -12,42 +11,29 @@ import com.sap.sse.security.shared.impl.SecuredSecurityTypes; * @author Axel Uhl (d043530) * */ -public abstract class AbstractUserGroup> - implements NamedWithID, WithQualifiedObjectIdentifier { +public abstract class SecurityUserGroupImpl implements NamedWithID, WithQualifiedObjectIdentifier, SecurityUserGroup { private static final long serialVersionUID = 1L; - private Set users; private UUID id; private String name; - public AbstractUserGroup(Set users, UUID id, String name) { + public SecurityUserGroupImpl(UUID id, String name) { super(); - this.users = users; this.id = id; this.name = name; } + /* (non-Javadoc) + * @see com.sap.sse.security.shared.SecurityUserGroup#getName() + */ @Override public String getName() { return name; } - public Iterable getUsers() { - return users; - } - - public void add(U user) { - users.add(user); - } - - public void remove(U user) { - users.remove(user); - } - - public boolean contains(U user) { - return users.contains(user); - } - + /* (non-Javadoc) + * @see com.sap.sse.security.shared.SecurityUserGroup#getId() + */ @Override public UUID getId() { return id; diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/AccessControlListDTO.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/AccessControlListDTO.java index 7d70c25370d..66ad716832b 100644 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/AccessControlListDTO.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/AccessControlListDTO.java @@ -5,7 +5,7 @@ import java.util.Set; import com.sap.sse.security.shared.impl.AbstractAccessControlList; -public class AccessControlListDTO extends AbstractAccessControlList { +public class AccessControlListDTO extends AbstractAccessControlList { private static final long serialVersionUID = 1L; @Deprecated @@ -14,7 +14,7 @@ public class AccessControlListDTO extends AbstractAccessControlList> permissionMap) { + public AccessControlListDTO(Map> permissionMap) { super(permissionMap); } diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/OwnershipDTO.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/OwnershipDTO.java index f62933d0808..aff183c819f 100644 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/OwnershipDTO.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/OwnershipDTO.java @@ -2,7 +2,7 @@ package com.sap.sse.security.shared.dto; import com.sap.sse.security.shared.AbstractOwnership; -public class OwnershipDTO extends AbstractOwnership { +public class OwnershipDTO extends AbstractOwnership { private static final long serialVersionUID = -6379054499434958440L; @Deprecated // for GWT serialization only @@ -10,7 +10,7 @@ public class OwnershipDTO extends AbstractOwnership { +public class RoleDTO extends AbstractRole { private static final long serialVersionUID = 1L; @Deprecated // gwt serialisation only RoleDTO() { } - public RoleDTO(RoleDefinitionDTO roleDefinition, UserGroupDTO qualifiedForTenant, + public RoleDTO(RoleDefinitionDTO roleDefinition, StrippedUserGroupDTO qualifiedForTenant, StrippedUserDTO qualifiedForUser) { super(roleDefinition, qualifiedForTenant, qualifiedForUser); } diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/StrippedUserDTO.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/StrippedUserDTO.java index 60d6c1db449..86c7c97d688 100644 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/StrippedUserDTO.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/StrippedUserDTO.java @@ -3,7 +3,7 @@ package com.sap.sse.security.shared.dto; import com.sap.sse.security.shared.WildcardPermission; import com.sap.sse.security.shared.impl.SecurityUserImpl; -public class StrippedUserDTO extends SecurityUserImpl { +public class StrippedUserDTO extends SecurityUserImpl { private static final long serialVersionUID = 1L; @Deprecated diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/StrippedUserGroupDTO.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/StrippedUserGroupDTO.java new file mode 100644 index 00000000000..9fcec670b0c --- /dev/null +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/StrippedUserGroupDTO.java @@ -0,0 +1,20 @@ +package com.sap.sse.security.shared.dto; + +import java.util.UUID; + +import com.sap.sse.security.shared.SecurityUserGroupImpl; + +public class StrippedUserGroupDTO extends SecurityUserGroupImpl { + private static final long serialVersionUID = 1L; + + @Deprecated + // GWT serializer only + StrippedUserGroupDTO() { + super(null, null); + } + + public StrippedUserGroupDTO(UUID id, String name) { + super(id, name); + } + +} diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/UserDTO.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/UserDTO.java index ab1d4a74ea2..baa24ec3edc 100644 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/UserDTO.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/UserDTO.java @@ -19,9 +19,9 @@ public class UserDTO extends StrippedUserDTO private String locale; private List accounts; private boolean emailValidated; - private List groups; + private List groups; private SecurityInformationDTO securityInformation = new SecurityInformationDTO(); - private UserGroupDTO defaultTenantForCurrentServer; + private StrippedUserGroupDTO defaultTenantForCurrentServer; @Deprecated // gwt only UserDTO() { @@ -32,9 +32,9 @@ public class UserDTO extends StrippedUserDTO * @param groups may be {@code null} which is equivalent to passing an empty groups collection */ public UserDTO(String name, String email, String fullName, String company, String locale, boolean emailValidated, - List accounts, Iterable roles, UserGroupDTO defaultTenant, + List accounts, Iterable roles, StrippedUserGroupDTO defaultTenant, Iterable permissions, - Iterable groups) { + Iterable groups) { super(name, roles, permissions); this.defaultTenantForCurrentServer = defaultTenant; this.email = email; @@ -50,7 +50,7 @@ public class UserDTO extends StrippedUserDTO /** * The tenant to use as {@link Ownership#getTenantOwner() tenant owner} of new objects created by this user */ - public UserGroupDTO getDefaultTenant() { + public StrippedUserGroupDTO getDefaultTenant() { return defaultTenantForCurrentServer; } @@ -91,7 +91,7 @@ public class UserDTO extends StrippedUserDTO * embedded. Note, however, that the response is not "live," so there is no round-trip to the server involved. */ @Override - public List getUserGroups() { + public List getUserGroups() { return groups; } @@ -127,7 +127,7 @@ public class UserDTO extends StrippedUserDTO this.securityInformation.setOwnership(ownership); } - public void setDefaultTenantForCurrentServer(UserGroupDTO defaultTenant) { + public void setDefaultTenantForCurrentServer(StrippedUserGroupDTO defaultTenant) { this.defaultTenantForCurrentServer = defaultTenant; } } diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/UserGroupDTO.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/UserGroupDTO.java index 4aca6837062..ef44ffd8aeb 100644 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/UserGroupDTO.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/UserGroupDTO.java @@ -3,9 +3,9 @@ package com.sap.sse.security.shared.dto; import java.util.HashSet; import java.util.UUID; -import com.sap.sse.security.shared.AbstractUserGroup; +import com.sap.sse.security.shared.AbstractUserGroupImpl; -public class UserGroupDTO extends AbstractUserGroup { +public class UserGroupDTO extends AbstractUserGroupImpl { private static final long serialVersionUID = 1L; @Deprecated diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/AbstractAccessControlList.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/AbstractAccessControlList.java index 457e4acc3a7..aa21fc80b17 100755 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/AbstractAccessControlList.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/AbstractAccessControlList.java @@ -6,19 +6,19 @@ import java.util.Map.Entry; import java.util.Set; import com.sap.sse.common.Util; -import com.sap.sse.security.shared.AbstractUserGroup; import com.sap.sse.security.shared.PermissionChecker; import com.sap.sse.security.shared.PermissionChecker.PermissionState; import com.sap.sse.security.shared.SecurityAccessControlList; import com.sap.sse.security.shared.SecurityUser; +import com.sap.sse.security.shared.SecurityUserGroup; import com.sap.sse.security.shared.WildcardPermission; -public abstract class AbstractAccessControlList, U extends SecurityUser> +public abstract class AbstractAccessControlList> implements SecurityAccessControlList { private static final long serialVersionUID = -8587238587604749862L; /** - * Maps from {@link UserGroup} to the actions allowed for this group on the + * Maps from {@link UserGroupImpl} to the actions allowed for this group on the * {@link #idOfAccessControlledObjectAsString object to which this ACL belongs}. The {@link WildcardPermission} * objects stored in the value sets represent only the action part, not the type or instance part. The * {@link WildcardPermission} abstraction is used for its wildcard implication logic. The @@ -36,7 +36,7 @@ public abstract class AbstractAccessControlList, private Map> allowedActionsByUserGroup; /** - * Maps from {@link UserGroup} to the actions denied for this group on the + * Maps from {@link UserGroupImpl} to the actions denied for this group on the * {@link #idOfAccessControlledObjectAsString object to which this ACL belongs}. The {@link WildcardPermission} * objects stored in the value sets represent only the action part, not the type or instance part. The * {@link WildcardPermission} abstraction is used for its wildcard implication logic. The diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/SecuredSecurityTypes.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/SecuredSecurityTypes.java index e8f96d60d24..8fbcee3920a 100755 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/SecuredSecurityTypes.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/SecuredSecurityTypes.java @@ -43,7 +43,7 @@ public class SecuredSecurityTypes extends HasPermissionsImpl { public static final HasPermissions ROLE_DEFINITION = new SecuredSecurityTypes("ROLE_DEFINITION"); /** - * type-relative identifier is the {@link UserGroup#getId() group ID's} string representation + * type-relative identifier is the {@link UserGroupImpl#getId() group ID's} string representation */ public static final HasPermissions USER_GROUP = new SecuredSecurityTypes("USER_GROUP"); diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/SecurityUserImpl.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/SecurityUserImpl.java index 0c6980479f3..c343d8891ee 100755 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/SecurityUserImpl.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/SecurityUserImpl.java @@ -7,12 +7,12 @@ import java.util.Set; import com.sap.sse.common.Util; import com.sap.sse.security.shared.AbstractRole; -import com.sap.sse.security.shared.AbstractUserGroup; import com.sap.sse.security.shared.RoleDefinition; import com.sap.sse.security.shared.SecurityUser; +import com.sap.sse.security.shared.SecurityUserGroup; import com.sap.sse.security.shared.WildcardPermission; -public abstract class SecurityUserImpl, G extends AbstractUserGroup> +public abstract class SecurityUserImpl, G extends SecurityUserGroup> implements SecurityUser { private static final long serialVersionUID = -3639860207453072248L; diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/User.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/User.java index ad18166a194..7a05024a511 100755 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/User.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/User.java @@ -6,11 +6,11 @@ import java.util.Map; import com.sap.sse.common.Named; import com.sap.sse.common.WithID; import com.sap.sse.security.shared.Account; +import com.sap.sse.security.shared.Account.AccountType; import com.sap.sse.security.shared.RoleDefinition; import com.sap.sse.security.shared.SecurityUser; import com.sap.sse.security.shared.WildcardPermission; import com.sap.sse.security.shared.WithQualifiedObjectIdentifier; -import com.sap.sse.security.shared.Account.AccountType; /** * The {@link Named#getName() name} is the ID for this user; usually a nickname or short name. Implements the diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/UserGroup.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/UserGroup.java index 9b93ede98d0..8b320ae7814 100755 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/UserGroup.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/UserGroup.java @@ -1,20 +1,16 @@ package com.sap.sse.security.shared.impl; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; +import com.sap.sse.security.shared.SecurityUserGroup; +import com.sap.sse.security.shared.WithQualifiedObjectIdentifier; -import com.sap.sse.security.shared.AbstractUserGroup; +public interface UserGroup extends SecurityUserGroup, WithQualifiedObjectIdentifier { -public class UserGroup extends AbstractUserGroup { - private static final long serialVersionUID = 1L; + Iterable getUsers(); - public UserGroup(Set users, UUID id, String name) { - super(users, id, name); - } + void add(User user); - public UserGroup(UUID id, String name) { - super(new HashSet(), id, name); - } + void remove(User user); + + boolean contains(User user); } diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/UserGroupImpl.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/UserGroupImpl.java new file mode 100644 index 00000000000..0cd92c8e91c --- /dev/null +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/UserGroupImpl.java @@ -0,0 +1,20 @@ +package com.sap.sse.security.shared.impl; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +import com.sap.sse.security.shared.AbstractUserGroupImpl; + +public class UserGroupImpl extends AbstractUserGroupImpl implements UserGroup { + private static final long serialVersionUID = 1L; + + public UserGroupImpl(Set users, UUID id, String name) { + super(users, id, name); + } + + public UserGroupImpl(UUID id, String name) { + super(new HashSet(), id, name); + } + +} diff --git a/java/com.sap.sse.security.replication.test/src/com/sap/sse/security/replication/test/SimpleSecurityReplicationTest.java b/java/com.sap.sse.security.replication.test/src/com/sap/sse/security/replication/test/SimpleSecurityReplicationTest.java index 67958ae0d6a..7d0f98fb4c9 100755 --- a/java/com.sap.sse.security.replication.test/src/com/sap/sse/security/replication/test/SimpleSecurityReplicationTest.java +++ b/java/com.sap.sse.security.replication.test/src/com/sap/sse/security/replication/test/SimpleSecurityReplicationTest.java @@ -12,7 +12,6 @@ import java.util.Locale; import org.junit.Test; import com.sap.sse.common.mail.MailException; -import com.sap.sse.security.UserImpl; import com.sap.sse.security.shared.UserGroupManagementException; import com.sap.sse.security.shared.UserManagementException; import com.sap.sse.security.shared.impl.User; @@ -27,7 +26,7 @@ public class SimpleSecurityReplicationTest extends AbstractSecurityReplicationTe final String company = "Ernie's Company"; final String validationBaseURL = "http://me.to.back.com"; assertNull(master.getUserByName(username)); - UserImpl user = master.createSimpleUser(username, email, password, fullName, company, Locale.ENGLISH, + User user = master.createSimpleUser(username, email, password, fullName, company, Locale.ENGLISH, validationBaseURL); assertNotNull(user); assertSame(user, master.getUserByName(username)); @@ -62,7 +61,7 @@ public class SimpleSecurityReplicationTest extends AbstractSecurityReplicationTe final String validationBaseURL = "http://me.to.back.com"; final String fullName = "Ernie's Full Name"; final String company = "Ernie's Company"; - UserImpl user = master.createSimpleUser(username, email, password, fullName, company, Locale.ENGLISH, + User user = master.createSimpleUser(username, email, password, fullName, company, Locale.ENGLISH, validationBaseURL); user.setFullName(fullName); user.setCompany(company); @@ -113,7 +112,7 @@ public class SimpleSecurityReplicationTest extends AbstractSecurityReplicationTe final String password = "BertMyFriend"; final String validationBaseURL = "http://me.to.back.com/validateemail"; final String passwordResetBaseURL = "http://me.to.back.com/passwordreset"; - UserImpl user = master.createSimpleUser(username, email, password, + User user = master.createSimpleUser(username, email, password, /* fullName */ null, /* company */ null, Locale.ENGLISH, validationBaseURL); master.validateEmail(username, user.getValidationSecret()); assertTrue(user.isEmailValidated()); diff --git a/java/com.sap.sse.security.test/src/com/sap/sse/security/test/AccessControlStoreTest.java b/java/com.sap.sse.security.test/src/com/sap/sse/security/test/AccessControlStoreTest.java index 8bb5dfb59db..4f0c576424e 100755 --- a/java/com.sap.sse.security.test/src/com/sap/sse/security/test/AccessControlStoreTest.java +++ b/java/com.sap.sse.security.test/src/com/sap/sse/security/test/AccessControlStoreTest.java @@ -26,7 +26,9 @@ import com.sap.sse.security.shared.UserGroupManagementException; import com.sap.sse.security.shared.UserManagementException; import com.sap.sse.security.shared.WildcardPermission; import com.sap.sse.security.shared.impl.QualifiedObjectIdentifierImpl; +import com.sap.sse.security.shared.impl.User; import com.sap.sse.security.shared.impl.UserGroup; +import com.sap.sse.security.shared.impl.UserGroupImpl; import com.sap.sse.security.userstore.mongodb.AccessControlStoreImpl; import com.sap.sse.security.userstore.mongodb.UserStoreImpl; import com.sap.sse.security.userstore.mongodb.impl.CollectionNames; @@ -39,12 +41,12 @@ public class AccessControlStoreTest { private final QualifiedObjectIdentifier testId = new QualifiedObjectIdentifierImpl("Test", "test"); private final String testDisplayName = "testDN"; - private final UserGroup testTenantOwner = new UserGroup(UUID.randomUUID(), "test-tenant"); + private final UserGroup testTenantOwner = new UserGroupImpl(UUID.randomUUID(), "test-tenant"); private final UUID testRoleId = UUID.randomUUID(); private UserStore userStore; private AccessControlStore accessControlStore; - private UserImpl testOwner; + private User testOwner; @Before public void setUp() throws UnknownHostException, MongoException, UserGroupManagementException { @@ -56,7 +58,7 @@ public class AccessControlStoreTest { db.getCollection(CollectionNames.ROLES.name()).drop(); newStores(); - UserGroup adminTenant = new UserGroup(UUID.randomUUID(), "admin-tenant"); + UserGroup adminTenant = new UserGroupImpl(UUID.randomUUID(), "admin-tenant"); Map defaultTenantForUser = new HashMap<>(); defaultTenantForUser.put("dummyServer", adminTenant); testOwner = new UserImpl("admin", "admin@sapsailing.com", defaultTenantForUser, diff --git a/java/com.sap.sse.security.test/src/com/sap/sse/security/test/LoginTest.java b/java/com.sap.sse.security.test/src/com/sap/sse/security/test/LoginTest.java index 0b498d13606..65fe543cc53 100755 --- a/java/com.sap.sse.security.test/src/com/sap/sse/security/test/LoginTest.java +++ b/java/com.sap.sse.security.test/src/com/sap/sse/security/test/LoginTest.java @@ -30,7 +30,7 @@ import com.sap.sse.security.shared.UserManagementException; import com.sap.sse.security.shared.WildcardPermission; import com.sap.sse.security.shared.impl.Role; import com.sap.sse.security.shared.impl.User; -import com.sap.sse.security.shared.impl.UserGroup; +import com.sap.sse.security.shared.impl.UserGroupImpl; import com.sap.sse.security.userstore.mongodb.AccessControlStoreImpl; import com.sap.sse.security.userstore.mongodb.UserStoreImpl; import com.sap.sse.security.userstore.mongodb.impl.CollectionNames; @@ -80,7 +80,7 @@ public class LoginTest { @Test public void rolesTest() throws UserManagementException, UserGroupManagementException { - userStore.createUser("me", "me@sap.com", new UserGroup(UUID.randomUUID(), "me-tenant")); + userStore.createUser("me", "me@sap.com", new UserGroupImpl(UUID.randomUUID(), "me-tenant")); RoleDefinition testRoleDefinition = userStore.createRoleDefinition(UUID.randomUUID(), "testRole", Collections.emptySet()); final Role testRole = new Role(testRoleDefinition); userStore.addRoleForUser("me", testRole); @@ -90,7 +90,7 @@ public class LoginTest { @Test public void roleWithQualifiersTest() throws UserManagementException, UserGroupManagementException { - UserGroup userDefaultTenant = userStore.createUserGroup(UUID.randomUUID(), "me-tenant"); + UserGroupImpl userDefaultTenant = userStore.createUserGroup(UUID.randomUUID(), "me-tenant"); User meUser = userStore.createUser("me", "me@sap.com", userDefaultTenant); RoleDefinition testRoleDefinition = userStore.createRoleDefinition(UUID.randomUUID(), "testRole", Collections.emptySet()); final Role testRole = new Role(testRoleDefinition, userDefaultTenant, meUser); @@ -104,7 +104,7 @@ public class LoginTest { @Test public void permissionsTest() throws UserManagementException, UserGroupManagementException { - userStore.createUser("me", "me@sap.com", new UserGroup(UUID.randomUUID(), "me-tenant")); + userStore.createUser("me", "me@sap.com", new UserGroupImpl(UUID.randomUUID(), "me-tenant")); userStore.addPermissionForUser("me", new WildcardPermission("a:b:c")); UserStoreImpl store2 = new UserStoreImpl(DEFAULT_TENANT_NAME); User allUser = userStore.getUserByName(SecurityService.ALL_USERNAME); diff --git a/java/com.sap.sse.security.test/src/com/sap/sse/security/test/RolesTest.java b/java/com.sap.sse.security.test/src/com/sap/sse/security/test/RolesTest.java index 41ae1275b28..eda95c495f6 100755 --- a/java/com.sap.sse.security.test/src/com/sap/sse/security/test/RolesTest.java +++ b/java/com.sap.sse.security.test/src/com/sap/sse/security/test/RolesTest.java @@ -10,17 +10,17 @@ import org.junit.Test; import com.sap.sse.security.shared.dto.RoleDTO; import com.sap.sse.security.shared.dto.RoleDefinitionDTO; import com.sap.sse.security.shared.dto.StrippedUserDTO; -import com.sap.sse.security.shared.dto.UserGroupDTO; +import com.sap.sse.security.shared.dto.StrippedUserGroupDTO; import com.sap.sse.security.shared.impl.Role; -import com.sap.sse.security.shared.impl.UserGroup; +import com.sap.sse.security.shared.impl.UserGroupImpl; public class RolesTest { @Test public void testRoleToString() { final RoleDefinitionDTO roleDefinition = new RoleDefinitionDTO(UUID.randomUUID(), "role", new ArrayList<>()); final Role role = new Role(roleDefinition); - final UserGroup tenant = new UserGroup(UUID.randomUUID(), "tenant"); - final UserGroupDTO tenantDTO = new UserGroupDTO(UUID.randomUUID(), "tenant"); + final UserGroupImpl tenant = new UserGroupImpl(UUID.randomUUID(), "tenant"); + final StrippedUserGroupDTO tenantDTO = new StrippedUserGroupDTO(UUID.randomUUID(), "tenant"); final StrippedUserDTO user = new StrippedUserDTO("user"); assertEquals("role", role.toString()); final Role role2 = new Role(roleDefinition, tenant, /* user qualification */ null); diff --git a/java/com.sap.sse.security.test/src/com/sap/sse/security/test/UserStoreWithPersistenceTest.java b/java/com.sap.sse.security.test/src/com/sap/sse/security/test/UserStoreWithPersistenceTest.java index 2c0efef6715..681f51e5150 100644 --- a/java/com.sap.sse.security.test/src/com/sap/sse/security/test/UserStoreWithPersistenceTest.java +++ b/java/com.sap.sse.security.test/src/com/sap/sse/security/test/UserStoreWithPersistenceTest.java @@ -37,6 +37,7 @@ import com.sap.sse.security.shared.impl.Ownership; import com.sap.sse.security.shared.impl.Role; import com.sap.sse.security.shared.impl.User; import com.sap.sse.security.shared.impl.UserGroup; +import com.sap.sse.security.shared.impl.UserGroupImpl; import com.sap.sse.security.userstore.mongodb.UserStoreImpl; import com.sap.sse.security.userstore.mongodb.impl.CollectionNames; @@ -54,7 +55,7 @@ public class UserStoreWithPersistenceTest { private final UUID userGroupId = UUID.randomUUID(); private final String userGroupName = "usergroup"; - private UserGroup defaultTenant; + private UserGroupImpl defaultTenant; private UserStoreImpl store; private HashMap defaultTenantForServers; @@ -158,7 +159,7 @@ public class UserStoreWithPersistenceTest { public void testCreateUserGroup() throws UserGroupManagementException, UserManagementException { store.deleteUserGroup(defaultTenant); final User user = store.createUser(username, email, defaultTenant); - final UserGroup group = store.createUserGroup(userGroupId, userGroupName); + final UserGroupImpl group = store.createUserGroup(userGroupId, userGroupName); group.add(user); store.updateUserGroup(group); assertNotNull(store.getUserGroup(userGroupId)); @@ -173,7 +174,7 @@ public class UserStoreWithPersistenceTest { @Test public void testDeleteUserGroup() throws UserGroupManagementException { - UserGroup userGroup = store.createUserGroup(userGroupId, userGroupName); + UserGroupImpl userGroup = store.createUserGroup(userGroupId, userGroupName); store.deleteUserGroup(userGroup); assertNull(store.getUserGroup(userGroupId)); assertNull(store.getUserGroupByName(userGroupName)); @@ -209,7 +210,7 @@ public class UserStoreWithPersistenceTest { public void testUserGroups() throws UserManagementException, UserGroupManagementException { final User user = store.createUser(username, email, defaultTenant); final String GROUP_NAME = "group"; - final UserGroup group = store.createUserGroup(UUID.randomUUID(), GROUP_NAME); + final UserGroupImpl group = store.createUserGroup(UUID.randomUUID(), GROUP_NAME); group.add(user); store.updateUserGroup(group); assertEquals(1, Util.size(group.getUsers())); @@ -234,7 +235,7 @@ public class UserStoreWithPersistenceTest { User user = store.createUser("def", "d@test.de", store.createUserGroup(UUID.randomUUID(), "def-tentant")); RoleDefinitionImpl roleDefinition = new RoleDefinitionImpl(UUID.randomUUID(), "My-Test-Role"); store.createRoleDefinition(roleDefinition.getId(), roleDefinition.getName(), new ArrayList<>()); - UserGroup userGroup = store.createUserGroup(UUID.randomUUID(), "Test-Usergroup"); + UserGroupImpl userGroup = store.createUserGroup(UUID.randomUUID(), "Test-Usergroup"); // tenant is null testWithTenantNull(user, roleDefinition, userGroup); @@ -266,7 +267,7 @@ public class UserStoreWithPersistenceTest { } /** Test getExistingQualificationsForRoleDefinition with both tenant and user not null. */ - private void testWithTenantAndUserNotNull(User user, RoleDefinitionImpl roleDefinition, UserGroup userGroup) + private void testWithTenantAndUserNotNull(User user, RoleDefinitionImpl roleDefinition, UserGroupImpl userGroup) throws UserManagementException { Role role = new Role(roleDefinition, userGroup, user); store.addRoleForUser(user.getName(), role); @@ -275,7 +276,7 @@ public class UserStoreWithPersistenceTest { } /** Test getExistingQualificationsForRoleDefinition with user null. */ - private void testWithUserNull(User user, RoleDefinitionImpl roleDefinition, UserGroup userGroup) + private void testWithUserNull(User user, RoleDefinitionImpl roleDefinition, UserGroupImpl userGroup) throws UserManagementException { Role role = new Role(roleDefinition, userGroup, null); store.addRoleForUser(user.getName(), role); @@ -284,7 +285,7 @@ public class UserStoreWithPersistenceTest { } /** Test getExistingQualificationsForRoleDefinition with tenant null. */ - private void testWithTenantNull(User user, RoleDefinitionImpl roleDefinition, UserGroup userGroup) + private void testWithTenantNull(User user, RoleDefinitionImpl roleDefinition, UserGroupImpl userGroup) throws UserManagementException { Role role = new Role(roleDefinition, null, user); store.addRoleForUser(user.getName(), role); @@ -296,7 +297,7 @@ public class UserStoreWithPersistenceTest { * assert that no user has a wildcard role getExistingQualificationsForRoleDefinition with both tenant and user not * null. */ - private void assertThatNoUserHasWildcardRole(UserGroup userGroup, User user, RoleDefinition roleDefinition) + private void assertThatNoUserHasWildcardRole(UserGroupImpl userGroup, User user, RoleDefinition roleDefinition) throws UserManagementException { Iterable rolesFromUser = store.getRolesFromUser(user.getName()); // check that role was added correctly diff --git a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/UserManagementService.java b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/UserManagementService.java index 11aefe2b2bb..4f61c09163c 100755 --- a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/UserManagementService.java +++ b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/UserManagementService.java @@ -21,6 +21,7 @@ import com.sap.sse.security.shared.dto.AccessControlListDTO; import com.sap.sse.security.shared.dto.OwnershipAnnotationDTO; import com.sap.sse.security.shared.dto.OwnershipDTO; import com.sap.sse.security.shared.dto.RoleDefinitionDTO; +import com.sap.sse.security.shared.dto.StrippedUserGroupDTO; import com.sap.sse.security.shared.dto.UserDTO; import com.sap.sse.security.shared.dto.UserGroupDTO; import com.sap.sse.security.ui.oauth.client.CredentialDTO; @@ -47,6 +48,8 @@ public interface UserManagementService extends RemoteService { Collection getUserGroups(); UserGroupDTO getUserGroupByName(String userGroupName) throws UnauthorizedException; + + StrippedUserGroupDTO getStrippedUserGroupByName(String userGroupName) throws UnauthorizedException; UserGroupDTO createUserGroup(String name) throws UserGroupManagementException, UnauthorizedException; diff --git a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/UserManagementServiceAsync.java b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/UserManagementServiceAsync.java index 84ba92ab358..b960044638b 100755 --- a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/UserManagementServiceAsync.java +++ b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/UserManagementServiceAsync.java @@ -17,6 +17,7 @@ import com.sap.sse.security.shared.dto.AccessControlListDTO; import com.sap.sse.security.shared.dto.OwnershipAnnotationDTO; import com.sap.sse.security.shared.dto.OwnershipDTO; import com.sap.sse.security.shared.dto.RoleDefinitionDTO; +import com.sap.sse.security.shared.dto.StrippedUserGroupDTO; import com.sap.sse.security.shared.dto.UserDTO; import com.sap.sse.security.shared.dto.UserGroupDTO; import com.sap.sse.security.ui.oauth.client.CredentialDTO; @@ -53,6 +54,8 @@ public interface UserManagementServiceAsync { void getUserGroups(AsyncCallback> callback); void getUserGroupByName(String userGroupName, AsyncCallback callback); + + void getStrippedUserGroupByName(String userGroupName, AsyncCallback callback); void createUserGroup(String name, AsyncCallback callback); diff --git a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/UserService.java b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/UserService.java index e164c5eeab8..37acbea77b4 100755 --- a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/UserService.java +++ b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/UserService.java @@ -28,8 +28,8 @@ import com.sap.sse.security.shared.PermissionChecker; import com.sap.sse.security.shared.WildcardPermission; import com.sap.sse.security.shared.dto.AccessControlListDTO; import com.sap.sse.security.shared.dto.OwnershipDTO; +import com.sap.sse.security.shared.dto.StrippedUserGroupDTO; import com.sap.sse.security.shared.dto.UserDTO; -import com.sap.sse.security.shared.dto.UserGroupDTO; import com.sap.sse.security.shared.impl.Ownership; import com.sap.sse.security.shared.impl.SecuredSecurityTypes; import com.sap.sse.security.ui.client.i18n.StringMessages; @@ -415,12 +415,12 @@ public class UserService { new OwnershipDTO(currentUser, getCurrentTenant())); } - public UserGroupDTO getCurrentTenant() { + public StrippedUserGroupDTO getCurrentTenant() { return currentUser == null ? null : currentUser.getDefaultTenant(); } public String getCurrentTenantName() { - final UserGroupDTO defaultTenant = getCurrentTenant(); + final StrippedUserGroupDTO defaultTenant = getCurrentTenant(); return defaultTenant == null ? null : defaultTenant.getName(); } diff --git a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/component/EditAccessControlListDialog.java b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/component/EditAccessControlListDialog.java index 59608fd8c82..5bc6e3fbbc4 100755 --- a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/component/EditAccessControlListDialog.java +++ b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/component/EditAccessControlListDialog.java @@ -23,7 +23,7 @@ import com.sap.sse.gwt.client.dialog.DataEntryDialog; import com.sap.sse.security.shared.QualifiedObjectIdentifier; import com.sap.sse.security.shared.dto.AccessControlListAnnotationDTO; import com.sap.sse.security.shared.dto.AccessControlListDTO; -import com.sap.sse.security.shared.dto.UserGroupDTO; +import com.sap.sse.security.shared.dto.StrippedUserGroupDTO; import com.sap.sse.security.ui.client.UserManagementServiceAsync; import com.sap.sse.security.ui.client.component.EditAccessControlListDialog.AccessControlListData; import com.sap.sse.security.ui.client.i18n.StringMessages; @@ -104,7 +104,7 @@ public class EditAccessControlListDialog extends DataEntryDialog> entry : acl.getAnnotation().getActionsByUserGroup().entrySet()) { + for (Entry> entry : acl.getAnnotation().getActionsByUserGroup().entrySet()) { Label label = new Label(entry.getKey().getName()); labels.add(label); String concatenated = ""; diff --git a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/component/EditOwnershipDialog.java b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/component/EditOwnershipDialog.java index b1dc84ca744..8b70e2c10ee 100644 --- a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/component/EditOwnershipDialog.java +++ b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/component/EditOwnershipDialog.java @@ -20,8 +20,8 @@ import com.sap.sse.security.shared.QualifiedObjectIdentifier; import com.sap.sse.security.shared.dto.OwnershipDTO; import com.sap.sse.security.shared.dto.SecuredDTO; import com.sap.sse.security.shared.dto.StrippedUserDTO; +import com.sap.sse.security.shared.dto.StrippedUserGroupDTO; import com.sap.sse.security.shared.dto.UserDTO; -import com.sap.sse.security.shared.dto.UserGroupDTO; import com.sap.sse.security.ui.client.UserManagementServiceAsync; import com.sap.sse.security.ui.client.component.EditOwnershipDialog.OwnershipDialogResult; import com.sap.sse.security.ui.client.i18n.StringMessages; @@ -35,7 +35,7 @@ public class EditOwnershipDialog extends DataEntryDialog private boolean resolvingUsername; private boolean resolvingUserGroupName; private StrippedUserDTO resolvedUser; - private UserGroupDTO resolvedUserGroup; + private StrippedUserGroupDTO resolvedUserGroup; static class OwnershipDialogResult { private final OwnershipDTO ownership; @@ -131,9 +131,9 @@ public class EditOwnershipDialog extends DataEntryDialog private void resolveUserGroup() { resolvedUserGroup = null; resolvingUserGroupName = true; - userManagementService.getUserGroupByName(groupnameBox.getText(), new AsyncCallback() { + userManagementService.getStrippedUserGroupByName(groupnameBox.getText(), new AsyncCallback() { @Override - public void onSuccess(UserGroupDTO result) { + public void onSuccess(StrippedUserGroupDTO result) { resolvedUserGroup = result; resolvingUserGroupName = false; validateAndUpdate(); diff --git a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/component/editacl/AclEditPanel.java b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/component/editacl/AclEditPanel.java index d9117022cf6..94d7142da94 100644 --- a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/component/editacl/AclEditPanel.java +++ b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/component/editacl/AclEditPanel.java @@ -36,9 +36,10 @@ import com.sap.sse.gwt.client.Notification.NotificationType; import com.sap.sse.gwt.client.controls.listedit.StringListEditorComposite; import com.sap.sse.security.shared.HasPermissions.Action; import com.sap.sse.security.shared.dto.AccessControlListDTO; +import com.sap.sse.security.shared.dto.StrippedUserGroupDTO; import com.sap.sse.security.shared.dto.UserGroupDTO; import com.sap.sse.security.shared.impl.AccessControlList; -import com.sap.sse.security.shared.impl.UserGroup; +import com.sap.sse.security.shared.impl.UserGroupImpl; import com.sap.sse.security.ui.client.UserManagementServiceAsync; import com.sap.sse.security.ui.client.i18n.StringMessages; @@ -63,12 +64,12 @@ public class AclEditPanel extends Composite { private final StringListEditorComposite allowedActionsEditor; private final StringListEditorComposite deniedActionsEditor; - private final SingleSelectionModel userGroupSingleSelectionModel = new SingleSelectionModel<>(); - private CellList userGroupList; + private final SingleSelectionModel userGroupSingleSelectionModel = new SingleSelectionModel<>(); + private CellList userGroupList; // denied actions start with '!' - private Map> userGroupsWithAllowedActions = new HashMap<>(); - private Map> userGroupsWithDeniedActions = new HashMap<>(); + private Map> userGroupsWithAllowedActions = new HashMap<>(); + private Map> userGroupsWithDeniedActions = new HashMap<>(); private UserManagementServiceAsync userManagementService; public AclEditPanel(UserManagementServiceAsync userManagementService, Action[] availableActions, @@ -123,12 +124,12 @@ public class AclEditPanel extends Composite { permissionsCellListPanelUi.add(deniedActionsPanel); } - /** Called when the selected {@link UserGroup} changes. */ + /** Called when the selected {@link UserGroupImpl} changes. */ private void onUserGroupsChange() { removeUserGroupButtonUi.setEnabled(userGroupSingleSelectionModel.getSelectedObject() != null); } - /** @return UI element for selection of {@link UserGroup} elements. */ + /** @return UI element for selection of {@link UserGroupImpl} elements. */ private SuggestBox createUserGroupSuggest(UserManagementServiceAsync userManagementService) { final MultiWordSuggestOracle userGroupOracle = new MultiWordSuggestOracle(); userManagementService.getUserGroups(new AsyncCallback>() { @@ -154,11 +155,11 @@ public class AclEditPanel extends Composite { return suggestBox; } - /** @return the UI element for visualizing {@link UserGroup} elements. */ - private CellList createUserGroupCellList() { - final CellList userGroupCellList = new CellList<>(new AbstractCell() { + /** @return the UI element for visualizing {@link UserGroupImpl} elements. */ + private CellList createUserGroupCellList() { + final CellList userGroupCellList = new CellList<>(new AbstractCell() { @Override - public void render(Context context, UserGroupDTO value, SafeHtmlBuilder sb) { + public void render(Context context, StrippedUserGroupDTO value, SafeHtmlBuilder sb) { if (value != null) { sb.appendEscaped(value.getName()); } @@ -174,7 +175,7 @@ public class AclEditPanel extends Composite { /** * Updates the {@link #allowedActionsEditor} and {@link #deniedActionsEditor} when the selected UserGroup changed. */ - private void updateActionEditors(UserGroupDTO selectedUserGroup) { + private void updateActionEditors(StrippedUserGroupDTO selectedUserGroup) { onUserGroupsChange(); allowedActionsEditor.setValue(userGroupsWithAllowedActions.get(selectedUserGroup), false); deniedActionsEditor @@ -215,11 +216,11 @@ public class AclEditPanel extends Composite { * {@link #deniedActionsEditor}. */ public void updateAcl(AccessControlListDTO acl) { - final Map> combinedActions = (acl != null) + final Map> combinedActions = (acl != null) ? acl.getActionsByUserGroup() != null ? new HashMap<>(acl.getActionsByUserGroup()) : new HashMap<>() : new HashMap<>(); - for (Map.Entry> combinedAction : combinedActions.entrySet()) { + for (Map.Entry> combinedAction : combinedActions.entrySet()) { final Set allowedActions = new HashSet<>(); final Set deniedActions = new HashSet<>(); for (String action : combinedAction.getValue()) { @@ -241,7 +242,7 @@ public class AclEditPanel extends Composite { * {@link #allowedActionsEditor} and {@link #deniedActionsEditor}. */ private void refreshUi() { - final Set combinedKeySet = new HashSet<>(); + final Set combinedKeySet = new HashSet<>(); combinedKeySet.addAll(userGroupsWithAllowedActions.keySet()); combinedKeySet.addAll(userGroupsWithDeniedActions.keySet()); userGroupList.setRowCount(combinedKeySet.size(), true); @@ -258,7 +259,7 @@ public class AclEditPanel extends Composite { final String userGroupName = suggestUserGroupUi.getValue(); // get UserGroup object corresponding to user group name - userManagementService.getUserGroupByName(userGroupName, new AsyncCallback() { + userManagementService.getStrippedUserGroupByName(userGroupName, new AsyncCallback() { @Override public void onFailure(Throwable caught) { Notification.notify(stringMessages.errorMessageUserGroupNameNotFound(userGroupName), @@ -266,7 +267,7 @@ public class AclEditPanel extends Composite { } @Override - public void onSuccess(UserGroupDTO result) { + public void onSuccess(StrippedUserGroupDTO result) { if (result == null) { Notification.notify(stringMessages.errorMessageUserGroupNameNotFound(userGroupName), NotificationType.ERROR); @@ -285,7 +286,7 @@ public class AclEditPanel extends Composite { /** Called when the user clicks on the 'Remove' button */ private void onUserGroupRemove(ClickEvent e) { - UserGroupDTO selectedObject = userGroupSingleSelectionModel.getSelectedObject(); + StrippedUserGroupDTO selectedObject = userGroupSingleSelectionModel.getSelectedObject(); if (selectedObject != null) { userGroupsWithAllowedActions.remove(selectedObject); userGroupsWithDeniedActions.remove(selectedObject); @@ -296,9 +297,9 @@ public class AclEditPanel extends Composite { } /** Merges {@link #userGroupsWithAllowedActions} and {@link #userGroupsWithDeniedActions}. */ - public Map> getUserGroupsWithCombinedActions() { - final Map> combinedActions = new HashMap<>(userGroupsWithAllowedActions); - for (Map.Entry> actionEntry : userGroupsWithDeniedActions.entrySet()) { + public Map> getUserGroupsWithCombinedActions() { + final Map> combinedActions = new HashMap<>(userGroupsWithAllowedActions); + for (Map.Entry> actionEntry : userGroupsWithDeniedActions.entrySet()) { if (combinedActions.containsKey(actionEntry.getKey())) { final Set set = combinedActions.get(actionEntry.getKey()); set.addAll(actionEntry.getValue()); diff --git a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/usermanagement/UserTableWrapper.java b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/usermanagement/UserTableWrapper.java index 9c0069cdd71..2095b45d158 100755 --- a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/usermanagement/UserTableWrapper.java +++ b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/usermanagement/UserTableWrapper.java @@ -43,8 +43,8 @@ import com.sap.sse.security.shared.HasPermissions; import com.sap.sse.security.shared.HasPermissions.DefaultActions; import com.sap.sse.security.shared.WildcardPermission; import com.sap.sse.security.shared.dto.RoleDTO; +import com.sap.sse.security.shared.dto.StrippedUserGroupDTO; import com.sap.sse.security.shared.dto.UserDTO; -import com.sap.sse.security.shared.dto.UserGroupDTO; import com.sap.sse.security.shared.impl.SecuredSecurityTypes; import com.sap.sse.security.ui.client.UserManagementServiceAsync; import com.sap.sse.security.ui.client.UserService; @@ -98,9 +98,9 @@ extends TableWrapper { @Override public SafeHtml getValue(UserDTO user) { SafeHtmlBuilder builder = new SafeHtmlBuilder(); - for (Iterator groupsIter = user.getUserGroups() + for (Iterator groupsIter = user.getUserGroups() .iterator(); groupsIter.hasNext();) { - final UserGroupDTO group = groupsIter.next(); + final StrippedUserGroupDTO group = groupsIter.next(); builder.appendEscaped(group.getName()); if (groupsIter.hasNext()) { builder.appendHtmlConstant("
"); diff --git a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/SecurityDTOFactory.java b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/SecurityDTOFactory.java index 68d7fa0998a..7f87092c69d 100755 --- a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/SecurityDTOFactory.java +++ b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/SecurityDTOFactory.java @@ -28,6 +28,7 @@ import com.sap.sse.security.shared.dto.OwnershipDTO; import com.sap.sse.security.shared.dto.RoleDTO; import com.sap.sse.security.shared.dto.RoleDefinitionDTO; import com.sap.sse.security.shared.dto.StrippedUserDTO; +import com.sap.sse.security.shared.dto.StrippedUserGroupDTO; import com.sap.sse.security.shared.dto.UserDTO; import com.sap.sse.security.shared.dto.UserGroupDTO; import com.sap.sse.security.shared.impl.AccessControlList; @@ -35,13 +36,14 @@ import com.sap.sse.security.shared.impl.Ownership; import com.sap.sse.security.shared.impl.Role; import com.sap.sse.security.shared.impl.User; import com.sap.sse.security.shared.impl.UserGroup; +import com.sap.sse.security.shared.impl.UserGroupImpl; import com.sap.sse.security.ui.oauth.client.SocialUserDTO; import com.sap.sse.security.ui.shared.UsernamePasswordAccountDTO; public class SecurityDTOFactory { private StrippedUserDTO createUserDTOFromUser(User user, Map fromOriginalToStrippedDownUser, - Map fromOriginalToStrippedDownUserGroup) { + Map fromOriginalToStrippedDownUserGroup) { StrippedUserDTO result; if (user == null) { result = null; @@ -57,7 +59,8 @@ public class SecurityDTOFactory { } private UserDTO createUserDTOFromUser(User user, Map fromOriginalToStrippedDownUser, - Map fromOriginalToStrippedDownUserGroup, SecurityService securityService) { + Map fromOriginalToStrippedDownUserGroup, + SecurityService securityService) { UserDTO userDTO; Map accounts = user.getAllAccounts(); List accountDTOs = new ArrayList<>(); @@ -79,11 +82,11 @@ public class SecurityDTOFactory { fromOriginalToStrippedDownUserGroup, securityService), /* default tenant filled in later */ null, user.getPermissions(), - createUserGroupDTOsFromUserGroups(securityService.getUserGroupsOfUser(user), + createStrippedUserGroupDTOsFromUserGroups(securityService.getUserGroupsOfUser(user), fromOriginalToStrippedDownUser, fromOriginalToStrippedDownUserGroup)); fromOriginalToStrippedDownUser.put(user, userDTO); - userDTO.setDefaultTenantForCurrentServer(createUserGroupDTOFromUserGroup(securityService.getDefaultTenantForCurrentUser(), - fromOriginalToStrippedDownUser, + userDTO.setDefaultTenantForCurrentServer(createStrippedUserGroupDTOFromUserGroup( + securityService.getDefaultTenantForCurrentUser(), fromOriginalToStrippedDownUserGroup)); SecurityDTOUtil.addSecurityInformation(this, securityService, userDTO, user.getIdentifier(), fromOriginalToStrippedDownUser, fromOriginalToStrippedDownUserGroup); @@ -93,19 +96,21 @@ public class SecurityDTOFactory { private Iterable createRolesDTOs(Iterable roles, Map fromOriginalToStrippedDownUser, - Map fromOriginalToStrippedDownUserGroup, SecurityService securityService) { + Map fromOriginalToStrippedDownUserGroup, + SecurityService securityService) { return Util.map(roles, role->createRoleDTO(role, fromOriginalToStrippedDownUser, fromOriginalToStrippedDownUserGroup, securityService)); } private RoleDTO createRoleDTO(Role role, Map fromOriginalToStrippedDownUser, - Map fromOriginalToStrippedDownUserGroup, SecurityService securityService) { + Map fromOriginalToStrippedDownUserGroup, + SecurityService securityService) { RoleDefinition rdef = role.getRoleDefinition(); RoleDefinitionDTO rdefDTO = createRoleDefinitionDTO(rdef, securityService, fromOriginalToStrippedDownUser, fromOriginalToStrippedDownUserGroup); RoleDTO mappedRole = new RoleDTO(rdefDTO, - createUserGroupDTOFromUserGroup(role.getQualifiedForTenant(), - fromOriginalToStrippedDownUser, fromOriginalToStrippedDownUserGroup), + createStrippedUserGroupDTOFromUserGroup(role.getQualifiedForTenant(), + fromOriginalToStrippedDownUserGroup), createUserDTOFromUser(role.getQualifiedForUser(), fromOriginalToStrippedDownUser, fromOriginalToStrippedDownUserGroup)); return mappedRole; @@ -113,7 +118,7 @@ public class SecurityDTOFactory { private RoleDefinitionDTO createRoleDefinitionDTO(final RoleDefinition roleDefinition, final SecurityService securityService, final Map fromOriginalToStrippedDownUser, - final Map fromOriginalToStrippedDownUserGroup) { + final Map fromOriginalToStrippedDownUserGroup) { final RoleDefinitionDTO roleDefDTO = new RoleDefinitionDTO(roleDefinition.getId(), roleDefinition.getName(), roleDefinition.getPermissions()); SecurityDTOUtil.addSecurityInformation(this, securityService, roleDefDTO, roleDefinition.getIdentifier(), @@ -129,7 +134,7 @@ public class SecurityDTOFactory { public Iterable createRoleDefinitionDTOs(final Iterable roleDefinitions, final SecurityService securityService) { final Map fromOriginalToStrippedDownUser = new HashMap<>(); - final Map fromOriginalToStrippedDownUserGroup = new HashMap<>(); + final Map fromOriginalToStrippedDownUserGroup = new HashMap<>(); return Util.map(roleDefinitions, roleDefinition -> createRoleDefinitionDTO(roleDefinition, securityService, fromOriginalToStrippedDownUser, fromOriginalToStrippedDownUserGroup)); } @@ -148,23 +153,25 @@ public class SecurityDTOFactory { return createUserDTOFromUser(user, new HashMap<>(), new HashMap<>(), securityService); } - private Iterable createUserGroupDTOsFromUserGroups(Iterable userGroups, + private Iterable createStrippedUserGroupDTOsFromUserGroups( + Iterable userGroups, Map fromOriginalToStrippedDownUser, - Map fromOriginalToStrippedDownUserGroup) { - final List result; + Map fromOriginalToStrippedDownUserGroup) { + final List result; if (userGroups == null) { result = null; } else { result = new ArrayList<>(); for (final UserGroup userGroup : userGroups) { - result.add(createUserGroupDTOFromUserGroup(userGroup, fromOriginalToStrippedDownUser, fromOriginalToStrippedDownUserGroup)); + result.add(createStrippedUserGroupDTOFromUserGroup(userGroup, + fromOriginalToStrippedDownUserGroup)); } } return result; } /** - * Produces a stripped-down {@link UserGroup} object that has stripped-down {@link User} objects + * Produces a stripped-down {@link UserGroupImpl} object that has stripped-down {@link User} objects * with their default tenants stripped down and mapped by this same method recursively where * for a single {@link User} object only a single stripped-down user object will be created, * as will for tenants. @@ -181,9 +188,22 @@ public class SecurityDTOFactory { } else { result = new UserGroupDTO(userGroup.getId(), userGroup.getName()); fromOriginalToStrippedDownUserGroup.put(userGroup, result); - for (final User user : userGroup.getUsers()) { - result.add(createUserDTOFromUser(user, fromOriginalToStrippedDownUser, fromOriginalToStrippedDownUserGroup)); - } + } + } + return result; + } + + public StrippedUserGroupDTO createStrippedUserGroupDTOFromUserGroup(UserGroup userGroup, + Map fromOriginalToStrippedDownUserGroup) { + final StrippedUserGroupDTO result; + if (userGroup == null) { + result = null; + } else { + if (fromOriginalToStrippedDownUserGroup.containsKey(userGroup)) { + result = fromOriginalToStrippedDownUserGroup.get(userGroup); + } else { + result = new StrippedUserGroupDTO(userGroup.getId(), userGroup.getName()); + fromOriginalToStrippedDownUserGroup.put(userGroup, result); } } return result; @@ -191,7 +211,7 @@ public class SecurityDTOFactory { public OwnershipDTO createOwnershipDTO(Ownership ownership, Map fromOriginalToStrippedDownUser, - Map fromOriginalToStrippedDownUserGroup) { + Map fromOriginalToStrippedDownUserGroup) { final OwnershipDTO result; if (ownership == null) { result = null; @@ -199,7 +219,7 @@ public class SecurityDTOFactory { result = new OwnershipDTO( createUserDTOFromUser(ownership.getUserOwner(), fromOriginalToStrippedDownUser, fromOriginalToStrippedDownUserGroup), - createUserGroupDTOFromUserGroup(ownership.getTenantOwner(), fromOriginalToStrippedDownUser, + createStrippedUserGroupDTOFromUserGroup(ownership.getTenantOwner(), fromOriginalToStrippedDownUserGroup)); } return result; @@ -213,9 +233,9 @@ public class SecurityDTOFactory { public AccessControlListAnnotationDTO createAccessControlListAnnotationDTO( AccessControlListAnnotation aclAnnotation, - Map fromOriginalToStrippedDownTenant, + Map fromOriginalToStrippedDownTenant, Map fromOriginalToStrippedDownUser, - Map fromOriginalToStrippedDownUserGroup) { + Map fromOriginalToStrippedDownUserGroup) { return new AccessControlListAnnotationDTO( createAccessControlListDTO(aclAnnotation.getAnnotation(), fromOriginalToStrippedDownUser, fromOriginalToStrippedDownUserGroup), @@ -228,15 +248,15 @@ public class SecurityDTOFactory { public AccessControlListDTO createAccessControlListDTO(AccessControlList acl, Map fromOriginalToStrippedDownUser, - Map fromOriginalToStrippedDownUserGroup) { + Map fromOriginalToStrippedDownUserGroup) { final AccessControlListDTO result; if (acl == null) { result = null; } else { - Map> permissionMapDTO = new HashMap<>(); + Map> permissionMapDTO = new HashMap<>(); for (final Entry> actionForGroup : acl.getActionsByUserGroup().entrySet()) { permissionMapDTO.put( - createUserGroupDTOFromUserGroup(actionForGroup.getKey(), fromOriginalToStrippedDownUser, + createStrippedUserGroupDTOFromUserGroup(actionForGroup.getKey(), fromOriginalToStrippedDownUserGroup), actionForGroup.getValue()); } @@ -253,13 +273,13 @@ public class SecurityDTOFactory { */ public AccessControlListDTO pruneAccessControlListForUser(AccessControlListDTO acl, StrippedUserDTO filterForUser) { final AccessControlListDTO result; - final Collection userGroups = Util.createSet(filterForUser.getUserGroups()); + final Collection userGroups = Util.createSet(filterForUser.getUserGroups()); if (acl != null) { - final Map> actionsByUserGroup = new HashMap<>(); - for (final Entry> entry : acl.getActionsByUserGroup().entrySet()) { + final Map> actionsByUserGroup = new HashMap<>(); + for (final Entry> entry : acl.getActionsByUserGroup().entrySet()) { if (userGroups.contains(entry.getKey())) { - UserGroupDTO key = entry.getKey(); + StrippedUserGroupDTO key = entry.getKey(); actionsByUserGroup.put(key, entry.getValue()); } } @@ -290,7 +310,7 @@ public class SecurityDTOFactory { public StrippedUserDTO createStrippedUserFromUser(User user, SecurityService securityService, Map fromOriginalToStrippedDownUser, - Map fromOriginalToStrippedDownUserGroup) { + Map fromOriginalToStrippedDownUserGroup) { StrippedUserDTO mappedUser = fromOriginalToStrippedDownUser.get(user); if (mappedUser == null) { Iterable roles = user.getRoles(); diff --git a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/SecurityDTOUtil.java b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/SecurityDTOUtil.java index 484957ba1f4..2b97622609c 100644 --- a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/SecurityDTOUtil.java +++ b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/SecurityDTOUtil.java @@ -12,12 +12,13 @@ import com.sap.sse.security.shared.dto.AccessControlListDTO; import com.sap.sse.security.shared.dto.NamedSecuredObjectDTO; import com.sap.sse.security.shared.dto.SecuredDTO; import com.sap.sse.security.shared.dto.StrippedUserDTO; +import com.sap.sse.security.shared.dto.StrippedUserGroupDTO; import com.sap.sse.security.shared.dto.UserDTO; -import com.sap.sse.security.shared.dto.UserGroupDTO; import com.sap.sse.security.shared.impl.AccessControlList; import com.sap.sse.security.shared.impl.Ownership; import com.sap.sse.security.shared.impl.User; import com.sap.sse.security.shared.impl.UserGroup; +import com.sap.sse.security.shared.impl.UserGroupImpl; public abstract class SecurityDTOUtil { @@ -61,7 +62,7 @@ public abstract class SecurityDTOUtil { public static void addSecurityInformation(final SecurityDTOFactory securityDTOFactory, final SecurityService securityService, final SecuredDTO securedObject, final QualifiedObjectIdentifier objectId, Map fromOriginalToStrippedDownUser, - Map fromOriginalToStrippedDownUserGroup) { + Map fromOriginalToStrippedDownUserGroup) { addSecurityInformation(securityDTOFactory, securityService, securedObject, objectId, fromOriginalToStrippedDownUser, fromOriginalToStrippedDownUserGroup, false); } @@ -69,11 +70,11 @@ public abstract class SecurityDTOUtil { /** * Adds {@link AccessControlList access control list} and {@link Ownership ownership} information for the given * {@link QualifiedObjectIdentifier qualified object identifier} to the provided {@link NamedSecuredObjectDTO - * secured object DTO} by using the provided mappings of {@link SecurityUser users} and {@link UserGroup user + * secured object DTO} by using the provided mappings of {@link SecurityUser users} and {@link UserGroupImpl user * groups}. *

* NOTE: This method can be used to reuse already stripped down {@link SecurityUser users} or - * {@link UserGroup user groups} in order to avoid multiple mappings of the the same instances. However, it must be + * {@link UserGroupImpl user groups} in order to avoid multiple mappings of the the same instances. However, it must be * used with caution, especially in the context of one or more {@link UserDTO} instances, which themselves contain * ownership information. Reusing an {@link UserDTO} as user owner object might cause infinite relation paths. *

@@ -89,13 +90,13 @@ public abstract class SecurityDTOUtil { * @param fromOriginalToStrippedDownUser * the {@link Map} to stripped down {@link SecurityUser user}s to use * @param fromOriginalToStrippedDownUserGroup - * the {@link Map} to stripped down {@link UserGroup user group}s to use + * the {@link Map} to stripped down {@link UserGroupImpl user group}s to use */ public static void addSecurityInformation(final SecurityDTOFactory securityDTOFactory, final SecurityService securityService, final SecuredDTO securedObject, final QualifiedObjectIdentifier objectId, final Map fromOriginalToStrippedDownUser, - final Map fromOriginalToStrippedDownUserGroup, + final Map fromOriginalToStrippedDownUserGroup, final boolean disablePruningForCurrentUser) { final AccessControlListAnnotation accessControlList = securityService.getAccessControlList(objectId); AccessControlListDTO accessControlListDTO = securityDTOFactory.createAccessControlListDTO( diff --git a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/UserManagementServiceImpl.java b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/UserManagementServiceImpl.java index 578641ecefc..a1bb53ee7db 100644 --- a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/UserManagementServiceImpl.java +++ b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/UserManagementServiceImpl.java @@ -33,18 +33,9 @@ import com.sap.sse.common.Util.Triple; import com.sap.sse.common.mail.MailException; import com.sap.sse.security.Credential; import com.sap.sse.security.SecurityService; -import com.sap.sse.security.UserImpl; import com.sap.sse.security.shared.AccessControlListAnnotation; import com.sap.sse.security.shared.AdminRole; import com.sap.sse.security.shared.HasPermissions.DefaultActions; -import com.sap.sse.security.shared.dto.AccessControlListAnnotationDTO; -import com.sap.sse.security.shared.dto.AccessControlListDTO; -import com.sap.sse.security.shared.dto.OwnershipAnnotationDTO; -import com.sap.sse.security.shared.dto.OwnershipDTO; -import com.sap.sse.security.shared.dto.RoleDefinitionDTO; -import com.sap.sse.security.shared.dto.StrippedUserDTO; -import com.sap.sse.security.shared.dto.UserDTO; -import com.sap.sse.security.shared.dto.UserGroupDTO; import com.sap.sse.security.shared.OwnershipAnnotation; import com.sap.sse.security.shared.QualifiedObjectIdentifier; import com.sap.sse.security.shared.RoleDefinition; @@ -52,12 +43,21 @@ import com.sap.sse.security.shared.UnauthorizedException; import com.sap.sse.security.shared.UserGroupManagementException; import com.sap.sse.security.shared.UserManagementException; import com.sap.sse.security.shared.WildcardPermission; +import com.sap.sse.security.shared.dto.AccessControlListAnnotationDTO; +import com.sap.sse.security.shared.dto.AccessControlListDTO; +import com.sap.sse.security.shared.dto.OwnershipAnnotationDTO; +import com.sap.sse.security.shared.dto.OwnershipDTO; +import com.sap.sse.security.shared.dto.RoleDefinitionDTO; +import com.sap.sse.security.shared.dto.StrippedUserDTO; +import com.sap.sse.security.shared.dto.StrippedUserGroupDTO; +import com.sap.sse.security.shared.dto.UserDTO; +import com.sap.sse.security.shared.dto.UserGroupDTO; import com.sap.sse.security.shared.impl.Ownership; import com.sap.sse.security.shared.impl.Role; import com.sap.sse.security.shared.impl.SecuredSecurityTypes; +import com.sap.sse.security.shared.impl.SecuredSecurityTypes.UserActions; import com.sap.sse.security.shared.impl.User; import com.sap.sse.security.shared.impl.UserGroup; -import com.sap.sse.security.shared.impl.SecuredSecurityTypes.UserActions; import com.sap.sse.security.ui.client.UserManagementService; import com.sap.sse.security.ui.oauth.client.CredentialDTO; import com.sap.sse.security.ui.oauth.shared.OAuthException; @@ -220,8 +220,7 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U private UserGroup getUserGroup(String groupIdAsString) { UUID groupId = UUID.fromString(groupIdAsString); - UserGroup userGroup = getSecurityService().getUserGroup(groupId); - return userGroup; + return getSecurityService().getUserGroup(groupId); } @Override @@ -259,6 +258,19 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U } } + @Override + public StrippedUserGroupDTO getStrippedUserGroupByName(String userGroupName) throws UnauthorizedException { + final UserGroup userGroup = getSecurityService().getUserGroupByName(userGroupName); + if (userGroup == null || SecurityUtils.getSubject().isPermitted(SecuredSecurityTypes.USER_GROUP + .getStringPermissionForObjects(DefaultActions.READ, userGroup.getId().toString()))) { + Map fromOriginalToStrippedDownUserGroup = new HashMap<>(); + return securityDTOFactory.createStrippedUserGroupDTOFromUserGroup(userGroup, + fromOriginalToStrippedDownUserGroup); + } else { + throw new UnauthorizedException("Not permitted to read user group " + userGroupName); + } + } + @Override public UserDTO getUserByName(String username) throws UnauthorizedException { final User user = getSecurityService().getUserByName(username); @@ -387,7 +399,7 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U public UserDTO createSimpleUser(String username, String email, String password, String fullName, String company, String localeName, String validationBaseURL) throws UserManagementException, MailException, UnauthorizedException { - final UserImpl u = getSecurityService().setOwnershipCheckPermissionForObjectCreationAndRevertOnError( + final User u = getSecurityService().setOwnershipCheckPermissionForObjectCreationAndRevertOnError( SecuredSecurityTypes.USER, username, username, () -> { try { return getSecurityService().createSimpleUser(username, email, password, fullName, company, @@ -807,9 +819,9 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U if (SecurityUtils.getSubject() .isPermitted(idOfAccessControlledObject.getStringPermission(DefaultActions.CHANGE_ACL))) { - Map> aclActionsByGroup = new HashMap<>(); - for (Map.Entry> entry : acl.getActionsByUserGroup().entrySet()) { - final UserGroupDTO groupDTO = entry.getKey(); + Map> aclActionsByGroup = new HashMap<>(); + for (Entry> entry : acl.getActionsByUserGroup().entrySet()) { + final StrippedUserGroupDTO groupDTO = entry.getKey(); final UserGroup userGroup; if (groupDTO == null) { userGroup = null; @@ -840,5 +852,4 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U throw new UnauthorizedException("Not permitted to get the unpruned ACL for a user"); } } - } diff --git a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/userprofile/shared/userdetails/AbstractUserDetails.java b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/userprofile/shared/userdetails/AbstractUserDetails.java index bfd7ec60dcb..050a396d462 100644 --- a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/userprofile/shared/userdetails/AbstractUserDetails.java +++ b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/userprofile/shared/userdetails/AbstractUserDetails.java @@ -15,8 +15,8 @@ import com.google.gwt.user.client.ui.ValueListBox; import com.google.gwt.user.client.ui.Widget; import com.sap.sse.common.Util; import com.sap.sse.gwt.client.GWTLocaleUtil; +import com.sap.sse.security.shared.dto.StrippedUserGroupDTO; import com.sap.sse.security.shared.dto.UserDTO; -import com.sap.sse.security.shared.dto.UserGroupDTO; import com.sap.sse.security.ui.client.i18n.StringMessages; /** @@ -88,10 +88,10 @@ public class AbstractUserDetails extends Composite implements UserDetailsView { } private void updateDefaultTenantSelection(UserDTO currentUser) { - UserGroupDTO defaultTennant = currentUser.getDefaultTenant(); + StrippedUserGroupDTO defaultTennant = currentUser.getDefaultTenant(); defaultTenantUi.clear(); int i = 0; - for (UserGroupDTO group : currentUser.getUserGroups()) { + for (StrippedUserGroupDTO group : currentUser.getUserGroups()) { defaultTenantUi.addItem(group.getName(), group.getId().toString()); if (Util.equalsWithNull(group, defaultTennant)) { defaultTenantUi.setSelectedIndex(i); diff --git a/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/DomainObjectFactory.java b/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/DomainObjectFactory.java index d6b9739f0bb..28c66821e88 100644 --- a/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/DomainObjectFactory.java +++ b/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/DomainObjectFactory.java @@ -12,6 +12,7 @@ import com.sap.sse.security.shared.SecurityUser; import com.sap.sse.security.shared.UserManagementException; import com.sap.sse.security.shared.impl.User; import com.sap.sse.security.shared.impl.UserGroup; +import com.sap.sse.security.shared.impl.UserGroupImpl; import com.sap.sse.security.userstore.mongodb.impl.FieldNames.Tenant; public interface DomainObjectFactory { @@ -22,11 +23,11 @@ public interface DomainObjectFactory { Iterable loadAllRoleDefinitions(); /** - * Loads user groups and tenants from the persistent store. The users {@link UserGroup#getUsers() contained} therein + * Loads user groups and tenants from the persistent store. The users {@link UserGroupImpl#getUsers() contained} therein * are proxies and must be replaced by the caller once the real {@link SecurityUser} objects have been loaded from * the store. The proxies only have the correct {@link SecurityUser#getName() name} field set which also acts as the - * {@link SecurityUser#getId() user ID}. {@link UserGroup#remove(SecurityUser)} and - * {@link UserGroup#add(SecurityUser)} have to be used for this process. + * {@link SecurityUser#getId() user ID}. {@link UserGroupImpl#remove(SecurityUser)} and + * {@link UserGroupImpl#add(SecurityUser)} have to be used for this process. *

*/ Iterable loadAllUserGroupsAndTenantsWithProxyUsers(); diff --git a/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/UserStoreImpl.java b/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/UserStoreImpl.java index b287f221436..0c5e68b1322 100644 --- a/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/UserStoreImpl.java +++ b/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/UserStoreImpl.java @@ -40,6 +40,7 @@ import com.sap.sse.security.shared.impl.Ownership; import com.sap.sse.security.shared.impl.Role; import com.sap.sse.security.shared.impl.User; import com.sap.sse.security.shared.impl.UserGroup; +import com.sap.sse.security.shared.impl.UserGroupImpl; import com.sap.sse.security.userstore.mongodb.impl.FieldNames.Tenant; /** @@ -48,8 +49,8 @@ import com.sap.sse.security.userstore.mongodb.impl.FieldNames.Tenant; * therefore not perform any changes to the database. This is also the reason why all access to the * {@link #mongoObjectFactory} field needs to be null-safe.

* - * The storage pattern for {@link UserGroup} and {@link Tenant} objects deserves some explanation. As a {@link Tenant} - * is a specialized {@link UserGroup}, this store mainly needs to keep track of the users in that {@link Tenant}. Hence, + * The storage pattern for {@link UserGroupImpl} and {@link Tenant} objects deserves some explanation. As a {@link Tenant} + * is a specialized {@link UserGroupImpl}, this store mainly needs to keep track of the users in that {@link Tenant}. Hence, * the same collection is used for the storage of these user lists, and hence the same methods can be used for * maintaining this collection. Additionally, the tenant ID is stored in a separate collection as a "marker" which * entries in the user groups collection are actually tenants and not only user groups. @@ -68,7 +69,7 @@ public class UserStoreImpl implements UserStore { /** * If a valid default tenant name was passed to the constructor, this field will contain a valid - * {@link UserGroup} object whose name equals that of the default tenant name. It will have been used + * {@link UserGroupImpl} object whose name equals that of the default tenant name. It will have been used * during role migration where string-based roles are mapped to a corresponding {@link RoleDefinition} * and the users with the original role will obtain a corresponding {@link Role} with this default * tenant as the {@link Role#getQualifiedForTenant() tenant qualifier}. @@ -80,14 +81,14 @@ public class UserStoreImpl implements UserStore { /** * Protects access to the two maps {@link #userGroupsContainingUser} and {@link #usersInUserGroups} which implement - * an efficient lookup for the m:n association between {@link UserGroup#getUsers()} and {@link SecurityUser}. The + * an efficient lookup for the m:n association between {@link UserGroupImpl#getUsers()} and {@link SecurityUser}. The * collections also contain the relationships for the specialized {@link Tenant} objects which are not part of * {@link #userGroups} but of {@link #tenants}. */ private final NamedReentrantReadWriteLock userGroupsUserCacheLock = new NamedReentrantReadWriteLock("User Groups Cache", /* fair */ false); private final ConcurrentHashMap> userGroupsContainingUser; /** - * This collection is important in particular to detect changes when {@link #updateUserGroup(UserGroup)} is called. + * This collection is important in particular to detect changes when {@link #updateUserGroup(UserGroupImpl)} is called. */ private final ConcurrentHashMap> usersInUserGroups; @@ -211,6 +212,9 @@ public class UserStoreImpl implements UserStore { Util.addToValueSet(userGroupsContainingUser, userInGroup, group); } } + // FIXME check for non migrated users, those are leftovers that are in some groups but have no user object + // anymore, remove them from the groups! + for (Entry> e : preferences.entrySet()) { if (e.getValue() != null) { final String accessToken = e.getValue().get(ACCESS_TOKEN_KEY); @@ -546,12 +550,12 @@ public class UserStoreImpl implements UserStore { } @Override - public UserGroup createUserGroup(UUID groupId, String name) throws UserGroupManagementException { + public UserGroupImpl createUserGroup(UUID groupId, String name) throws UserGroupManagementException { if (userGroups.contains(groupId)) { throw new UserGroupManagementException(UserGroupManagementException.USER_GROUP_ALREADY_EXISTS); } logger.info("Creating user group: " + groupId + " with name "+name); - UserGroup group = new UserGroup(new HashSet(), groupId, name); + UserGroupImpl group = new UserGroupImpl(new HashSet(), groupId, name); if (mongoObjectFactory != null) { mongoObjectFactory.storeUserGroup(group); } @@ -598,7 +602,7 @@ public class UserStoreImpl implements UserStore { } finally { LockUtil.unlockAfterRead(userGroupsUserCacheLock); } - return preResult == null ? Collections.emptySet() : preResult; + return preResult == null ? Collections. emptySet() : preResult; } @Override @@ -628,13 +632,14 @@ public class UserStoreImpl implements UserStore { } @Override - public UserImpl createUser(String name, String email, UserGroup defaultTenant, Account... accounts) throws UserManagementException { + public User createUser(String name, String email, UserGroup defaultTenant, Account... accounts) + throws UserManagementException { if (getUserByName(name) != null) { throw new UserManagementException(UserManagementException.USER_ALREADY_EXISTS); } ConcurrentHashMap tenantsForServer = new ConcurrentHashMap<>(); tenantsForServer.put(ServerInfo.getName(), defaultTenant); - UserImpl user = new UserImpl(name, email, tenantsForServer, /* user group provider */ this, accounts); + User user = new UserImpl(name, email, tenantsForServer, /* user group provider */ this, accounts); logger.info("Creating user: " + user + " with e-mail "+email); if (mongoObjectFactory != null) { mongoObjectFactory.storeUser(user); diff --git a/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/impl/DomainObjectFactoryImpl.java b/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/impl/DomainObjectFactoryImpl.java index 6719faf1084..a7e384f7a15 100644 --- a/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/impl/DomainObjectFactoryImpl.java +++ b/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/impl/DomainObjectFactoryImpl.java @@ -39,6 +39,7 @@ import com.sap.sse.security.shared.impl.QualifiedObjectIdentifierImpl; import com.sap.sse.security.shared.impl.Role; import com.sap.sse.security.shared.impl.User; import com.sap.sse.security.shared.impl.UserGroup; +import com.sap.sse.security.shared.impl.UserGroupImpl; import com.sap.sse.security.userstore.mongodb.DomainObjectFactory; import com.sap.sse.security.userstore.mongodb.impl.FieldNames.Tenant; @@ -162,8 +163,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory { users.add(new UserProxy((String) o)); } } - UserGroup result = new UserGroup(users, id, name); - return result; + return new UserGroupImpl(users, id, name); } /** @@ -231,8 +231,9 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory { * {@link Role#getQualifiedForUser() user qualifier} where only the username is set properly to identify the * user in the calling method where ultimately all users will be known. */ - private UserImpl loadUserWithProxyRoleUserQualifiers(DBObject userDBObject, - Map roleDefinitionsById, UserGroup defaultTenantForRoleMigration, Map tenants, UserGroupProvider userGroupProvider) { + private User loadUserWithProxyRoleUserQualifiers(DBObject userDBObject, + Map roleDefinitionsById, UserGroup defaultTenantForRoleMigration, + Map tenants, UserGroupProvider userGroupProvider) { final String name = (String) userDBObject.get(FieldNames.User.NAME.name()); final String email = (String) userDBObject.get(FieldNames.User.EMAIL.name()); final String fullName = (String) userDBObject.get(FieldNames.User.FULLNAME.name()); @@ -311,7 +312,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory { } DBObject accountsMap = (DBObject) userDBObject.get(FieldNames.User.ACCOUNTS.name()); Map accounts = createAccountMapFromdDBObject(accountsMap); - UserImpl result = new UserImpl(name, email, fullName, company, locale, + User result = new UserImpl(name, email, fullName, company, locale, emailValidated == null ? false : emailValidated, passwordResetSecret, validationSecret, defaultTenant, accounts.values(), userGroupProvider); for (final Role role : roles) { @@ -330,7 +331,8 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory { return result; } - private Role loadRoleWithProxyUserQualifier(DBObject rolesO, Map roleDefinitionsById, Map userGroups) { + private Role loadRoleWithProxyUserQualifier(DBObject rolesO, Map roleDefinitionsById, + Map userGroups) { final RoleDefinition roleDefinition = roleDefinitionsById.get(rolesO.get(FieldNames.Role.ID.name())); final UUID qualifyingTenantId = (UUID) rolesO.get(FieldNames.Role.QUALIFYING_TENANT_ID.name()); final UserGroup qualifyingTenant = qualifyingTenantId == null ? null : userGroups.get(qualifyingTenantId); diff --git a/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/impl/MongoObjectFactoryImpl.java b/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/impl/MongoObjectFactoryImpl.java index 3796517d420..078b15f59b0 100644 --- a/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/impl/MongoObjectFactoryImpl.java +++ b/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/impl/MongoObjectFactoryImpl.java @@ -177,7 +177,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { dbUser.put(FieldNames.User.PERMISSIONS.name(), dbPermissions); List defaultTennants = new BasicDBList(); - for(Entry entries:user.getDefaultTenantMap().entrySet()) { + for (Entry entries : user.getDefaultTenantMap().entrySet()) { BasicDBObject tenant = new BasicDBObject(); tenant.put(FieldNames.User.DEFAULT_TENANT_SERVER.name(), entries.getKey()); tenant.put(FieldNames.User.DEFAULT_TENANT_GROUP.name(), entries.getValue().getId()); diff --git a/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/impl/UserProxy.java b/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/impl/UserProxy.java index c0934c3fee3..c34302be887 100644 --- a/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/impl/UserProxy.java +++ b/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/impl/UserProxy.java @@ -12,6 +12,7 @@ import com.sap.sse.security.shared.WildcardPermission; import com.sap.sse.security.shared.impl.Role; import com.sap.sse.security.shared.impl.User; import com.sap.sse.security.shared.impl.UserGroup; +import com.sap.sse.security.shared.impl.UserGroupImpl; public class UserProxy implements User { private static final long serialVersionUID = 1L; @@ -177,7 +178,7 @@ public class UserProxy implements User { } @Override - public UserGroup getDefaultTenant(String serverName) { + public UserGroupImpl getDefaultTenant(String serverName) { throw new UnsupportedOperationException(); } diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/AccessControlStore.java b/java/com.sap.sse.security/src/com/sap/sse/security/AccessControlStore.java index 4bb76312b4f..78d5bb7f801 100755 --- a/java/com.sap.sse.security/src/com/sap/sse/security/AccessControlStore.java +++ b/java/com.sap.sse.security/src/com/sap/sse/security/AccessControlStore.java @@ -24,10 +24,16 @@ public interface AccessControlStore extends Named { * @param displayNameOfAccessControlledObject the display name of the object the ACL is attached to */ AccessControlListAnnotation setEmptyAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject, String displayNameOfAccessControlledObject); - void setAclPermissions(QualifiedObjectIdentifier idOfAccessControlledObject, UserGroup userGroup, Set actions); + + void setAclPermissions(QualifiedObjectIdentifier idOfAccessControlledObject, UserGroup userGroup, + Set actions); + void addAclPermission(QualifiedObjectIdentifier idOfAccessControlledObject, UserGroup userGroup, String action); + void removeAclPermission(QualifiedObjectIdentifier idOfAccessControlledObject, UserGroup userGroup, String action); + void removeAclDenial(QualifiedObjectIdentifier idOfAccessControlledObject, UserGroup userGroup, String action); + void denyAclPermission(QualifiedObjectIdentifier idOfAccessControlledObject, UserGroup userGroup, String action); void removeAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject); diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/SecurityService.java b/java/com.sap.sse.security/src/com/sap/sse/security/SecurityService.java index bb8a2454a87..c77f186bd40 100755 --- a/java/com.sap.sse.security/src/com/sap/sse/security/SecurityService.java +++ b/java/com.sap.sse.security/src/com/sap/sse/security/SecurityService.java @@ -74,7 +74,8 @@ public interface SecurityService extends ReplicableWithObjectInputStream> permissionMap); + AccessControlList updateAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject, + Map> permissionMap); AccessControlList overrideAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject, Map> permissionMap); @@ -82,12 +83,14 @@ public interface SecurityService extends ReplicableWithObjectInputStreamnull, no validation will be attempted */ - UserImpl createSimpleUser(String username, String email, String password, String fullName, String company, + User createSimpleUser(String username, String email, String password, String fullName, String company, Locale locale, String validationBaseURL) throws UserManagementException, MailException, UserGroupManagementException; diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/UserStore.java b/java/com.sap.sse.security/src/com/sap/sse/security/UserStore.java index 926dd252a5a..698f9473993 100644 --- a/java/com.sap.sse.security/src/com/sap/sse/security/UserStore.java +++ b/java/com.sap.sse.security/src/com/sap/sse/security/UserStore.java @@ -15,9 +15,10 @@ import com.sap.sse.security.shared.impl.Ownership; import com.sap.sse.security.shared.impl.Role; import com.sap.sse.security.shared.impl.User; import com.sap.sse.security.shared.impl.UserGroup; +import com.sap.sse.security.shared.impl.UserGroupImpl; /** - * Keeps track of all {@link User}, {@link UserGroup} and {@link Role} + * Keeps track of all {@link User}, {@link UserGroupImpl} and {@link Role} * objects persistently; furthermore, aspects such as user access tokens, preferences and * settings are stored durably.

* @@ -60,7 +61,8 @@ public interface UserStore extends UserGroupProvider, Named { User getUserByAccessToken(String accessToken); - UserImpl createUser(String name, String email, UserGroup defaultTenant, Account... accounts) throws UserManagementException; + User createUser(String name, String email, UserGroup defaultTenant, Account... accounts) + throws UserManagementException; void updateUser(User user); @@ -220,7 +222,7 @@ public interface UserStore extends UserGroupProvider, Named { /** * If a valid default tenant name was passed to the constructor, this field will contain a valid - * {@link UserGroup} object whose name equals that of the default tenant name. It will have been used + * {@link UserGroupImpl} object whose name equals that of the default tenant name. It will have been used * during role migration where string-based roles are mapped to a corresponding {@link RoleDefinition} * and the users with the original role will obtain a corresponding {@link Role} with this default * tenant as the {@link Role#getQualifiedForTenant() tenant qualifier}. diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/impl/SecurityServiceImpl.java b/java/com.sap.sse.security/src/com/sap/sse/security/impl/SecurityServiceImpl.java index d1c5a2be43d..45c0d070f5f 100644 --- a/java/com.sap.sse.security/src/com/sap/sse/security/impl/SecurityServiceImpl.java +++ b/java/com.sap.sse.security/src/com/sap/sse/security/impl/SecurityServiceImpl.java @@ -120,9 +120,9 @@ import com.sap.sse.security.shared.impl.AccessControlList; import com.sap.sse.security.shared.impl.Ownership; import com.sap.sse.security.shared.impl.Role; import com.sap.sse.security.shared.impl.SecuredSecurityTypes; +import com.sap.sse.security.shared.impl.SecuredSecurityTypes.ServerActions; import com.sap.sse.security.shared.impl.User; import com.sap.sse.security.shared.impl.UserGroup; -import com.sap.sse.security.shared.impl.SecuredSecurityTypes.ServerActions; import com.sap.sse.util.ClearStateTestSupport; public class SecurityServiceImpl implements ReplicableSecurityService, ClearStateTestSupport { @@ -431,7 +431,8 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat } @Override - public AccessControlList updateAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject, Map> permissionMap) { + public AccessControlList updateAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject, + Map> permissionMap) { if (getAccessControlList(idOfAccessControlledObject) == null) { setEmptyAccessControlList(idOfAccessControlledObject); } @@ -454,7 +455,8 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat * @param name The name of the user group to add */ @Override - public AccessControlList addToAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject, UserGroup group, String action) { + public AccessControlList addToAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject, + UserGroup group, String action) { if (getAccessControlList(idOfAccessControlledObject) == null) { setEmptyAccessControlList(idOfAccessControlledObject); } @@ -473,7 +475,8 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat * @param name The name of the user group to remove */ @Override - public AccessControlList removeFromAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObjectAsString, UserGroup group, String permission) { + public AccessControlList removeFromAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObjectAsString, + UserGroup group, String permission) { final AccessControlList result; if (getAccessControlList(idOfAccessControlledObjectAsString) != null) { final UUID groupId = group.getId(); @@ -702,14 +705,14 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat } @Override - public UserImpl createSimpleUser(final String username, final String email, String password, String fullName, + public User createSimpleUser(final String username, final String email, String password, String fullName, String company, Locale locale, final String validationBaseURL) throws UserManagementException, MailException, UserGroupManagementException { return createSimpleUser(username, email, password, fullName, company, locale, validationBaseURL, getDefaultTenantForCurrentUser()); } - private UserImpl createSimpleUser(final String username, final String email, String password, String fullName, + private User createSimpleUser(final String username, final String email, String password, String fullName, String company, Locale locale, final String validationBaseURL, UserGroup userOwner) throws UserManagementException, MailException, UserGroupManagementException { logger.info("Creating user "+username); @@ -735,7 +738,7 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat byte[] salt = rng.nextBytes().getBytes(); String hashedPasswordBase64 = hashPassword(password, salt); UsernamePasswordAccount upa = new UsernamePasswordAccount(username, hashedPasswordBase64, salt); - final UserImpl result = createUserInternal(username, email, tenant, upa); + final User result = createUserInternal(username, email, tenant, upa); addRoleForUser(result, new Role(UserRole.getInstance(), /* tenant qualifier */ null, /* user qualifier */ result)); addUserToUserGroup(tenant, result); @@ -769,8 +772,10 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat return result; } - private UserImpl createUserInternal(String username, String email, UserGroup defaultTenant, Account... accounts) throws UserManagementException { - final UserImpl result = userStore.createUser(username, email, defaultTenant, accounts); // TODO: get the principal as owner + private User createUserInternal(String username, String email, UserGroup defaultTenant, Account... accounts) + throws UserManagementException { + final User result = userStore.createUser(username, email, defaultTenant, accounts); // TODO: get the principal + // as owner // now the user creation needs to be replicated so that when replicating role addition and group assignment // the replica will be able to resolve the user correctly apply(s -> s.internalStoreUser(result));