From 77f5936591c38f3ce820e9106307dcff9a7387f6 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Fri, 6 Mar 2020 23:49:29 +0100 Subject: [PATCH 1/6] for UserDTO and CompetitorDTO clear non-public fields if user has no READ but only READ_PUBLIC permission --- .../domain/common/dto/CompetitorDTO.java | 6 +++++ .../domain/common/dto/CompetitorDTOImpl.java | 5 ++++ .../common/dto/PreviousCompetitorDTOImpl.java | 6 +++++ .../gwt/ui/server/SailingServiceImpl.java | 12 +++++++++ .../sap/sse/security/shared/dto/UserDTO.java | 7 +++++ .../ui/server/UserManagementServiceImpl.java | 26 +++++++------------ 6 files changed, 46 insertions(+), 16 deletions(-) diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorDTO.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorDTO.java index 8b4fa9bf666..fddecb9bb8e 100644 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorDTO.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorDTO.java @@ -73,4 +73,10 @@ public interface CompetitorDTO extends Named, WithID, SecuredDTO, Serializable, * from the previous version of the enclosing leaderboard. */ CompetitorDTO getCompetitorFromPrevious(LeaderboardDTO previousVersion); + + /** + * Erases the fields a user is not supposed to read with only the READ_PUBLIC and not the + * READ permission. + */ + void clearNonPublicFields(); } diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorDTOImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorDTOImpl.java index b7a471a30d8..077bca525c0 100755 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorDTOImpl.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorDTOImpl.java @@ -260,4 +260,9 @@ public class CompetitorDTOImpl extends NamedSecuredObjectDTO implements Competit return new TypeRelativeObjectIdentifier(idAsString); } + @Override + public void clearNonPublicFields() { + email = null; + } + } diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/PreviousCompetitorDTOImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/PreviousCompetitorDTOImpl.java index 8a0a384fe26..c6a77cdd72c 100755 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/PreviousCompetitorDTOImpl.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/PreviousCompetitorDTOImpl.java @@ -150,6 +150,12 @@ public class PreviousCompetitorDTOImpl extends NamedSecuredObjectDTO implements " need to be replaced by an object of "+CompetitorWithBoatDTOImpl.class.getName()+" after deserialization"); } + @Override + public void clearNonPublicFields() { + throw new RuntimeException("Internal error. Objects of type "+PreviousCompetitorDTOImpl.class.getName()+ + " need to be replaced by an object of "+CompetitorWithBoatDTOImpl.class.getName()+" after deserialization"); + } + @Override public Double getTimeOnTimeFactor() { throw new RuntimeException("Internal error. Objects of type "+PreviousCompetitorDTOImpl.class.getName()+ diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index 0a12dcd238a..696736466a5 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -1363,12 +1363,22 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet private CompetitorDTO convertToCompetitorDTO(Competitor competitor) { CompetitorDTO competitorDTO = baseDomainFactory.convertToCompetitorDTO(competitor); SecurityDTOUtil.addSecurityInformation(getSecurityService(), competitorDTO, competitor.getIdentifier()); + clearNonPublicFieldsIfCurrentUserHasNoReadPermission(competitor, competitorDTO); return competitorDTO; } + + private void clearNonPublicFieldsIfCurrentUserHasNoReadPermission(Competitor competitor, + CompetitorDTO competitorDTO) { + if (!getSecurityService().hasCurrentUserReadPermission(competitor)) { + // probably only READ_PUBLIC; remove e-mail address from DTO: + competitorDTO.clearNonPublicFields(); + } + } private CompetitorWithBoatDTO convertToCompetitorWithBoatDTO(CompetitorWithBoat competitor) { CompetitorWithBoatDTO competitorDTO = baseDomainFactory.convertToCompetitorWithBoatDTO(competitor); SecurityDTOUtil.addSecurityInformation(getSecurityService(), competitorDTO, competitor.getIdentifier()); + clearNonPublicFieldsIfCurrentUserHasNoReadPermission(competitor, competitorDTO); BoatDTO boatDTO = competitorDTO.getBoat(); SecurityDTOUtil.addSecurityInformation(getSecurityService(), boatDTO, competitor.getBoat().getIdentifier()); return competitorDTO; @@ -1383,6 +1393,7 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet for (final Entry c : competitorsAndTheirBoats.entrySet()) { CompetitorAndBoatDTO competitorAndBoatDTO = baseDomainFactory.convertToCompetitorAndBoatDTO(c.getKey(), c.getValue()); SecurityDTOUtil.addSecurityInformation(getSecurityService(), competitorAndBoatDTO.getCompetitor(), c.getKey().getIdentifier()); + clearNonPublicFieldsIfCurrentUserHasNoReadPermission(c.getKey(), competitorAndBoatDTO.getCompetitor()); SecurityDTOUtil.addSecurityInformation(getSecurityService(), competitorAndBoatDTO.getBoat(), c.getValue().getIdentifier()); result.add(competitorAndBoatDTO); } @@ -1398,6 +1409,7 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet for (CompetitorWithBoat c : iterable) { CompetitorWithBoatDTO competitorDTO = baseDomainFactory.convertToCompetitorWithBoatDTO(c); SecurityDTOUtil.addSecurityInformation(getSecurityService(), competitorDTO, c.getIdentifier()); + clearNonPublicFieldsIfCurrentUserHasNoReadPermission(c, competitorDTO); SecurityDTOUtil.addSecurityInformation(getSecurityService(), competitorDTO.getBoat(), c.getBoat().getIdentifier()); result.add(competitorDTO); } diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/UserDTO.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/UserDTO.java index 27a4a27d3e5..a63883d2fda 100644 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/UserDTO.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/UserDTO.java @@ -155,4 +155,11 @@ public class UserDTO extends return new TypeRelativeObjectIdentifier(getName()); } + /** + * Erases the fields a user is not supposed to read with only the READ_PUBLIC and not the + * READ permission. + */ + public void clearNonPublicFields() { + this.email = null; + } } 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 77ed3b98abd..f5ecaf21fe8 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 @@ -36,6 +36,7 @@ import com.sap.sse.security.Action; import com.sap.sse.security.SecurityService; import com.sap.sse.security.interfaces.Credential; import com.sap.sse.security.shared.AccessControlListAnnotation; +import com.sap.sse.security.shared.HasPermissions; import com.sap.sse.security.shared.HasPermissions.DefaultActions; import com.sap.sse.security.shared.OwnershipAnnotation; import com.sap.sse.security.shared.QualifiedObjectIdentifier; @@ -204,13 +205,10 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U @Override public OwnershipDTO setOwnership(final String username, final UUID userGroupId, final QualifiedObjectIdentifier idOfOwnedObject, final String displayNameOfOwnedObject) { - SecurityUtils.getSubject() .checkPermission(idOfOwnedObject.getStringPermission(DefaultActions.CHANGE_OWNERSHIP)); - final User user = getSecurityService().getUserByName(username); // no security check if current user can see the user associated with the given username - final Ownership result = getSecurityService().setOwnership(idOfOwnedObject, user, getSecurityService().getUserGroup(userGroupId), displayNameOfOwnedObject); return securityDTOFactory.createOwnershipDTO(result, new HashMap<>(), new HashMap<>()); @@ -452,18 +450,10 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U @Override public Collection getUserList() throws UnauthorizedException { - List users = new ArrayList<>(); - for (User u : getSecurityService().getUserList()) { - if (SecurityUtils.getSubject() - .isPermitted(SecuredSecurityTypes.USER.getStringPermissionForObject(DefaultActions.READ, u)) - || SecurityUtils.getSubject().isPermitted(SecuredSecurityTypes.USER - .getStringPermissionForObject(SecuredSecurityTypes.PublicReadableActions.READ_PUBLIC, u))) { - // TODO: pruning if subject only has READ_PUBLIC permission - final UserDTO userDTO = getUserDTOWithFilteredRolesAndPermissions(u); - users.add(userDTO); - } - } - return users; + final HasPermissions.Action[] requiredActionsForRead = SecuredSecurityTypes.PublicReadableActions.READ_AND_READ_PUBLIC_ACTIONS; + return getSecurityService().mapAndFilterByAnyExplicitPermissionForCurrentUser(SecuredSecurityTypes.USER, + requiredActionsForRead, getSecurityService().getUserList(), + this::getUserDTOWithFilteredRolesAndPermissions); } @Override @@ -1110,7 +1100,7 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U * user can actually see. */ private UserDTO getUserDTOWithFilteredRolesAndPermissions(final User user) { - return securityDTOFactory.createUserDTOFromUser(user, getSecurityService(), permission -> { + final UserDTO result = securityDTOFactory.createUserDTOFromUser(user, getSecurityService(), permission -> { final TypeRelativeObjectIdentifier typeRelativeObjectIdentifier = PermissionAndRoleAssociation .get(permission, user); return SecurityUtils.getSubject().isPermitted(SecuredSecurityTypes.PERMISSION_ASSOCIATION @@ -1121,6 +1111,10 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U return SecurityUtils.getSubject().isPermitted(SecuredSecurityTypes.ROLE_ASSOCIATION .getStringPermissionForTypeRelativeIdentifier(DefaultActions.READ, typeRelativeObjectIdentifier)); }); + if (!getSecurityService().hasCurrentUserReadPermission(user)) { + result.clearNonPublicFields(); + } + return result; } @Override From 94137efb534572c68cb62063bf69905a7c0754ef Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Sat, 7 Mar 2020 19:18:53 +0100 Subject: [PATCH 2/6] allow for more log files to be kept before being overwritten by rotation --- java/target/configuration/logging.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/target/configuration/logging.properties b/java/target/configuration/logging.properties index c8044f9f153..4fa734e5918 100644 --- a/java/target/configuration/logging.properties +++ b/java/target/configuration/logging.properties @@ -8,7 +8,7 @@ handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler java.util.logging.FileHandler.level = ALL java.util.logging.FileHandler.pattern = logs/sailing%u.log java.util.logging.FileHandler.limit = 500000000 -java.util.logging.FileHandler.count = 10 +java.util.logging.FileHandler.count = 50 java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter # consoleHandler specific properties From d0960f95c465f8dd828df17d88b40faed469fb49 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Sun, 8 Mar 2020 00:17:07 +0100 Subject: [PATCH 3/6] log exceptions during start-up of automatic replication in activator --- .../sap/sse/replication/impl/Activator.java | 74 ++++++++++--------- 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/java/com.sap.sse.replication/src/com/sap/sse/replication/impl/Activator.java b/java/com.sap.sse.replication/src/com/sap/sse/replication/impl/Activator.java index 587587aab6c..47e448476ed 100644 --- a/java/com.sap.sse.replication/src/com/sap/sse/replication/impl/Activator.java +++ b/java/com.sap.sse.replication/src/com/sap/sse/replication/impl/Activator.java @@ -170,42 +170,46 @@ public class Activator implements BundleActivator { new Thread("ServiceTracker waiting for Replicables "+Arrays.toString(replicableIdsAsStrings)) { @Override public void run() { - logger.info("Waiting for Replicables " + Arrays.toString(replicableIdsAsStrings) + - " before firing up replication automatically..."); - final List> replicables = new ArrayList<>(); - for (String replicableIdAsString : replicableIdsAsStrings) { - Replicable replicable = replicablesProvider.getReplicable(replicableIdAsString, /* wait */true); - logger.info("Obtained Replicable " + replicableIdAsString); - replicables.add(replicable); - } - logger.info("Configuration requested automatic replication for replicables "+ - Arrays.toString(replicableIdsAsStrings)+". Starting it up..."); - String replicateFromExchangeName = System.getProperty(PROPERTY_NAME_REPLICATE_MASTER_EXCHANGE_NAME); - if (replicateFromExchangeName == null) { - replicateFromExchangeName = masterExchangeName; - } - final String servletHost = System.getProperty(PROPERTY_NAME_REPLICATE_MASTER_SERVLET_HOST); - final int servletPort = Integer.valueOf(System.getProperty(PROPERTY_NAME_REPLICATE_MASTER_SERVLET_PORT).trim()); - final String bearerToken; - if (System.getProperty(PROPERTY_NAME_REPLICATE_MASTER_BEARER_TOKEN) != null) { - bearerToken = System.getProperty(PROPERTY_NAME_REPLICATE_MASTER_BEARER_TOKEN).trim(); - } else { - bearerToken = RemoteServerUtil.resolveBearerTokenForRemoteServer(servletHost, servletPort, - System.getProperty(PROPERTY_NAME_REPLICATE_MASTER_USERNAME), - System.getProperty(PROPERTY_NAME_REPLICATE_MASTER_PASSWORD)); - } - ReplicationMasterDescriptorImpl master = new ReplicationMasterDescriptorImpl( - System.getProperty(PROPERTY_NAME_REPLICATE_MASTER_QUEUE_HOST), - replicateFromExchangeName, - Integer.valueOf(System.getProperty(PROPERTY_NAME_REPLICATE_MASTER_QUEUE_PORT).trim()), - serverReplicationMasterService.getServerIdentifier().toString(), - servletHost, servletPort, bearerToken, replicables); try { - serverReplicationMasterService.startToReplicateFrom(master); - serverReplicationMasterService.setReplicationStarting(false); - logger.info("Automatic replication has been started."); - } catch (ClassNotFoundException | IOException | InterruptedException e) { - logger.log(Level.SEVERE, "Error with automatic replication from "+master, e); + logger.info("Waiting for Replicables " + Arrays.toString(replicableIdsAsStrings) + + " before firing up replication automatically..."); + final List> replicables = new ArrayList<>(); + for (String replicableIdAsString : replicableIdsAsStrings) { + Replicable replicable = replicablesProvider.getReplicable(replicableIdAsString, /* wait */true); + logger.info("Obtained Replicable " + replicableIdAsString); + replicables.add(replicable); + } + logger.info("Configuration requested automatic replication for replicables "+ + Arrays.toString(replicableIdsAsStrings)+". Starting it up..."); + String replicateFromExchangeName = System.getProperty(PROPERTY_NAME_REPLICATE_MASTER_EXCHANGE_NAME); + if (replicateFromExchangeName == null) { + replicateFromExchangeName = masterExchangeName; + } + final String servletHost = System.getProperty(PROPERTY_NAME_REPLICATE_MASTER_SERVLET_HOST); + final int servletPort = Integer.valueOf(System.getProperty(PROPERTY_NAME_REPLICATE_MASTER_SERVLET_PORT).trim()); + final String bearerToken; + if (System.getProperty(PROPERTY_NAME_REPLICATE_MASTER_BEARER_TOKEN) != null) { + bearerToken = System.getProperty(PROPERTY_NAME_REPLICATE_MASTER_BEARER_TOKEN).trim(); + } else { + bearerToken = RemoteServerUtil.resolveBearerTokenForRemoteServer(servletHost, servletPort, + System.getProperty(PROPERTY_NAME_REPLICATE_MASTER_USERNAME), + System.getProperty(PROPERTY_NAME_REPLICATE_MASTER_PASSWORD)); + } + ReplicationMasterDescriptorImpl master = new ReplicationMasterDescriptorImpl( + System.getProperty(PROPERTY_NAME_REPLICATE_MASTER_QUEUE_HOST), + replicateFromExchangeName, + Integer.valueOf(System.getProperty(PROPERTY_NAME_REPLICATE_MASTER_QUEUE_PORT).trim()), + serverReplicationMasterService.getServerIdentifier().toString(), + servletHost, servletPort, bearerToken, replicables); + try { + serverReplicationMasterService.startToReplicateFrom(master); + serverReplicationMasterService.setReplicationStarting(false); + logger.info("Automatic replication has been started."); + } catch (ClassNotFoundException | IOException | InterruptedException e) { + logger.log(Level.SEVERE, "Error with automatic replication from "+master, e); + } + } catch (Exception e) { + logger.log(Level.SEVERE, "Error starting automatic replication", e); } } }.start(); From 79ac0dbf5c17c9e10bbec00bdab262f7f43bfd22 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Sun, 8 Mar 2020 13:22:38 +0100 Subject: [PATCH 4/6] fixed typo in security REST API doc --- java/com.sap.sse.security/webservices/api/ownership.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/com.sap.sse.security/webservices/api/ownership.html b/java/com.sap.sse.security/webservices/api/ownership.html index c9be17e146b..98b86d03a87 100644 --- a/java/com.sap.sse.security/webservices/api/ownership.html +++ b/java/com.sap.sse.security/webservices/api/ownership.html @@ -9,7 +9,7 @@

SAP Sponsorships Engine Security Webservices API

-

URL: /api/restsecurity/onwership

+

URL: /api/restsecurity/ownership

Description:

The service obtains or changes the ownership of object, or obtains or changes access control list (ACL) properties of an object.

From c4687e456cbdc45dac9a5ddf6312a3b705a16c03 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Sun, 8 Mar 2020 14:01:17 +0100 Subject: [PATCH 5/6] enhanced ownerships REST API to allow for composite type-relative object IDs --- .../security/jaxrs/api/OwnershipResource.java | 18 ++++++++++++-- .../webservices/api/ownership.html | 24 +++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/jaxrs/api/OwnershipResource.java b/java/com.sap.sse.security/src/com/sap/sse/security/jaxrs/api/OwnershipResource.java index fbe346f7840..68e99b80601 100644 --- a/java/com.sap.sse.security/src/com/sap/sse/security/jaxrs/api/OwnershipResource.java +++ b/java/com.sap.sse.security/src/com/sap/sse/security/jaxrs/api/OwnershipResource.java @@ -2,6 +2,7 @@ package com.sap.sse.security.jaxrs.api; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; @@ -13,6 +14,7 @@ import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; @@ -101,12 +103,24 @@ public class OwnershipResource extends AbstractSecurityResource { @Produces("application/json;charset=UTF-8") public Response getOwnership(@PathParam("objectType") String objectType, @PathParam("typeRelativeObjectId") String typeRelativeObjectId) throws OwnershipException { + return getOwnership(objectType, new String[] { typeRelativeObjectId }); + } + + @Path("{objectType}") + @GET + @Produces("application/json;charset=UTF-8") + public Response getOwnershipWithMultiId(@PathParam("objectType") String objectType, + @QueryParam("id") List compositeTypeRelativeObjectId) throws OwnershipException { + return getOwnership(objectType, compositeTypeRelativeObjectId.toArray(new String[0])); + } + + private Response getOwnership(String objectType, final String[] typeRelativeObjectIdArray) { QualifiedObjectIdentifier identifier = new QualifiedObjectIdentifierImpl(objectType, - new TypeRelativeObjectIdentifier(typeRelativeObjectId)); + new TypeRelativeObjectIdentifier(typeRelativeObjectIdArray)); final OwnershipAnnotation existingOwnership = getService().getOwnership(identifier); final JSONObject result = new JSONObject(); result.put(KEY_OBJECT_TYPE, objectType); - result.put(KEY_OBJECT_ID, typeRelativeObjectId); + result.put(KEY_OBJECT_ID, identifier.getTypeRelativeObjectIdentifier()); result.put(KEY_GROUP_ID, existingOwnership == null || existingOwnership.getAnnotation().getTenantOwner() == null ? null : existingOwnership.getAnnotation().getTenantOwner().getId().toString()); result.put(KEY_USERNAME, existingOwnership == null || existingOwnership.getAnnotation().getUserOwner() == null ? null : existingOwnership.getAnnotation().getUserOwner().getName()); result.put(KEY_DISPLAY_NAME, existingOwnership == null || existingOwnership.getDisplayNameOfAnnotatedObject() == null ? null : existingOwnership.getDisplayNameOfAnnotatedObject()); diff --git a/java/com.sap.sse.security/webservices/api/ownership.html b/java/com.sap.sse.security/webservices/api/ownership.html index 98b86d03a87..32677c44e62 100644 --- a/java/com.sap.sse.security/webservices/api/ownership.html +++ b/java/com.sap.sse.security/webservices/api/ownership.html @@ -70,6 +70,30 @@ Will provide a JSON document as explained above. + + Request Method: + GET /{objectType}?id={typeRelativeObjectIdPart1}&id={typeRelativeObjectIdPart2}&... + + + Output format: + a JSON document of the following format
+
{"objectType":"USER_GROUP","objectId":"82832851-07ac-47ee-9ddf-6f4f9eaa7823","groupId":"82832851-07ac-47ee-9ddf-6f4f9eaa7823","username":"admin"}
+ + + + Parameter (path) + +
objectType
Object type represents the type of object to change the ownership. +
id
Can be used multiple times, e.g., in order to encode a composite type-relative object ID such as they + are used for objects of type TRACKED_RACE. + + + + Example: + curl "http://127.0.0.1:8888/security/api/restsecurity/ownership/TRACKED_RACE?id=Croatia%20Coast%20Cup%202019%20-%20ORC%20with%20Spinnaker&id=Race%201%20-%20ORC%20mit%20Spi"
+ Will provide a JSON document as explained above. + + Request Method: GET /{objectType}/{typeRelativeObjectId}/acl From ac5ae389115e3a405362f58f10d530ba3caf5f34 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Mon, 9 Mar 2020 00:45:11 +0100 Subject: [PATCH 6/6] avoid ORC / ToT/ToD detail types where possible --- .../sap/sailing/domain/common/DetailType.java | 8 +++---- .../EventSeriesLeaderboardsTabView.java | 23 ++----------------- .../gwt/ui/server/SailingServiceImpl.java | 23 +++++++++++-------- 3 files changed, 20 insertions(+), 34 deletions(-) diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/DetailType.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/DetailType.java index c8eba0b2e79..835bfc675f3 100755 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/DetailType.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/DetailType.java @@ -263,7 +263,6 @@ public enum DetailType implements Serializable { availableDetailsTypes.add(DetailType.LEG_GAP_TO_LEADER_IN_SECONDS); availableDetailsTypes.add(DetailType.RACE_CURRENT_SPEED_OVER_GROUND_IN_KNOTS); availableDetailsTypes.add(DetailType.RACE_RANK); - availableDetailsTypes.add(DetailType.RACE_IMPLIED_WIND); availableDetailsTypes.add(DetailType.REGATTA_RANK); availableDetailsTypes.add(DetailType.CHART_DISTANCE_TO_START_LINE); availableDetailsTypes.add(DetailType.CHART_BEAT_ANGLE); @@ -390,9 +389,8 @@ public enum DetailType implements Serializable { } /** - * Returns all types in the enum, minus those for expedition, bravo and bravo extended - * - * @return + * Returns all types in the enum, minus those for expedition, bravo, bravo extended + * and the ToT/ToD/ORC PCS ones */ public static Collection getAllNonRestrictedDetailTypes() { final Collection all = new LinkedHashSet<>(Arrays.asList(values())); @@ -402,6 +400,8 @@ public enum DetailType implements Serializable { all.removeAll(getRaceExpeditionDetailTypes()); all.removeAll(getLegExpeditionDetailColumnTypes()); all.removeAll(getOverallBravoDetailTypes()); + all.removeAll(getAllToTToDHandicapDetailTypes()); + all.removeAll(getAllOrcPerformanceCurveDetailTypes()); return all; } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/fakeseries/leaderboardstab/EventSeriesLeaderboardsTabView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/fakeseries/leaderboardstab/EventSeriesLeaderboardsTabView.java index 40d6bd3739a..597b44b38c3 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/fakeseries/leaderboardstab/EventSeriesLeaderboardsTabView.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/fakeseries/leaderboardstab/EventSeriesLeaderboardsTabView.java @@ -72,20 +72,15 @@ public class EventSeriesLeaderboardsTabView extends Composite implements SeriesT public void start(final EventSeriesLeaderboardsPlace myPlace, final AcceptsOneWidget contentArea) { contentArea.setWidget(currentPresenter.getErrorAndBusyClientFactory().createBusyView()); String leaderboardName = currentPresenter.getSeriesDTO().getLeaderboardId(); - if (leaderboardName != null && !leaderboardName.isEmpty()) { final EventSeriesAnalyticsDataManager regattaAnalyticsManager = currentPresenter.getCtx() .getAnalyticsManager(); - regattaAnalyticsManager.getAvailableDetailTypesForLeaderboard(leaderboardName, null, new AsyncCallback>() { - @Override public void onSuccess(Iterable result) { - final boolean autoExpandLastRaceColumn = GwtHttpRequestUtils.getBooleanParameter( LeaderboardUrlSettings.PARAM_AUTO_EXPAND_LAST_RACE_COLUMN, false); - final ComponentContext componentContext = createLeaderboardComponentContext( leaderboardName, currentPresenter.getUserService(), /* FIXME placeToken */ null, result); componentContext.getInitialSettings( @@ -93,32 +88,19 @@ public class EventSeriesLeaderboardsTabView extends Composite implements SeriesT @Override public void onSuccess(MultiRaceLeaderboardSettings settings) { MultiLeaderboardProxyPanel leaderboardPanel = regattaAnalyticsManager - .createMultiLeaderboardPanel(null, componentContext, settings, null, // TODO: - // preselectedLeaderboardName - "leaderboardGroupName", leaderboardName, true, // TODO @FM - // this - // information - // came from - // place, now - // hard - // coded. - // check with - // frank + .createMultiLeaderboardPanel(null, componentContext, settings, null, // TODO: preselectedLeaderboardName + "leaderboardGroupName", leaderboardName, true, // TODO @FM this information came from place, now hard coded. check with frank autoExpandLastRaceColumn, result); leaderboardPanel.addAttachHandler(new Handler() { - @Override public void onAttachOrDetach(AttachEvent event) { if (!event.isAttached()) { componentContext.dispose(); } } - }); - initWidget( ourUiBinder.createAndBindUi(EventSeriesLeaderboardsTabView.this)); - leaderboard.setMultiLeaderboard(leaderboardPanel, currentPresenter.getAutoRefreshTimer()); leaderboardPanel @@ -133,7 +115,6 @@ public class EventSeriesLeaderboardsTabView extends Composite implements SeriesT regattaAnalyticsManager.hideCompetitorChart(); leaderboardPanel.setVisible(true); contentArea.setWidget(EventSeriesLeaderboardsTabView.this); - } }); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index 696736466a5..b42fb1d1836 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -8340,9 +8340,9 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet @Override public Iterable determineDetailTypesForCompetitorChart(String leaderboardGroupName, RegattaAndRaceIdentifier identifier) { - final LinkedHashSet availableDetailsTypes = new LinkedHashSet<>(); - availableDetailsTypes.addAll(DetailType.getAutoplayDetailTypesForChart()); - availableDetailsTypes.removeAll(DetailType.getRaceBravoDetailTypes()); + final LinkedHashSet availableDetailTypes = new LinkedHashSet<>(); + availableDetailTypes.addAll(DetailType.getAutoplayDetailTypesForChart()); + availableDetailTypes.removeAll(DetailType.getRaceBravoDetailTypes()); final DynamicTrackedRace trackedRace = getService().getTrackedRace(identifier); if (trackedRace != null) { boolean hasBravoTrack = false; @@ -8355,31 +8355,36 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet } } if (hasBravoTrack) { - availableDetailsTypes.addAll(DetailType.getRaceBravoDetailTypes()); + availableDetailTypes.addAll(DetailType.getRaceBravoDetailTypes()); } if (hasExtendedBravoFixes) { - availableDetailsTypes.addAll(DetailType.getRaceExtendedBravoDetailTypes()); - availableDetailsTypes.addAll(DetailType.getRaceExpeditionDetailTypes()); + availableDetailTypes.addAll(DetailType.getRaceExtendedBravoDetailTypes()); + availableDetailTypes.addAll(DetailType.getRaceExpeditionDetailTypes()); } final RankingMetrics rankingMetricType = trackedRace.getRankingMetric().getType(); switch (rankingMetricType) { case ONE_DESIGN: + availableDetailTypes.removeAll(DetailType.getAllToTToDHandicapDetailTypes()); + availableDetailTypes.removeAll(DetailType.getAllOrcPerformanceCurveDetailTypes()); + break; case TIME_ON_TIME_AND_DISTANCE: + availableDetailTypes.addAll(DetailType.getAllToTToDHandicapDetailTypes()); + availableDetailTypes.removeAll(DetailType.getAllOrcPerformanceCurveDetailTypes()); break; case ORC_PERFORMANCE_CURVE: case ORC_PERFORMANCE_CURVE_BY_IMPLIED_WIND: case ORC_PERFORMANCE_CURVE_LEADER_FOR_BASELINE: - availableDetailsTypes.addAll(DetailType.getAllOrcPerformanceCurveDetailTypes()); + availableDetailTypes.addAll(DetailType.getAllOrcPerformanceCurveDetailTypes()); break; } } if (leaderboardGroupName != null) { final LeaderboardGroupDTO group = getLeaderboardGroupByName(leaderboardGroupName, false); if (group != null ? group.hasOverallLeaderboard() : false) { - availableDetailsTypes.add(DetailType.OVERALL_RANK); + availableDetailTypes.add(DetailType.OVERALL_RANK); } } - return availableDetailsTypes; + return availableDetailTypes; } @Override