From 0e6118d14c9073a93b355b50662b2ba9eb01f43a Mon Sep 17 00:00:00 2001 From: Alessandro Stolten Date: Tue, 18 Dec 2018 12:23:04 +0000 Subject: [PATCH 1/9] Updated WaypointInferrer (markdown) --- wiki/planning/WaypointInferrer.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/wiki/planning/WaypointInferrer.md b/wiki/planning/WaypointInferrer.md index bd4028b45b7..44d16fd8e16 100644 --- a/wiki/planning/WaypointInferrer.md +++ b/wiki/planning/WaypointInferrer.md @@ -1,11 +1,12 @@ -This page is used to think through the features a Waypoint-inferring mechanism needs to have from a end-to-end perspective. +This page is used to think through the features a Waypoint-inferring mechanism needs to have from an end-to-end perspective. ### Scenario 1: Starting a race with no information about Marks and Waypoints. WaypointInferrer should detect possible Marks, decide for the PassingInstructions and then store the Waypoint persistent in the race: -* If we decide for a Mark position based on a threeshold number of competitors already passed should we take in consideration the upcoming competitors for the final Mark position and if we do so how can we achieve that? + * First approach is to work only with smartphone tracked races. A check box in Smartphone Tracking connector is needed. The checkbox should be integrated in the CourseLayoutEditor. Also SailInsight2.0 should have an option to use that feature. + * If that checkbox is checked the inferred marks and waypoints should also appear in CourseLayoutEditor. They can then be updated and/or refined. The EditMarkPositions feature on the RaceMap is then also enabled. + * That checkbox is default unchecked. If a race is reloaded the stored Waypoints are used. The WaypointInferrer can be forced to detect Waypoints in a race that already has some by checking the box and saving the CourseLayoutEditor. Then it will delete the Waypoints already in the race before trying to infer new ones, those will be stored. Old ones are lost, but the Marks are still avalaible so there is a possibility to restore the original Waypoints manually. + * There should be a course-designer in the regatta configuration with the effect to check the box and prevent the RaceManagerApp from interferring with the WaypointInferrer. -* First approach is to work only with smartphone tracked races. A check box in Smartphone Tracking connector is needed. Also SailInsight2.0 should have an option to use that feature. - -* If that checkbox is checked the inferred marks and waypoints should also appear in CourseLayoutEditor. They can then be updated and/or refined. The EditMarkPositions feature on the RaceMap is then also enabled. + * If we decide for a Mark position based on a threeshold number of competitors already passed should we take in consideration the upcoming competitors for the final Mark position and if we do so how can we achieve that? \ No newline at end of file From e162b0215b66e06ecfa23195df87d5abf9da1229 Mon Sep 17 00:00:00 2001 From: Alessandro Stolten Date: Tue, 18 Dec 2018 12:32:47 +0000 Subject: [PATCH 2/9] Updated WaypointInferrer (markdown) --- wiki/planning/WaypointInferrer.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/wiki/planning/WaypointInferrer.md b/wiki/planning/WaypointInferrer.md index 44d16fd8e16..db568a84fe8 100644 --- a/wiki/planning/WaypointInferrer.md +++ b/wiki/planning/WaypointInferrer.md @@ -6,7 +6,11 @@ WaypointInferrer should detect possible Marks, decide for the PassingInstruction * First approach is to work only with smartphone tracked races. A check box in Smartphone Tracking connector is needed. The checkbox should be integrated in the CourseLayoutEditor. Also SailInsight2.0 should have an option to use that feature. * If that checkbox is checked the inferred marks and waypoints should also appear in CourseLayoutEditor. They can then be updated and/or refined. The EditMarkPositions feature on the RaceMap is then also enabled. - * That checkbox is default unchecked. If a race is reloaded the stored Waypoints are used. The WaypointInferrer can be forced to detect Waypoints in a race that already has some by checking the box and saving the CourseLayoutEditor. Then it will delete the Waypoints already in the race before trying to infer new ones, those will be stored. Old ones are lost, but the Marks are still avalaible so there is a possibility to restore the original Waypoints manually. - * There should be a course-designer in the regatta configuration with the effect to check the box and prevent the RaceManagerApp from interferring with the WaypointInferrer. + * That checkbox is default unchecked not checkable. The box becomes checkable only if the correct course-designer is chosen in regatta configuration. If a race is reloaded the stored Waypoints are used. The WaypointInferrer can be forced to detect Waypoints in a race that already has some by checking the box and saving the CourseLayoutEditor. Then it will delete the Waypoints already in the race before trying to infer new ones, those will be stored. Old ones are lost, but the Marks are still avalaible so there is a possibility to restore the original Waypoints manually. + * There should be a course-designer in the regatta configuration with the effect to check to make the box checkable and prevent the RaceManagerApp from interferring with the WaypointInferrer. - * If we decide for a Mark position based on a threeshold number of competitors already passed should we take in consideration the upcoming competitors for the final Mark position and if we do so how can we achieve that? \ No newline at end of file + * If we decide for a Mark position based on a threeshold number of competitors already passed should we take in consideration the upcoming competitors for the final Mark position and if we do so how can we achieve that? + +### Next steps: + * Implement the above mentioned mechanisms to update a race. + * Improve the WaypointInferrer algorithm. \ No newline at end of file From 18df63ac5ca8c40912a410de0572ff1242fca2d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20B=C3=B6rnert?= Date: Tue, 18 Dec 2018 14:03:54 +0100 Subject: [PATCH 3/9] added missing this in StrippedUserDTO --- .../src/com/sap/sse/security/shared/dto/StrippedUserDTO.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/StrippedUserDTO.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/StrippedUserDTO.java index 5b29c41b98d..928a29819ec 100644 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/StrippedUserDTO.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/StrippedUserDTO.java @@ -20,7 +20,7 @@ public class StrippedUserDTO extends SecurityUserImpl roles, Iterable permissions) { super(name, permissions); - roles = new HashSet<>(); + this.roles = new HashSet<>(); Util.addAll(roles, this.getRolesInternal()); } From 1db66a16af1b757db1cedb9941e7490232876d4e Mon Sep 17 00:00:00 2001 From: Alessandro Stolten Date: Tue, 18 Dec 2018 13:54:58 +0000 Subject: [PATCH 4/9] Updated WaypointInferrer (markdown) --- wiki/planning/WaypointInferrer.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/wiki/planning/WaypointInferrer.md b/wiki/planning/WaypointInferrer.md index db568a84fe8..1015146e98a 100644 --- a/wiki/planning/WaypointInferrer.md +++ b/wiki/planning/WaypointInferrer.md @@ -1,16 +1,15 @@ This page is used to think through the features a Waypoint-inferring mechanism needs to have from an end-to-end perspective. -### Scenario 1: Starting a race with no information about Marks and Waypoints. +### Version 2: -WaypointInferrer should detect possible Marks, decide for the PassingInstructions and then store the Waypoint persistent in the race: +WaypointInferrer should detect Marks and Waypoins in a tracked race and decide wether to add new ones to the race or update given information about the race (e.g. waypoint list already prepared, positions pinged for all marks except the windward mark, so WaypointInferrer should detect that mark position.) - * First approach is to work only with smartphone tracked races. A check box in Smartphone Tracking connector is needed. The checkbox should be integrated in the CourseLayoutEditor. Also SailInsight2.0 should have an option to use that feature. - * If that checkbox is checked the inferred marks and waypoints should also appear in CourseLayoutEditor. They can then be updated and/or refined. The EditMarkPositions feature on the RaceMap is then also enabled. - * That checkbox is default unchecked not checkable. The box becomes checkable only if the correct course-designer is chosen in regatta configuration. If a race is reloaded the stored Waypoints are used. The WaypointInferrer can be forced to detect Waypoints in a race that already has some by checking the box and saving the CourseLayoutEditor. Then it will delete the Waypoints already in the race before trying to infer new ones, those will be stored. Old ones are lost, but the Marks are still avalaible so there is a possibility to restore the original Waypoints manually. - * There should be a course-designer in the regatta configuration with the effect to check to make the box checkable and prevent the RaceManagerApp from interferring with the WaypointInferrer. +The WaypointInferrer should be treated similar to the MarkPassingCalculator, the information is only stored in-memory, every reload of a tracked race would need the algorithm to start again. + +A checkbox in smartphone tracking connector next to start tracking button is needed. If checked the race is tracked with an instance of WaypointInferrer. - * If we decide for a Mark position based on a threeshold number of competitors already passed should we take in consideration the upcoming competitors for the final Mark position and if we do so how can we achieve that? ### Next steps: - * Implement the above mentioned mechanisms to update a race. - * Improve the WaypointInferrer algorithm. \ No newline at end of file + * Implement the checkbox and the restore functionality. + * Improve the WaypointInferrer algorithm to match the desired behaviour. + * Create test cases with real data and scenarios. \ No newline at end of file From 7974171b093c9657bfcfa66c39a47b667dbdaed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20B=C3=B6rnert?= Date: Tue, 18 Dec 2018 15:14:50 +0100 Subject: [PATCH 5/9] updated No Proxy winddbTest launch config --- .../SailingServer (No Proxy, winddbTest).launch | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch index a49695df91a..806cf4e323f 100755 --- a/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch @@ -29,9 +29,9 @@ - + - + From ac5597a621d13f082313b6eaadef305aa024b17c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20B=C3=B6rnert?= Date: Tue, 18 Dec 2018 16:38:10 +0100 Subject: [PATCH 6/9] added missing null check in equals --- .../com/sap/sse/security/shared/AbstractRole.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractRole.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractRole.java index 969b6b13efb..423f1919e24 100755 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractRole.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractRole.java @@ -16,7 +16,7 @@ public abstract class AbstractRole Date: Tue, 18 Dec 2018 18:47:41 +0100 Subject: [PATCH 7/9] Removed unnecessary generic --- .../com/sap/sse/security/shared/dto/AccessControlListDTO.java | 2 +- .../sse/security/shared/impl/AbstractAccessControlList.java | 3 +-- .../com/sap/sse/security/shared/impl/AccessControlList.java | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/AccessControlListDTO.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/AccessControlListDTO.java index 972859d0679..b5711a93cac 100644 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/AccessControlListDTO.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/AccessControlListDTO.java @@ -6,7 +6,7 @@ import java.util.Set; import com.sap.sse.security.shared.impl.AbstractAccessControlList; -public class AccessControlListDTO extends AbstractAccessControlList { +public class AccessControlListDTO extends AbstractAccessControlList { private static final long serialVersionUID = 2878270565599189728L; diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/AbstractAccessControlList.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/AbstractAccessControlList.java index 87916376773..e43d34c4d72 100755 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/AbstractAccessControlList.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/AbstractAccessControlList.java @@ -9,11 +9,10 @@ import com.sap.sse.common.Util; import com.sap.sse.security.shared.PermissionChecker; import com.sap.sse.security.shared.PermissionChecker.PermissionState; import com.sap.sse.security.shared.SecurityAccessControlList; -import com.sap.sse.security.shared.SecurityUser; import com.sap.sse.security.shared.SecurityUserGroup; import com.sap.sse.security.shared.WildcardPermission; -public abstract class AbstractAccessControlList> +public abstract class AbstractAccessControlList implements SecurityAccessControlList { private static final long serialVersionUID = -8587238587604749862L; diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/AccessControlList.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/AccessControlList.java index 2c69da78fde..b62fe3b386f 100644 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/AccessControlList.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/AccessControlList.java @@ -4,7 +4,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; -public class AccessControlList extends AbstractAccessControlList { +public class AccessControlList extends AbstractAccessControlList { private static final long serialVersionUID = 1L; public AccessControlList(Map> permissionMap) { From 4eaa69cec4507ecf8b10641943d304cde999ed4c Mon Sep 17 00:00:00 2001 From: Steffen Schaefer Date: Tue, 18 Dec 2018 19:27:16 +0100 Subject: [PATCH 8/9] Further reduced size of security relevant objects --- .../security/shared/AbstractOwnership.java | 2 +- .../sap/sse/security/shared/AbstractRole.java | 2 +- .../shared/AbstractUserGroupImpl.java | 2 +- .../security/shared/PermissionChecker.java | 15 +++++----- .../sap/sse/security/shared/SecurityUser.java | 3 +- .../sse/security/shared/UserReference.java | 7 +++++ .../security/shared/dto/StrippedUserDTO.java | 24 ++------------- .../sap/sse/security/shared/dto/UserDTO.java | 20 +++++++++++-- .../shared/impl/AbstractUserReference.java | 30 +++++++++++++++++++ .../shared/impl/SecurityUserImpl.java | 19 ++---------- .../sse/security/ui/client/UserService.java | 4 +-- .../client/component/EditOwnershipDialog.java | 2 +- .../component/UserGroupDetailPanel.java | 2 +- .../ui/server/SecurityDTOFactory.java | 29 +++++------------- .../security/ui/server/SecurityDTOUtil.java | 28 ++++++++--------- 15 files changed, 97 insertions(+), 92 deletions(-) create mode 100644 java/com.sap.sse.security.common/src/com/sap/sse/security/shared/UserReference.java create mode 100644 java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/AbstractUserReference.java diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractOwnership.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractOwnership.java index c84a150a953..37ffd04cdab 100644 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractOwnership.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractOwnership.java @@ -2,7 +2,7 @@ package com.sap.sse.security.shared; import java.io.Serializable; -public abstract class AbstractOwnership> +public abstract class AbstractOwnership implements Serializable { private static final long serialVersionUID = 1L; diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractRole.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractRole.java index 423f1919e24..62678816a1c 100755 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractRole.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractRole.java @@ -12,7 +12,7 @@ import com.sap.sse.common.Util.Triple; * * @author Axel Uhl (D043530) */ -public abstract class AbstractRole> +public abstract class AbstractRole implements Named { private static final String QUALIFIER_SEPARATOR = WildcardPermission.PART_DIVIDER_TOKEN; private static final long serialVersionUID = 1243342091492822614L; diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractUserGroupImpl.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractUserGroupImpl.java index 76896bfcf72..ab366f8a14d 100644 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractUserGroupImpl.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/AbstractUserGroupImpl.java @@ -9,7 +9,7 @@ import java.util.UUID; * @author Axel Uhl (d043530) * */ -public abstract class AbstractUserGroupImpl> +public abstract class AbstractUserGroupImpl extends SecurityUserGroupImpl { private static final long serialVersionUID = 1L; diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/PermissionChecker.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/PermissionChecker.java index fb04c222953..3e86cf9beff 100644 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/PermissionChecker.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/PermissionChecker.java @@ -61,7 +61,7 @@ public class PermissionChecker { * @param acl * may be {@code null} in which case no ACL-specific checks are performed */ - public static , O extends AbstractOwnership, U extends SecurityUser, G extends SecurityUserGroup, A extends SecurityAccessControlList> boolean isPermitted( + public static , O extends AbstractOwnership, UR extends UserReference, U extends SecurityUser, G extends SecurityUserGroup, A extends SecurityAccessControlList> boolean isPermitted( WildcardPermission permission, U user, U allUser, O ownership, A acl) { return isPermitted(permission, user, (Iterable) (user == null ? null : user.getUserGroups()), allUser, @@ -80,7 +80,7 @@ public class PermissionChecker { * @param acl * may be {@code null} in which case no ACL-specific checks are performed */ - public static , O extends AbstractOwnership, U extends SecurityUser, G extends SecurityUserGroup, A extends SecurityAccessControlList> boolean isPermitted( + public static , O extends AbstractOwnership, UR extends UserReference, U extends SecurityUser, G extends SecurityUserGroup, A extends SecurityAccessControlList> boolean isPermitted( WildcardPermission permission, U user, Iterable groupsOfWhichUserIsMember, U allUser, Iterable allUserGroupsOfWhichUserIsMember, O ownership, A acl) { @@ -180,7 +180,7 @@ public class PermissionChecker { * complete list for the running system. Otherwise we potentially do not check for all required types if the given * {@link WildcardPermission} has a wildcard as type part. */ - public static , O extends AbstractOwnership, U extends SecurityUser, G extends SecurityUserGroup, A extends SecurityAccessControlList> boolean checkMetaPermission( + public static , O extends AbstractOwnership, UR extends UserReference, U extends SecurityUser, G extends SecurityUserGroup, A extends SecurityAccessControlList> boolean checkMetaPermission( WildcardPermission permission, Iterable allPermissionTypes, U user, U allUser, O ownership) { assert permission != null; @@ -275,7 +275,7 @@ public class PermissionChecker { * because only users that have an unqualified version of a permission would pass that permission check. This means * we need to check the permission for any possibly existing object ID. */ - public static , O extends AbstractOwnership, U extends SecurityUser, G extends SecurityUserGroup, A extends SecurityAccessControlList> boolean hasUserAnyPermission( + public static , O extends AbstractOwnership, UR extends UserReference, U extends SecurityUser, G extends SecurityUserGroup, A extends SecurityAccessControlList> boolean hasUserAnyPermission( WildcardPermission permission, Iterable allPermissionTypes, U user, U allUser, O ownership) { assert permission != null; @@ -293,7 +293,7 @@ public class PermissionChecker { return false; } - private static , O extends AbstractOwnership, U extends SecurityUser, G extends SecurityUserGroup, A extends SecurityAccessControlList> PermissionState checkUserPermissions( + private static , O extends AbstractOwnership, UR extends UserReference, U extends SecurityUser, G extends SecurityUserGroup, A extends SecurityAccessControlList> PermissionState checkUserPermissions( WildcardPermission permission, U user, O ownership, WildcardPermissionChecker permissionChecker, boolean matchOnlyNonQualifiedRolesIfNoOwnershipIsGiven) { @@ -336,7 +336,7 @@ public class PermissionChecker { * @param ownership * Ownership of the data object for which the {@code permission} is requested */ - private static , O extends AbstractOwnership, U extends SecurityUser, G extends SecurityUserGroup, A extends SecurityAccessControlList> boolean implies( + private static , O extends AbstractOwnership, UR extends UserReference, U extends SecurityUser, G extends SecurityUserGroup, A extends SecurityAccessControlList> boolean implies( R role, WildcardPermission permission, O ownership, WildcardPermissionChecker permissionChecker, boolean matchOnlyNonQualifiedRolesIfNoOwnershipIsGiven) { @@ -373,8 +373,7 @@ public class PermissionChecker { /** * There are cases where need to check instances of different implementations if they represent the same user. */ - public static , O extends AbstractOwnership, U extends SecurityUser, G extends SecurityUserGroup, A extends SecurityAccessControlList> boolean isSameUser( - U user1, U user2) { + public static boolean isSameUser(UserReference user1, UserReference user2) { if (user1 == user2) { return true; } diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/SecurityUser.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/SecurityUser.java index 81ce75282d1..e4386f898cd 100755 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/SecurityUser.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/SecurityUser.java @@ -1,7 +1,6 @@ package com.sap.sse.security.shared; import com.sap.sse.common.Named; -import com.sap.sse.common.NamedWithID; import com.sap.sse.common.WithID; /** @@ -13,7 +12,7 @@ import com.sap.sse.common.WithID; * */ public interface SecurityUser, G extends SecurityUserGroup> - extends NamedWithID { + extends UserReference { /** * Returns the "raw" permissions explicitly set for this user. This does not include permissions * inferred by any {@link PermissionsForRoleProvider} for the {@link #getRoles() roles} that this diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/UserReference.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/UserReference.java new file mode 100644 index 00000000000..557c3519eec --- /dev/null +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/UserReference.java @@ -0,0 +1,7 @@ +package com.sap.sse.security.shared; + +import com.sap.sse.common.NamedWithID; + +public interface UserReference extends NamedWithID { + +} diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/StrippedUserDTO.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/StrippedUserDTO.java index 928a29819ec..25c24e90dd7 100644 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/StrippedUserDTO.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/StrippedUserDTO.java @@ -1,35 +1,17 @@ package com.sap.sse.security.shared.dto; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; +import com.sap.sse.security.shared.impl.AbstractUserReference; -import com.sap.sse.common.Util; -import com.sap.sse.security.shared.WildcardPermission; -import com.sap.sse.security.shared.impl.SecurityUserImpl; - -public class StrippedUserDTO extends SecurityUserImpl { +public class StrippedUserDTO extends AbstractUserReference { private static final long serialVersionUID = 1L; - private Set roles; @Deprecated private StrippedUserDTO() { super(null); } - public StrippedUserDTO(String name, Iterable roles, Iterable permissions) { - super(name, permissions); - this.roles = new HashSet<>(); - Util.addAll(roles, this.getRolesInternal()); - } - public StrippedUserDTO(String name) { - this(name, Collections.emptySet(), Collections.emptySet()); - } - - @Override - protected Set getRolesInternal() { - return roles; + super(name); } } 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 baa24ec3edc..060c8b497a6 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 @@ -2,13 +2,16 @@ package com.sap.sse.security.shared.dto; import java.io.Serializable; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import com.sap.sse.common.Util; import com.sap.sse.security.shared.WildcardPermission; import com.sap.sse.security.shared.impl.Ownership; +import com.sap.sse.security.shared.impl.SecurityUserImpl; -public class UserDTO extends StrippedUserDTO +public class UserDTO extends SecurityUserImpl implements Serializable, SecuredDTO { private static final long serialVersionUID = 7556217539893146187L; @@ -23,6 +26,8 @@ public class UserDTO extends StrippedUserDTO private SecurityInformationDTO securityInformation = new SecurityInformationDTO(); private StrippedUserGroupDTO defaultTenantForCurrentServer; + private Set roles; + @Deprecated // gwt only UserDTO() { super(null); @@ -35,7 +40,7 @@ public class UserDTO extends StrippedUserDTO List accounts, Iterable roles, StrippedUserGroupDTO defaultTenant, Iterable permissions, Iterable groups) { - super(name, roles, permissions); + super(name, permissions); this.defaultTenantForCurrentServer = defaultTenant; this.email = email; this.fullName = fullName; @@ -45,6 +50,13 @@ public class UserDTO extends StrippedUserDTO this.accounts = accounts; this.groups = new ArrayList<>(); Util.addAll(groups, this.groups); + this.roles = new HashSet<>(); + Util.addAll(roles, this.getRolesInternal()); + } + + @Override + protected Set getRolesInternal() { + return roles; } /** @@ -130,4 +142,8 @@ public class UserDTO extends StrippedUserDTO public void setDefaultTenantForCurrentServer(StrippedUserGroupDTO defaultTenant) { this.defaultTenantForCurrentServer = defaultTenant; } + + public StrippedUserDTO asStrippedUser() { + return new StrippedUserDTO(getName()); + } } diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/AbstractUserReference.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/AbstractUserReference.java new file mode 100644 index 00000000000..c778ac37682 --- /dev/null +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/AbstractUserReference.java @@ -0,0 +1,30 @@ +package com.sap.sse.security.shared.impl; + +import java.io.Serializable; + +import com.sap.sse.security.shared.UserReference; + +public abstract class AbstractUserReference implements UserReference { + private static final long serialVersionUID = -3639860207453072248L; + + private String name; + + public AbstractUserReference(String name) { + this.name = name; + } + + @Override + public String getName() { + return name; + } + + @Override + public Serializable getId() { + return getName(); + } + + @Override + public String toString() { + return name; + } +} diff --git a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/SecurityUserImpl.java b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/SecurityUserImpl.java index 8ba35e6dce9..baa6e8c022a 100755 --- a/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/SecurityUserImpl.java +++ b/java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/SecurityUserImpl.java @@ -1,6 +1,5 @@ package com.sap.sse.security.shared.impl; -import java.io.Serializable; import java.util.Collections; import java.util.HashSet; import java.util.Set; @@ -12,11 +11,9 @@ import com.sap.sse.security.shared.SecurityUserGroup; import com.sap.sse.security.shared.WildcardPermission; public abstract class SecurityUserImpl, G extends SecurityUserGroup> - implements SecurityUser { + extends AbstractUserReference implements SecurityUser { private static final long serialVersionUID = -3639860207453072248L; - private String name; - private Set permissions; /** @@ -27,7 +24,7 @@ public abstract class SecurityUserImpl permissions) { - this.name = name; + super(name); this.permissions = new HashSet<>(); for (WildcardPermission permission : permissions) { this.permissions.add(permission); @@ -35,16 +32,6 @@ public abstract class SecurityUserImpl getRolesInternal(); - - @Override - public String getName() { - return name; - } - - @Override - public Serializable getId() { - return getName(); - } @Override public Iterable getRoles() { @@ -79,7 +66,7 @@ public abstract class SecurityUserImpl userManagementService.getUserByName(usernameBox.getText(), new AsyncCallback() { @Override public void onSuccess(UserDTO result) { - resolvedUser = result; + resolvedUser = result == null ? null : result.asStrippedUser(); resolvingUsername = false; validateAndUpdate(); } diff --git a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/component/UserGroupDetailPanel.java b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/component/UserGroupDetailPanel.java index 3a5df02b2ef..7bc47a912e8 100755 --- a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/component/UserGroupDetailPanel.java +++ b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/component/UserGroupDetailPanel.java @@ -211,7 +211,7 @@ public class UserGroupDetailPanel extends HorizontalPanel implements Handler, Ch } @Override public void onSuccess(Void result) { - tenant.add(user); + tenant.add(user.asStrippedUser()); allUsersListDataProvider.updateDisplays(); tenantUsersListDataProvider.updateDisplays(); } diff --git a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/SecurityDTOFactory.java b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/SecurityDTOFactory.java index 20cd32ab7c9..96e3ab0d593 100755 --- a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/SecurityDTOFactory.java +++ b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/SecurityDTOFactory.java @@ -20,7 +20,6 @@ import com.sap.sse.security.shared.RoleDefinition; import com.sap.sse.security.shared.SecurityUser; import com.sap.sse.security.shared.SocialUserAccount; import com.sap.sse.security.shared.UsernamePasswordAccount; -import com.sap.sse.security.shared.WildcardPermission; import com.sap.sse.security.shared.dto.AccessControlListAnnotationDTO; import com.sap.sse.security.shared.dto.AccessControlListDTO; import com.sap.sse.security.shared.dto.AccountDTO; @@ -85,7 +84,6 @@ public class SecurityDTOFactory { user.getPermissions(), createStrippedUserGroupDTOsFromUserGroups(securityService.getUserGroupsOfUser(user), fromOriginalToStrippedDownUser, fromOriginalToStrippedDownUserGroup)); - fromOriginalToStrippedDownUser.put(user, userDTO); userDTO.setDefaultTenantForCurrentServer(createStrippedUserGroupDTOFromUserGroup( securityService.getDefaultTenantForCurrentUser(), fromOriginalToStrippedDownUserGroup)); @@ -279,24 +277,21 @@ public class SecurityDTOFactory { * @param fromOriginalToStrippedDownUser * @param fromOriginalToStrippedDownUserGroup */ - public AccessControlListDTO pruneAccessControlListForUser(AccessControlListDTO acl, StrippedUserDTO filterForUser, + public AccessControlListDTO pruneAccessControlListForUser(AccessControlListDTO acl, Iterable groupsOfUser, Iterable allUserGroups) { final AccessControlListDTO result; // add user groups of filterForUser user - final Collection userGroups = Util.createSet(filterForUser.getUserGroups()); + final Collection userGroups = new HashSet<>(); + Util.addAll(groupsOfUser, userGroups); // add user groups of alluser - if (allUserGroups != null) { - userGroups.addAll(Util.createSet(allUserGroups)); - } - // add null user group - userGroups.add(null); + Util.addAll(allUserGroups, userGroups); if (acl != null) { final Map> actionsByUserGroup = new HashMap<>(); for (final Entry> entry : acl.getActionsByUserGroup().entrySet()) { - if (userGroups.contains(entry.getKey())) { - StrippedUserGroupDTO key = entry.getKey(); - actionsByUserGroup.put(key, entry.getValue()); + StrippedUserGroupDTO userGroup = entry.getKey(); + if (userGroup == null || userGroups.contains(userGroup)) { + actionsByUserGroup.put(userGroup, entry.getValue()); } } result = new AccessControlListDTO(actionsByUserGroup); @@ -338,18 +333,8 @@ public class SecurityDTOFactory { Map fromOriginalToStrippedDownUserGroup) { StrippedUserDTO mappedUser = fromOriginalToStrippedDownUser.get(user); if (mappedUser == null) { - Iterable roles = user.getRoles(); mappedUser = new StrippedUserDTO(user.getName()); fromOriginalToStrippedDownUser.put(user, mappedUser); - Iterable rolesDTO = createRolesDTOs(roles, fromOriginalToStrippedDownUser, - fromOriginalToStrippedDownUserGroup, securityService); - for (RoleDTO r : rolesDTO) { - mappedUser.addRole(r); - } - for (WildcardPermission p : user.getPermissions()) { - mappedUser.addPermission(p); - } - fromOriginalToStrippedDownUser.put(user, mappedUser); } return mappedUser; } diff --git a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/SecurityDTOUtil.java b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/SecurityDTOUtil.java index 3ffe0733b11..d39b7b59cca 100644 --- a/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/SecurityDTOUtil.java +++ b/java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/SecurityDTOUtil.java @@ -1,5 +1,6 @@ package com.sap.sse.security.ui.server; +import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -25,8 +26,6 @@ public abstract class SecurityDTOUtil { private SecurityDTOUtil() { } - private static Iterable allUserGroups; - /** * Adds {@link AccessControlList access control list} and {@link Ownership ownership} information for the given * {@link QualifiedObjectIdentifier qualified object identifier} to the provided {@link NamedSecuredObjectDTO @@ -109,12 +108,12 @@ public abstract class SecurityDTOUtil { } else { User user = securityService.getCurrentUser(); if (user != null) { - StrippedUserDTO userDTO = new SecurityDTOFactory().createStrippedUserFromUser(user, securityService, - fromOriginalToStrippedDownUser, fromOriginalToStrippedDownUserGroup); - final Iterable allUserGroups2 = getUserGroupsForAlluser(securityService, - securityDTOFactory); + final Iterable userGroups = getUserGroupsForUser(securityService, + securityDTOFactory, user); + final Iterable allUserGroups2 = getUserGroupsForUser(securityService, + securityDTOFactory, securityService.getAllUser()); securedObject.setAccessControlList( - securityDTOFactory.pruneAccessControlListForUser(accessControlListDTO, userDTO, + securityDTOFactory.pruneAccessControlListForUser(accessControlListDTO, userGroups, allUserGroups2)); } } @@ -123,15 +122,16 @@ public abstract class SecurityDTOUtil { securityDTOFactory.createOwnershipDTO(ownership == null ? null : ownership.getAnnotation(), fromOriginalToStrippedDownUser, fromOriginalToStrippedDownUserGroup)); } - + /** Get the UserGroups for the user alluser. */ - private static Iterable getUserGroupsForAlluser(SecurityService securityService, - SecurityDTOFactory securityDTOFactory) { - if (allUserGroups == null) { - if (securityService.getAllUser() != null) { + private static Iterable getUserGroupsForUser(SecurityService securityService, + SecurityDTOFactory securityDTOFactory, User user) { + Iterable allUserGroups; + if (user != null) { allUserGroups = securityDTOFactory.createStrippedUserGroupDTOFromUserGroups( - securityService.getAllUser().getUserGroups(), new HashMap<>()); - } + user.getUserGroups(), new HashMap<>()); + } else { + allUserGroups = Collections.emptySet(); } return allUserGroups; } From 3fb153809a7f443c8fe9c79cee182bec4d02bd95 Mon Sep 17 00:00:00 2001 From: Steffen Schaefer Date: Wed, 19 Dec 2018 08:18:17 +0100 Subject: [PATCH 9/9] Fixed updating TracTrac/SwissTiming configurations --- .../persistence/impl/SwissTimingAdapterPersistenceImpl.java | 4 ++-- .../persistence/impl/MongoObjectFactoryImpl.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java/com.sap.sailing.domain.swisstimingadapter.persistence/src/com/sap/sailing/domain/swisstimingadapter/persistence/impl/SwissTimingAdapterPersistenceImpl.java b/java/com.sap.sailing.domain.swisstimingadapter.persistence/src/com/sap/sailing/domain/swisstimingadapter/persistence/impl/SwissTimingAdapterPersistenceImpl.java index e17f7983b13..7df63b76b2f 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter.persistence/src/com/sap/sailing/domain/swisstimingadapter/persistence/impl/SwissTimingAdapterPersistenceImpl.java +++ b/java/com.sap.sailing.domain.swisstimingadapter.persistence/src/com/sap/sailing/domain/swisstimingadapter/persistence/impl/SwissTimingAdapterPersistenceImpl.java @@ -108,7 +108,7 @@ public class SwissTimingAdapterPersistenceImpl implements SwissTimingAdapterPers final Document updateQuery = new Document(FieldNames.ST_CONFIG_JSON_URL.name(), swissTimingConfiguration.getJsonURL()); - stConfigCollection.withWriteConcern(WriteConcern.ACKNOWLEDGED).updateOne(updateQuery, result, + stConfigCollection.withWriteConcern(WriteConcern.ACKNOWLEDGED).replaceOne(updateQuery, result, new UpdateOptions().upsert(true)); } @@ -125,7 +125,7 @@ public class SwissTimingAdapterPersistenceImpl implements SwissTimingAdapterPers Document result = new Document(); result.put(FieldNames.ST_ARCHIVE_JSON_URL.name(), createSwissTimingArchiveConfiguration.getJsonUrl()); - stArchiveConfigCollection.withWriteConcern(WriteConcern.ACKNOWLEDGED).updateOne(result, result, + stArchiveConfigCollection.withWriteConcern(WriteConcern.ACKNOWLEDGED).replaceOne(result, result, new UpdateOptions().upsert(true)); } diff --git a/java/com.sap.sailing.domain.tractracadapter.persistence/src/com/sap/sailing/domain/tractracadapter/persistence/impl/MongoObjectFactoryImpl.java b/java/com.sap.sailing.domain.tractracadapter.persistence/src/com/sap/sailing/domain/tractracadapter/persistence/impl/MongoObjectFactoryImpl.java index 6aad4a3591e..d6407cad625 100755 --- a/java/com.sap.sailing.domain.tractracadapter.persistence/src/com/sap/sailing/domain/tractracadapter/persistence/impl/MongoObjectFactoryImpl.java +++ b/java/com.sap.sailing.domain.tractracadapter.persistence/src/com/sap/sailing/domain/tractracadapter/persistence/impl/MongoObjectFactoryImpl.java @@ -39,7 +39,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { // Object with given name is updated or created if it does not exist yet final Document updateQuery = new Document(FieldNames.TT_CONFIG_JSON_URL.name(), tracTracConfiguration.getJSONURL()); - ttConfigCollection.withWriteConcern(WriteConcern.ACKNOWLEDGED).updateOne(updateQuery, result, + ttConfigCollection.withWriteConcern(WriteConcern.ACKNOWLEDGED).replaceOne(updateQuery, result, new UpdateOptions().upsert(true)); }