mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-13 22:15:26 +00:00
Merge branch 'permission-vertical' into bug4813
Conflicts: java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/AdminConsoleEntryPoint.java java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/EventsResource.java
This commit is contained in:
commit
320ac4a597
12 files changed
+203
-96
No files matched your search
+13
-9
@@ -242,19 +242,22 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint
|
||||
this, this, getStringMessages());
|
||||
tractracEventManagementPanel.ensureDebugId("TracTracEventManagement");
|
||||
panel.addToTabPanel(connectorsTabPanel, new DefaultRefreshableAdminConsolePanel<TracTracEventManagementPanel>(tractracEventManagementPanel),
|
||||
getStringMessages().tracTracEvents()); // no permissions required; we show those TracTrac connector stuff the user may read
|
||||
getStringMessages().tracTracEvents(),
|
||||
SecuredDomainType.TRACTRAC_ACCOUNT.getPermission(DefaultActions.values()));
|
||||
regattasDisplayers.add(tractracEventManagementPanel);
|
||||
|
||||
SwissTimingReplayConnectorPanel swissTimingReplayConnectorPanel = new SwissTimingReplayConnectorPanel(
|
||||
getSailingService(), this, this, getStringMessages());
|
||||
panel.addToTabPanel(connectorsTabPanel, new DefaultRefreshableAdminConsolePanel<SwissTimingReplayConnectorPanel>(swissTimingReplayConnectorPanel),
|
||||
getStringMessages().swissTimingArchiveConnector()); // no permissions required; we show those SwissTiming connector stuff the user may read
|
||||
getStringMessages().swissTimingArchiveConnector(),
|
||||
SecuredDomainType.SWISS_TIMING_ARCHIVE_ACCOUNT.getPermission(DefaultActions.values()));
|
||||
regattasDisplayers.add(swissTimingReplayConnectorPanel);
|
||||
|
||||
SwissTimingEventManagementPanel swisstimingEventManagementPanel = new SwissTimingEventManagementPanel(
|
||||
getSailingService(), this, this, getStringMessages());
|
||||
panel.addToTabPanel(connectorsTabPanel, new DefaultRefreshableAdminConsolePanel<SwissTimingEventManagementPanel>(swisstimingEventManagementPanel),
|
||||
getStringMessages().swissTimingEvents()); // no permissions required; we show those SwissTiming connector stuff the user may read
|
||||
getStringMessages().swissTimingEvents(),
|
||||
SecuredDomainType.SWISS_TIMING_ACCOUNT.getPermission(DefaultActions.values()));
|
||||
regattasDisplayers.add(swisstimingEventManagementPanel);
|
||||
|
||||
final SmartphoneTrackingEventManagementPanel raceLogTrackingEventManagementPanel = new SmartphoneTrackingEventManagementPanel(
|
||||
@@ -272,8 +275,8 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint
|
||||
IgtimiAccountsPanel igtimiAccountsPanel = new IgtimiAccountsPanel(getSailingService(), this, getStringMessages());
|
||||
igtimiAccountsPanel.ensureDebugId("IgtimiAccounts");
|
||||
panel.addToTabPanel(connectorsTabPanel, new DefaultRefreshableAdminConsolePanel<IgtimiAccountsPanel>(igtimiAccountsPanel),
|
||||
getStringMessages().igtimiAccounts()); // Igtimi accounts are displayed based on permissions
|
||||
|
||||
getStringMessages().igtimiAccounts(),
|
||||
SecuredDomainType.IGTIMI_ACCOUNT.getPermission(DefaultActions.values()));
|
||||
ExpeditionDeviceConfigurationsPanel expeditionDeviceConfigurationsPanel = new ExpeditionDeviceConfigurationsPanel(getSailingService(), this, getStringMessages());
|
||||
expeditionDeviceConfigurationsPanel.ensureDebugId("ExpeditionDeviceConfigurations");
|
||||
panel.addToTabPanel(connectorsTabPanel, new DefaultRefreshableAdminConsolePanel<ExpeditionDeviceConfigurationsPanel>(expeditionDeviceConfigurationsPanel) {
|
||||
@@ -281,12 +284,13 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint
|
||||
public void refreshAfterBecomingVisible() {
|
||||
expeditionDeviceConfigurationsPanel.refresh();
|
||||
}
|
||||
}, getStringMessages().expeditionDeviceConfigurations()); // Expedition device configurations are displayed based on individual user permissions
|
||||
}, getStringMessages().expeditionDeviceConfigurations(),
|
||||
SecuredDomainType.EXPEDITION_DEVICE_CONFIGURATION.getPermission(DefaultActions.values()));
|
||||
|
||||
ResultImportUrlsManagementPanel resultImportUrlsManagementPanel = new ResultImportUrlsManagementPanel(getSailingService(), this, getStringMessages());
|
||||
panel.addToTabPanel(connectorsTabPanel, new DefaultRefreshableAdminConsolePanel<ResultImportUrlsManagementPanel>(resultImportUrlsManagementPanel),
|
||||
getStringMessages().resultImportUrls()); // result import URLs have ownerships and are displayed as the user can see / update / delete them
|
||||
|
||||
getStringMessages().resultImportUrls(),
|
||||
SecuredDomainType.RESULT_IMPORT_URL.getPermission(DefaultActions.values()));
|
||||
StructureImportManagementPanel structureImportUrlsManagementPanel = new StructureImportManagementPanel(
|
||||
getSailingService(), getUserService(), this, getStringMessages(), this, eventManagementPanel);
|
||||
panel.addToTabPanel(connectorsTabPanel, new DefaultRefreshableAdminConsolePanel<StructureImportManagementPanel>(structureImportUrlsManagementPanel),
|
||||
@@ -315,7 +319,7 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint
|
||||
panel.addToTabPanel(advancedTabPanel, new DefaultRefreshableAdminConsolePanel<RemoteServerInstancesManagementPanel>(remoteServerInstancesManagementPanel),
|
||||
getStringMessages().remoteServerInstances(),
|
||||
SecuredSecurityTypes.SERVER.getPermissionForObject(
|
||||
SecuredSecurityTypes.ServerActions.CONFIGURE_LOCAL_SERVER, serverInfo.getServerName()));
|
||||
SecuredSecurityTypes.ServerActions.CONFIGURE_REMOTE_INSTANCES, serverInfo.getServerName()));
|
||||
|
||||
LocalServerManagementPanel localServerInstancesManagementPanel = new LocalServerManagementPanel(getSailingService(), this, getStringMessages());
|
||||
panel.addToTabPanel(advancedTabPanel, new DefaultRefreshableAdminConsolePanel<LocalServerManagementPanel>(localServerInstancesManagementPanel),
|
||||
|
||||
+26
-37
@@ -4636,45 +4636,34 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
public void removeRegatta(RegattaIdentifier regattaIdentifier) {
|
||||
Regatta regatta = getService().getRegatta(regattaIdentifier);
|
||||
if (regatta != null) {
|
||||
getSecurityService().checkPermissionAndDeleteOwnershipForObjectRemoval(regatta, new Action() {
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
// if there were any tracked races, free all ownerships
|
||||
for (RaceDefinition race : regatta.getAllRaces()) {
|
||||
String typeRelativeObjectIdentifier = WildcardPermissionEncoder.encode(regatta.getName(),
|
||||
race.getName());
|
||||
QualifiedObjectIdentifier identifier = SecuredDomainType.TRACKED_RACE
|
||||
.getQualifiedObjectIdentifier(typeRelativeObjectIdentifier);
|
||||
getSecurityService().checkPermissionAndDeleteOwnershipForObjectRemoval(identifier,
|
||||
new ActionWithResult<Void>() {
|
||||
@Override
|
||||
public Void run() throws Exception {
|
||||
RegattaNameAndRaceName raceIdentifier = new RegattaNameAndRaceName(
|
||||
regatta.getName(), race.getName());
|
||||
ArrayList<RegattaAndRaceIdentifier> trackedRace = new ArrayList<>();
|
||||
trackedRace.add(raceIdentifier);
|
||||
removeAndUntrackRaces(trackedRace);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
// remove all leaderboards using the proper call that will clean and remove the owner as well
|
||||
Set<RegattaLeaderboard> leaderboardsToRemove = new HashSet<>();
|
||||
for (Leaderboard leaderboard : getService().getLeaderboards().values()) {
|
||||
if (leaderboard instanceof RegattaLeaderboard) {
|
||||
RegattaLeaderboard regattaLeaderboard = (RegattaLeaderboard) leaderboard;
|
||||
if (regattaLeaderboard.getRegatta() == regatta) {
|
||||
leaderboardsToRemove.add(regattaLeaderboard);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (RegattaLeaderboard regattaLeaderboardToRemove : leaderboardsToRemove) {
|
||||
removeLeaderboard(regattaLeaderboardToRemove.getName());
|
||||
}
|
||||
Set<QualifiedObjectIdentifier> objectsThatWillBeImplicitlyCleanedByRemoveRegatta = new HashSet<>();
|
||||
objectsThatWillBeImplicitlyCleanedByRemoveRegatta.add(regatta.getIdentifier());
|
||||
for (RaceDefinition race : regatta.getAllRaces()) {
|
||||
String typeRelativeObjectIdentifier = WildcardPermissionEncoder.encode(regatta.getName(),
|
||||
race.getName());
|
||||
QualifiedObjectIdentifier identifier = SecuredDomainType.TRACKED_RACE
|
||||
.getQualifiedObjectIdentifier(typeRelativeObjectIdentifier);
|
||||
objectsThatWillBeImplicitlyCleanedByRemoveRegatta.add(identifier);
|
||||
}
|
||||
for (Leaderboard leaderboard : getService().getLeaderboards().values()) {
|
||||
if (leaderboard instanceof RegattaLeaderboard) {
|
||||
RegattaLeaderboard regattaLeaderboard = (RegattaLeaderboard) leaderboard;
|
||||
if (regattaLeaderboard.getRegatta() == regatta) {
|
||||
objectsThatWillBeImplicitlyCleanedByRemoveRegatta.add(regattaLeaderboard.getIdentifier());
|
||||
}
|
||||
getService().apply(new RemoveRegatta(regattaIdentifier));
|
||||
}
|
||||
});
|
||||
}
|
||||
// check if we can delete everything RemoveRegatta will remove
|
||||
for (QualifiedObjectIdentifier toRemovePermissionObjects : objectsThatWillBeImplicitlyCleanedByRemoveRegatta) {
|
||||
getSecurityService().checkCurrentUserDeletePermission(toRemovePermissionObjects);
|
||||
}
|
||||
// we have all permissions, execute
|
||||
getService().apply(new RemoveRegatta(regattaIdentifier));
|
||||
// cleanup the Ownership and ACLs
|
||||
for (QualifiedObjectIdentifier toRemovePermissionObjects : objectsThatWillBeImplicitlyCleanedByRemoveRegatta) {
|
||||
getSecurityService().deleteOwnership(toRemovePermissionObjects);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.sap.sailing.server.gateway.deserialization.impl;
|
||||
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
|
||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.MongoDbFriendlyPositionJsonSerializer;
|
||||
|
||||
public class MongoDbFriendlyPositionJsonDeserializer implements JsonDeserializer<Position> {
|
||||
|
||||
@Override
|
||||
public Position deserialize(JSONObject object) throws JsonDeserializationException {
|
||||
JSONArray coordinatesJson = (JSONArray) object.get(MongoDbFriendlyPositionJsonSerializer.FIELD_COORDINATES);
|
||||
Number longitudeDeg = (Number) coordinatesJson.get(0);
|
||||
Number latitudeDeg = (Number) coordinatesJson.get(1);
|
||||
return new DegreePosition(latitudeDeg.doubleValue(), longitudeDeg.doubleValue());
|
||||
}
|
||||
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.sap.sailing.server.gateway.serialization.impl;
|
||||
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
|
||||
|
||||
public class MongoDbFriendlyPositionJsonSerializer implements JsonSerializer<Position> {
|
||||
|
||||
public static final String FIELD_TYPE = "type";
|
||||
public static final String FIELD_TYPE_VALUE = "Point";
|
||||
public static final String FIELD_COORDINATES = "coordinates";
|
||||
|
||||
@Override
|
||||
public JSONObject serialize(Position position) {
|
||||
JSONObject result = new JSONObject();
|
||||
JSONArray coordinates = new JSONArray();
|
||||
coordinates.add(position.getLngDeg());
|
||||
coordinates.add(position.getLatDeg());
|
||||
result.put(FIELD_TYPE, FIELD_TYPE_VALUE);
|
||||
result.put(FIELD_COORDINATES, coordinates);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
+3
-2
@@ -31,7 +31,7 @@ public class RaceWindJsonSerializer extends AbstractTrackedRaceDataJsonSerialize
|
||||
public static final String SAMPLING_RATE = "samplingRate";
|
||||
public static final String FIXES = "fixes";
|
||||
|
||||
private final PositionJsonSerializer positionSerializer = new PositionJsonSerializer();
|
||||
private final MongoDbFriendlyPositionJsonSerializer positionSerializer = new MongoDbFriendlyPositionJsonSerializer();
|
||||
private final WindJsonSerializer windSerializer = new WindJsonSerializer(positionSerializer);
|
||||
|
||||
@Override
|
||||
@@ -85,7 +85,8 @@ public class RaceWindJsonSerializer extends AbstractTrackedRaceDataJsonSerialize
|
||||
windSourceJson.put(FIRST_POSITION, positionSerializer.serialize(firstWindSourcePosition));
|
||||
windSourceJson.put(START_TIME_POINT, firstWindSourceTimePoint.asMillis());
|
||||
windSourceJson.put(END_TIME_POINT, lastWindSourceTimePoint.asMillis());
|
||||
double samplingRate = duration.asSeconds() > 0 ? windFixesJson.size() / duration.asSeconds() : 0;
|
||||
double samplingRate = duration.asSeconds() > 0 ? windFixesJson.size() / duration.asSeconds()
|
||||
: 0;
|
||||
windSourceJson.put(SAMPLING_RATE, samplingRate);
|
||||
windSourceJson.put(FIXES, windFixesJson);
|
||||
windSourcesJson.add(windSourceJson);
|
||||
|
||||
@@ -55,8 +55,8 @@ authc.successUrl = /api/restsecurity/hello
|
||||
# authentication with POST parameters "username" and "password".
|
||||
bearerToken = com.sap.sailing.server.security.BearerTokenOrBasicOrFormAuthenticationFilterSAPSailing
|
||||
|
||||
# The same as bearerToken, but with additional fallback to anonymous authentification.
|
||||
# In this case sufficent permission checks have to be done on the application side.
|
||||
# The same as bearerToken, but with additional fallback to anonymous authentication.
|
||||
# In this case sufficient permission checks have to be done on the application side.
|
||||
bearerTokenOrAnonymous = com.sap.sailing.server.security.BearerTokenOrBasicOrFormOrAnonymousAuthenticationFilterSAPSailing
|
||||
|
||||
# Specifying filter chains for URL patterns
|
||||
|
||||
+61
-39
@@ -93,6 +93,7 @@ import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.security.ActionWithResult;
|
||||
import com.sap.sse.security.shared.HasPermissions.DefaultActions;
|
||||
import com.sap.sse.security.shared.impl.User;
|
||||
import com.sap.sse.security.shared.impl.UserGroup;
|
||||
import com.sap.sse.shared.media.ImageDescriptor;
|
||||
import com.sap.sse.shared.media.VideoDescriptor;
|
||||
|
||||
@@ -417,27 +418,7 @@ public class EventsResource extends AbstractSailingServerResource {
|
||||
Map<Locale, URL> sailorsInfoWebsiteURLs = new HashMap<Locale,URL>();
|
||||
Iterable<ImageDescriptor> images = Collections.<ImageDescriptor> emptyList();
|
||||
Iterable<VideoDescriptor> videos = Collections.<VideoDescriptor> emptyList();
|
||||
Event event = getSecurityService().setOwnershipCheckPermissionForObjectCreationAndRevertOnError(
|
||||
SecuredDomainType.EVENT, eventId,
|
||||
eventName, new ActionWithResult<Event>() {
|
||||
|
||||
@Override
|
||||
public Event run() throws Exception {
|
||||
return getService()
|
||||
.apply(new CreateEvent(eventName, eventDescription, startDate, endDate, venueName, isPublic, eventId,
|
||||
officialWebsiteURL, baseURL, sailorsInfoWebsiteURLs, images, videos, leaderboardGroupIds));
|
||||
}
|
||||
});
|
||||
|
||||
CourseArea courseArea = addCourseArea(event, "Default");
|
||||
final LeaderboardGroup leaderboardGroup;
|
||||
if (createLeaderboardGroup) {
|
||||
leaderboardGroup = validateAndAddLeaderboardGroup(event.getId(), event.getName(), event.getDescription(), /* leaderboardGroupDisplayNameParam */ null,
|
||||
/* displayGroupsInReverseOrderParam */ false, /* leaderboardNamesParam */ null,
|
||||
/* overallLeaderboardDiscardThresholdsParam */ null, /* overallLeaderboardScoringSchemeTypeParam */ null);
|
||||
} else {
|
||||
leaderboardGroup = null;
|
||||
}
|
||||
final CompetitorRegistrationType competitorRegistrationType;
|
||||
try {
|
||||
competitorRegistrationType = CompetitorRegistrationType.valueOfOrDefault(competitorRegistrationTypeString, /* failForUnknown */ true);
|
||||
@@ -445,27 +426,68 @@ public class EventsResource extends AbstractSailingServerResource {
|
||||
throw new IllegalArgumentException(ExceptionManager.incorrectParameterValue(competitorRegistrationTypeString,
|
||||
StringUtils.join(CompetitorRegistrationType.values(), ", ")));
|
||||
}
|
||||
final RegattaLeaderboard leaderboard;
|
||||
if (createRegatta) {
|
||||
leaderboard = validateAndCreateRegatta(event.getName(), boatClassName,
|
||||
/* scoringSchemeParam */ null, courseArea.getId(), /* buoyZoneRadiusInHullLengthsParam */ null,
|
||||
/* useStartTimeInterferenceParam */ null, /* controlTrackingFromStartAndFinishTimesParam */ null,
|
||||
/* rankingMetricParam */ null, /* leaderboardDiscardThresholdsParam */ null,
|
||||
numberOfRacesParam, canBoatsOfCompetitorsChangePerRace, competitorRegistrationType, competitorRegistrationSecret);
|
||||
if (leaderboardGroup != null) {
|
||||
getService().apply(new UpdateLeaderboardGroup(leaderboardGroup.getName(), leaderboardGroup.getName(),
|
||||
leaderboardGroup.getDescription(), leaderboardGroup.getDisplayName(),
|
||||
Collections.singletonList(leaderboard.getName()),
|
||||
leaderboardGroup.getOverallLeaderboard() == null ? null
|
||||
: ((ThresholdBasedResultDiscardingRule) leaderboardGroup.getOverallLeaderboard()
|
||||
.getResultDiscardingRule()).getDiscardIndexResultsStartingWithHowManyRaces(),
|
||||
leaderboardGroup.getOverallLeaderboard() == null ? null
|
||||
: leaderboardGroup.getOverallLeaderboard().getScoringScheme().getType()));
|
||||
|
||||
ActionWithResult<Util.Triple<Event, LeaderboardGroup, RegattaLeaderboard>> doCreationAction = new ActionWithResult<Util.Triple<Event, LeaderboardGroup, RegattaLeaderboard>>() {
|
||||
@Override
|
||||
public Util.Triple<Event, LeaderboardGroup, RegattaLeaderboard> run() throws Exception {
|
||||
Event event = getSecurityService().setOwnershipCheckPermissionForObjectCreationAndRevertOnError(
|
||||
SecuredDomainType.EVENT, eventId,
|
||||
eventName, new ActionWithResult<Event>() {
|
||||
|
||||
@Override
|
||||
public Event run() throws Exception {
|
||||
return getService()
|
||||
.apply(new CreateEvent(eventName, eventDescription, startDate, endDate, venueName, isPublic, eventId,
|
||||
officialWebsiteURL, baseURL, sailorsInfoWebsiteURLs, images, videos, leaderboardGroupIds));
|
||||
}
|
||||
});
|
||||
|
||||
CourseArea courseArea = addCourseArea(event.getId(), "Default");
|
||||
final LeaderboardGroup leaderboardGroup;
|
||||
if (createLeaderboardGroup) {
|
||||
leaderboardGroup = validateAndAddLeaderboardGroup(event.getId(), event.getName(), event.getDescription(), /* leaderboardGroupDisplayNameParam */ null,
|
||||
/* displayGroupsInReverseOrderParam */ false, /* leaderboardNamesParam */ null,
|
||||
/* overallLeaderboardDiscardThresholdsParam */ null, /* overallLeaderboardScoringSchemeTypeParam */ null);
|
||||
} else {
|
||||
leaderboardGroup = null;
|
||||
}
|
||||
final RegattaLeaderboard leaderboard;
|
||||
if (createRegatta) {
|
||||
leaderboard = validateAndCreateRegatta(event.getName(), boatClassName,
|
||||
/* scoringSchemeParam */ null, courseArea.getId(), /* buoyZoneRadiusInHullLengthsParam */ null,
|
||||
/* useStartTimeInterferenceParam */ null, /* controlTrackingFromStartAndFinishTimesParam */ null,
|
||||
/* rankingMetricParam */ null, /* leaderboardDiscardThresholdsParam */ null,
|
||||
numberOfRacesParam, canBoatsOfCompetitorsChangePerRace, competitorRegistrationType, competitorRegistrationSecret);
|
||||
if (leaderboardGroup != null) {
|
||||
getService().apply(new UpdateLeaderboardGroup(leaderboardGroup.getName(), leaderboardGroup.getName(),
|
||||
leaderboardGroup.getDescription(), leaderboardGroup.getDisplayName(),
|
||||
Collections.singletonList(leaderboard.getName()),
|
||||
leaderboardGroup.getOverallLeaderboard() == null ? null
|
||||
: ((ThresholdBasedResultDiscardingRule) leaderboardGroup.getOverallLeaderboard()
|
||||
.getResultDiscardingRule()).getDiscardIndexResultsStartingWithHowManyRaces(),
|
||||
leaderboardGroup.getOverallLeaderboard() == null ? null
|
||||
: leaderboardGroup.getOverallLeaderboard().getScoringScheme().getType()));
|
||||
}
|
||||
} else {
|
||||
leaderboard = null;
|
||||
}
|
||||
return new Util.Triple<>(event, leaderboardGroup, leaderboard);
|
||||
}
|
||||
} else {
|
||||
leaderboard = null;
|
||||
};
|
||||
|
||||
|
||||
try {
|
||||
if (competitorRegistrationType == CompetitorRegistrationType.OPEN_UNMODERATED) {
|
||||
UUID newTenantId = UUID.randomUUID();
|
||||
UserGroup ownerGroup = getSecurityService().createUserGroup(newTenantId, eventName + "-owner");
|
||||
getSecurityService().addUserToUserGroup(ownerGroup, getCurrentUser());
|
||||
return getSecurityService().doWithTemporaryDefaultTenant(ownerGroup, doCreationAction);
|
||||
} else {
|
||||
return doCreationAction.run();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return new Util.Triple<>(event, leaderboardGroup, leaderboard);
|
||||
}
|
||||
|
||||
private LeaderboardGroup validateAndAddLeaderboardGroup(UUID eventId, String leaderboardGroupName,
|
||||
|
||||
-3
@@ -46,7 +46,6 @@ import com.sap.sailing.domain.tracking.TrackedRegatta;
|
||||
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
|
||||
import com.sap.sailing.server.impl.RacingEventServiceImpl;
|
||||
import com.sap.sailing.server.operationaltransformation.CreateFlexibleLeaderboard;
|
||||
import com.sap.sailing.server.operationaltransformation.RemoveAndUntrackRace;
|
||||
import com.sap.sailing.server.operationaltransformation.RemoveEvent;
|
||||
import com.sap.sailing.server.operationaltransformation.RemoveLeaderboard;
|
||||
import com.sap.sailing.server.operationaltransformation.RemoveLeaderboardGroup;
|
||||
@@ -120,8 +119,6 @@ public class RemoveLeaderboardTest {
|
||||
public void testRaceLogOfRaceColumnInSeriesDetachedWhenRegattaIsRemoved() {
|
||||
regatta.getRaceColumnByName(R1).setTrackedRace(defaultFleet, trackedRace);
|
||||
assertEquals(1, Util.size(trackedRace.getAttachedRaceLogs()));
|
||||
// removal of races is no longer done automatically, due to restrictions based on permission-vertical
|
||||
server.apply(new RemoveAndUntrackRace(trackedRace.getRaceIdentifier()));
|
||||
server.apply(new RemoveRegatta(new RegattaName(regatta.getName())));
|
||||
assertTrue(Util.isEmpty(trackedRace.getAttachedRaceLogs()));
|
||||
}
|
||||
|
||||
+13
-1
@@ -2503,11 +2503,23 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
||||
|
||||
@Override
|
||||
public void removeRegatta(Regatta regatta) throws MalformedURLException, IOException, InterruptedException {
|
||||
Set<RegattaLeaderboard> leaderboardsToRemove = new HashSet<>();
|
||||
for (Leaderboard leaderboard : getLeaderboards().values()) {
|
||||
if (leaderboard instanceof RegattaLeaderboard) {
|
||||
RegattaLeaderboard regattaLeaderboard = (RegattaLeaderboard) leaderboard;
|
||||
if (regattaLeaderboard.getRegatta() == regatta) {
|
||||
leaderboardsToRemove.add(regattaLeaderboard);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (RegattaLeaderboard regattaLeaderboardToRemove : leaderboardsToRemove) {
|
||||
removeLeaderboard(regattaLeaderboardToRemove.getName());
|
||||
}
|
||||
// avoid ConcurrentModificationException by copying the races to remove:
|
||||
Set<RaceDefinition> racesToRemove = new HashSet<>();
|
||||
Util.addAll(regatta.getAllRaces(), racesToRemove);
|
||||
for (RaceDefinition race : racesToRemove) {
|
||||
// FIXME can this be removed//moved to the removeRace part?
|
||||
removeRace(regatta, race);
|
||||
mongoObjectFactory.removeRegattaForRaceID(race.getName(), regatta);
|
||||
persistentRegattasForRaceIDs.remove(race.getId().toString());
|
||||
}
|
||||
|
||||
+5
@@ -298,6 +298,11 @@ public class AdminConsolePanel extends HeaderPanel implements HandleTabSelectabl
|
||||
return scrollPanel;
|
||||
}
|
||||
|
||||
public void addToTabPanel(final HorizontalTabLayoutPanel tabPanel, RefreshableAdminConsolePanel panelToAdd,
|
||||
String tabTitle) {
|
||||
this.addToTabPanel(tabPanel, panelToAdd, tabTitle, new WildcardPermission(WildcardPermission.WILDCARD_TOKEN));
|
||||
}
|
||||
|
||||
public void addToTabPanel(final HorizontalTabLayoutPanel tabPanel, RefreshableAdminConsolePanel panelToAdd, String tabTitle, WildcardPermission... requiresAnyOfThesePermissions) {
|
||||
VerticalOrHorizontalTabLayoutPanel wrapper = new VerticalOrHorizontalTabLayoutPanel() {
|
||||
@Override
|
||||
|
||||
@@ -375,6 +375,8 @@ public interface SecurityService extends ReplicableWithObjectInputStream<Replica
|
||||
|
||||
void checkCurrentUserDeletePermission(WithQualifiedObjectIdentifier object);
|
||||
|
||||
void checkCurrentUserDeletePermission(QualifiedObjectIdentifier object);
|
||||
|
||||
void checkCurrentUserExplicitPermissions(WithQualifiedObjectIdentifier object, HasPermissions.Action... actions);
|
||||
|
||||
/**
|
||||
@@ -421,4 +423,6 @@ public interface SecurityService extends ReplicableWithObjectInputStream<Replica
|
||||
*/
|
||||
<T> T checkPermissionAndDeleteOwnershipForObjectRemoval(QualifiedObjectIdentifier identifier,
|
||||
ActionWithResult<T> actionToDeleteObject);
|
||||
|
||||
<T> T doWithTemporaryDefaultTenant(UserGroup tenant, ActionWithResult<T> action);
|
||||
}
|
||||
@@ -165,6 +165,8 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
|
||||
|
||||
private ThreadLocal<Boolean> currentlyFillingFromInitialLoadOrApplyingOperationReceivedFromMaster = ThreadLocal.withInitial(() -> false);
|
||||
|
||||
private ThreadLocal<UserGroup> temporaryDefaultTenant = new InheritableThreadLocal<>();
|
||||
|
||||
// private TimerTask migrationCompleteCheckTask;
|
||||
|
||||
private static Ini shiroConfiguration;
|
||||
@@ -359,10 +361,13 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
|
||||
}
|
||||
|
||||
public UserGroup getDefaultTenantForUser(User user) {
|
||||
UserGroup specificTenant = user.getDefaultTenant(ServerInfo.getName());
|
||||
UserGroup specificTenant = temporaryDefaultTenant.get();
|
||||
if (specificTenant == null) {
|
||||
String defaultTenantName = getDefaultTenantNameForUsername(user.getName());
|
||||
specificTenant = getUserGroupByName(defaultTenantName);
|
||||
specificTenant = user.getDefaultTenant(ServerInfo.getName());
|
||||
if (specificTenant == null) {
|
||||
String defaultTenantName = getDefaultTenantNameForUsername(user.getName());
|
||||
specificTenant = getUserGroupByName(defaultTenantName);
|
||||
}
|
||||
}
|
||||
return specificTenant;
|
||||
}
|
||||
@@ -1890,6 +1895,11 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
|
||||
SecurityUtils.getSubject().checkPermission(object.getType().getStringPermissionForObject(DefaultActions.DELETE, object));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkCurrentUserDeletePermission(QualifiedObjectIdentifier identifier) {
|
||||
SecurityUtils.getSubject().checkPermission(identifier.getStringPermission(DefaultActions.DELETE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkCurrentUserExplicitPermissions(WithQualifiedObjectIdentifier object, HasPermissions.Action... actions) {
|
||||
if (object == null || actions.length == 0) {
|
||||
@@ -1947,4 +1957,19 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
|
||||
new Role(existingRole.getRoleDefinition(), destination, existingRole.getQualifiedForUser()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T doWithTemporaryDefaultTenant(UserGroup tenant, ActionWithResult<T> action) {
|
||||
final UserGroup previousValue = temporaryDefaultTenant.get();
|
||||
temporaryDefaultTenant.set(tenant);
|
||||
try {
|
||||
return action.run();
|
||||
} catch (RuntimeException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
temporaryDefaultTenant.set(previousValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user