From d21bff91443ee019f2463b60903bec137fbc899a Mon Sep 17 00:00:00 2001 From: Usman Ali Date: Mon, 6 Jan 2020 00:32:21 +0500 Subject: [PATCH 01/19] ownership change api --- java/com.sap.sse.security/resources/shiro.ini | 1 + .../exceptions/OwnershipException.java | 28 +++++++++ .../handler/OwnershipExceptionHandler.java | 28 +++++++++ .../security/jaxrs/api/OwnershipResource.java | 63 +++++++++++++++++++ .../jaxrs/api/RestApiApplication.java | 4 +- .../sse/security/model/GeneralResponse.java | 43 +++++++++++++ 6 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 java/com.sap.sse.security/src/com/sap/sse/security/exceptions/OwnershipException.java create mode 100644 java/com.sap.sse.security/src/com/sap/sse/security/exceptions/handler/OwnershipExceptionHandler.java create mode 100644 java/com.sap.sse.security/src/com/sap/sse/security/jaxrs/api/OwnershipResource.java create mode 100644 java/com.sap.sse.security/src/com/sap/sse/security/model/GeneralResponse.java diff --git a/java/com.sap.sse.security/resources/shiro.ini b/java/com.sap.sse.security/resources/shiro.ini index e609445da71..7379336928c 100644 --- a/java/com.sap.sse.security/resources/shiro.ini +++ b/java/com.sap.sse.security/resources/shiro.ini @@ -76,3 +76,4 @@ bearerToken = com.sap.sse.security.BearerTokenOrBasicOrFormAuthenticationFilter /api/restsecurity/usergroup = bearerToken /api/restsecurity/role = bearerToken /api/restsecurity/role/** = bearerToken +/api/restsecurity/ownership/** = bearerToken \ No newline at end of file diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/exceptions/OwnershipException.java b/java/com.sap.sse.security/src/com/sap/sse/security/exceptions/OwnershipException.java new file mode 100644 index 00000000000..a7100729bc2 --- /dev/null +++ b/java/com.sap.sse.security/src/com/sap/sse/security/exceptions/OwnershipException.java @@ -0,0 +1,28 @@ +package com.sap.sse.security.exceptions; + +import javax.ws.rs.core.Response.Status; +import com.sap.sse.security.jaxrs.api.OwnershipResource; + +/*** + * OwnershipException is used for {@link OwnershipResource} class to handle any exception in ownership Api's. + * @author Usman Ali + * + */ +public class OwnershipException extends Exception{ + + private static final long serialVersionUID = 1L; + + private Status status; + + public OwnershipException(String message, Status status) { + super(message); + this.status = status; + } + + public Status getStatus() { + return status; + } + + + +} diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/exceptions/handler/OwnershipExceptionHandler.java b/java/com.sap.sse.security/src/com/sap/sse/security/exceptions/handler/OwnershipExceptionHandler.java new file mode 100644 index 00000000000..986012b0be6 --- /dev/null +++ b/java/com.sap.sse.security/src/com/sap/sse/security/exceptions/handler/OwnershipExceptionHandler.java @@ -0,0 +1,28 @@ +package com.sap.sse.security.exceptions.handler; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; +import javax.ws.rs.ext.Provider; + +import com.sap.sse.security.exceptions.OwnershipException; +import com.sap.sse.security.jaxrs.ShiroAuthorizationExceptionTo401ResponseMapper; +import com.sap.sse.security.model.GeneralResponse; + + +/*** + * This class is used to handle {@link OwnershipException} thrown from any API of project. + * @author Usman Ali + * + */ +@Provider +public class OwnershipExceptionHandler implements ExceptionMapper { + private static final Logger logger = Logger.getLogger(ShiroAuthorizationExceptionTo401ResponseMapper.class.getName()); + @Override + public Response toResponse(OwnershipException exception) { + logger.log(Level.WARNING, "OwnershipException occurred in REST call: " + exception.getMessage()); + return Response.status(exception.getStatus()).entity(new GeneralResponse(false, exception.getMessage()).toString()).build(); + } +} 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 new file mode 100644 index 00000000000..18a13827afe --- /dev/null +++ b/java/com.sap.sse.security/src/com/sap/sse/security/jaxrs/api/OwnershipResource.java @@ -0,0 +1,63 @@ +package com.sap.sse.security.jaxrs.api; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.apache.shiro.SecurityUtils; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + +import com.sap.sse.security.exceptions.OwnershipException; +import com.sap.sse.security.jaxrs.AbstractSecurityResource; +import com.sap.sse.security.model.GeneralResponse; +import com.sap.sse.security.shared.HasPermissions.DefaultActions; +import com.sap.sse.security.shared.QualifiedObjectIdentifier; +import com.sap.sse.security.shared.TypeRelativeObjectIdentifier; +import com.sap.sse.security.shared.impl.QualifiedObjectIdentifierImpl; +import com.sap.sse.security.shared.impl.User; +import com.sap.sse.security.shared.impl.UserGroup; + +@Path("/restsecurity/ownership") +public class OwnershipResource extends AbstractSecurityResource { + private static final String KEY_OBJECT_ID = "objectId"; + private static final String KEY_OBJECT_TYPE = "objectType"; + private static final String KEY_USERNAME = "username"; + private static final String KEY_GROUP_ID="groupId"; + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces("application/json;charset=UTF-8") + public Response createUser(String jsonBody) throws OwnershipException { + + final JSONObject json = (JSONObject) JSONValue.parse(jsonBody); + User user =getService().getUserByName((String)json.get(KEY_USERNAME)); + if(user == null) { + throw new OwnershipException("User Not found",Status.BAD_REQUEST); + } + UserGroup userGroup =getService().getUserGroupByName((String)json.get(KEY_GROUP_ID)); + if(userGroup == null) { + throw new OwnershipException("UserGroup Not found",Status.BAD_REQUEST); + } + QualifiedObjectIdentifier identifier = new QualifiedObjectIdentifierImpl( + (String)json.get(KEY_OBJECT_TYPE), + new TypeRelativeObjectIdentifier((String)json.get(KEY_OBJECT_ID)) + ); + + try { + SecurityUtils.getSubject() + .checkPermission(identifier.getStringPermission(DefaultActions.CHANGE_OWNERSHIP)); + }catch(Exception ex) { + throw new OwnershipException("Not permitted to change ownership.", Status.FORBIDDEN); + } + + getService().setOwnership(identifier, user, userGroup); + + + return Response.ok(new GeneralResponse(true, "Ownership changed successfully").toString()).build(); + } +} diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/jaxrs/api/RestApiApplication.java b/java/com.sap.sse.security/src/com/sap/sse/security/jaxrs/api/RestApiApplication.java index 1289d310e70..5caf9ec1301 100644 --- a/java/com.sap.sse.security/src/com/sap/sse/security/jaxrs/api/RestApiApplication.java +++ b/java/com.sap.sse.security/src/com/sap/sse/security/jaxrs/api/RestApiApplication.java @@ -5,6 +5,7 @@ import java.util.Set; import javax.ws.rs.core.Application; +import com.sap.sse.security.exceptions.handler.OwnershipExceptionHandler; import com.sap.sse.security.jaxrs.ShiroAuthorizationExceptionTo401ResponseMapper; public class RestApiApplication extends Application { @@ -13,9 +14,10 @@ public class RestApiApplication extends Application { classes.add(SecurityResource.class); classes.add(UserGroupResource.class); classes.add(RoleResource.class); - + classes.add(OwnershipResource.class); // exception mapper classes.add(ShiroAuthorizationExceptionTo401ResponseMapper.class); + classes.add(OwnershipExceptionHandler.class); return classes; } } diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/model/GeneralResponse.java b/java/com.sap.sse.security/src/com/sap/sse/security/model/GeneralResponse.java new file mode 100644 index 00000000000..d4027b8f7ec --- /dev/null +++ b/java/com.sap.sse.security/src/com/sap/sse/security/model/GeneralResponse.java @@ -0,0 +1,43 @@ +package com.sap.sse.security.model; + +import java.io.Serializable; + +/*** + * This Class will be used to send general response in JSON format. + * @author Usman Ali + * + */ +public class GeneralResponse implements Serializable{ + + private static final long serialVersionUID = 1L; + + private boolean responseStatus; + private String responseMessage; + + public GeneralResponse(boolean responseStatus, String responseMessage) { + super(); + this.responseStatus = responseStatus; + this.responseMessage = responseMessage; + } + + public boolean isResponseStatus() { + return responseStatus; + } + public void setResponseStatus(boolean responseStatus) { + this.responseStatus = responseStatus; + } + public String getResponseMessage() { + return responseMessage; + } + public void setResponseMessage(String responseMessage) { + this.responseMessage = responseMessage; + } + + @Override + public String toString() { + return " {\"responseStatus\":\"" + responseStatus + "\", \"responseMessage\":\"" + responseMessage + "\"}"; + + } + + +} From 1b686fc5c5630c683557eb7fd957d51e9ddc195b Mon Sep 17 00:00:00 2001 From: Usman Ali Date: Tue, 7 Jan 2020 01:44:27 +0500 Subject: [PATCH 02/19] adding ownership page into webservices/api folder --- .../webservices/api/index.html | 4 ++ .../webservices/api/ownership.html | 51 +++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 java/com.sap.sse.security/webservices/api/ownership.html diff --git a/java/com.sap.sse.security/webservices/api/index.html b/java/com.sap.sse.security/webservices/api/index.html index 50901420d93..4fcd574b8ca 100755 --- a/java/com.sap.sse.security/webservices/api/index.html +++ b/java/com.sap.sse.security/webservices/api/index.html @@ -62,6 +62,10 @@ be http://sapsailing.com/security/api/restsecurity/login. /api/restsecurity/remove_access_token Remove an existing access token, rendering it invalid for authenticating to the server + + /api/restsecurity/ownership + Change Object ownership + diff --git a/java/com.sap.sse.security/webservices/api/ownership.html b/java/com.sap.sse.security/webservices/api/ownership.html new file mode 100644 index 00000000000..8cb51d0976d --- /dev/null +++ b/java/com.sap.sse.security/webservices/api/ownership.html @@ -0,0 +1,51 @@ + + + + + + + + SAP Sponsorships Engine Security Webservices API + + +

SAP Sponsorships Engine Security Webservices API

+

URL: /api/restsecurity/onwership

+ +Description: +

The service changes the ownership of object.

+
+ +Change Ownership + + + + + + + + + + + + + + + + + +
Request Method:POST
Output format:a JSON document of the following format
+
{ "responseStatus": "true", "responseMessage": "Ownership changed successfully"}
+
Parameter (JSON Body): +
objectId
Unique Object id. +
objectType
Object type represents the type of object to change the ownership. +
groupId
GroupId to assign given group to ownership of object object. +
username
Username to search the user in order to attach it with given Object ownership. +
Example:curl -X POST -d '{ + "objectId":"427ebd42-ac69-4f74-a171-376d9bea9457", + "objectType":"USER_GROUP", + "groupId":"admin-tenant", + "username":"admin" + }' "http://admin:admin@127.0.0.1:8888/security/api/restsecurity/ownership"
+ Will provide a JSON document as explained above.
+ + From 24c5fad1cb0bbd8e23e83ecbba2373a878d4cf95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Hessenm=C3=BCller?= Date: Fri, 10 Jan 2020 12:17:12 +0100 Subject: [PATCH 03/19] Fixed issue letting TaggingPanel be pushed off screen --- .../ui/raceboard/tagging/TaggingPanel.java | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TaggingPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TaggingPanel.java index 58cd73853ea..66a007faeba 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TaggingPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TaggingPanel.java @@ -192,7 +192,13 @@ public class TaggingPanel extends ComponentWithoutSettings tagButtons = new ArrayList(); - taggingPanel = new DockLayoutPanel(Style.Unit.PX); + taggingPanel = new DockLayoutPanel(Style.Unit.PX) { + @Override + public void onResize() { + super.onResize(); + taggingPanel.setWidgetSize(footerPanel, calculateFooterPanelHeight()); + } + }; filterbarAndContentPanel = new HeaderPanel(); tagFooterPanel = new TagFooterPanel(this, sailingService, stringMessages, userService); footerPanel = new ScrollPanel(tagFooterPanel); @@ -705,15 +711,7 @@ public class TaggingPanel extends ComponentWithoutSettings Scheduler.get().scheduleFinally(new RepeatingCommand() { @Override public boolean execute() { - // Default size of 2/3 the TaggingPanel - int height = (int) Math.round(taggingPanel.getOffsetHeight() / 3f * 2f); - // Get actual size of the footerPanel which might be 0 if the browser screwed up - final int vScroll = footerPanel.getWidget().getElement().getScrollHeight(); - if (vScroll != 0) { - height = Math.min(height, vScroll); - } - height = Math.max(200, height); - taggingPanel.setWidgetSize(footerPanel, height); + taggingPanel.setWidgetSize(footerPanel, calculateFooterPanelHeight()); taggingPanel.animate(FOOTERPANEL_ANIMATION_PERIOD_MS); return false; } @@ -728,6 +726,15 @@ public class TaggingPanel extends ComponentWithoutSettings } } + private int calculateFooterPanelHeight() { + // Start with footerPanel content height + int height = footerPanel.getWidget().getElement().getOffsetHeight(); + // Limit size if we take up the entire height of the viewing area + // to make sure we don't get pushed out of it at the top making parts of the footerPanel inaccessible + height = Math.min(height, taggingPanel.getOffsetHeight()); + return height; + } + /** * Checks whether current user has permission to modify public tags. * From 210908d0ed15b16efdfe12bc4081a5513b7ae438 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Sat, 11 Jan 2020 14:11:17 +0100 Subject: [PATCH 04/19] fixed documentation of usergroup REST API --- java/com.sap.sse.security/webservices/api/usergroup.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/java/com.sap.sse.security/webservices/api/usergroup.html b/java/com.sap.sse.security/webservices/api/usergroup.html index 54e9eb342ec..e9e7139dda6 100644 --- a/java/com.sap.sse.security/webservices/api/usergroup.html +++ b/java/com.sap.sse.security/webservices/api/usergroup.html @@ -113,7 +113,7 @@
-Delete a user from a UserGroup +Delete a user from a UserGroup @@ -151,12 +151,12 @@ - +
Request Method:
groupId (Path)
Unique name of the UserGroup to add the role to.
roleId (Path)
Unique ID of the role to add to the UserGroup. -
roleAssociated (JSON Body)
True or false, depending whether the role's permissions are applied regardless of the user performing the access, only requiring the object access to be owned by this group; otherwise, the role's permissions are only granted if the object accessed is owned by this group and the user performing the access belongs to this group. +
forAll (JSON Body)
True or false, depending whether the role's permissions are applied regardless of the user performing the access, only requiring the object access to be owned by this group; otherwise, the role's permissions are only granted if the object accessed is owned by this group and the user performing the access belongs to this group.
Example:curl -X PUT -d '{"roleAssociated": true}' "127.0.0.1:8888/security/api/restsecurity/usergroup/9201d7cb-969e-4975-8cf1-32972bb2c8ba/role/29914406-b0fc-43cd-acc7-62a83931f587"
curl -X PUT -d '{"forAll": true}' "127.0.0.1:8888/security/api/restsecurity/usergroup/9201d7cb-969e-4975-8cf1-32972bb2c8ba/role/29914406-b0fc-43cd-acc7-62a83931f587"

From 637e833497753f357780ab5d09a3f07c65b49761 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Sat, 11 Jan 2020 14:11:46 +0100 Subject: [PATCH 05/19] improved error messages in UserGroupResource --- .../com/sap/sse/security/impl/Activator.java | 1 - .../security/jaxrs/api/UserGroupResource.java | 17 ++++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/impl/Activator.java b/java/com.sap.sse.security/src/com/sap/sse/security/impl/Activator.java index 4c855362064..0025865fb9a 100644 --- a/java/com.sap.sse.security/src/com/sap/sse/security/impl/Activator.java +++ b/java/com.sap.sse.security/src/com/sap/sse/security/impl/Activator.java @@ -140,7 +140,6 @@ public class Activator implements BundleActivator { waitForUserStoreService(bundleContext); } context.registerService(ClearStateTestSupport.class, new ClearStateTestSupport() { - @Override public void clearState() throws Exception { Activator.this.clearState(); diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/jaxrs/api/UserGroupResource.java b/java/com.sap.sse.security/src/com/sap/sse/security/jaxrs/api/UserGroupResource.java index 769a349725b..abfc9c480e8 100644 --- a/java/com.sap.sse.security/src/com/sap/sse/security/jaxrs/api/UserGroupResource.java +++ b/java/com.sap.sse.security/src/com/sap/sse/security/jaxrs/api/UserGroupResource.java @@ -268,19 +268,17 @@ public class UserGroupResource extends AbstractSecurityResource { public Response addRoleToUserGroup(@PathParam(KEY_GROUP_ID) String userGroupId, @PathParam(KEY_ROLE_ID) String roleIdString, String body) { Response response; - try { final UUID groupId = UUID.fromString(userGroupId); - final UserGroup usergroup = getService().getUserGroup(groupId); - final UUID roleId = UUID.fromString(roleIdString); + final UserGroup usergroup = getService().getUserGroup(groupId); if (usergroup == null) { - response = Response.status(Status.BAD_REQUEST).entity("Usergroup with this name does not exist.") - .build(); + response = Response.status(Status.BAD_REQUEST).entity( + String.format("Usergroup with ID %s does not exist.", userGroupId)).build(); } else { final RoleDefinition role = getService().getRoleDefinition(roleId); if (role == null) { - response = Response.status(Status.BAD_REQUEST).entity("Role with this id does not exist.").build(); + response = Response.status(Status.BAD_REQUEST).entity(String.format("Role with ID %s does not exist.", roleId)).build(); } else { if (getService().hasCurrentUserUpdatePermission(usergroup) && getService().hasCurrentUserReadPermission(role)) { @@ -291,15 +289,16 @@ public class UserGroupResource extends AbstractSecurityResource { if (!getService().hasCurrentUserMetaPermissionsOfRoleDefinitionWithQualification(role, new Ownership(null, usergroup))) { response = Response.status(Status.UNAUTHORIZED) - .entity(String.format("Not permitted to add role %s to group", role.getName())) - .build(); + .entity(String.format("Not permitted to add role %s to group %s", + role.getName(), usergroup.getName())).build(); } else { getService().putRoleDefinitionToUserGroup(usergroup, role, roleForAll); response = Response.ok().build(); } } else { response = Response.status(Status.BAD_REQUEST) - .entity("Role was already added to the group.").build(); + .entity(String.format("Role %s was already added to group %s.", role.getName(), + usergroup.getName())).build(); } } else { response = Response.status(Status.UNAUTHORIZED).build(); From b94bd2fb07a91570414ffad345c9a3503a8a7e37 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Sat, 11 Jan 2020 14:22:30 +0100 Subject: [PATCH 06/19] fixed typo in comment --- .../src/com/sap/sse/security/impl/Activator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/impl/Activator.java b/java/com.sap.sse.security/src/com/sap/sse/security/impl/Activator.java index 0025865fb9a..29a09428183 100644 --- a/java/com.sap.sse.security/src/com/sap/sse/security/impl/Activator.java +++ b/java/com.sap.sse.security/src/com/sap/sse/security/impl/Activator.java @@ -148,7 +148,7 @@ public class Activator implements BundleActivator { } /** - * This method will clean the userStore and AccessControllStore, and reset the securityService. It will then + * This method will clean the userStore and AccessControlStore, and reset the securityService. It will then * reinitialize them in the same fashion an empty server will do. */ protected void clearState() throws InterruptedException, UserGroupManagementException, UserManagementException { From 110fd63b2ff94b9433530387c89a67f927015105 Mon Sep 17 00:00:00 2001 From: Usman Ali Date: Sun, 12 Jan 2020 00:54:07 +0500 Subject: [PATCH 07/19] setting up date format for new ORC certificate --- .../domain/orc/impl/ORCPublicCertificateDatabaseImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/orc/impl/ORCPublicCertificateDatabaseImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/orc/impl/ORCPublicCertificateDatabaseImpl.java index af8e896ea81..09592c247e7 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/orc/impl/ORCPublicCertificateDatabaseImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/orc/impl/ORCPublicCertificateDatabaseImpl.java @@ -330,7 +330,7 @@ public class ORCPublicCertificateDatabaseImpl implements ORCPublicCertificateDat builder = child.getTextContent(); break; case "dxtDate": - issueDate = new MillisecondsTimePoint(isoTimestampFormat.parse(child.getTextContent()+"+0000")); // assume UTC + issueDate = new MillisecondsTimePoint(isoTimestampFormat.parse(child.getTextContent().replaceAll("Z", "+0000"))); // assume UTC break; case "CertType": certType = Integer.valueOf(child.getTextContent().trim()); From 820c421a1f5adc6ca18ace152f1740ff39c1c5a7 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Sun, 12 Jan 2020 13:23:43 +0100 Subject: [PATCH 08/19] preparing for SailInsight3 mail type; added several TODOs for properly forwarding mail invitation type from server to client --- .../domain/common/BranchIOConstants.java | 7 ++++-- .../domain/common/MailInvitationType.java | 3 ++- ...2RaceLogTrackingInvitationMailBuilder.java | 2 -- ...3RaceLogTrackingInvitationMailBuilder.java | 24 +++++++++++++++++++ .../impl/RaceLogTrackingAdapterImpl.java | 3 +++ .../desktop/places/qrcode/QRCodePlace.java | 1 + .../adminconsole/RegattaDetailsComposite.java | 3 --- .../RegattaLogAddDeviceMappingDialog.java | 19 ++++++++++----- .../RegistrationLinkWithQRCodeDialog.java | 19 +++------------ .../local-test-environment.xml | 10 ++++---- .../selenium/api/test/RegattaApiTest.java | 6 ----- 11 files changed, 57 insertions(+), 40 deletions(-) create mode 100644 java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/BranchIO3RaceLogTrackingInvitationMailBuilder.java diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/BranchIOConstants.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/BranchIOConstants.java index 66a1686828b..c8bfdb36e06 100644 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/BranchIOConstants.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/BranchIOConstants.java @@ -1,14 +1,17 @@ package com.sap.sailing.domain.common; public class BranchIOConstants { - public static final String SAILINSIGHT_2_APP_BRANCHIO = "https://sailinsight20-app.sapsailing.com/invite"; public static final String SAILINSIGHT_APP_BRANCHIO = "https://sailinsight-app.sapsailing.com/invite"; + public static final String SAILINSIGHT_2_APP_BRANCHIO = "https://sailinsight20-app.sapsailing.com/invite"; + public static final String SAILINSIGHT_3_APP_BRANCHIO = "https://sailinsight30-app.sapsailing.com/invite"; public static final String SAILINSIGHT_APP_BRANCHIO_PATH = "checkinUrl"; public static final String BUOYPINGER_APP_BRANCHIO = "https://buoypinger-app.sapsailing.com/invite"; public static final String BUOYPINGER_APP_BRANCHIO_PATH = "checkinUrl"; public static final String OPEN_REGATTA_2_APP_BRANCHIO = "https://sailinsight20-app.sapsailing.com/publicInvite"; public static final String OPEN_REGATTA_2_APP_BRANCHIO_PATH = "checkinUrl"; + public static final String OPEN_REGATTA_3_APP_BRANCHIO = "https://sailinsight30-app.sapsailing.com/publicInvite"; + public static final String OPEN_REGATTA_3_APP_BRANCHIO_PATH = "checkinUrl"; private BranchIOConstants() { - }; + } } diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/MailInvitationType.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/MailInvitationType.java index 990c29d9ffb..555332fb6db 100644 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/MailInvitationType.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/MailInvitationType.java @@ -3,7 +3,8 @@ package com.sap.sailing.domain.common; public enum MailInvitationType { LEGACY, SailInsight1, - SailInsight2; + SailInsight2, + SailInsight3; public static final String SYSTEM_PROPERTY_NAME = "com.sap.sailing.domain.tracking.MailInvitationType"; } \ No newline at end of file diff --git a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/BranchIO2RaceLogTrackingInvitationMailBuilder.java b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/BranchIO2RaceLogTrackingInvitationMailBuilder.java index c102111dab9..a445a6aaa6d 100644 --- a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/BranchIO2RaceLogTrackingInvitationMailBuilder.java +++ b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/BranchIO2RaceLogTrackingInvitationMailBuilder.java @@ -5,7 +5,6 @@ import java.util.Locale; import com.sap.sailing.domain.common.BranchIOConstants; public class BranchIO2RaceLogTrackingInvitationMailBuilder extends BranchIORaceLogTrackingInvitationMailBuilder { - BranchIO2RaceLogTrackingInvitationMailBuilder(Locale locale) { super(locale); } @@ -20,5 +19,4 @@ public class BranchIO2RaceLogTrackingInvitationMailBuilder extends BranchIORaceL // FIXME the app should in the future at some point also support bouy pinging, replace this then return BranchIOConstants.BUOYPINGER_APP_BRANCHIO; } - } diff --git a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/BranchIO3RaceLogTrackingInvitationMailBuilder.java b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/BranchIO3RaceLogTrackingInvitationMailBuilder.java new file mode 100644 index 00000000000..135beb4b49d --- /dev/null +++ b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/BranchIO3RaceLogTrackingInvitationMailBuilder.java @@ -0,0 +1,24 @@ +package com.sap.sailing.domain.racelogtracking.impl; + +import java.util.Locale; + +import com.sap.sailing.domain.common.BranchIOConstants; + +public class BranchIO3RaceLogTrackingInvitationMailBuilder extends BranchIORaceLogTrackingInvitationMailBuilder { + + BranchIO3RaceLogTrackingInvitationMailBuilder(Locale locale) { + super(locale); + } + + @Override + protected String getSailInsightBranchIO() { + return BranchIOConstants.SAILINSIGHT_3_APP_BRANCHIO; + } + + @Override + protected String getBouyPingerBranchIO() { + // FIXME the app should in the future at some point also support bouy pinging, replace this then + return BranchIOConstants.BUOYPINGER_APP_BRANCHIO; + } + +} diff --git a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogTrackingAdapterImpl.java b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogTrackingAdapterImpl.java index 93af240a594..1d64ae14dc4 100755 --- a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogTrackingAdapterImpl.java +++ b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogTrackingAdapterImpl.java @@ -362,6 +362,9 @@ public class RaceLogTrackingAdapterImpl implements RaceLogTrackingAdapter { case SailInsight2: mail = new BranchIO2RaceLogTrackingInvitationMailBuilder(locale); break; + case SailInsight3: + mail = new BranchIO3RaceLogTrackingInvitationMailBuilder(locale); + break; default: throw new IllegalArgumentException("Unhandled mail type"); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/qrcode/QRCodePlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/qrcode/QRCodePlace.java index 742ec059b09..25cf582a8c1 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/qrcode/QRCodePlace.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/qrcode/QRCodePlace.java @@ -166,6 +166,7 @@ public class QRCodePlace extends AbstractBasePlace { } public String getPublicInviteBranchIOUrl() { + // TODO why is this specific to version 2 and not considering the default server setting for mailInvitationType? return BranchIOConstants.OPEN_REGATTA_2_APP_BRANCHIO + "?" + QRCodePlace.PARAM_REGATTA_NAME + "=" + encodeUrl(publicRegattaName) + "&" + QRCodePlace.PARAM_REGATTA_SECRET + "=" + encodeUrl(regattaRegistrationLinkSecret) + "&" + QRCodePlace.PARAM_SERVER + "=" diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaDetailsComposite.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaDetailsComposite.java index 87133a873eb..767bda207d4 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaDetailsComposite.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaDetailsComposite.java @@ -144,12 +144,9 @@ public class RegattaDetailsComposite extends Composite { Button button = new Button(stringMessages.registrationLinkShare(), new ClickHandler() { @Override public void onClick(ClickEvent event) { - RegistrationLinkWithQRCode registrationLinkWithQRCode = new RegistrationLinkWithQRCode(); registrationLinkWithQRCode.setSecret(regatta.registrationLinkSecret); - sailingService.getMailType(new AsyncCallback() { - @Override public void onFailure(Throwable caught) { logger.log(Level.SEVERE, "Could not determine MailInvitationType", caught); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaLogAddDeviceMappingDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaLogAddDeviceMappingDialog.java index 400eca6a6ce..5ffa0bba26a 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaLogAddDeviceMappingDialog.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaLogAddDeviceMappingDialog.java @@ -221,21 +221,28 @@ public class RegattaLogAddDeviceMappingDialog extends DataEntryDialogWithDateTim String url = DeviceMappingConstants.getDeviceMappingForRegattaLogUrl(baseUrlWithoutTrailingSlash, eventIdAsString, leaderboardName, mappedItemType, mappedItemId, regattaRegisterSecret, GwtUrlHelper.INSTANCE); - if (mailInvitationType == MailInvitationType.LEGACY) { + switch (mailInvitationType) { + case LEGACY: // URL is already legacy - } else if (mailInvitationType == MailInvitationType.SailInsight1) { + break; + case SailInsight1: url = BranchIOConstants.SAILINSIGHT_APP_BRANCHIO + "?" + BranchIOConstants.SAILINSIGHT_APP_BRANCHIO_PATH + "=" + GwtUrlHelper.INSTANCE.encodeQueryString(url); - } else if (mailInvitationType == MailInvitationType.SailInsight2) { + break; + case SailInsight2: url = BranchIOConstants.SAILINSIGHT_2_APP_BRANCHIO + "?" + BranchIOConstants.OPEN_REGATTA_2_APP_BRANCHIO_PATH + "=" + GwtUrlHelper.INSTANCE.encodeQueryString(url); - } - else { + break; + case SailInsight3: + url = BranchIOConstants.SAILINSIGHT_3_APP_BRANCHIO + "?" + + BranchIOConstants.OPEN_REGATTA_3_APP_BRANCHIO_PATH + "=" + + GwtUrlHelper.INSTANCE.encodeQueryString(url); + break; + default: throw new QRCodeURLCreationException("Unknown mail invitation type: " + mailInvitationType); } - return url; } }); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegistrationLinkWithQRCodeDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegistrationLinkWithQRCodeDialog.java index 4817fa55eb4..de2b6288d2a 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegistrationLinkWithQRCodeDialog.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegistrationLinkWithQRCodeDialog.java @@ -63,14 +63,10 @@ public class RegistrationLinkWithQRCodeDialog extends DataEntryDialog() { @Override public String getValue(EventDTO item) { @@ -98,10 +94,8 @@ public class RegistrationLinkWithQRCodeDialog extends DataEntryDialog parameters = new HashMap(); parameters.put("regatta_name", regattaName); parameters.put("secret", secret); parameters.put("server", baseUrl); parameters.put("event_id", eventIdAsString); + // TODO decide OPEN_REGATTA link variant based on invitationType String deeplinkUrl = BranchIO.generateLink(BranchIOConstants.OPEN_REGATTA_2_APP_BRANCHIO, parameters, URL::encodeQueryString); urlTextBox.setText(deeplinkUrl); - if (invitationType != MailInvitationType.SailInsight2) { + if (invitationType != MailInvitationType.SailInsight2 && + invitationType != MailInvitationType.SailInsight3) { // TODO it would be better to make it a property of an enum literal whether open regatta invitation is possible getStatusLabel().setText(stringMessages.warningSailInsightVersion()); getStatusLabel().setStyleName("errorLabel"); } sailingService.openRegattaRegistrationQrCode(deeplinkUrl, new AsyncCallback() { - @Override public void onFailure(Throwable caught) { GWT.log("Qrcode generation failed: ", caught); @@ -187,9 +176,7 @@ public class RegistrationLinkWithQRCodeDialog extends DataEntryDialog webdriver.chrome.driver - C:\apps\ChromeSeleniumDriver\chromedriver.exe + /usr/bin/chromedriver webdriver.gecko.driver - /path/to/geckodriver.exe + /usr/bin/geckodriver - - --> + +