mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-25 06:58:39 +00:00
more consistent user/group/tenant handling and serialization
Change-Id: Ib7621e2cbddb913db0e32e2607d122e38505d87b
This commit is contained in:
+11
-2
@@ -1,7 +1,6 @@
|
||||
package com.sap.sailing.domain.common.security;
|
||||
|
||||
|
||||
|
||||
import com.sap.sse.security.shared.WildcardPermission;
|
||||
|
||||
public enum Permission implements com.sap.sse.security.shared.Permission {
|
||||
// AdminConsole permissions
|
||||
@@ -63,6 +62,11 @@ public enum Permission implements com.sap.sse.security.shared.Permission {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WildcardPermission getPermission(com.sap.sse.security.shared.Permission.Mode... modes) {
|
||||
return new WildcardPermission(getStringPermission(modes));
|
||||
}
|
||||
|
||||
// TODO once we can use Java8 here, move this up into a "default" method on the Permission interface
|
||||
@Override
|
||||
public String getStringPermissionForObjects(com.sap.sse.security.shared.Permission.Mode mode, String... objectIdentifiers) {
|
||||
@@ -82,6 +86,11 @@ public enum Permission implements com.sap.sse.security.shared.Permission {
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WildcardPermission getPermissionForObjects(com.sap.sse.security.shared.Permission.Mode mode, String... objectIdentifiers) {
|
||||
return new WildcardPermission(getStringPermissionForObjects(mode, objectIdentifiers));
|
||||
}
|
||||
|
||||
/**
|
||||
* The mode of interaction with a resource; used as the second element of a wildcard permission
|
||||
*
|
||||
|
||||
+6
-5
@@ -352,11 +352,12 @@ public class EventListComposite extends Composite implements EventsRefresher, Le
|
||||
public Iterable<Action> getAllowedActions(EventDTO event) {
|
||||
ArrayList<Action> allowedActions = new ArrayList<>();
|
||||
for (Action action : Arrays.asList(DefaultActions.EDIT, DefaultActions.REMOVE)) {
|
||||
if (user.hasPermission(
|
||||
PermissionBuilderImpl.getInstance().getPermission("com.sap.sailing.domain.base.Event", action, event.id.toString()),
|
||||
event.getAcl(), event.getOwnership())) {
|
||||
allowedActions.add(action);
|
||||
}
|
||||
if (user.hasPermission(
|
||||
PermissionBuilderImpl.getInstance().getPermission(
|
||||
"com.sap.sailing.domain.base.Event", action, event.id.toString()),
|
||||
event.getOwnership(), event.getAcl())) {
|
||||
allowedActions.add(action);
|
||||
}
|
||||
}
|
||||
return allowedActions;
|
||||
}
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ public class RaceTimePanel extends TimePanel<RaceTimePanelSettings> implements R
|
||||
@Override
|
||||
public void onUserStatusChange(UserDTO user, boolean preAuthenticated) {
|
||||
RaceTimePanel.this.hasCanReplayDuringLiveRacesPermission = user != null && user.hasPermission(
|
||||
Permission.CAN_REPLAY_DURING_LIVE_RACES.getStringPermission());
|
||||
Permission.CAN_REPLAY_DURING_LIVE_RACES.getPermission(), /* TODO race ownership */ null, /* TODO race acl */ null);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -489,7 +489,7 @@ public class MediaPlayerManagerComponent extends AbstractComponent<MediaPlayerSe
|
||||
final VideoSynchPlayer videoPlayer;
|
||||
final UserDTO currentUser = userService.getCurrentUser();
|
||||
boolean showSynchControls = currentUser != null
|
||||
&& currentUser.hasPermission(Permission.MANAGE_MEDIA.getStringPermission());
|
||||
&& currentUser.hasPermission(Permission.MANAGE_MEDIA.getPermission(), /* TODO race ownership */ null, /* TODO race ACL */ null);
|
||||
if (videoTrack.isYoutube()) {
|
||||
videoPlayer = new VideoYoutubePlayer(videoTrack, getRaceStartTime(), showSynchControls, raceTimer);
|
||||
} else {
|
||||
@@ -673,7 +673,7 @@ public class MediaPlayerManagerComponent extends AbstractComponent<MediaPlayerSe
|
||||
public boolean allowsEditing() {
|
||||
UserDTO currentUser = userService.getCurrentUser();
|
||||
return currentUser != null
|
||||
&& currentUser.hasPermission(Permission.MANAGE_MEDIA.getStringPermission());
|
||||
&& currentUser.hasPermission(Permission.MANAGE_MEDIA.getPermission(), /* TODO race ownership */ null, /* TODO race ACL */ null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-2
@@ -307,7 +307,7 @@ public class SideBySideComponentViewer implements UserStatusEventHandler {
|
||||
final Splitter markPassingsSplitter = splitLayoutPanel.getAssociatedSplitter(markPassingsPanel);
|
||||
final Splitter markPositionSplitter = splitLayoutPanel.getAssociatedSplitter(markPositionPanel);
|
||||
boolean forceLayout = false;
|
||||
if (user != null && user.hasPermission(Permission.MANAGE_MARK_PASSINGS.getStringPermission())) {
|
||||
if (user != null && user.hasPermission(Permission.MANAGE_MARK_PASSINGS.getPermission(), /* TODO race ownership */ null, /* TODO race acl */ null)) {
|
||||
if (markPassingsSplitter != null) { // if the panel is not present, the splitter may not be found
|
||||
markPassingsSplitter.getToggleButton().setVisible(true);
|
||||
}
|
||||
@@ -318,7 +318,7 @@ public class SideBySideComponentViewer implements UserStatusEventHandler {
|
||||
markPassingsSplitter.getToggleButton().setVisible(false);
|
||||
}
|
||||
}
|
||||
if (user != null && user.hasPermission(Permission.MANAGE_MARK_POSITIONS.getStringPermission())) {
|
||||
if (user != null && user.hasPermission(Permission.MANAGE_MARK_POSITIONS.getPermission(), /* TODO race ownership */ null, /* TODO race acl */ null)) {
|
||||
if (markPositionSplitter != null) { // if the panel is not present, the splitter may not be found
|
||||
markPositionSplitter.getToggleButton().setVisible(true);
|
||||
}
|
||||
|
||||
+1
-1
@@ -191,7 +191,7 @@ public class EventsResource extends AbstractSailingServerResource {
|
||||
@FormParam("numberofraces") String numberOfRacesParam) throws ParseException, NotFoundException,
|
||||
NumberFormatException, IOException, org.json.simple.parser.ParseException, InvalidDateException {
|
||||
if (enforceSecurityChecks) {
|
||||
SecurityUtils.getSubject().checkPermission(Permission.EVENT.getStringPermission(Mode.CREATE));
|
||||
SecurityUtils.getSubject().checkPermission(Permission.EVENT.getStringPermissionForObjects(Mode.CREATE, eventId));
|
||||
}
|
||||
final Response response;
|
||||
UUID id;
|
||||
|
||||
+1
-1
@@ -441,7 +441,7 @@ public class AdminConsolePanel extends HeaderPanel implements HandleTabSelectabl
|
||||
*/
|
||||
private boolean userHasPermissionsToSeeWidget(UserDTO user, Widget widget) {
|
||||
for (Permission requiredStringPermission : permissionsAnyOfWhichIsRequiredToSeeWidget.get(widget)) {
|
||||
WildcardPermission requiredPermission = new WildcardPermission(requiredStringPermission.getStringPermission());
|
||||
WildcardPermission requiredPermission = requiredStringPermission.getPermission();
|
||||
// TODO use PermissionChecker instead of enumerating all permissions
|
||||
for (WildcardPermission userPermission : user.getAllPermissions()) {
|
||||
if (requiredPermission.implies(userPermission) || userPermission.implies(requiredPermission)) {
|
||||
|
||||
+11
@@ -28,6 +28,11 @@ public enum DefaultPermissions implements Permission {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WildcardPermission getPermission(Mode... modes) {
|
||||
return new WildcardPermission(getStringPermission(modes));
|
||||
}
|
||||
|
||||
// TODO once we can use Java8 here, move this up into a "default" method on the Permission interface
|
||||
public String getStringPermissionForObjects(Mode mode, String... objectIdentifiers) {
|
||||
final StringBuilder result = new StringBuilder(getStringPermission(mode));
|
||||
@@ -46,5 +51,11 @@ public enum DefaultPermissions implements Permission {
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WildcardPermission getPermissionForObjects(Mode mode, String... objectIdentifiers) {
|
||||
return new WildcardPermission(getStringPermissionForObjects(mode, objectIdentifiers));
|
||||
}
|
||||
|
||||
private final String stringPermission;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,30 +2,42 @@ package com.sap.sse.security.shared;
|
||||
|
||||
public interface Permission {
|
||||
String name();
|
||||
|
||||
|
||||
int ordinal();
|
||||
|
||||
|
||||
/**
|
||||
* If one or more modes are specified, a string permission is rendered that has the
|
||||
* {@link Mode#getStringPermission() permission strings} of those modes listed in the second wildcard permission
|
||||
* component. Otherwise, only the primary permission with one segment is returned.
|
||||
*/
|
||||
String getStringPermission(Mode... modes);
|
||||
|
||||
|
||||
/**
|
||||
* Produces a string permission for this permission, the <code>mode</code> specified as the second wildcard permission
|
||||
* segment, and the <code>objectIdentifier</code> as the third wildcard permission segment.
|
||||
* Same as {@link #getStringPermission(Mode...)}, only that the result is a {@link WildcardPermission} instead of a
|
||||
* {@link String}
|
||||
*/
|
||||
WildcardPermission getPermission(Mode... modes);
|
||||
|
||||
/**
|
||||
* Produces a string permission for this permission, the <code>mode</code> specified as the second wildcard
|
||||
* permission segment, and the <code>objectIdentifier</code> as the third wildcard permission segment.
|
||||
*/
|
||||
String getStringPermissionForObjects(Mode mode, String... objectIdentifiers);
|
||||
|
||||
|
||||
/**
|
||||
* Same as {@link #getStringPermissionForObjects(Mode, String...)}, only that the result is a
|
||||
* {@link WildcardPermission} instead of a {@link String}
|
||||
*/
|
||||
WildcardPermission getPermissionForObjects(Mode mode, String... objectIdentifiers);
|
||||
|
||||
public static interface Mode {
|
||||
String name();
|
||||
|
||||
|
||||
int ordinal();
|
||||
|
||||
|
||||
String getStringPermission();
|
||||
}
|
||||
|
||||
|
||||
public enum DefaultModes implements Mode {
|
||||
CREATE, READ, UPDATE, DELETE;
|
||||
|
||||
|
||||
+8
-3
@@ -27,9 +27,14 @@ public class PermissionChecker {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param permission Permission of the form "data_object_type:action:instance_id".
|
||||
* The instance id can be omitted when a general permission for the data
|
||||
* object type is asked after (e.g. "event:create").
|
||||
* @param permission
|
||||
* Permission of the form "data_object_type:action:instance_id". The instance id can be omitted when a
|
||||
* general permission for the data object type is asked after (e.g. "event:create").
|
||||
* @param ownership
|
||||
* may be {@code null}, causing user- or tenant-parameterized roles and no user ownership override to be
|
||||
* applied
|
||||
* @param acl
|
||||
* may be {@code null} in which case no ACL-specific checks are performed
|
||||
*/
|
||||
public static boolean isPermitted(WildcardPermission permission, SecurityUser user, Iterable<UserGroup> groupsOfWhichUserIsMember,
|
||||
Iterable<Role> roles, Ownership ownership,
|
||||
|
||||
@@ -15,8 +15,33 @@ import com.sap.sse.common.WithID;
|
||||
public interface SecurityUser extends NamedWithID {
|
||||
Tenant getDefaultTenant();
|
||||
|
||||
/**
|
||||
* Checks whether this user has the {@code permission} requested. For this, the {@link #getRoles() roles}
|
||||
* and {@link #getPermissions() permissions} are checked; however, since this method does not accept
|
||||
* {@link Ownership} or {@link AccessControlList} parameters, no further inferences are made.
|
||||
*/
|
||||
boolean hasPermission(WildcardPermission permission);
|
||||
|
||||
/**
|
||||
* Checks whether this user has the {@code permission} requested. For this, the {@link #getRoles() roles} and
|
||||
* {@link #getPermissions() permissions} are checked, furthermore if this user is the
|
||||
* {@link Ownership#getUserOwner() user owner} as per the {@code ownership} information, the permission will be
|
||||
* granted because users have all rights to the objects they own. Furthermore, tenant and user parameterized roles
|
||||
* will be applied based on the {@code ownership} information. No {@link AccessControlList} rules are applied here.
|
||||
*/
|
||||
boolean hasPermission(WildcardPermission permission, Ownership ownership);
|
||||
|
||||
/**
|
||||
* Checks whether this user has the {@code permission} requested. For this, the {@link #getRoles() roles} and
|
||||
* {@link #getPermissions() permissions} are checked, furthermore if this user is the
|
||||
* {@link Ownership#getUserOwner() user owner} as per the {@code ownership} information, the permission will be
|
||||
* granted because users have all rights to the objects they own. Furthermore, tenant and user parameterized roles
|
||||
* will be applied based on the {@code ownership} information. If the user belongs to one or more groups
|
||||
* ({@code groupsThisUserIsPartOf}) and a non-{@code null} {@code acl} is provided, the access control list
|
||||
* permissions are applied accordingly.
|
||||
*/
|
||||
boolean hasPermission(WildcardPermission permission, Ownership ownership, Iterable<UserGroup> groupsThisUserIsPartOf, AccessControlList acl);
|
||||
|
||||
/**
|
||||
* Returns the "raw" permissions explicitly set for this user. This does not include permissions
|
||||
* inferred by any {@link PermissionsForRoleProvider} for the {@link #getRoles() roles} that this
|
||||
|
||||
+16
-1
@@ -5,9 +5,13 @@ import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.security.shared.AccessControlList;
|
||||
import com.sap.sse.security.shared.Ownership;
|
||||
import com.sap.sse.security.shared.PermissionChecker;
|
||||
import com.sap.sse.security.shared.Role;
|
||||
import com.sap.sse.security.shared.SecurityUser;
|
||||
import com.sap.sse.security.shared.Tenant;
|
||||
import com.sap.sse.security.shared.UserGroup;
|
||||
import com.sap.sse.security.shared.WildcardPermission;
|
||||
|
||||
public class SecurityUserImpl implements SecurityUser {
|
||||
@@ -76,9 +80,20 @@ public class SecurityUserImpl implements SecurityUser {
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(WildcardPermission permission) {
|
||||
return permissions.contains(permission);
|
||||
return hasPermission(permission, /* ownership */ null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(WildcardPermission permission, Ownership ownership) {
|
||||
return hasPermission(permission, ownership, /* user groups */ null, /* ACL */ null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(WildcardPermission permission, Ownership ownership,
|
||||
Iterable<UserGroup> groupsThisUserIsPartOf, AccessControlList acl) {
|
||||
return PermissionChecker.isPermitted(permission, this, groupsThisUserIsPartOf, getRoles(), ownership, acl);
|
||||
}
|
||||
|
||||
public void addRole(Role role) {
|
||||
roles.add(role);
|
||||
}
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ public class AuthenticationContextImpl implements AuthenticationContext {
|
||||
|
||||
private final UserDTO currentUser;
|
||||
private final static UserDTO ANONYMOUS = new UserDTO("Anonymous", "", "", "", null, false, new ArrayList<AccountDTO>(),
|
||||
new ArrayList<Role>(), /* default tenant */ null, new ArrayList<WildcardPermission>());
|
||||
new ArrayList<Role>(), /* default tenant */ null, new ArrayList<WildcardPermission>(), /* groups */ null);
|
||||
|
||||
/**
|
||||
* Creating an {@link AuthenticationContextImpl} containing an anonymous {@link UserDTO} object.
|
||||
|
||||
+2
-1
@@ -5,6 +5,7 @@ import com.google.gwt.resources.client.ImageResource;
|
||||
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
|
||||
import com.google.gwt.user.cellview.client.CellList;
|
||||
import com.google.gwt.user.client.ui.ImageResourceRenderer;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.security.ui.client.IconResources;
|
||||
import com.sap.sse.security.ui.shared.UserDTO;
|
||||
|
||||
@@ -28,7 +29,7 @@ public class UserList extends CellList<UserDTO> {
|
||||
sb.appendHtmlConstant("</td>");
|
||||
sb.appendHtmlConstant("<td>");
|
||||
sb.appendHtmlConstant("<div>");
|
||||
sb.appendEscaped(value.getName());
|
||||
sb.appendEscaped(value.getName()+" ("+Util.join(", ", value.getUserGroups())+")");
|
||||
sb.appendHtmlConstant("</div>");
|
||||
sb.appendHtmlConstant("</td>");
|
||||
sb.appendHtmlConstant("</tr>");
|
||||
|
||||
+56
-11
@@ -55,6 +55,7 @@ import com.sap.sse.security.shared.UsernamePasswordAccount;
|
||||
import com.sap.sse.security.shared.WildcardPermission;
|
||||
import com.sap.sse.security.shared.impl.SecurityUserImpl;
|
||||
import com.sap.sse.security.shared.impl.TenantImpl;
|
||||
import com.sap.sse.security.shared.impl.UserGroupImpl;
|
||||
import com.sap.sse.security.ui.client.UserManagementService;
|
||||
import com.sap.sse.security.ui.oauth.client.CredentialDTO;
|
||||
import com.sap.sse.security.ui.oauth.client.SocialUserDTO;
|
||||
@@ -100,13 +101,14 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U
|
||||
}.start();
|
||||
}
|
||||
|
||||
private SecurityUser createUserDTOFromUser(SecurityUser user, Map<Tenant, Tenant> fromOriginalToStrippedDownTenant, Map<SecurityUser, SecurityUser> fromOriginalToStrippedDownUser) {
|
||||
private SecurityUser createUserDTOFromUser(SecurityUser user, Map<Tenant, Tenant> fromOriginalToStrippedDownTenant, Map<SecurityUser, SecurityUser> fromOriginalToStrippedDownUser,
|
||||
Map<UserGroup, UserGroup> fromOriginalToStrippedDownUserGroup) {
|
||||
SecurityUser result = fromOriginalToStrippedDownUser.get(user);
|
||||
if (result == null) {
|
||||
final SecurityUserImpl preResult = new SecurityUserImpl(user.getName(), /* default tenant to be set later: */ null);
|
||||
result = preResult;
|
||||
fromOriginalToStrippedDownUser.put(user, result);
|
||||
preResult.setDefaultTenant(createTenantDTOFromTenant(user.getDefaultTenant(), fromOriginalToStrippedDownTenant, fromOriginalToStrippedDownUser));
|
||||
preResult.setDefaultTenant(createTenantDTOFromTenant(user.getDefaultTenant(), fromOriginalToStrippedDownTenant, fromOriginalToStrippedDownUser, fromOriginalToStrippedDownUserGroup));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -125,10 +127,12 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U
|
||||
* as will for tenants.
|
||||
*/
|
||||
private Tenant createTenantDTOFromTenant(Tenant tenant) {
|
||||
return createTenantDTOFromTenant(tenant, new HashMap<>(), new HashMap<>());
|
||||
return createTenantDTOFromTenant(tenant, new HashMap<>(), new HashMap<>(), new HashMap<>());
|
||||
}
|
||||
|
||||
private Tenant createTenantDTOFromTenant(Tenant tenant, Map<Tenant, Tenant> fromOriginalToStrippedDownTenant, Map<SecurityUser, SecurityUser> fromOriginalToStrippedDownUser) {
|
||||
private Tenant createTenantDTOFromTenant(Tenant tenant, Map<Tenant, Tenant> fromOriginalToStrippedDownTenant,
|
||||
Map<SecurityUser, SecurityUser> fromOriginalToStrippedDownUser,
|
||||
Map<UserGroup, UserGroup> fromOriginalToStrippedDownUserGroup) {
|
||||
final Tenant result;
|
||||
if (tenant == null) {
|
||||
result = null;
|
||||
@@ -138,7 +142,8 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U
|
||||
result = new TenantImpl(tenant.getId(), tenant.getName());
|
||||
fromOriginalToStrippedDownTenant.put(tenant, result);
|
||||
for (final SecurityUser user : tenant.getUsers()) {
|
||||
result.add(createUserDTOFromUser(user, fromOriginalToStrippedDownTenant, fromOriginalToStrippedDownUser));
|
||||
result.add(createUserDTOFromUser(user, fromOriginalToStrippedDownTenant, fromOriginalToStrippedDownUser,
|
||||
fromOriginalToStrippedDownUserGroup));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -261,10 +266,11 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U
|
||||
if (SecurityUtils.getSubject().isPermitted("tenant:delete:" + tenantIdAsString)) {
|
||||
try {
|
||||
UUID tenantId = UUID.fromString(tenantIdAsString);
|
||||
getSecurityService().deleteTenant(getSecurityService().getTenant(tenantId));
|
||||
final Tenant tenant = getSecurityService().getTenant(tenantId);
|
||||
getSecurityService().deleteTenant(tenant);
|
||||
getSecurityService().deleteACL(tenantIdAsString);
|
||||
getSecurityService().deleteOwnership(tenantIdAsString);
|
||||
return new SuccessInfo(true, "Deleted tenant: " + tenantIdAsString + ".", /* redirectURL */ null, null);
|
||||
return new SuccessInfo(true, "Deleted tenant: " + tenant.getName() + ".", /* redirectURL */ null, null);
|
||||
} catch (UserGroupManagementException e) {
|
||||
return new SuccessInfo(false, "Could not delete tenant.", /* redirectURL */ null, null);
|
||||
}
|
||||
@@ -518,10 +524,11 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U
|
||||
}
|
||||
|
||||
private UserDTO createUserDTOFromUser(User user) {
|
||||
return createUserDTOFromUser(user, new HashMap<>(), new HashMap<>());
|
||||
return createUserDTOFromUser(user, new HashMap<>(), new HashMap<>(), new HashMap<>());
|
||||
}
|
||||
|
||||
private UserDTO createUserDTOFromUser(User user, Map<Tenant, Tenant> fromOriginalToStrippedDownTenant, Map<SecurityUser, SecurityUser> fromOriginalToStrippedDownUser) {
|
||||
private UserDTO createUserDTOFromUser(User user, Map<Tenant, Tenant> fromOriginalToStrippedDownTenant, Map<SecurityUser, SecurityUser> fromOriginalToStrippedDownUser,
|
||||
Map<UserGroup, UserGroup> fromOriginalToStrippedDownUserGroup) {
|
||||
UserDTO userDTO;
|
||||
Map<AccountType, Account> accounts = user.getAllAccounts();
|
||||
List<AccountDTO> accountDTOs = new ArrayList<>();
|
||||
@@ -544,12 +551,50 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U
|
||||
userDTO = new UserDTO(user.getName(), user.getEmail(), user.getFullName(), user.getCompany(),
|
||||
user.getLocale() != null ? user.getLocale().toLanguageTag() : null, user.isEmailValidated(),
|
||||
accountDTOs, user.getRoles(), /* default tenant filled in later */ null,
|
||||
user.getPermissions());
|
||||
user.getPermissions(),
|
||||
createUserGroupDTOsFromUserGroups(getSecurityService().getUserGroupsOfUser(user),
|
||||
fromOriginalToStrippedDownTenant, fromOriginalToStrippedDownUser,
|
||||
fromOriginalToStrippedDownUserGroup));
|
||||
fromOriginalToStrippedDownUser.put(user, userDTO);
|
||||
userDTO.setDefaultTenant(createTenantDTOFromTenant(user.getDefaultTenant(), fromOriginalToStrippedDownTenant, fromOriginalToStrippedDownUser));
|
||||
userDTO.setDefaultTenant(createTenantDTOFromTenant(user.getDefaultTenant(), fromOriginalToStrippedDownTenant,
|
||||
fromOriginalToStrippedDownUser, fromOriginalToStrippedDownUserGroup));
|
||||
return userDTO;
|
||||
}
|
||||
|
||||
private Iterable<UserGroup> createUserGroupDTOsFromUserGroups(Iterable<UserGroup> userGroups,
|
||||
Map<Tenant, Tenant> fromOriginalToStrippedDownTenant,
|
||||
Map<SecurityUser, SecurityUser> fromOriginalToStrippedDownUser,
|
||||
Map<UserGroup, UserGroup> fromOriginalToStrippedDownUserGroup) {
|
||||
final List<UserGroup> result;
|
||||
if (userGroups == null) {
|
||||
result = null;
|
||||
} else {
|
||||
result = new ArrayList<>();
|
||||
for (final UserGroup userGroup : userGroups) {
|
||||
result.add(createUserDTOFromUserGroup(userGroup, fromOriginalToStrippedDownTenant,
|
||||
fromOriginalToStrippedDownUser, fromOriginalToStrippedDownUserGroup));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private UserGroup createUserDTOFromUserGroup(UserGroup userGroup,
|
||||
Map<Tenant, Tenant> fromOriginalToStrippedDownTenant,
|
||||
Map<SecurityUser, SecurityUser> fromOriginalToStrippedDownUser,
|
||||
Map<UserGroup, UserGroup> fromOriginalToStrippedDownUserGroup) {
|
||||
final UserGroup result;
|
||||
if (fromOriginalToStrippedDownUserGroup.containsKey(userGroup)) {
|
||||
result = fromOriginalToStrippedDownUserGroup.get(userGroup);
|
||||
} else {
|
||||
result = new UserGroupImpl(userGroup.getId(), userGroup.getName());
|
||||
fromOriginalToStrippedDownUserGroup.put(userGroup, result);
|
||||
for (final SecurityUser user : userGroup.getUsers()) {
|
||||
result.add(createUserDTOFromUser(user, fromOriginalToStrippedDownTenant, fromOriginalToStrippedDownUser, fromOriginalToStrippedDownUserGroup));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getSettings() {
|
||||
Map<String, String> settings = new TreeMap<String, String>();
|
||||
|
||||
+15
-13
@@ -10,7 +10,6 @@ import com.google.gwt.user.client.rpc.IsSerializable;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.security.shared.AccessControlList;
|
||||
import com.sap.sse.security.shared.Ownership;
|
||||
import com.sap.sse.security.shared.PermissionChecker;
|
||||
import com.sap.sse.security.shared.Role;
|
||||
import com.sap.sse.security.shared.Tenant;
|
||||
import com.sap.sse.security.shared.UserGroup;
|
||||
@@ -26,6 +25,7 @@ public class UserDTO extends SecurityUserImpl implements IsSerializable {
|
||||
private String locale;
|
||||
private List<AccountDTO> accounts;
|
||||
private boolean emailValidated;
|
||||
private List<UserGroup> groups;
|
||||
|
||||
// for GWT serialization only
|
||||
@Deprecated
|
||||
@@ -33,8 +33,12 @@ public class UserDTO extends SecurityUserImpl implements IsSerializable {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @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<AccountDTO> accounts, Iterable<Role> roles, Tenant defaultTenant, Iterable<WildcardPermission> permissions) {
|
||||
List<AccountDTO> accounts, Iterable<Role> roles, Tenant defaultTenant, Iterable<WildcardPermission> permissions,
|
||||
Iterable<UserGroup> groups) {
|
||||
super(name, roles, defaultTenant, permissions);
|
||||
this.email = email;
|
||||
this.fullName = fullName;
|
||||
@@ -42,6 +46,8 @@ public class UserDTO extends SecurityUserImpl implements IsSerializable {
|
||||
this.locale = locale;
|
||||
this.emailValidated = emailValidated;
|
||||
this.accounts = accounts;
|
||||
this.groups = new ArrayList<>();
|
||||
Util.addAll(groups, this.groups);
|
||||
}
|
||||
|
||||
public String getFullName() {
|
||||
@@ -105,20 +111,16 @@ public class UserDTO extends SecurityUserImpl implements IsSerializable {
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<UserGroup> getUserGroups() {
|
||||
return groups;
|
||||
}
|
||||
|
||||
public boolean hasPermission(String permission) {
|
||||
return hasPermission(new WildcardPermission(permission));
|
||||
}
|
||||
|
||||
public boolean hasPermission(String permission, AccessControlList acl, Ownership ownership) {
|
||||
return hasPermission(new WildcardPermission(permission), acl, ownership);
|
||||
}
|
||||
|
||||
public boolean hasPermission(WildcardPermission permission, AccessControlList acl, Ownership ownership) {
|
||||
ArrayList<UserGroup> groupsTheUserBelongsTo = new ArrayList<>();
|
||||
if (acl != null) {
|
||||
groupsTheUserBelongsTo = new ArrayList<>(acl.getActionsByUserGroup().keySet());
|
||||
}
|
||||
return PermissionChecker.isPermitted(permission, this, groupsTheUserBelongsTo, getRoles(), ownership, acl);
|
||||
|
||||
public boolean hasPermission(WildcardPermission permission, Ownership ownership, AccessControlList acl) {
|
||||
return hasPermission(permission, ownership, getUserGroups(), acl);
|
||||
}
|
||||
|
||||
public List<AccountDTO> getAccounts() {
|
||||
|
||||
+3
-1
@@ -72,7 +72,9 @@ 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}.
|
||||
* an efficient lookup for the m:n association between {@link UserGroup#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<SecurityUser, Set<UserGroup>> userGroupsContainingUser;
|
||||
|
||||
+4
-1
@@ -170,7 +170,10 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
||||
BasicDBList usersO = (BasicDBList) groupDBObject.get(FieldNames.UserGroup.USERNAMES.name());
|
||||
if (usersO != null) {
|
||||
for (Object o : usersO) {
|
||||
users.add(usersByName.get((String) o));
|
||||
final UserImpl user = usersByName.get((String) o);
|
||||
if (user != null) {
|
||||
users.add(user);
|
||||
}
|
||||
}
|
||||
}
|
||||
UserGroup result = new UserGroupImpl(id, name, users);
|
||||
|
||||
@@ -104,6 +104,8 @@ public interface SecurityService extends ReplicableWithObjectInputStream<Replica
|
||||
UserGroup getUserGroup(UUID id);
|
||||
|
||||
UserGroup getUserGroupByName(String name);
|
||||
|
||||
Iterable<UserGroup> getUserGroupsOfUser(SecurityUser user);
|
||||
|
||||
Iterable<Tenant> getTenants();
|
||||
|
||||
|
||||
@@ -490,6 +490,11 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
|
||||
return userStore.getUserGroupByName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<UserGroup> getUserGroupsOfUser(SecurityUser user) {
|
||||
return userStore.getUserGroupsOfUser(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Tenant> getTenants() {
|
||||
return userStore.getTenants();
|
||||
@@ -552,7 +557,8 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
|
||||
@Override
|
||||
public void deleteTenant(Tenant tenant) throws TenantManagementException, UserGroupManagementException {
|
||||
for (Ownership ownership : accessControlStore.getOwnerships()) {
|
||||
if (ownership.getTenantOwner().equals(tenant)) {
|
||||
if (!Util.equalsWithNull(ownership.getIdOfOwnedObjectAsString(), tenant.getId().toString()) &&
|
||||
Util.equalsWithNull(ownership.getTenantOwner(), tenant)) {
|
||||
throw new TenantManagementException("The tenant "+tenant.getName()+
|
||||
" is still used as tenant owner and therefore cannot be removed");
|
||||
}
|
||||
@@ -620,7 +626,12 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
|
||||
|
||||
@Override
|
||||
public Void internalDeleteUserGroup(UUID groupId) throws UserGroupManagementException {
|
||||
userStore.deleteUserGroup(getUserGroup(groupId));
|
||||
final UserGroup userGroup = getUserGroup(groupId);
|
||||
if (userGroup == null) {
|
||||
logger.warning("Strange: the user group with ID "+groupId+" which is about to be deleted couldn't be found");
|
||||
} else {
|
||||
userStore.deleteUserGroup(userGroup);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user