mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-20 04:35:32 +00:00
bug5569: synchronizing the initialization of a server as "public" with the ReplicationService and skip if becoming a replica
This commit is contained in:
+2
-2
@@ -17,7 +17,7 @@ import com.google.gwt.user.client.ui.SimplePanel;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.gwt.ui.adminconsole.places.AdminConsoleView.Presenter;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceWriteAsync;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.shared.ServerConfigurationDTO;
|
||||
import com.sap.sse.gwt.client.ErrorReporter;
|
||||
@@ -36,7 +36,7 @@ import com.sap.sse.security.ui.client.component.EditOwnershipDialog;
|
||||
import com.sap.sse.security.ui.client.component.editacl.EditACLDialog;
|
||||
|
||||
public class LocalServerManagementPanel extends SimplePanel {
|
||||
private final SailingServiceAsync sailingService;
|
||||
private final SailingServiceWriteAsync sailingService;
|
||||
private final ErrorReporter errorReporter;
|
||||
private final StringMessages stringMessages;
|
||||
|
||||
|
||||
-2
@@ -240,8 +240,6 @@ public interface SailingService extends RemoteService, RemoteReplicationService
|
||||
|
||||
ServerConfigurationDTO getServerConfiguration() throws UnauthorizedException;
|
||||
|
||||
void updateServerConfiguration(ServerConfigurationDTO serverConfiguration) throws UnauthorizedException;
|
||||
|
||||
List<RemoteSailingServerReferenceDTO> getRemoteSailingServerReferences() throws UnauthorizedException;
|
||||
|
||||
List<UrlDTO> getResultImportUrls(String resultProviderName) throws UnauthorizedException;
|
||||
|
||||
-2
@@ -263,8 +263,6 @@ public interface SailingServiceAsync extends RemoteReplicationServiceAsync {
|
||||
|
||||
void getServerConfiguration(AsyncCallback<ServerConfigurationDTO> callback);
|
||||
|
||||
void updateServerConfiguration(ServerConfigurationDTO serverConfiguration, AsyncCallback<Void> callback);
|
||||
|
||||
void getRemoteSailingServerReferences(AsyncCallback<List<RemoteSailingServerReferenceDTO>> callback);
|
||||
|
||||
void getResultImportUrls(String resultProviderName, AsyncCallback<List<UrlDTO>> callback);
|
||||
|
||||
+2
@@ -72,6 +72,7 @@ import com.sap.sailing.gwt.ui.shared.RaceLogSetFinishingAndFinishTimeDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceLogSetStartTimeAndProcedureDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RemoteSailingServerReferenceDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.ServerConfigurationDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTOWithSecurity;
|
||||
import com.sap.sailing.gwt.ui.shared.SwissTimingArchiveConfigurationWithSecurityDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.SwissTimingConfigurationWithSecurityDTO;
|
||||
@@ -694,4 +695,5 @@ public interface SailingServiceWrite extends FileStorageManagementGwtService, Sa
|
||||
List<DeviceMappingDTO> getDeviceMappings(String leaderboardName)
|
||||
throws UnauthorizedException, DoesNotHaveRegattaLogException, TransformationException, NotFoundException;
|
||||
|
||||
void updateServerConfiguration(ServerConfigurationDTO serverConfiguration) throws UnauthorizedException;
|
||||
}
|
||||
|
||||
+3
@@ -57,6 +57,7 @@ import com.sap.sailing.gwt.ui.shared.RaceLogSetFinishingAndFinishTimeDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceLogSetStartTimeAndProcedureDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RemoteSailingServerReferenceDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.ServerConfigurationDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTOWithSecurity;
|
||||
import com.sap.sailing.gwt.ui.shared.SwissTimingArchiveConfigurationWithSecurityDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.SwissTimingConfigurationWithSecurityDTO;
|
||||
@@ -619,4 +620,6 @@ public interface SailingServiceWriteAsync extends FileStorageManagementGwtServic
|
||||
AsyncCallback<MarkTrackDTO> callback);
|
||||
|
||||
void getDeviceMappings(String leaderboardName, AsyncCallback<List<DeviceMappingDTO>> asyncCallback);
|
||||
|
||||
void updateServerConfiguration(ServerConfigurationDTO serverConfiguration, AsyncCallback<Void> callback);
|
||||
}
|
||||
|
||||
+1
-51
@@ -70,7 +70,6 @@ import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authz.AuthorizationException;
|
||||
import org.apache.shiro.authz.UnauthorizedException;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.json.simple.JSONArray;
|
||||
@@ -152,7 +151,6 @@ import com.sap.sailing.domain.base.configuration.impl.RegattaConfigurationImpl;
|
||||
import com.sap.sailing.domain.base.configuration.impl.SWCStartConfigurationImpl;
|
||||
import com.sap.sailing.domain.base.configuration.procedures.ConfigurableStartModeFlagRacingProcedureConfiguration;
|
||||
import com.sap.sailing.domain.base.impl.CourseDataImpl;
|
||||
import com.sap.sailing.domain.base.impl.SailingServerConfigurationImpl;
|
||||
import com.sap.sailing.domain.common.CompetitorDescriptor;
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.domain.common.DeviceIdentifier;
|
||||
@@ -413,7 +411,6 @@ import com.sap.sailing.server.gateway.deserialization.racelog.impl.ORCCertificat
|
||||
import com.sap.sailing.server.gateway.serialization.LeaderboardGroupConstants;
|
||||
import com.sap.sailing.server.interfaces.RacingEventService;
|
||||
import com.sap.sailing.server.interfaces.SimulationService;
|
||||
import com.sap.sailing.server.operationaltransformation.UpdateServerConfiguration;
|
||||
import com.sap.sailing.server.security.SailingViewerRole;
|
||||
import com.sap.sailing.shared.server.SharedSailingData;
|
||||
import com.sap.sailing.simulator.Path;
|
||||
@@ -478,7 +475,6 @@ import com.sap.sse.security.shared.RoleDefinition;
|
||||
import com.sap.sse.security.shared.TypeRelativeObjectIdentifier;
|
||||
import com.sap.sse.security.shared.dto.StrippedUserGroupDTO;
|
||||
import com.sap.sse.security.shared.impl.AccessControlList;
|
||||
import com.sap.sse.security.shared.impl.Ownership;
|
||||
import com.sap.sse.security.shared.impl.SecuredSecurityTypes;
|
||||
import com.sap.sse.security.shared.impl.SecuredSecurityTypes.ServerActions;
|
||||
import com.sap.sse.security.shared.impl.UserGroup;
|
||||
@@ -3979,52 +3975,6 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
// FIXME See bug 5569: this shall move to SailingServiceWriteImpl
|
||||
public void updateServerConfiguration(ServerConfigurationDTO serverConfiguration) {
|
||||
getSecurityService().checkCurrentUserServerPermission(ServerActions.CONFIGURE_LOCAL_SERVER);
|
||||
getService().apply(new UpdateServerConfiguration(
|
||||
new SailingServerConfigurationImpl(serverConfiguration.isStandaloneServer())));
|
||||
if (serverConfiguration.isSelfService() != null) {
|
||||
final boolean isCurrentlySelfService = isSelfServiceServer();
|
||||
final boolean shouldBeSelfService = serverConfiguration.isSelfService();
|
||||
if (isCurrentlySelfService != shouldBeSelfService) {
|
||||
SecurityUtils.getSubject().checkPermission(getServerInfo().getIdentifier().getStringPermission(DefaultActions.CHANGE_ACL));
|
||||
if (shouldBeSelfService) {
|
||||
getSecurityService().addToAccessControlList(getServerInfo().getIdentifier(), null, ServerActions.CREATE_OBJECT.name());
|
||||
} else {
|
||||
getSecurityService().removeFromAccessControlList(getServerInfo().getIdentifier(), null, ServerActions.CREATE_OBJECT.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (serverConfiguration.isPublic() != null) {
|
||||
final RoleDefinition viewerRole = getSecurityService()
|
||||
.getRoleDefinition(SailingViewerRole.getInstance().getId());
|
||||
final UserGroup serverGroup = getSecurityService().getServerGroup();
|
||||
if (viewerRole != null && serverGroup != null) {
|
||||
final boolean isCurrentlyPublic = Boolean.TRUE.equals(serverGroup.getRoleAssociation(viewerRole));
|
||||
final boolean shouldBePublic = serverConfiguration.isPublic();
|
||||
if (isCurrentlyPublic != shouldBePublic) {
|
||||
// value changed
|
||||
if (getSecurityService().hasCurrentUserUpdatePermission(serverGroup)
|
||||
&& getSecurityService().hasCurrentUserMetaPermissionsOfRoleDefinitionWithQualification(
|
||||
viewerRole, new Ownership(null, serverGroup))) {
|
||||
if (serverConfiguration.isPublic()) {
|
||||
getSecurityService().putRoleDefinitionToUserGroup(serverGroup, viewerRole, /* forAll */ true);
|
||||
} else {
|
||||
getSecurityService().removeRoleDefintionFromUserGroup(serverGroup, viewerRole);
|
||||
}
|
||||
} else {
|
||||
throw new AuthorizationException("No permission to make the server public");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
SailingViewerRole.getInstance().getName() + " role or default server tenant does not exist");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
//??
|
||||
public List<RemoteSailingServerReferenceDTO> getRemoteSailingServerReferences() {
|
||||
@@ -5829,7 +5779,7 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
|
||||
return result;
|
||||
}
|
||||
|
||||
private Boolean isSelfServiceServer() {
|
||||
protected Boolean isSelfServiceServer() {
|
||||
final AccessControlListAnnotation serverAclOrNull = getSecurityService().getAccessControlList(getServerInfo().getIdentifier());
|
||||
final Boolean result;
|
||||
if (serverAclOrNull == null) {
|
||||
|
||||
+52
@@ -153,6 +153,7 @@ import com.sap.sailing.domain.base.impl.DynamicPerson;
|
||||
import com.sap.sailing.domain.base.impl.DynamicTeam;
|
||||
import com.sap.sailing.domain.base.impl.EventBaseImpl;
|
||||
import com.sap.sailing.domain.base.impl.PersonImpl;
|
||||
import com.sap.sailing.domain.base.impl.SailingServerConfigurationImpl;
|
||||
import com.sap.sailing.domain.base.impl.TeamImpl;
|
||||
import com.sap.sailing.domain.common.CompetitorDescriptor;
|
||||
import com.sap.sailing.domain.common.CompetitorRegistrationType;
|
||||
@@ -274,6 +275,7 @@ import com.sap.sailing.gwt.ui.shared.RaceLogSetStartTimeAndProcedureDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RemoteSailingServerReferenceDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.SeriesDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.ServerConfigurationDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTOWithSecurity;
|
||||
import com.sap.sailing.gwt.ui.shared.SwissTimingArchiveConfigurationWithSecurityDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.SwissTimingConfigurationWithSecurityDTO;
|
||||
@@ -342,7 +344,9 @@ import com.sap.sailing.server.operationaltransformation.UpdateLeaderboardScoreCo
|
||||
import com.sap.sailing.server.operationaltransformation.UpdateRaceDelayToLive;
|
||||
import com.sap.sailing.server.operationaltransformation.UpdateSailingServerReference;
|
||||
import com.sap.sailing.server.operationaltransformation.UpdateSeries;
|
||||
import com.sap.sailing.server.operationaltransformation.UpdateServerConfiguration;
|
||||
import com.sap.sailing.server.operationaltransformation.UpdateSpecificRegatta;
|
||||
import com.sap.sailing.server.security.SailingViewerRole;
|
||||
import com.sap.sailing.server.util.WaitForTrackedRaceUtil;
|
||||
import com.sap.sailing.xrr.schema.RegattaResults;
|
||||
import com.sap.sse.common.Duration;
|
||||
@@ -374,7 +378,10 @@ import com.sap.sse.gwt.shared.filestorage.FileStorageServicePropertyErrorsDTO;
|
||||
import com.sap.sse.security.Action;
|
||||
import com.sap.sse.security.shared.HasPermissions.DefaultActions;
|
||||
import com.sap.sse.security.shared.QualifiedObjectIdentifier;
|
||||
import com.sap.sse.security.shared.RoleDefinition;
|
||||
import com.sap.sse.security.shared.TypeRelativeObjectIdentifier;
|
||||
import com.sap.sse.security.shared.impl.Ownership;
|
||||
import com.sap.sse.security.shared.impl.UserGroup;
|
||||
import com.sap.sse.security.shared.impl.SecuredSecurityTypes.ServerActions;
|
||||
import com.sap.sse.security.ui.server.SecurityDTOUtil;
|
||||
import com.sap.sse.security.ui.shared.SuccessInfo;
|
||||
@@ -3778,4 +3785,49 @@ public class SailingServiceWriteImpl extends SailingServiceImpl implements Saili
|
||||
RegattaLog regattaLog = getRegattaLogInternal(leaderboardName);
|
||||
return getDeviceMappings(regattaLog);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateServerConfiguration(ServerConfigurationDTO serverConfiguration) {
|
||||
getSecurityService().checkCurrentUserServerPermission(ServerActions.CONFIGURE_LOCAL_SERVER);
|
||||
getService().apply(new UpdateServerConfiguration(
|
||||
new SailingServerConfigurationImpl(serverConfiguration.isStandaloneServer())));
|
||||
if (serverConfiguration.isSelfService() != null) {
|
||||
final boolean isCurrentlySelfService = isSelfServiceServer();
|
||||
final boolean shouldBeSelfService = serverConfiguration.isSelfService();
|
||||
if (isCurrentlySelfService != shouldBeSelfService) {
|
||||
SecurityUtils.getSubject().checkPermission(getServerInfo().getIdentifier().getStringPermission(DefaultActions.CHANGE_ACL));
|
||||
if (shouldBeSelfService) {
|
||||
getSecurityService().addToAccessControlList(getServerInfo().getIdentifier(), null, ServerActions.CREATE_OBJECT.name());
|
||||
} else {
|
||||
getSecurityService().removeFromAccessControlList(getServerInfo().getIdentifier(), null, ServerActions.CREATE_OBJECT.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (serverConfiguration.isPublic() != null) {
|
||||
final RoleDefinition viewerRole = getSecurityService()
|
||||
.getRoleDefinition(SailingViewerRole.getInstance().getId());
|
||||
final UserGroup serverGroup = getSecurityService().getServerGroup();
|
||||
if (viewerRole != null && serverGroup != null) {
|
||||
final boolean isCurrentlyPublic = Boolean.TRUE.equals(serverGroup.getRoleAssociation(viewerRole));
|
||||
final boolean shouldBePublic = serverConfiguration.isPublic();
|
||||
if (isCurrentlyPublic != shouldBePublic) {
|
||||
// value changed
|
||||
if (getSecurityService().hasCurrentUserUpdatePermission(serverGroup)
|
||||
&& getSecurityService().hasCurrentUserMetaPermissionsOfRoleDefinitionWithQualification(
|
||||
viewerRole, new Ownership(null, serverGroup))) {
|
||||
if (serverConfiguration.isPublic()) {
|
||||
getSecurityService().putRoleDefinitionToUserGroup(serverGroup, viewerRole, /* forAll */ true);
|
||||
} else {
|
||||
getSecurityService().removeRoleDefintionFromUserGroup(serverGroup, viewerRole);
|
||||
}
|
||||
} else {
|
||||
throw new AuthorizationException("No permission to make the server public");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
SailingViewerRole.getInstance().getName() + " role or default server tenant does not exist");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,9 +71,9 @@ import com.sap.sse.security.SecurityService;
|
||||
import com.sap.sse.security.SecurityUrlPathProvider;
|
||||
import com.sap.sse.security.interfaces.PreferenceConverter;
|
||||
import com.sap.sse.security.shared.HasPermissions.DefaultActions;
|
||||
import com.sap.sse.security.util.GenericJSONPreferenceConverter;
|
||||
import com.sap.sse.security.shared.HasPermissionsProvider;
|
||||
import com.sap.sse.security.shared.RoleDefinition;
|
||||
import com.sap.sse.security.util.GenericJSONPreferenceConverter;
|
||||
import com.sap.sse.util.ClearStateTestSupport;
|
||||
import com.sap.sse.util.ServiceTrackerFactory;
|
||||
|
||||
@@ -229,19 +229,33 @@ public class Activator implements BundleActivator {
|
||||
registrations.add(context.registerService(HasPermissionsProvider.class, SecuredDomainType::getAllInstances, null));
|
||||
registrations.add(context.registerService(SecurityInitializationCustomizer.class,
|
||||
(SecurityInitializationCustomizer) securityService -> {
|
||||
final RoleDefinition sailingViewerRoleDefinition = securityService
|
||||
.getOrCreateRoleDefinitionFromPrototype(SailingViewerRole.getInstance());
|
||||
if (securityService.isNewServer()) {
|
||||
// The server is initially set to be public by adding sailing_viewer role to the server group
|
||||
// with forAll=true
|
||||
securityService.putRoleDefinitionToUserGroup(securityService.getServerGroup(),
|
||||
sailingViewerRoleDefinition, true);
|
||||
}
|
||||
if (securityService.isInitialOrMigration()) {
|
||||
// sailing_viewer role is publicly readable
|
||||
securityService.addToAccessControlList(sailingViewerRoleDefinition.getIdentifier(),
|
||||
null, DefaultActions.READ.name());
|
||||
}
|
||||
final Thread backgroundThread = new Thread(()->{
|
||||
ReplicationService replicationService;
|
||||
try {
|
||||
replicationService = ServiceTrackerFactory.createAndOpen(context, ReplicationService.class).waitForService(0);
|
||||
if (!replicationService.isReplicationStarting() && securityService.getMasterDescriptor() == null) {
|
||||
// see also bug 5569: this must only be done if it is clear that this instance is not to become a replica
|
||||
final RoleDefinition sailingViewerRoleDefinition = securityService
|
||||
.getOrCreateRoleDefinitionFromPrototype(SailingViewerRole.getInstance());
|
||||
if (securityService.isNewServer()) {
|
||||
// The server is initially set to be public by adding sailing_viewer role to the server group
|
||||
// with forAll=true
|
||||
securityService.putRoleDefinitionToUserGroup(securityService.getServerGroup(),
|
||||
sailingViewerRoleDefinition, true);
|
||||
}
|
||||
if (securityService.isInitialOrMigration()) {
|
||||
// sailing_viewer role is publicly readable
|
||||
securityService.addToAccessControlList(sailingViewerRoleDefinition.getIdentifier(),
|
||||
null, DefaultActions.READ.name());
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
logger.log(Level.SEVERE, "Couldn't get a hold of the ReplicationService to tell whether this SecurityService is to become a replica; "+
|
||||
"not setting server to public, not enforcing READability of sailing_viewer role", e);
|
||||
}
|
||||
}, "Waiting for replication service to tell whether this SecurityService will become a replica");
|
||||
backgroundThread.setDaemon(true);
|
||||
backgroundThread.start();
|
||||
}, null));
|
||||
final TrackedRaceStatisticsCache trackedRaceStatisticsCache = new TrackedRaceStatisticsCacheImpl();
|
||||
registrations.add(context.registerService(TrackedRaceStatisticsCache.class.getName(),
|
||||
|
||||
+4
-1
@@ -128,11 +128,14 @@ public interface ReplicationService {
|
||||
void removeReplicationStartingListener(ReplicationStartingListener listener);
|
||||
|
||||
/**
|
||||
* When this service has been registered in the OSGi service registry and auto-replication has been configured,
|
||||
* this method will return {@code true} already as soon as the service can be discovered in the registry.
|
||||
*
|
||||
* @return {@code true} if replication is starting; during this phase it is clear that the replicables managed by
|
||||
* this service instance are about to be {@link Replicable#clearReplicaState() cleared} and to be initialized
|
||||
* with an {@link Replicable#initiallyFillFrom(java.io.InputStream) initial load} obtained from the master
|
||||
* instance. However, this initial load process may not yet have started and hence the {@link #getReplicator} method
|
||||
*
|
||||
* may return nothing.
|
||||
*/
|
||||
boolean isReplicationStarting();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user