diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/security/SailingPermissionsForRoleProvider.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/security/SailingPermissionsForRoleProvider.java index d9f27375d73..b3729c1e503 100755 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/security/SailingPermissionsForRoleProvider.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/security/SailingPermissionsForRoleProvider.java @@ -15,7 +15,7 @@ public class SailingPermissionsForRoleProvider implements PermissionsForRoleProv public Iterable getPermissions(String role, RolePermissionModel rolePermissionModel) { final Iterable result; if (rolePermissionModel == null) { - if (AdminRole.getInstance().getDisplayName().equals(role)) { + if (AdminRole.getInstance().getName().equals(role)) { ArrayList permissions = new ArrayList<>(); permissions.add("*"); result = permissions; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningEntryPoint.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningEntryPoint.java index acdff825d09..31a1b15bcf8 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningEntryPoint.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningEntryPoint.java @@ -10,7 +10,6 @@ import com.google.gwt.user.client.ui.RootLayoutPanel; import com.google.gwt.user.client.ui.SplitLayoutPanel; import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.domain.common.security.Permission; -import com.sap.sailing.domain.common.security.SailingPermissionsForRoleProvider; import com.sap.sailing.gwt.common.authentication.FixedSailingAuthentication; import com.sap.sailing.gwt.ui.client.AbstractSailingEntryPoint; import com.sap.sailing.gwt.ui.client.RemoteServiceMappingConstants; @@ -49,7 +48,7 @@ public class DataMiningEntryPoint extends AbstractSailingEntryPoint { SAPHeaderWithAuthentication header = new SAPHeaderWithAuthentication(getStringMessages().sapSailingAnalytics(), getStringMessages().dataMining()); GenericAuthentication genericSailingAuthentication = new FixedSailingAuthentication(getUserService(), header.getAuthenticationMenuView()); AuthorizedContentDecorator authorizedContentDecorator = new GenericAuthorizedContentDecorator(genericSailingAuthentication); - authorizedContentDecorator.setPermissionToCheck(Permission.DATA_MINING, SailingPermissionsForRoleProvider.INSTANCE); + authorizedContentDecorator.setPermissionToCheck(Permission.DATA_MINING); authorizedContentDecorator.setContentWidgetFactory(new WidgetFactory() { @Override public Widget get() { diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboardedit/LeaderboardEditPage.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboardedit/LeaderboardEditPage.java index 3c18919f6ae..7eac76ff564 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboardedit/LeaderboardEditPage.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboardedit/LeaderboardEditPage.java @@ -11,7 +11,6 @@ import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.ScrollPanel; import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.domain.common.security.Permission; -import com.sap.sailing.domain.common.security.SailingPermissionsForRoleProvider; import com.sap.sailing.gwt.common.authentication.FixedSailingAuthentication; import com.sap.sailing.gwt.common.authentication.SAPSailingHeaderWithAuthentication; import com.sap.sailing.gwt.settings.client.leaderboardedit.LeaderboardEditContextDefinition; @@ -42,7 +41,7 @@ public class LeaderboardEditPage extends AbstractSailingEntryPoint { SAPHeaderWithAuthentication header = initHeader(); GenericAuthentication genericSailingAuthentication = new FixedSailingAuthentication(getUserService(), header.getAuthenticationMenuView()); AuthorizedContentDecorator authorizedContentDecorator = new GenericAuthorizedContentDecorator(genericSailingAuthentication); - authorizedContentDecorator.setPermissionToCheck(Permission.MANAGE_LEADERBOARD_RESULTS, SailingPermissionsForRoleProvider.INSTANCE); + authorizedContentDecorator.setPermissionToCheck(Permission.MANAGE_LEADERBOARD_RESULTS); authorizedContentDecorator.setContentWidgetFactory(new WidgetFactory() { @Override public Widget get() { diff --git a/java/com.sap.sse.gwt.adminconsole/src/com/sap/sse/gwt/adminconsole/AdminConsolePanel.java b/java/com.sap.sse.gwt.adminconsole/src/com/sap/sse/gwt/adminconsole/AdminConsolePanel.java index 1c706bf363e..be6f1f23414 100755 --- a/java/com.sap.sse.gwt.adminconsole/src/com/sap/sse/gwt/adminconsole/AdminConsolePanel.java +++ b/java/com.sap.sse.gwt.adminconsole/src/com/sap/sse/gwt/adminconsole/AdminConsolePanel.java @@ -446,8 +446,7 @@ public class AdminConsolePanel extends DockLayoutPanel implements HandleTabSelec private boolean userHasPermissionsToSeeWidget(UserDTO user, Widget widget) { for (Permission requiredStringPermission : permissionsAnyOfWhichIsRequiredToSeeWidget.get(widget)) { WildcardPermission requiredPermission = new WildcardPermission(requiredStringPermission.getStringPermission()); - for (String userStringPermission : user.getAllPermissions(permissionsForRoleProvider)) { - WildcardPermission userPermission = new WildcardPermission(userStringPermission); + for (WildcardPermission userPermission : user.getAllPermissions(permissionsForRoleProvider)) { if (requiredPermission.implies(userPermission) || userPermission.implies(requiredPermission)) { return true; } diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AdminRole.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AdminRole.java index a9b0588539d..d1a83f1a382 100755 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AdminRole.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AdminRole.java @@ -6,13 +6,14 @@ import java.util.Set; import java.util.UUID; public class AdminRole implements Role { + private static final long serialVersionUID = 3291793984984443193L; + private static AdminRole INSTANCE; private static final String NAME = "admin"; private static final String UUID_STRING = "dc77e3d1-d405-435e-8699-ce7245f6fd7a"; private final UUID id; private final Set permissions; - AdminRole() { id = UUID.fromString(UUID_STRING); permissions = new HashSet<>(); @@ -20,7 +21,7 @@ public class AdminRole implements Role { } @Override - public String getDisplayName() { + public String getName() { return NAME; } 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 0a4dfb04d17..47a4cd26ed6 100755 --- 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 @@ -2,6 +2,7 @@ package com.sap.sse.security.shared; import java.util.List; import java.util.Set; +import java.util.UUID; /** * The {@link PermissionChecker} is an implementation of the permission @@ -31,7 +32,7 @@ public class PermissionChecker { * The instance id can be omitted when a general permission for the data * object type is asked after (e.g. "event:create"). */ - public static boolean isPermitted(WildcardPermission permission, String user, Iterable tenants, Iterable directPermissions, Iterable roles, + public static boolean isPermitted(WildcardPermission permission, String user, Iterable tenants, Iterable directPermissions, Iterable roles, RolePermissionModel rolePermissionModel, Owner ownership, AccessControlList acl) { List> parts = permission.getParts(); // permission has at least data object type and action as parts @@ -43,7 +44,7 @@ public class PermissionChecker { PermissionState result = PermissionState.NONE; // 1. check ownership - if (ownership != null && user.equals(ownership.getOwner())) { // TODO check for tenant ownership + if (ownership != null && user.equals(ownership.getOwner())) { result = PermissionState.GRANTED; } // 2. check ACL @@ -61,7 +62,7 @@ public class PermissionChecker { } // 4. check role permissions if (result == PermissionState.NONE) { - for (String role : roles) { + for (UUID role : roles) { if (rolePermissionModel.implies(role, permission, ownership)) { result = PermissionState.GRANTED; break; diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/Role.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/Role.java index 1d47363b84d..4830d1500a5 100755 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/Role.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/Role.java @@ -2,9 +2,8 @@ package com.sap.sse.security.shared; import java.util.Set; -import com.sap.sse.common.WithID; +import com.sap.sse.common.NamedWithID; -public interface Role extends WithID { - String getDisplayName(); +public interface Role extends NamedWithID { Set getPermissions(); } diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/RoleImpl.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/RoleImpl.java index 2c8de6a2667..ce07148d13e 100755 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/RoleImpl.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/RoleImpl.java @@ -6,32 +6,34 @@ import java.util.Set; import java.util.UUID; public class RoleImpl implements Role { + private static final long serialVersionUID = -402472324567793082L; + private final UUID id; - private final String displayName; + private final String name; private final Set permissions; public RoleImpl(UUID id, String displayName) { this(id, displayName, new HashSet()); } - public RoleImpl(UUID id, String displayName, Set permissions) { + public RoleImpl(UUID id, String name, Set permissions) { this.id = id; - this.displayName = displayName; + this.name = name; this.permissions = permissions; } + + @Override + public Serializable getId() { + return id; + } + + @Override + public String getName() { + return name; + } @Override public Set getPermissions() { return permissions; } - - @Override - public String getDisplayName() { - return displayName; - } - - @Override - public Serializable getId() { - return id; - } } diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/RolePermissionModel.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/RolePermissionModel.java index 702fc5671b7..886efb496d0 100755 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/RolePermissionModel.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/RolePermissionModel.java @@ -1,11 +1,16 @@ package com.sap.sse.security.shared; +import java.util.UUID; + public interface RolePermissionModel { - Iterable getPermissions(String role); + String getName(UUID id); + Iterable getPermissions(UUID id); - boolean implies(String role, WildcardPermission permission); + boolean implies(UUID id, WildcardPermission permission); + boolean implies(UUID id, WildcardPermission permission, Owner ownership); /** - * @param role Role of the for "role_title:tenant". The tenant is an optional + * @param id Id of role + * @param name Role name of the form "role_title:tenant". The tenant is an optional * parameter. It restricts permissions with a * as the instance id * to data objects where the tenant parameter equals the tenant owner * of the data object. E.g.: @@ -16,5 +21,5 @@ public interface RolePermissionModel { * "tw2016-dyas" would have "tw2016" as the tenant owner) * @param ownership Ownership of the data object */ - boolean implies(String role, WildcardPermission permission, Owner ownership); + boolean implies(UUID id, String name, WildcardPermission permission, Owner ownership); } 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 c8e24a533b4..618dad77408 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 @@ -6,6 +6,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.net.UnknownHostException; +import java.util.UUID; import org.apache.shiro.SecurityUtils; import org.junit.Before; @@ -69,9 +70,10 @@ public class LoginTest { @Test public void rolesTest() throws UserManagementException { store.createUser("me", "me@sap.com", "admin"); - store.addRoleForUser("me", "testrole"); + UUID testId = UUID.randomUUID(); + store.addRoleForUser("me", testId); UserStoreImpl store2 = new UserStoreImpl(); - assertTrue(Util.contains(store2.getUserByName("me").getRoles(), "testrole")); + assertTrue(Util.contains(store2.getUserByName("me").getRoles(), testId)); } @Test diff --git a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/authentication/app/AuthenticationContextImpl.java b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/authentication/app/AuthenticationContextImpl.java index 5773ed030bd..29e0c030554 100644 --- a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/authentication/app/AuthenticationContextImpl.java +++ b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/authentication/app/AuthenticationContextImpl.java @@ -1,7 +1,8 @@ package com.sap.sse.security.ui.authentication.app; import java.util.ArrayList; -import java.util.HashSet; +import java.util.HashMap; +import java.util.UUID; import com.sap.sse.security.ui.shared.AccountDTO; import com.sap.sse.security.ui.shared.RolePermissionModelDTO; @@ -14,7 +15,7 @@ public class AuthenticationContextImpl implements AuthenticationContext { private final UserDTO currentUser; private final static UserDTO ANONYMOUS = new UserDTO("Anonymous", "", "", "", null, false, new ArrayList(), - new ArrayList(), new RolePermissionModelDTO(new HashSet<>()), new ArrayList()); + new ArrayList(), new RolePermissionModelDTO(new HashMap<>()), new ArrayList()); /** * Creating an {@link AuthenticationContextImpl} containing an anonymous {@link UserDTO} object. diff --git a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/authentication/decorator/AuthorizedContentDecorator.java b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/authentication/decorator/AuthorizedContentDecorator.java index d50f4a6e24f..f81c0c84ec7 100644 --- a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/authentication/decorator/AuthorizedContentDecorator.java +++ b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/authentication/decorator/AuthorizedContentDecorator.java @@ -9,7 +9,6 @@ import com.google.gwt.user.client.ui.RequiresResize; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Widget; import com.sap.sse.security.shared.Permission; -import com.sap.sse.security.shared.PermissionsForRoleProvider; import com.sap.sse.security.ui.authentication.app.AuthenticationContext; import com.sap.sse.security.ui.authentication.app.NeedsAuthenticationContext; import com.sap.sse.security.ui.client.i18n.StringMessages; @@ -20,13 +19,11 @@ import com.sap.sse.security.ui.client.i18n.StringMessages; * */ public class AuthorizedContentDecorator extends Composite implements RequiresResize, NeedsAuthenticationContext { - private final SimplePanel contentHolder = new SimplePanel(); private Widget content; private WidgetFactory contentWidgetFactory; private final NotLoggedInView notLoggedInView; private String permissionToCheck; - private PermissionsForRoleProvider permissionsForRoleProvider; public AuthorizedContentDecorator(NotLoggedInPresenter presenter, NotLoggedInView notLoggedInView) { this.notLoggedInView = notLoggedInView; @@ -116,13 +113,6 @@ public class AuthorizedContentDecorator extends Composite implements RequiresRes || userManagementContext.getCurrentUser().hasPermission(permissionToCheck); } - /** - * @param permissionsForRoleProvider the PermissionsForRoleProvider used when checking the required permission of a user. - */ - public void setPermissionsForRoleProvider(PermissionsForRoleProvider permissionsForRoleProvider) { - this.permissionsForRoleProvider = permissionsForRoleProvider; - } - /** * Setting a permission causes that the user not only needs to be logged in but also needs to have the given permission. * @@ -140,16 +130,4 @@ public class AuthorizedContentDecorator extends Composite implements RequiresRes public void setPermissionToCheck(Permission permissionToCheck) { setPermissionToCheck(permissionToCheck.getStringPermission()); } - - - /** - * Setting a permission causes that the user not only needs to be logged in but also needs to have the given permission. - * - * @param permissionToCheck the permission to check - * @param permissionsForRoleProvider the PermissionsForRoleProvider used when checking the required permission of a user. - */ - public void setPermissionToCheck(Permission permissionToCheck, PermissionsForRoleProvider permissionsForRoleProvider) { - setPermissionToCheck(permissionToCheck); - setPermissionsForRoleProvider(permissionsForRoleProvider); - } } 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 9e012c4bdd0..d309958de92 100644 --- 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 @@ -4,6 +4,7 @@ import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.UUID; import com.google.gwt.user.client.rpc.RemoteService; import com.sap.sse.common.mail.MailException; @@ -71,7 +72,7 @@ public interface UserManagementService extends RemoteService { SuccessInfo logout(); - SuccessInfo setRolesForUser(String username, Iterable roles); + SuccessInfo setRolesForUser(String username, Iterable roles); SuccessInfo setPermissionsForUser(String username, Iterable permissions); diff --git a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/component/UserDetailsView.java b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/component/UserDetailsView.java index 7cc806584a5..4efdc5efd4b 100644 --- a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/component/UserDetailsView.java +++ b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/component/UserDetailsView.java @@ -32,6 +32,7 @@ import com.sap.sse.security.shared.Permission; import com.sap.sse.security.shared.PermissionsForRoleProvider; import com.sap.sse.security.shared.Role; import com.sap.sse.security.shared.UserManagementException; +import com.sap.sse.security.shared.WildcardPermission; import com.sap.sse.security.ui.client.IconResources; import com.sap.sse.security.ui.client.UserChangeEventHandler; import com.sap.sse.security.ui.client.UserManagementServiceAsync; @@ -75,7 +76,7 @@ public class UserDetailsView extends FlowPanel { for (Permission permission : additionalPermissions) { defaultPermissionNames.add(permission.getStringPermission()); } - rolesEditor = new StringListEditorComposite(user==null?Collections.emptySet():user.getRoles(), stringMessages, com.sap.sse.gwt.client.IconResources.INSTANCE.removeIcon(), defaultRoleNames, + rolesEditor = new StringListEditorComposite(user==null?Collections.emptySet():user.getStringRoles(), stringMessages, com.sap.sse.gwt.client.IconResources.INSTANCE.removeIcon(), defaultRoleNames, stringMessages.enterRoleName()); rolesEditor.addValueChangeHandler(new ValueChangeHandler>() { @Override @@ -254,11 +255,11 @@ public class UserDetailsView extends FlowPanel { } accountPanels.add(accountPanelDecorator); } - rolesEditor.setValue(user.getRoles(), /* fireEvents */ false); + rolesEditor.setValue(user.getStringRoles(), /* fireEvents */ false); permissionsEditor.setValue(user.getStringPermissions(), /* fireEvents */ false); allPermissionsList.clear(); - for (String permission : user.getAllPermissions(permissionForRoleProvider)) { - allPermissionsList.addItem(permission); + for (WildcardPermission permission : user.getAllPermissions(permissionForRoleProvider)) { + allPermissionsList.addItem(permission.toString()); } } } 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 ab152d852f1..367235da879 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 @@ -332,7 +332,7 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U public void updateSimpleUserPassword(final String username, String oldPassword, String passwordResetSecret, String newPassword) throws UserManagementException { final Subject subject = SecurityUtils.getSubject(); // the signed-in subject has role ADMIN - if (subject.hasRole(AdminRole.getInstance().getDisplayName()) + if (subject.hasRole(AdminRole.getInstance().getName()) // someone knew a username and the correct password for that user || (oldPassword != null && getSecurityService().checkPassword(username, oldPassword)) // someone provided the correct password reset secret for the correct username @@ -355,7 +355,7 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U private void ensureThatUserInQuestionIsLoggedInOrCurrentUserIsAdmin(String username) throws UserManagementException { final Subject subject = SecurityUtils.getSubject(); // the signed-in subject has role ADMIN or is changing own user - if (!subject.hasRole(AdminRole.getInstance().getDisplayName()) && (subject.getPrincipal() == null + if (!subject.hasRole(AdminRole.getInstance().getName()) && (subject.getPrincipal() == null || !username.equals(subject.getPrincipal().toString()))) { throw new UserManagementException(UserManagementException.INVALID_CREDENTIALS); } @@ -410,23 +410,23 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U } @Override - public SuccessInfo setRolesForUser(String username, Iterable roles) { + public SuccessInfo setRolesForUser(String username, Iterable roles) { Subject currentSubject = SecurityUtils.getSubject(); - if (currentSubject.hasRole(AdminRole.getInstance().getDisplayName())) { + if (currentSubject.hasRole(AdminRole.getInstance().getName())) { User u = getSecurityService().getUserByName(username); if (u == null) { return new SuccessInfo(false, "User does not exist.", /* redirectURL */null, null); } - Set rolesToRemove = new HashSet<>(); + Set rolesToRemove = new HashSet<>(); Util.addAll(u.getRoles(), rolesToRemove); Util.removeAll(roles, rolesToRemove); - for (String roleToRemove : rolesToRemove) { + for (UUID roleToRemove : rolesToRemove) { getSecurityService().removeRoleFromUser(username, roleToRemove); } - Set rolesToAdd = new HashSet<>(); + Set rolesToAdd = new HashSet<>(); Util.addAll(roles, rolesToAdd); Util.removeAll(u.getRoles(), rolesToAdd); - for (String roleToAdd : rolesToAdd) { + for (UUID roleToAdd : rolesToAdd) { getSecurityService().addRoleForUser(username, roleToAdd); } return new SuccessInfo(true, "Set roles " + roles + " for user " + username, /* redirectURL */null, @@ -439,7 +439,7 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U @Override public SuccessInfo setPermissionsForUser(String username, Iterable permissions) { Subject currentSubject = SecurityUtils.getSubject(); - if (currentSubject.hasRole(AdminRole.getInstance().getDisplayName()) || currentSubject.isPermitted(Permission.MANAGE_USERS.getStringPermissionForObjects(DefaultModes.UPDATE, username))) { + if (currentSubject.hasRole(AdminRole.getInstance().getName()) || currentSubject.isPermitted(Permission.MANAGE_USERS.getStringPermissionForObjects(DefaultModes.UPDATE, username))) { User u = getSecurityService().getUserByName(username); if (u == null) { return new SuccessInfo(false, "User does not exist.", /* redirectURL */null, null); @@ -493,7 +493,7 @@ 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(), new RolePermissionModelDTO(new HashSet<>()), user.getPermissions()); + accountDTOs, user.getRoles(), new RolePermissionModelDTO(new HashMap<>()), user.getPermissions()); return userDTO; } diff --git a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/shared/RolePermissionModelDTO.java b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/shared/RolePermissionModelDTO.java index 33981110e38..e5c55472d3b 100755 --- a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/shared/RolePermissionModelDTO.java +++ b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/shared/RolePermissionModelDTO.java @@ -1,38 +1,51 @@ package com.sap.sse.security.ui.shared; -import java.util.Set; +import java.util.Map; +import java.util.UUID; import com.google.gwt.user.client.rpc.IsSerializable; import com.sap.sse.security.shared.Owner; +import com.sap.sse.security.shared.Role; import com.sap.sse.security.shared.RolePermissionModel; import com.sap.sse.security.shared.WildcardPermission; public class RolePermissionModelDTO implements RolePermissionModel, IsSerializable { - private Set rules; + private Map roles; RolePermissionModelDTO() {} // for serialization only - public RolePermissionModelDTO(Set rules) { - this.rules = rules; + public RolePermissionModelDTO(Map roles) { + this.roles = roles; } @Override - public Iterable getPermissions(String role) { - return rules; + public String getName(UUID id) { + return roles.get(id).getName(); } @Override - public boolean implies(String role, WildcardPermission permission) { // TODO as default implementation in interface - return implies(role, permission, null); + public Iterable getPermissions(UUID id) { + return roles.get(id).getPermissions(); + } + + // TODO as default implementation in interface + @Override + public boolean implies(UUID id, WildcardPermission permission) { + return implies(id, permission, null); } @Override - public boolean implies(String role, WildcardPermission permission, Owner ownership) { // TODO as default implementation in interface - String[] parts = role.split(":"); + public boolean implies(UUID id, WildcardPermission permission, Owner ownership) { + return implies(id, roles.get(id).getName(), permission, ownership); + } + + // TODO as default implementation in interface + @Override + public boolean implies(UUID id, String name, WildcardPermission permission, Owner ownership) { + String[] parts = name.split(":"); // if there is no parameter or the first parameter (tenant) equals the tenant owner if (parts.length < 2 || (ownership != null && ownership.getTenantOwner().equals(parts[1]))) { - for (String rolePermissionString : getPermissions(role)) { - WildcardPermission rolePermission = new WildcardPermission(rolePermissionString, true); + for (WildcardPermission rolePermission : getPermissions(id)) { if (rolePermission.implies(permission)) { return true; } diff --git a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/shared/UserDTO.java b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/shared/UserDTO.java index 2208542806f..9888dded2ba 100644 --- a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/shared/UserDTO.java +++ b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/shared/UserDTO.java @@ -5,6 +5,7 @@ import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; +import java.util.UUID; import com.google.gwt.user.client.rpc.IsSerializable; import com.sap.sse.common.Util; @@ -20,15 +21,15 @@ public class UserDTO implements IsSerializable { private String company; private String locale; private List accounts; - private Set roles; - private RolePermissionModelDTO rolePermissionModelDTO; + private Set roles; + private RolePermissionModelDTO rolePermissionModel; private Set permissions; private boolean emailValidated; UserDTO() {} // for serialization only public UserDTO(String name, String email, String fullName, String company, String locale, boolean emailValidated, - List accounts, Iterable roles, RolePermissionModelDTO rolePermissionModelDTO, + List accounts, Iterable roles, RolePermissionModelDTO rolePermissionModelDTO, Iterable stringPermissions) { this.name = name; this.email = email; @@ -39,7 +40,7 @@ public class UserDTO implements IsSerializable { this.accounts = accounts; this.roles = new HashSet<>(); Util.addAll(roles, this.roles); - this.rolePermissionModelDTO = rolePermissionModelDTO; + this.rolePermissionModel = rolePermissionModelDTO; this.permissions = new HashSet<>(); for (String permission : stringPermissions) { this.permissions.add(new WildcardPermission(permission, true)); @@ -62,10 +63,18 @@ public class UserDTO implements IsSerializable { return locale; } - public Iterable getRoles() { + public Iterable getRoles() { return roles; } + public Iterable getStringRoles() { + ArrayList result = new ArrayList<>(); + for (UUID id : roles) { + result.add(rolePermissionModel.getName(id)); + } + return result; + } + public boolean hasRole(String role) { return roles.contains(role); } @@ -102,12 +111,12 @@ public class UserDTO implements IsSerializable { * @return a set of permissions with no duplicates, all in the format parsable by * {@link WildcardPermission#WildcardPermission(String)} */ - public Iterable getAllPermissions(PermissionsForRoleProvider permissionsForRoleProvider) { - Set result = new LinkedHashSet<>(); - Util.addAll(getStringPermissions(), result); - if (permissionsForRoleProvider != null) { - for (String role : getRoles()) { - Util.addAll(permissionsForRoleProvider.getPermissions(role, null), result); + public Iterable getAllPermissions(PermissionsForRoleProvider permissionsForRoleProvider) { + Set result = new LinkedHashSet<>(); + Util.addAll(permissions, result); + if (rolePermissionModel != null) { + for (UUID role : getRoles()) { + Util.addAll(rolePermissionModel.getPermissions(role), result); } } return result; @@ -130,7 +139,7 @@ public class UserDTO implements IsSerializable { if (acl != null) { userGroups = new ArrayList<>(acl.getUserGroupPermissionMap().keySet()); } - return PermissionChecker.isPermitted(permission, name, userGroups, permissions, roles, rolePermissionModelDTO, owner, acl); + return PermissionChecker.isPermitted(permission, name, userGroups, permissions, roles, rolePermissionModel, owner, acl); } public List getAccounts() { diff --git a/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/AccessControlStoreImpl.java b/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/AccessControlStoreImpl.java index b951346a726..5b3fcc85b40 100755 --- a/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/AccessControlStoreImpl.java +++ b/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/AccessControlStoreImpl.java @@ -183,7 +183,7 @@ public class AccessControlStoreImpl implements AccessControlStore { @Override public AccessControlStore setRolePermissions(UUID id, Set permissions) { Role role = roleList.get(id); - role = new RoleImpl(id, role.getDisplayName(), permissions); + role = new RoleImpl(id, role.getName(), permissions); mongoObjectFactory.storeRole(role); return this; } @@ -193,7 +193,7 @@ public class AccessControlStoreImpl implements AccessControlStore { Role role = roleList.get(id); Set permissions = role.getPermissions(); permissions.add(permission); - role = new RoleImpl(id, role.getDisplayName(), permissions); + role = new RoleImpl(id, role.getName(), permissions); mongoObjectFactory.storeRole(role); return this; } @@ -203,7 +203,7 @@ public class AccessControlStoreImpl implements AccessControlStore { Role role = roleList.get(id); Set permissions = role.getPermissions(); permissions.remove(permission); - role = new RoleImpl(id, role.getDisplayName(), permissions); + role = new RoleImpl(id, role.getName(), permissions); mongoObjectFactory.storeRole(role); return this; } 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 cc098c49604..81258d52a3b 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 @@ -249,7 +249,7 @@ public class UserStoreImpl implements UserStore { public String getAccessToken(String username) { // only the user or an administrator may request a user's access token final Object principal = SecurityUtils.getSubject().getPrincipal(); - if (SecurityUtils.getSubject().hasRole(AdminRole.getInstance().getDisplayName()) || + if (SecurityUtils.getSubject().hasRole(AdminRole.getInstance().getName()) || (principal != null && principal.toString().equals(username))) { return getPreference(username, ACCESS_TOKEN_KEY); } else { @@ -260,7 +260,7 @@ public class UserStoreImpl implements UserStore { @Override public void removeAccessToken(String username) { // only the user or an administrator may request a user's access token - if (SecurityUtils.getSubject().hasRole(AdminRole.getInstance().getDisplayName()) || + if (SecurityUtils.getSubject().hasRole(AdminRole.getInstance().getName()) || SecurityUtils.getSubject().getPrincipal().toString().equals(username)) { User user = users.get(username); if (user != null) { @@ -508,7 +508,7 @@ public class UserStoreImpl implements UserStore { } @Override - public Iterable getRolesFromUser(String username) throws UserManagementException { + public Iterable getRolesFromUser(String username) throws UserManagementException { if (users.get(username) == null) { throw new UserManagementException(UserManagementException.USER_DOES_NOT_EXIST); } @@ -516,7 +516,7 @@ public class UserStoreImpl implements UserStore { } @Override - public void addRoleForUser(String name, String role) throws UserManagementException { + public void addRoleForUser(String name, UUID role) throws UserManagementException { final User user = users.get(name); if (user == null) { throw new UserManagementException(UserManagementException.USER_DOES_NOT_EXIST); @@ -528,7 +528,7 @@ public class UserStoreImpl implements UserStore { } @Override - public void removeRoleFromUser(String name, String role) throws UserManagementException { + public void removeRoleFromUser(String name, UUID role) throws UserManagementException { if (users.get(name) == null) { throw new UserManagementException(UserManagementException.USER_DOES_NOT_EXIST); } 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 30cd8065918..ea5e851d264 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 @@ -129,7 +129,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory { private Role loadRole(DBObject roleDBObject) { final String id = (String) roleDBObject.get(FieldNames.Role.ID.name()); - final String displayName = (String) roleDBObject.get(FieldNames.Role.DISPLAY_NAME.name()); + final String displayName = (String) roleDBObject.get(FieldNames.Role.NAME.name()); final Set permissions = new HashSet<>(); for (Object o : (BasicDBList) roleDBObject.get(FieldNames.Role.PERMISSIONS.name())) { permissions.add(new WildcardPermission(o.toString(), true)); @@ -217,12 +217,12 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory { Boolean emailValidated = (Boolean) userDBObject.get(FieldNames.User.EMAIL_VALIDATED.name()); String passwordResetSecret = (String) userDBObject.get(FieldNames.User.PASSWORD_RESET_SECRET.name()); String validationSecret = (String) userDBObject.get(FieldNames.User.VALIDATION_SECRET.name()); - Set roles = new HashSet(); - Set permissions = new HashSet(); + Set roles = new HashSet<>(); + Set permissions = new HashSet<>(); BasicDBList rolesO = (BasicDBList) userDBObject.get(FieldNames.User.ROLES.name()); if (rolesO != null) { for (Object o : rolesO) { - roles.add((String) o); + roles.add(UUID.fromString((String) o)); } } BasicDBList permissionsO = (BasicDBList) userDBObject.get(FieldNames.User.PERMISSIONS.name()); @@ -234,7 +234,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory { DBObject accountsMap = (DBObject) userDBObject.get(FieldNames.User.ACCOUNTS.name()); Map accounts = createAccountMapFromdDBObject(accountsMap); User result = new User(name, email, fullName, company, locale, emailValidated==null?false:emailValidated, passwordResetSecret, validationSecret, accounts.values()); - for (String role : roles) { + for (UUID role : roles) { result.addRole(role); } for (String permission : permissions) { diff --git a/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/impl/FieldNames.java b/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/impl/FieldNames.java index 136ba1313fb..5b138e0ca78 100644 --- a/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/impl/FieldNames.java +++ b/java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/impl/FieldNames.java @@ -17,7 +17,7 @@ public class FieldNames { public static enum Role { ID, - DISPLAY_NAME, + NAME, PERMISSIONS } 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 8e7186ddecc..d99631c3ab1 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 @@ -91,7 +91,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { DBObject dbRole = new BasicDBObject(); DBObject query = new BasicDBObject(FieldNames.Role.ID.name(), role.getId().toString()); dbRole.put(FieldNames.Role.ID.name(), role.getId().toString()); - dbRole.put(FieldNames.Role.DISPLAY_NAME.name(), role.getDisplayName()); + dbRole.put(FieldNames.Role.NAME.name(), role.getName()); HashSet stringPermissions = new HashSet<>(); for (WildcardPermission permission : role.getPermissions()) { stringPermissions.add(permission.toString()); @@ -161,7 +161,11 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { dbUser.put(FieldNames.User.PASSWORD_RESET_SECRET.name(), user.getPasswordResetSecret()); dbUser.put(FieldNames.User.VALIDATION_SECRET.name(), user.getValidationSecret()); dbUser.put(FieldNames.User.ACCOUNTS.name(), createAccountMapObject(user.getAllAccounts())); - dbUser.put(FieldNames.User.ROLES.name(), user.getRoles()); + HashSet roles = new HashSet<>(); + for (UUID id : user.getRoles()) { + roles.add(id.toString()); + } + dbUser.put(FieldNames.User.ROLES.name(), roles); dbUser.put(FieldNames.User.PERMISSIONS.name(), user.getPermissions()); usersCollection.update(query, dbUser, /* upsrt */true, /* multi */false, WriteConcern.SAFE); } diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/AbstractCompositeAuthrizingRealm.java b/java/com.sap.sse.security/src/com/sap/sse/security/AbstractCompositeAuthrizingRealm.java index a9687dc084a..a7a884c935d 100755 --- a/java/com.sap.sse.security/src/com/sap/sse/security/AbstractCompositeAuthrizingRealm.java +++ b/java/com.sap.sse.security/src/com/sap/sse/security/AbstractCompositeAuthrizingRealm.java @@ -3,6 +3,7 @@ package com.sap.sse.security; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @@ -21,7 +22,7 @@ import org.osgi.util.tracker.ServiceTracker; import com.sap.sse.security.impl.Activator; import com.sap.sse.security.shared.Owner; import com.sap.sse.security.shared.PermissionChecker; -import com.sap.sse.security.shared.PermissionsForRoleProvider; +import com.sap.sse.security.shared.Role; import com.sap.sse.security.shared.RolePermissionModel; import com.sap.sse.security.shared.UserManagementException; import com.sap.sse.security.shared.WildcardPermission; @@ -30,7 +31,6 @@ public abstract class AbstractCompositeAuthrizingRealm extends AuthorizingRealm private static final Logger logger = Logger.getLogger(AbstractCompositeAuthrizingRealm.class.getName()); private final Future userStore; private final Future aclStore; - private PermissionsForRoleProvider permissionsForRoleProvider; /** * In a non-OSGi test environment, having Shiro instantiate this class with a default constructor makes it difficult @@ -61,10 +61,6 @@ public abstract class AbstractCompositeAuthrizingRealm extends AuthorizingRealm aclStore = null; } } - - public void setPermissionsForRoleProvider(PermissionsForRoleProvider permissionsForRoleProvider) { - this.permissionsForRoleProvider = permissionsForRoleProvider; - } private Future createUserStoreFuture(BundleContext bundleContext) { final ServiceTracker tracker = new ServiceTracker<>(bundleContext, UserStore.class, /* customizer */ null); @@ -213,8 +209,8 @@ public abstract class AbstractCompositeAuthrizingRealm extends AuthorizingRealm public boolean hasRole(PrincipalCollection principal, String roleIdentifier) { String user = (String) principal.getPrimaryPrincipal(); try { - for (String role : getUserStore().getRolesFromUser(user)) { - if (role.equals(roleIdentifier)) { + for (UUID role : getUserStore().getRolesFromUser(user)) { + if (role.equals(UUID.fromString(roleIdentifier))) { return true; } } @@ -266,23 +262,58 @@ public abstract class AbstractCompositeAuthrizingRealm extends AuthorizingRealm return null; // As all the public methods of AuthorizingRealm are overridden to not use this, this should never be called. } - @Override - public Iterable getPermissions(String role) { - return permissionsForRoleProvider.getPermissions(role, null); + private Role getRole(UUID id) { + try { + return aclStore.get().getRole(id); + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + return null; + } } @Override - public boolean implies(String role, WildcardPermission permission) { // TODO as default implementation in interface - return implies(role, permission, null); + public String getName(UUID id) { + Role role = getRole(id); + if (role != null) { + return role.getName(); + } else { + return ""; + } } @Override - public boolean implies(String role, WildcardPermission permission, Owner ownership) { // TODO as default implementation in interface - String[] parts = role.split(":"); + public Iterable getPermissions(UUID id) { + Role role = getRole(id); + if (role != null) { + return role.getPermissions(); + } else { + return new ArrayList<>(); + } + } + + // TODO as default implementation in interface + @Override + public boolean implies(UUID id, WildcardPermission permission) { + return implies(id, permission, null); + } + + @Override + public boolean implies(UUID id, WildcardPermission permission, Owner ownership) { + Role role = getRole(id); + if (role != null) { + return implies(id, role.getName(), permission, ownership); + } else { + return false; + } + } + + // TODO as default implementation in interface + @Override + public boolean implies(UUID id, String name, WildcardPermission permission, Owner ownership) { + String[] parts = name.split(":"); // if there is no parameter or the first parameter (tenant) equals the tenant owner if (parts.length < 2 || (ownership != null && ownership.getTenantOwner().equals(parts[1]))) { - for (String rolePermissionString : getPermissions(role)) { - WildcardPermission rolePermission = new WildcardPermission(rolePermissionString, true); + for (WildcardPermission rolePermission : getPermissions(id)) { if (rolePermission.implies(permission)) { return true; } diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/BearerTokenRealm.java b/java/com.sap.sse.security/src/com/sap/sse/security/BearerTokenRealm.java index 1f8828cd8cc..a8fb0970335 100755 --- a/java/com.sap.sse.security/src/com/sap/sse/security/BearerTokenRealm.java +++ b/java/com.sap.sse.security/src/com/sap/sse/security/BearerTokenRealm.java @@ -30,5 +30,4 @@ public class BearerTokenRealm extends AbstractCompositeAuthrizingRealm { SaltedAuthenticationInfo sai = new SimpleSaltedAuthenticationInfo(user.getName(), accessToken.getCredentials(), /* salt */ null); return sai; } - } 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 b2fde6a74d0..e615ed1d45b 100644 --- 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 @@ -134,11 +134,11 @@ public interface SecurityService extends ReplicableWithObjectInputStream getRolesFromUser(String username) throws UserManagementException; + Iterable getRolesFromUser(String username) throws UserManagementException; - void addRoleForUser(String username, String role); + void addRoleForUser(String username, UUID role); - void removeRoleFromUser(String username, String role); + void removeRoleFromUser(String username, UUID role); Iterable getPermissionsFromUser(String username) throws UserManagementException; diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/User.java b/java/com.sap.sse.security/src/com/sap/sse/security/User.java index d14b7d5aef5..5a2e00a464e 100644 --- a/java/com.sap.sse.security/src/com/sap/sse/security/User.java +++ b/java/com.sap.sse.security/src/com/sap/sse/security/User.java @@ -10,6 +10,7 @@ import java.util.Locale; import java.util.Map; import java.util.Random; import java.util.Set; +import java.util.UUID; import org.apache.shiro.crypto.hash.Sha256Hash; @@ -64,7 +65,7 @@ public class User implements NamedWithID { private boolean emailValidated; - private final Set roles; + private final Set roles; private final Set permissions; private final Map accounts; @@ -136,19 +137,19 @@ public class User implements NamedWithID { return locale == null ? Locale.ENGLISH : locale; } - public Iterable getRoles() { + public Iterable getRoles() { return roles; } - public void addRole(String role) { + public void addRole(UUID role) { roles.add(role); } - public boolean hasRole(String role) { + public boolean hasRole(UUID role) { return roles.contains(role); } - public void removeRole(String role) { + public void removeRole(UUID role) { roles.remove(role); } 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 c9e45c16ce0..e33bd2dbcbf 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 @@ -55,11 +55,11 @@ public interface UserStore extends Named { void updateUser(User user); - Iterable getRolesFromUser(String username) throws UserManagementException; + Iterable getRolesFromUser(String username) throws UserManagementException; - void addRoleForUser(String name, String role) throws UserManagementException; + void addRoleForUser(String name, UUID role) throws UserManagementException; - void removeRoleFromUser(String name, String role) throws UserManagementException; + void removeRoleFromUser(String name, UUID role) throws UserManagementException; Iterable getPermissionsFromUser(String username) throws UserManagementException; diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/impl/ReplicableSecurityService.java b/java/com.sap.sse.security/src/com/sap/sse/security/impl/ReplicableSecurityService.java index d043946fa40..511fe2da3ef 100755 --- a/java/com.sap.sse.security/src/com/sap/sse/security/impl/ReplicableSecurityService.java +++ b/java/com.sap.sse.security/src/com/sap/sse/security/impl/ReplicableSecurityService.java @@ -63,9 +63,9 @@ public interface ReplicableSecurityService extends SecurityService { Void internalAddSetting(String key, Class clazz); - Void internalAddRoleForUser(String username, String role) throws UserManagementException; + Void internalAddRoleForUser(String username, UUID role) throws UserManagementException; - Void internalRemoveRoleFromUser(String username, String role) throws UserManagementException; + Void internalRemoveRoleFromUser(String username, UUID role) throws UserManagementException; Void internalAddPermissionForUser(String username, String permissionToAdd) throws UserManagementException; 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 5bad7ec90d0..ba2682ffbf6 100755 --- 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 @@ -207,7 +207,7 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat logger.info("No users found, creating default user \"admin\" with password \"admin\""); createSimpleUser("admin", "nobody@sapsailing.com", "admin", /* fullName */ null, /* company */ null, /* validationBaseURL */ null); - addRoleForUser("admin", AdminRole.getInstance().getDisplayName()); + addRoleForUser("admin", (UUID) AdminRole.getInstance().getId()); } catch (UserManagementException | MailException e) { logger.log(Level.SEVERE, "Exception while creating default admin user", e); } @@ -223,7 +223,7 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat Set adminPermissions = new HashSet<>(); adminPermissions.add("*"); AdminRole role = AdminRole.getInstance(); - aclStore.createRole((UUID) role.getId(), role.getDisplayName(), role.getPermissions()); + aclStore.createRole((UUID) role.getId(), role.getName(), role.getPermissions()); } } @@ -748,28 +748,28 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat } @Override - public Iterable getRolesFromUser(String name) throws UserManagementException { + public Iterable getRolesFromUser(String name) throws UserManagementException { return userStore.getRolesFromUser(name); } @Override - public void addRoleForUser(String username, String role) { + public void addRoleForUser(String username, UUID role) { apply(s->s.internalAddRoleForUser(username, role)); } @Override - public Void internalAddRoleForUser(String username, String role) throws UserManagementException { + public Void internalAddRoleForUser(String username, UUID role) throws UserManagementException { userStore.addRoleForUser(username, role); return null; } @Override - public void removeRoleFromUser(String username, String role) { + public void removeRoleFromUser(String username, UUID role) { apply(s->s.internalRemoveRoleFromUser(username, role)); } @Override - public Void internalRemoveRoleFromUser(String username, String role) throws UserManagementException { + public Void internalRemoveRoleFromUser(String username, UUID role) throws UserManagementException { userStore.removeRoleFromUser(username, role); return null; } @@ -1127,7 +1127,7 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat private void ensureThatUserInQuestionIsLoggedInOrCurrentUserIsAdmin(String username) { final Subject subject = SecurityUtils.getSubject(); - if (!subject.hasRole(AdminRole.getInstance().getDisplayName()) && (subject.getPrincipal() == null + if (!subject.hasRole(AdminRole.getInstance().getName()) && (subject.getPrincipal() == null || !username.equals(subject.getPrincipal().toString()))) { final String currentUserName = subject.getPrincipal() == null ? "" : subject.getPrincipal().toString(); @@ -1228,7 +1228,7 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat @Override public void removeAccessToken(String username) { Subject subject = SecurityUtils.getSubject(); - if (subject.hasRole(AdminRole.getInstance().getDisplayName()) || username.equals(subject.getPrincipal().toString())) { + if (subject.hasRole(AdminRole.getInstance().getName()) || username.equals(subject.getPrincipal().toString())) { apply(s -> s.internalRemoveAccessToken(username)); } else { throw new org.apache.shiro.authz.AuthorizationException("User " + subject.getPrincipal().toString() diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/jaxrs/api/SecurityResource.java b/java/com.sap.sse.security/src/com/sap/sse/security/jaxrs/api/SecurityResource.java index 242d5d1d633..e7a339844be 100644 --- a/java/com.sap.sse.security/src/com/sap/sse/security/jaxrs/api/SecurityResource.java +++ b/java/com.sap.sse.security/src/com/sap/sse/security/jaxrs/api/SecurityResource.java @@ -68,7 +68,7 @@ public class SecurityResource extends AbstractSecurityResource { @Produces("text/plain;charset=UTF-8") public Response changePassword(@FormParam("username") String username, @FormParam("password") String password) { final Subject subject = SecurityUtils.getSubject(); - if (!subject.hasRole(AdminRole.getInstance().getDisplayName()) && (subject.getPrincipal() == null + if (!subject.hasRole(AdminRole.getInstance().getName()) && (subject.getPrincipal() == null || !username.equals(subject.getPrincipal().toString()))) { return Response.status(Status.UNAUTHORIZED).build(); } else { @@ -144,7 +144,7 @@ public class SecurityResource extends AbstractSecurityResource { final Subject subject = SecurityUtils.getSubject(); // ADMIN can query all; otherwise, only the owning user can query // TODO: ideally, we would introduce a USER:READ: permission which later can be granted to tenant admins for all users of that tenant - if (subject.getPrincipal() == null || (username != null && !subject.hasRole(AdminRole.getInstance().getDisplayName()))) { + if (subject.getPrincipal() == null || (username != null && !subject.hasRole(AdminRole.getInstance().getName()))) { return Response.status(Status.UNAUTHORIZED).build(); } else { final User user = getService().getUserByName(username == null ? subject.getPrincipal().toString() : username); @@ -167,7 +167,7 @@ public class SecurityResource extends AbstractSecurityResource { public Response deleteUser(@QueryParam("username") String username) { final Subject subject = SecurityUtils.getSubject(); // the signed-in subject has role ADMIN - if (!subject.hasRole(AdminRole.getInstance().getDisplayName()) && (subject.getPrincipal() == null + if (!subject.hasRole(AdminRole.getInstance().getName()) && (subject.getPrincipal() == null || !username.equals(subject.getPrincipal().toString()))) { return Response.status(Status.UNAUTHORIZED).build(); } else { @@ -188,7 +188,7 @@ public class SecurityResource extends AbstractSecurityResource { @QueryParam("company") String company) { final Subject subject = SecurityUtils.getSubject(); // the signed-in subject has role ADMIN - if (!subject.hasRole(AdminRole.getInstance().getDisplayName()) && (subject.getPrincipal() == null + if (!subject.hasRole(AdminRole.getInstance().getName()) && (subject.getPrincipal() == null || !username.equals(subject.getPrincipal().toString()))) { return Response.status(Status.UNAUTHORIZED).build(); } else {