Merge branch 'permission-vertical' into bug4813

Conflicts:
	java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/component/UserGroupManagementPanel.java
This commit is contained in:
Thomas Wiese committed 2018-12-06 14:32:05 +01:00
commit 1d427a3f5c
18 files changed
+128 -232

No files matched your search

@@ -106,10 +106,9 @@ public class Activator implements BundleActivator {
final SecurityService securityService = securityServiceServiceTracker.waitForService(0);
IgtimiConnectionFactoryImpl igtimiConnectionFactory = connectionFactory.get();
for (Account account : igtimiConnectionFactory.getAllAccounts()) {
securityService.migrateOwnership(account, SecuredDomainType.getAllInstances());
securityService.migrateOwnership(account);
}
securityService.assumeOwnershipMigrated(SecuredDomainType.IGTIMI_ACCOUNT.getName(),
SecuredDomainType.getAllInstances());
securityService.assumeOwnershipMigrated(SecuredDomainType.IGTIMI_ACCOUNT.getName());
} catch (Exception e) {
logger.log(Level.SEVERE, "Exception trying to migrate IgtimiAccounts implementation", e);
}
@@ -56,19 +56,17 @@ public class Activator implements BundleActivator {
for (SwissTimingArchiveConfiguration swissTimingArchive : SwissTimingAdapterPersistence.INSTANCE
.getSwissTimingArchiveConfigurations()) {
securityService.migrateOwnership(swissTimingArchive, SecuredDomainType.getAllInstances());
securityService.migrateOwnership(swissTimingArchive);
}
for (SwissTimingConfiguration swissTiming : SwissTimingAdapterPersistence.INSTANCE
.getSwissTimingConfigurations()) {
securityService.migrateOwnership(swissTiming, SecuredDomainType.getAllInstances());
securityService.migrateOwnership(swissTiming);
}
// we do not necessarily have swisstiming configs, so ensure that migration is marked as done
securityService.assumeOwnershipMigrated(SecuredDomainType.SWISS_TIMING_ACCOUNT.getName(),
SecuredDomainType.getAllInstances());
securityService.assumeOwnershipMigrated(SecuredDomainType.SWISS_TIMING_ARCHIVE_ACCOUNT.getName(),
SecuredDomainType.getAllInstances());
securityService.assumeOwnershipMigrated(SecuredDomainType.SWISS_TIMING_ACCOUNT.getName());
securityService.assumeOwnershipMigrated(SecuredDomainType.SWISS_TIMING_ARCHIVE_ACCOUNT.getName());
} catch (Exception e) {
logger.log(Level.SEVERE, "Exception trying to register SwissTiming RaceTrackingConnectivityParametersHandler implementation", e);
@@ -62,11 +62,10 @@ public class Activator implements BundleActivator {
com.sap.sailing.domain.tractracadapter.persistence.DomainObjectFactory tractracDomainObjectFactory = com.sap.sailing.domain.tractracadapter.persistence.PersistenceFactory.INSTANCE
.createDomainObjectFactory(mongoObjectFactory.getDatabase(), domainFactory);
for (TracTracConfiguration trackTrackConfig : tractracDomainObjectFactory.getTracTracConfigurations()) {
securityService.migrateOwnership(trackTrackConfig, SecuredDomainType.getAllInstances());
securityService.migrateOwnership(trackTrackConfig);
}
// we do not necessarily have tractrac configs, so ensure that migration is marked as done
securityService.assumeOwnershipMigrated(SecuredDomainType.TRACTRAC_ACCOUNT.getName(),
SecuredDomainType.getAllInstances());
securityService.assumeOwnershipMigrated(SecuredDomainType.TRACTRAC_ACCOUNT.getName());
properties.put(TypeBasedServiceFinder.TYPE, RaceTrackingConnectivityParametersImpl.TYPE);
context.registerService(RaceTrackingConnectivityParametersHandler.class, paramsHandler, properties);
@@ -12,9 +12,12 @@ import java.util.logging.Logger;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.util.tracker.ServiceTracker;
import com.sap.sailing.domain.common.security.SecuredDomainType;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifierStringSerializationHandler;
import com.sap.sailing.domain.tracking.WindTrackerFactory;
import com.sap.sailing.expeditionconnector.ExpeditionDeviceConfiguration;
import com.sap.sailing.expeditionconnector.ExpeditionSensorDeviceIdentifier;
import com.sap.sailing.expeditionconnector.ExpeditionTrackerFactory;
import com.sap.sailing.expeditionconnector.persistence.DomainObjectFactory;
@@ -23,7 +26,12 @@ import com.sap.sailing.expeditionconnector.persistence.ExpeditionGpsDeviceIdenti
import com.sap.sailing.expeditionconnector.persistence.MongoObjectFactory;
import com.sap.sailing.expeditionconnector.persistence.PersistenceFactory;
import com.sap.sailing.server.gateway.serialization.racelog.tracking.DeviceIdentifierJsonHandler;
import com.sap.sse.ServerInfo;
import com.sap.sse.common.TypeBasedServiceFinder;
import com.sap.sse.security.SecurityService;
import com.sap.sse.security.shared.QualifiedObjectIdentifier;
import com.sap.sse.security.shared.impl.WildcardPermissionEncoder;
import com.sap.sse.util.ServiceTrackerFactory;
import com.sap.sse.util.impl.ThreadFactoryWithPriority;
public class Activator implements BundleActivator {
@@ -81,6 +89,26 @@ public class Activator implements BundleActivator {
registrations.add(context.registerService(DeviceIdentifierStringSerializationHandler.class, new ExpeditionGpsStringSerializationHandler(), getDict(ExpeditionGpsDeviceIdentifier.TYPE)));
registrations.add(context.registerService(DeviceIdentifierJsonHandler.class, new ExpeditionSensorDeviceIdentifierJsonHandler(), getDict(ExpeditionSensorDeviceIdentifier.TYPE)));
registrations.add(context.registerService(DeviceIdentifierStringSerializationHandler.class, new ExpeditionSensorStringSerializationHandler(), getDict(ExpeditionSensorDeviceIdentifier.TYPE)));
new Thread(() -> {
final ServiceTracker<SecurityService, SecurityService> securityServiceServiceTracker = ServiceTrackerFactory
.createAndOpen(context, SecurityService.class);
try {
final SecurityService securityService = securityServiceServiceTracker.waitForService(0);
for (ExpeditionDeviceConfiguration deviceConfiguration : expeditionTrackerFactory
.getDeviceConfigurations()) {
QualifiedObjectIdentifier identifier = SecuredDomainType.EXPEDITION_DEVICE_CONFIGURATION
.getQualifiedObjectIdentifier(WildcardPermissionEncoder.encode(ServerInfo.getName(),
deviceConfiguration.getName()));
securityService.migrateOwnership(identifier, identifier.getTypeRelativeObjectIdentifier());
}
securityService
.assumeOwnershipMigrated(SecuredDomainType.EXPEDITION_DEVICE_CONFIGURATION.getName());
} catch (Exception e) {
logger.log(Level.SEVERE, "Exception trying to migrate IgtimiAccounts implementation", e);
}
}, getClass().getName() + " registering connectivity handler").start();
});
}
@@ -27,8 +27,8 @@ import com.sap.sailing.gwt.ui.client.RemoteServiceMappingConstants;
import com.sap.sailing.gwt.ui.masterdataimport.MasterDataImportPanel;
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTOWithSecurity;
import com.sap.sailing.gwt.ui.shared.SecurityStylesheetResources;
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTOWithSecurity;
import com.sap.sse.gwt.adminconsole.AdminConsolePanel;
import com.sap.sse.gwt.adminconsole.AdminConsoleTableResources;
import com.sap.sse.gwt.adminconsole.DefaultRefreshableAdminConsolePanel;
@@ -310,7 +310,7 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint
new DefaultRefreshableAdminConsolePanel<UserManagementPanel<AdminConsoleTableResources>>(userManagementPanel) {
@Override
public void refreshAfterBecomingVisible() {
userManagementPanel.updateUsersAndACLs();
userManagementPanel.updateUsers();
}
}, getStringMessages().userManagement(), SecuredSecurityTypes.USER.getPermission(DefaultActions.MUTATION_ACTIONS));
@@ -34,9 +34,9 @@ public class BoatConfigImagesBarCell extends ImagesBarCell {
new ImageSpec(ACTION_UPDATE, stringMessages.actionEdit(),
makeImagePrototype(IconResources.INSTANCE.editIcon())),
new ImageSpec(ACTION_REFRESH, stringMessages.reload(), makeImagePrototype(resources.reloadIcon())),
new ImageSpec(ACTION_CHANGE_ACL, stringMessages.actionChangeACL(),
IconResources.INSTANCE.changeACLIcon()),
new ImageSpec(ACTION_CHANGE_OWNERSHIP, stringMessages.actionChangeOwnership(),
IconResources.INSTANCE.changeOwnershipIcon()));
IconResources.INSTANCE.changeOwnershipIcon()),
new ImageSpec(ACTION_CHANGE_ACL, stringMessages.actionChangeACL(),
IconResources.INSTANCE.changeACLIcon()));
}
}
@@ -34,9 +34,9 @@ public class CompetitorConfigImagesBarCell extends ImagesBarCell {
new ImageSpec(ACTION_UPDATE, stringMessages.actionEdit(),
makeImagePrototype(IconResources.INSTANCE.editIcon())),
new ImageSpec(ACTION_REFRESH, stringMessages.reload(), makeImagePrototype(resources.reloadIcon())),
new ImageSpec(ACTION_CHANGE_ACL, stringMessages.actionChangeACL(),
IconResources.INSTANCE.changeACLIcon()),
new ImageSpec(ACTION_CHANGE_OWNERSHIP, stringMessages.actionChangeOwnership(),
IconResources.INSTANCE.changeOwnershipIcon()));
IconResources.INSTANCE.changeOwnershipIcon()),
new ImageSpec(ACTION_CHANGE_ACL, stringMessages.actionChangeACL(),
IconResources.INSTANCE.changeACLIcon()));
}
}
@@ -48,6 +48,7 @@ import com.sap.sse.common.media.MimeType;
import com.sap.sse.mongodb.MongoDBConfiguration;
import com.sap.sse.mongodb.MongoDBService;
import com.sap.sse.security.SecurityService;
import com.sap.sse.security.UserImpl;
import com.sap.sse.security.shared.WithQualifiedObjectIdentifier;
import com.sap.sse.security.shared.impl.User;
import com.sap.sse.security.shared.impl.UserGroupImpl;
@@ -192,7 +193,7 @@ public class MediaReplicationTest extends AbstractServerReplicationTest {
ClassNotFoundException {
UserGroupImpl defaultTenant = new UserGroupImpl(new UUID(0, 1), "defaultTenant");
User currentUser = Mockito.mock(User.class);
User currentUser = new UserImpl("test", "email@test", Collections.emptyMap(), null);
SecurityService securityService = Mockito.mock(SecurityService.class);
Mockito.doReturn(defaultTenant).when(securityService).getDefaultTenant();
@@ -272,7 +273,7 @@ public class MediaReplicationTest extends AbstractServerReplicationTest {
fmaster.addMasterDataClassLoader(this.getClass().getClassLoader());
ByteArrayInputStream inputStream = new ByteArrayInputStream(os.toByteArray());
MasterDataImporter importer = new MasterDataImporter(domainFactory, fmaster,
null, null);
currentUser, null);
importer.importFromStream(inputStream, randomUUID, false);
} finally {
os.close();
@@ -103,12 +103,17 @@ public class RemoveLeaderboardGroupTest {
assertNull(pfingstbusch.getLeaderboardGroups().iterator().next().getOverallLeaderboard());
}
/**
* Unlike earlier versions, the RemoveLeaderboardGroup no longer removes the OverallLeaderboard, because it cannot
* ensure proper Ownership handling. This is no handled in the SailingServiceImpl
*/
@Test
public void testRemovingLeaderboardGroupRemovesOverallLeaderboardAndUnlinksItFromEvent() {
public void testRemovingLeaderboardGroupDoesNotRemoveOverallLeaderboard() {
assertEquals(1, Util.size(pfingstbusch.getLeaderboardGroups()));
server.apply(new RemoveLeaderboardGroup("Pfingstbusch"));
final Leaderboard overallLeaderboard = server.getLeaderboardByName("Pfingstbusch "+LeaderboardNameConstants.OVERALL);
assertNull(overallLeaderboard);
final Leaderboard overallLeaderboard = server
.getLeaderboardByName("Pfingstbusch " + LeaderboardNameConstants.OVERALL);
assertNotNull(overallLeaderboard);
assertFalse(pfingstbusch.getLeaderboardGroups().iterator().hasNext());
}
}
@@ -187,6 +187,7 @@ import com.sap.sailing.domain.tracking.RaceListener;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.domain.tracking.RaceTrackingConnectivityParameters;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.RaceTrackingHandler.DefaultRaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRaceStatus;
import com.sap.sailing.domain.tracking.TrackedRegatta;
@@ -194,7 +195,6 @@ import com.sap.sailing.domain.tracking.TrackedRegattaListener;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tracking.WindTracker;
import com.sap.sailing.domain.tracking.WindTrackerFactory;
import com.sap.sailing.domain.tracking.RaceTrackingHandler.DefaultRaceTrackingHandler;
import com.sap.sailing.domain.tracking.impl.AbstractRaceChangeListener;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl;
import com.sap.sailing.domain.tracking.impl.TrackedRaceImpl;
@@ -948,73 +948,56 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
public void ensureOwnerships() {
SecurityService securityService = getSecurityService();
securityService.assumeOwnershipMigrated(SecuredDomainType.MANAGE_MARK_PASSINGS.getName(),
SecuredDomainType.getAllInstances());
securityService.assumeOwnershipMigrated(SecuredDomainType.EXPEDITION_DEVICE_CONFIGURATION.getName(),
SecuredDomainType.getAllInstances());
securityService.assumeOwnershipMigrated(SecuredDomainType.RACE_MANAGER_APP_DEVICE_CONFIGURATION.getName(),
SecuredDomainType.getAllInstances());
securityService.assumeOwnershipMigrated(SecuredDomainType.RESULT_IMPORT_URL.getName(),
SecuredDomainType.getAllInstances());
securityService.assumeOwnershipMigrated(SecuredDomainType.MANAGE_MARK_POSITIONS.getName(),
SecuredDomainType.getAllInstances());
securityService.assumeOwnershipMigrated(SecuredDomainType.CAN_REPLAY_DURING_LIVE_RACES.getName(),
SecuredDomainType.getAllInstances());
securityService.assumeOwnershipMigrated(SecuredDomainType.DETAIL_TIMER.getName(),
SecuredDomainType.getAllInstances());
securityService.assumeOwnershipMigrated(SecuredDomainType.DATA_MINING.getName(),
SecuredDomainType.getAllInstances());
securityService.assumeOwnershipMigrated(SecuredDomainType.REPLICATOR.getName(),
SecuredDomainType.getAllInstances());
securityService.assumeOwnershipMigrated(SecuredDomainType.MANAGE_MARK_PASSINGS.getName());
securityService.assumeOwnershipMigrated(SecuredDomainType.RACE_MANAGER_APP_DEVICE_CONFIGURATION.getName());
securityService.assumeOwnershipMigrated(SecuredDomainType.RESULT_IMPORT_URL.getName());
securityService.assumeOwnershipMigrated(SecuredDomainType.MANAGE_MARK_POSITIONS.getName());
securityService.assumeOwnershipMigrated(SecuredDomainType.CAN_REPLAY_DURING_LIVE_RACES.getName());
securityService.assumeOwnershipMigrated(SecuredDomainType.DETAIL_TIMER.getName());
securityService.assumeOwnershipMigrated(SecuredDomainType.DATA_MINING.getName());
securityService.assumeOwnershipMigrated(SecuredDomainType.REPLICATOR.getName());
for (Event event : getAllEvents()) {
securityService.migrateOwnership(event, SecuredDomainType.getAllInstances());
securityService.migrateOwnership(event);
}
securityService.assumeOwnershipMigrated(SecuredDomainType.EVENT.getName(), SecuredDomainType.getAllInstances());
securityService.assumeOwnershipMigrated(SecuredDomainType.EVENT.getName());
for (Regatta regatta : getAllRegattas()) {
securityService.migrateOwnership(regatta, SecuredDomainType.getAllInstances());
securityService.migrateOwnership(regatta);
// FIXME add listener for all TrackedRaces here and migrate them as they become available!
DynamicTrackedRegatta trackedRegatta = getTrackedRegatta(regatta);
if (trackedRegatta != null) {
trackedRegatta.lockTrackedRacesForRead();
try {
for (DynamicTrackedRace trackedRace : trackedRegatta.getTrackedRaces()) {
securityService.migrateOwnership(trackedRace, SecuredDomainType.getAllInstances());
securityService.migrateOwnership(trackedRace);
}
} finally {
trackedRegatta.unlockTrackedRacesAfterRead();
}
}
}
securityService.assumeOwnershipMigrated(SecuredDomainType.TRACKED_RACE.getName(),
SecuredDomainType.getAllInstances());
securityService.assumeOwnershipMigrated(SecuredDomainType.REGATTA.getName(),
SecuredDomainType.getAllInstances());
securityService.assumeOwnershipMigrated(SecuredDomainType.TRACKED_RACE.getName());
securityService.assumeOwnershipMigrated(SecuredDomainType.REGATTA.getName());
for (Leaderboard leaderboard : getLeaderboards().values()) {
securityService.migrateOwnership(leaderboard, SecuredDomainType.getAllInstances());
securityService.migrateOwnership(leaderboard);
}
securityService.assumeOwnershipMigrated(SecuredDomainType.LEADERBOARD.getName(),
SecuredDomainType.getAllInstances());
securityService.assumeOwnershipMigrated(SecuredDomainType.LEADERBOARD.getName());
for (LeaderboardGroup leaderboardGroup : getLeaderboardGroups().values()) {
securityService.migrateOwnership(leaderboardGroup, SecuredDomainType.getAllInstances());
securityService.migrateOwnership(leaderboardGroup);
}
securityService.assumeOwnershipMigrated(SecuredDomainType.LEADERBOARD_GROUP.getName(),
SecuredDomainType.getAllInstances());
securityService.assumeOwnershipMigrated(SecuredDomainType.LEADERBOARD_GROUP.getName());
for (MediaTrack mediaTrack : getAllMediaTracks()) {
securityService.migrateOwnership(mediaTrack, SecuredDomainType.getAllInstances());
securityService.migrateOwnership(mediaTrack);
}
securityService.assumeOwnershipMigrated(SecuredDomainType.MEDIA_TRACK.getName(),
SecuredDomainType.getAllInstances());
securityService.assumeOwnershipMigrated(SecuredDomainType.MEDIA_TRACK.getName());
for (Competitor competitor : getCompetitorAndBoatStore().getAllCompetitors()) {
securityService.migrateOwnership(competitor, SecuredDomainType.getAllInstances());
securityService.migrateOwnership(competitor);
}
securityService.assumeOwnershipMigrated(SecuredDomainType.COMPETITOR.getName(),
SecuredDomainType.getAllInstances());
securityService.assumeOwnershipMigrated(SecuredDomainType.COMPETITOR.getName());
for (Boat boat : getCompetitorAndBoatStore().getBoats()) {
securityService.migrateOwnership(boat, SecuredDomainType.getAllInstances());
securityService.migrateOwnership(boat);
}
securityService.assumeOwnershipMigrated(SecuredDomainType.BOAT.getName(), SecuredDomainType.getAllInstances());
securityService.assumeOwnershipMigrated(SecuredDomainType.BOAT.getName());
securityService.checkMigration(SecuredDomainType.getAllInstances());
}
@@ -1,7 +1,6 @@
package com.sap.sse.security.shared;
import com.sap.sse.security.shared.HasPermissions.DefaultActions;
import com.sap.sse.security.shared.impl.SecuredSecurityTypes;
public class UserRole extends RolePrototype {
private static final long serialVersionUID = 3291793984984443193L;
@@ -10,8 +9,7 @@ public class UserRole extends RolePrototype {
UserRole() {
super("user", "ad1d5148-b13d-4464-90c4-7c396e4d4e2e",
new WildcardPermission(SecuredSecurityTypes.USER.getStringPermission(DefaultActions.READ, DefaultActions.UPDATE)),
WildcardPermission.builder().withActions(DefaultActions.READ_AND_WRITE_ACTIONS).build());
WildcardPermission.builder().withActions(DefaultActions.values()).build());
}
public static UserRole getInstance() {
@@ -1,17 +1,18 @@
package com.sap.sse.security.shared.dto;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import com.sap.sse.security.shared.impl.AbstractAccessControlList;
public class AccessControlListDTO extends AbstractAccessControlList<StrippedUserGroupDTO, StrippedUserDTO> {
private static final long serialVersionUID = 1L;
@Deprecated
// gwt only
private static final long serialVersionUID = 2878270565599189728L;
@Deprecated // gwt only
AccessControlListDTO() {
super(null);
super(Collections.<StrippedUserGroupDTO, Set<String>> emptyMap());
}
public AccessControlListDTO(Map<StrippedUserGroupDTO, Set<String>> permissionMap) {
@@ -53,7 +53,7 @@ public abstract class AbstractAccessControlList<G extends SecurityUserGroup, U e
*/
private Map<G, Set<WildcardPermission>> deniedActionsByUserGroup;
public AbstractAccessControlList(Map<G, Set<String>> permissionMap) {
protected AbstractAccessControlList(Map<G, Set<String>> permissionMap) {
this.allowedActionsByUserGroup = new HashMap<>();
this.deniedActionsByUserGroup = new HashMap<>();
for (final Entry<G, Set<String>> permissionMapEntry : permissionMap.entrySet()) {
@@ -1,26 +1,23 @@
package com.sap.sse.security.ui.client.component;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import static com.sap.sse.security.shared.impl.SecuredSecurityTypes.USER_GROUP;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CaptionPanel;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.celltable.CellTableWithCheckboxResources;
import com.sap.sse.gwt.client.panels.LabeledAbstractFilterablePanel;
import com.sap.sse.security.shared.HasPermissions;
import com.sap.sse.security.shared.dto.AccessControlListAnnotationDTO;
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;
import com.sap.sse.security.ui.client.component.editacl.EditACLDialog;
import com.sap.sse.security.ui.client.i18n.StringMessages;
import com.sap.sse.security.ui.shared.SuccessInfo;
@@ -31,7 +28,6 @@ import com.sap.sse.security.ui.shared.SuccessInfo;
public class UserGroupManagementPanel extends DockPanel {
private final UserGroupListDataProvider userGroupListDataProvider;
private UserGroupDetailPanel userGroupDetailPanel;
private Button editACLForNullUsergroup = null;
private final UserGroupTableWrapper userGroupTableWrapper;
@@ -42,8 +38,7 @@ public class UserGroupManagementPanel extends DockPanel {
final VerticalPanel west = new VerticalPanel();
// create button bar
final HorizontalPanel buttonPanel = createButtonPanel(userService, stringMessages, userManagementService);
west.add(buttonPanel);
west.add(createButtonPanel(userService, stringMessages, userManagementService));
// create UserGroup Table
userGroupListDataProvider = new UserGroupListDataProvider(userManagementService, new TextBox());
@@ -66,69 +61,32 @@ public class UserGroupManagementPanel extends DockPanel {
}
/** Creates the button bar with add/remove/refresh buttons. */
private HorizontalPanel createButtonPanel(final UserService userService, final StringMessages stringMessages,
private Widget createButtonPanel(final UserService userService, final StringMessages stringMessages,
final UserManagementServiceAsync userManagementService) {
final HorizontalPanel buttonPanel = new HorizontalPanel();
buttonPanel.add(new Button(stringMessages.refresh(), new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
updateUserGroups();
}
}));
buttonPanel.add(new Button(stringMessages.createUserGroup(), new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
new CreateUserGroupDialog(stringMessages, userService, userManagementService, userGroupListDataProvider)
.show();
}
}));
editACLForNullUsergroup = new Button("Edit ACL for Null Usergroup", new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
userManagementService.getAccessControlList(null, new AsyncCallback<AccessControlListAnnotationDTO>() {
final AccessControlledButtonPanel buttonPanel = new AccessControlledButtonPanel(userService, USER_GROUP);
buttonPanel.addUnsecuredAction(stringMessages.refresh(), () -> updateUserGroups());
buttonPanel.addCreateAction(stringMessages.createUserGroup(), () -> new CreateUserGroupDialog(stringMessages,
userService, userManagementService, userGroupListDataProvider).show());
buttonPanel.addRemoveAction(stringMessages.removeUserGroup(), () -> {
UserGroupDTO userGroup = userGroupTableWrapper.getSelectionModel().getSelectedObject();
if (userGroup == null) {
Window.alert(stringMessages.youHaveToSelectAUserGroup());
} else if (Window.confirm(stringMessages.doYouReallyWantToRemoveUserGroup(userGroup.getName()))) {
userManagementService.deleteUserGroup(userGroup.getId().toString(), new AsyncCallback<SuccessInfo>() {
@Override
public void onFailure(Throwable caught) {
// TODO Auto-generated method stub
public void onSuccess(SuccessInfo result) {
userGroupListDataProvider.updateDisplays();
Window.alert(result.getMessage());
updateUserGroups();
}
@Override
public void onSuccess(AccessControlListAnnotationDTO result) {
final EditACLDialog.DialogConfig<UserGroupDTO> configACL = EditACLDialog.create(
userService.getUserManagementService(), SecuredSecurityTypes.USER_GROUP,
user -> result.getAnnotation(), stringMessages);
configACL.openDialog(null);
public void onFailure(Throwable caught) {
Window.alert(stringMessages.couldNotDeleteUserGroup());
}
});
}
});
buttonPanel.add(editACLForNullUsergroup);
buttonPanel.add(new Button(stringMessages.removeUserGroup(), new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
UserGroupDTO userGroup = userGroupTableWrapper.getSelectionModel().getSelectedObject();
if (userGroup == null) {
Window.alert(stringMessages.youHaveToSelectAUserGroup());
} else if (Window.confirm(stringMessages.doYouReallyWantToRemoveUserGroup(userGroup.getName()))) {
userManagementService.deleteUserGroup(userGroup.getId().toString(),
new AsyncCallback<SuccessInfo>() {
@Override
public void onSuccess(SuccessInfo result) {
userGroupListDataProvider.updateDisplays();
Window.alert(result.getMessage());
updateUserGroups();
}
@Override
public void onFailure(Throwable caught) {
Window.alert(stringMessages.couldNotDeleteUserGroup());
}
});
}
}
}));
return buttonPanel;
}
@@ -10,17 +10,12 @@ import java.util.Set;
import com.google.gwt.core.client.Callback;
import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.cellview.client.SimplePager.TextLocation;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.view.client.SingleSelectionModel;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.Notification;
import com.sap.sse.gwt.client.Notification.NotificationType;
@@ -28,26 +23,19 @@ import com.sap.sse.gwt.client.celltable.CellTableWithCheckboxResources;
import com.sap.sse.gwt.client.celltable.RefreshableMultiSelectionModel;
import com.sap.sse.gwt.client.panels.LabeledAbstractFilterablePanel;
import com.sap.sse.security.shared.HasPermissions;
import com.sap.sse.security.shared.dto.AccessControlListAnnotationDTO;
import com.sap.sse.security.shared.dto.UserDTO;
import com.sap.sse.security.ui.client.UserManagementServiceAsync;
import com.sap.sse.security.ui.client.UserService;
import com.sap.sse.security.ui.client.component.AccessControlListListDataProvider;
import com.sap.sse.security.ui.client.component.AccessControlledButtonPanel;
import com.sap.sse.security.ui.client.component.CreateUserDialog;
import com.sap.sse.security.ui.client.component.EditAccessControlListDialog;
import com.sap.sse.security.ui.client.i18n.StringMessages;
import com.sap.sse.security.ui.shared.SuccessInfo;
public class UserManagementPanel<TR extends CellTableWithCheckboxResources> extends DockPanel {
private final List<UserCreatedEventHandler> userCreatedHandlers = new ArrayList<>();
private final List<UserDeletedEventHandler> userDeletedHandlers = new ArrayList<>();
private final SingleSelectionModel<AccessControlListAnnotationDTO> aclSingleSelectionModel;
private final AccessControlListListDataProvider aclListDataProvider;
private final UserTableWrapper<RefreshableMultiSelectionModel<UserDTO>, TR> userList;
private final RefreshableMultiSelectionModel<UserDTO> userSelectionModel;
@@ -62,21 +50,11 @@ public class UserManagementPanel<TR extends CellTableWithCheckboxResources> exte
final VerticalPanel west = new VerticalPanel();
final AccessControlledButtonPanel buttonPanel = new AccessControlledButtonPanel(userService, USER);
west.add(buttonPanel);
buttonPanel.addUnsecuredAction(stringMessages.refresh(), this::updateUsersAndACLs);
buttonPanel.addUnsecuredAction(stringMessages.refresh(), this::updateUsers);
buttonPanel.addCreateAction(stringMessages.createUser(),
() -> new CreateUserDialog(stringMessages, userManagementService, userCreatedHandlers, userService)
.show());
aclListDataProvider = new AccessControlListListDataProvider(userManagementService);
aclSingleSelectionModel = new SingleSelectionModel<>();
// TODO: find the right place for the acl controls
final Button editACLButton = buttonPanel.addUnsecuredAction(stringMessages.editACL(),
() -> new EditAccessControlListDialog(stringMessages, userManagementService, aclListDataProvider,
aclSingleSelectionModel.getSelectedObject()).show());
editACLButton.setEnabled(false);
aclSingleSelectionModel.addSelectionChangeHandler(
event -> editACLButton.setEnabled(aclSingleSelectionModel.getSelectedObject() != null));
userList = new UserTableWrapper<>(userService, additionalPermissions, stringMessages, errorReporter,
/* multiSelection */ true, /* enablePager */ true, tableResources);
userSelectionModel = userList.getSelectionModel();
@@ -118,30 +96,6 @@ public class UserManagementPanel<TR extends CellTableWithCheckboxResources> exte
deleteButton.setEnabled(userSelectionModel.getSelectedSet().size() >= 1);
});
final CellTable<AccessControlListAnnotationDTO> aclTable = new CellTable<>();
TextColumn<AccessControlListAnnotationDTO> idColumn = new TextColumn<AccessControlListAnnotationDTO>() {
@Override
public String getValue(AccessControlListAnnotationDTO acl) {
return acl.getIdOfAnnotatedObject().toString();
}
};
TextColumn<AccessControlListAnnotationDTO> displayNameColumn = new TextColumn<AccessControlListAnnotationDTO>() {
@Override
public String getValue(AccessControlListAnnotationDTO acl) {
return acl.getDisplayNameOfAnnotatedObject()==null?"":acl.getDisplayNameOfAnnotatedObject();
}
};
aclTable.addColumn(idColumn, stringMessages.id());
aclTable.addColumn(displayNameColumn, stringMessages.displayName());
aclTable.setSelectionModel(aclSingleSelectionModel);
aclTable.setPageSize(20);
aclListDataProvider.addDataDisplay(aclTable);
SimplePager aclPager = new SimplePager(TextLocation.CENTER, false, /* fast forward step size */ 50, true);
aclPager.setDisplay(aclTable);
ScrollPanel aclPanel = new ScrollPanel(aclTable);
west.add(aclPager);
west.add(aclPanel);
ScrollPanel scrollPanel = new ScrollPanel(userList.asWidget());
LabeledAbstractFilterablePanel<UserDTO> filterBox = userList.getFilterField();
filterBox.getElement().setPropertyString("placeholder", stringMessages.filterUsers());
@@ -164,12 +118,11 @@ public class UserManagementPanel<TR extends CellTableWithCheckboxResources> exte
userList.getFilterField().remove(user);
}
});
updateUsersAndACLs();
updateUsers();
}
public void updateUsersAndACLs() {
public void updateUsers() {
userList.refreshUserList((Callback<Iterable<UserDTO>, Throwable>) null);
aclListDataProvider.updateDisplays();
}
public void addUserCreatedEventHandler(UserCreatedEventHandler handler){
@@ -62,16 +62,15 @@ public class Activator implements BundleActivator {
securityServiceServiceTracker.open();
final SecurityService securityService = securityServiceServiceTracker.waitForService(0);
for (User user : userStore.getUsers()) {
securityService.migrateOwnership(user, SecuredSecurityTypes.getAllInstances());
securityService.migrateOwnership(user);
}
for (UserGroup group : userStore.getUserGroups()) {
securityService.migrateOwnership(group, SecuredSecurityTypes.getAllInstances());
securityService.migrateOwnership(group);
}
for (RoleDefinition role : userStore.getRoleDefinitions()) {
securityService.migrateOwnership(role, SecuredSecurityTypes.getAllInstances());
securityService.migrateOwnership(role);
}
securityService.assumeOwnershipMigrated(SecuredSecurityTypes.SERVER.getName(),
SecuredSecurityTypes.getAllInstances());
securityService.assumeOwnershipMigrated(SecuredSecurityTypes.SERVER.getName());
securityService.checkMigration(SecuredSecurityTypes.getAllInstances());
} catch (InterruptedException e) {
logger.log(Level.SEVERE, "Error in migration", e);
@@ -381,10 +381,11 @@ public interface SecurityService extends ReplicableWithObjectInputStream<Replica
* Since there are some HasPermission objects, that have no Ownership, this method is used to explicitly mention
* that they are to be assumed as migrated.
*/
void assumeOwnershipMigrated(String typeName, Iterable<HasPermissions> permissions);
void migrateOwnership(WithQualifiedObjectIdentifier object, Iterable<HasPermissions> permissions);
void assumeOwnershipMigrated(String typeName);
void migrateOwnership(QualifiedObjectIdentifier object, String displayName, Iterable<HasPermissions> permissions);
void migrateOwnership(WithQualifiedObjectIdentifier object);
void migrateOwnership(QualifiedObjectIdentifier object, String displayName);
void checkMigration(Iterable<HasPermissions> allInstances);
@@ -22,7 +22,7 @@ import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.logging.Level;
@@ -135,7 +135,7 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
// private static final long MIGRATION_CHECK_DELAY = 20000;
private final Map<Pair<Class<? extends HasPermissions>, List<String>>, List<String>> migratedHasPermissionTypes = new ConcurrentHashMap<>();
private final Set<String> migratedHasPermissionTypes = new ConcurrentSkipListSet<>();;
// private final Timer migrationTimer;
@@ -1548,15 +1548,11 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
ActionWithResult<User> createActionReturningCreatedObject) {
QualifiedObjectIdentifier identifier = SecuredSecurityTypes.USER.getQualifiedObjectIdentifier(username);
User result = null;
boolean didSetOwnerShip = false;
try {
SecurityUtils.getSubject().checkPermission(identifier.getStringPermission(DefaultActions.CREATE));
result = createActionReturningCreatedObject.run();
setOwnership(identifier, result, getDefaultTenantForCurrentUser());
} catch (AuthorizationException e) {
if (didSetOwnerShip) {
deleteOwnership(identifier);
}
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
@@ -1816,16 +1812,13 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
}
@Override
public void migrateOwnership(WithQualifiedObjectIdentifier identifier, Iterable<HasPermissions> permissions) {
migrateOwnership(identifier.getIdentifier(), identifier.getName(), permissions);
public void migrateOwnership(WithQualifiedObjectIdentifier identifier) {
migrateOwnership(identifier.getIdentifier(), identifier.getName());
}
@Override
public void migrateOwnership(final QualifiedObjectIdentifier identifier, final String displayName,
final Iterable<HasPermissions> permissions) {
public void migrateOwnership(final QualifiedObjectIdentifier identifier, final String displayName) {
final List<String> alreadyMigrated = getMigrationInfoForKey(permissions);
final OwnershipAnnotation owner = this.getOwnership(identifier);
final UserGroup defaultTenant = this.getDefaultTenant();
// fix unowned objects, also fix wrongly converted objects due to older codebase that could not handle null
@@ -1836,34 +1829,15 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
+ defaultTenant);
this.setOwnership(identifier, null, defaultTenant, displayName);
}
if (!alreadyMigrated.contains(identifier.getTypeIdentifier())) {
alreadyMigrated.add(identifier.getTypeIdentifier());
}
}
private List<String> getMigrationInfoForKey(final Iterable<HasPermissions> permissions) {
final List<String> allRequiredPermissionsAsString = new ArrayList<>();
for (HasPermissions permission : permissions) {
allRequiredPermissionsAsString.add(permission.getName());
}
// the given Iterable cannot guarantee, that the order is always the same
Collections.sort(allRequiredPermissionsAsString);
Pair<Class<? extends HasPermissions>, List<String>> key = new Pair<>(Util.first(permissions).getClass(),
allRequiredPermissionsAsString);
final List<String> alreadyMigrated = migratedHasPermissionTypes.computeIfAbsent(key,
t -> new CopyOnWriteArrayList<>());
return alreadyMigrated;
migratedHasPermissionTypes.add(identifier.getTypeIdentifier());
}
@Override
public void checkMigration(Iterable<HasPermissions> allInstances) {
Class<? extends HasPermissions> clazz = Util.first(allInstances).getClass();
List<String> alreadyMigrated = getMigrationInfoForKey(allInstances);
boolean allChecksSucessfull = true;
for (HasPermissions shouldBeMigrated : allInstances) {
if (!alreadyMigrated.contains(shouldBeMigrated.getName())) {
if (!migratedHasPermissionTypes.contains(shouldBeMigrated.getName())) {
logger.severe("Permission-Vertical Migration: Did not migrate all Types for " + clazz.getName()
+ " missing: " + shouldBeMigrated);
allChecksSucessfull = false;
@@ -1944,9 +1918,8 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
}
@Override
public void assumeOwnershipMigrated(String typeName, Iterable<HasPermissions> permissions) {
final List<String> alreadyMigrated = getMigrationInfoForKey(permissions);
alreadyMigrated.add(typeName);
public void assumeOwnershipMigrated(String typeName) {
migratedHasPermissionTypes.add(typeName);
}
@Override