mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-23 14:08:40 +00:00
Bug 4104: Added new exception handling in TaggingService.
This commit is contained in:
@@ -17,12 +17,13 @@ Export-Package: com.sap.sailing.domain.common,
|
||||
com.sap.sailing.domain.common.quadtree,
|
||||
com.sap.sailing.domain.common.quadtree.impl;x-friends:="com.sap.sailing.domain.test",
|
||||
com.sap.sailing.domain.common.racelog,
|
||||
com.sap.sailing.domain.common.sharding,
|
||||
com.sap.sailing.domain.common.racelog.tracking,
|
||||
com.sap.sailing.domain.common.racelog.utils,
|
||||
com.sap.sailing.domain.common.scalablevalue.impl,
|
||||
com.sap.sailing.domain.common.security,
|
||||
com.sap.sailing.domain.common.sensordata,
|
||||
com.sap.sailing.domain.common.sharding,
|
||||
com.sap.sailing.domain.common.tagging,
|
||||
com.sap.sailing.domain.common.trackfiles,
|
||||
com.sap.sailing.domain.common.tracking,
|
||||
com.sap.sailing.domain.common.tracking.impl,
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.sap.sailing.domain.common.tagging;
|
||||
|
||||
public class RaceLogNotFoundException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = -1935079125197798550L;
|
||||
|
||||
public RaceLogNotFoundException() {
|
||||
|
||||
}
|
||||
|
||||
public RaceLogNotFoundException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.sap.sailing.domain.common.tagging;
|
||||
|
||||
public class ServiceNotFoundException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 4354757061181985766L;
|
||||
|
||||
public ServiceNotFoundException() {
|
||||
|
||||
}
|
||||
|
||||
public ServiceNotFoundException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.sap.sailing.domain.common.tagging;
|
||||
|
||||
public class TagAlreadyExistsException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = -3908869597780348971L;
|
||||
|
||||
public TagAlreadyExistsException() {
|
||||
|
||||
}
|
||||
|
||||
public TagAlreadyExistsException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
+93
-22
@@ -63,6 +63,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authz.AuthorizationException;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.InvalidSyntaxException;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
@@ -289,6 +290,9 @@ import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
||||
import com.sap.sailing.domain.common.security.Permission;
|
||||
import com.sap.sailing.domain.common.security.Permission.Mode;
|
||||
import com.sap.sailing.domain.common.sharding.ShardingType;
|
||||
import com.sap.sailing.domain.common.tagging.RaceLogNotFoundException;
|
||||
import com.sap.sailing.domain.common.tagging.ServiceNotFoundException;
|
||||
import com.sap.sailing.domain.common.tagging.TagAlreadyExistsException;
|
||||
import com.sap.sailing.domain.common.tracking.BravoFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
@@ -6464,12 +6468,27 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet
|
||||
public SuccessInfo addTag(String leaderboardName, String raceColumnName, String fleetName, String tag,
|
||||
String comment, String imageURL, boolean visibleForPublic, TimePoint raceTimepoint) {
|
||||
SuccessInfo successInfo = new SuccessInfo(true, null, null, null);
|
||||
boolean successful = getService().getTaggingService().addTag(leaderboardName, raceColumnName, fleetName, tag,
|
||||
comment, imageURL, visibleForPublic, raceTimepoint);
|
||||
if (!successful) {
|
||||
String message = serverStringMessages.get(getClientLocale(),
|
||||
getService().getTaggingService().getLastErrorCode().getCode());
|
||||
successInfo = new SuccessInfo(false, message, null, null);
|
||||
try {
|
||||
getService().getTaggingService().addTag(leaderboardName, raceColumnName, fleetName, tag, comment, imageURL,
|
||||
visibleForPublic, raceTimepoint);
|
||||
} catch (AuthorizationException e) {
|
||||
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "missingAuthorization"),
|
||||
null, null);
|
||||
} catch (IllegalArgumentException e) {
|
||||
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "invalidParameters"), null,
|
||||
null);
|
||||
} catch (RaceLogNotFoundException e) {
|
||||
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "raceLogNotFound"), null,
|
||||
null);
|
||||
} catch (ServiceNotFoundException e) {
|
||||
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "securityServiceNotFound"),
|
||||
null, null);
|
||||
} catch (TagAlreadyExistsException e) {
|
||||
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "tagAlreadyExists"), null,
|
||||
null);
|
||||
} catch (Exception e) {
|
||||
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "unknownError"), null,
|
||||
null);
|
||||
}
|
||||
return successInfo;
|
||||
}
|
||||
@@ -6477,12 +6496,26 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet
|
||||
@Override
|
||||
public SuccessInfo removeTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tag) {
|
||||
SuccessInfo successInfo = new SuccessInfo(true, null, null, null);
|
||||
boolean successful = getService().getTaggingService().removeTag(leaderboardName, raceColumnName, fleetName,
|
||||
tag);
|
||||
if (!successful) {
|
||||
String message = serverStringMessages.get(getClientLocale(),
|
||||
getService().getTaggingService().getLastErrorCode().getCode());
|
||||
successInfo = new SuccessInfo(false, message, null, null);
|
||||
try {
|
||||
getService().getTaggingService().removeTag(leaderboardName, raceColumnName, fleetName, tag);
|
||||
} catch (AuthorizationException e) {
|
||||
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "missingAuthorization"),
|
||||
null, null);
|
||||
} catch (IllegalArgumentException e) {
|
||||
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "invalidParameters"), null,
|
||||
null);
|
||||
} catch (NotRevokableException e) {
|
||||
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "tagNotRevokable"), null,
|
||||
null);
|
||||
} catch (RaceLogNotFoundException e) {
|
||||
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "raceLogNotFound"), null,
|
||||
null);
|
||||
} catch (ServiceNotFoundException e) {
|
||||
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "securityServiceNotFound"),
|
||||
null, null);
|
||||
} catch (Exception e) {
|
||||
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "unknownError"), null,
|
||||
null);
|
||||
}
|
||||
return successInfo;
|
||||
}
|
||||
@@ -6491,12 +6524,30 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet
|
||||
public SuccessInfo updateTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tagToUpdate,
|
||||
String tag, String comment, String imageURL, boolean visibleForPublic) {
|
||||
SuccessInfo successInfo = new SuccessInfo(true, null, null, null);
|
||||
boolean successful = getService().getTaggingService().updateTag(leaderboardName, raceColumnName, fleetName,
|
||||
tagToUpdate, tag, comment, imageURL, visibleForPublic);
|
||||
if (!successful) {
|
||||
String message = serverStringMessages.get(getClientLocale(),
|
||||
getService().getTaggingService().getLastErrorCode().getCode());
|
||||
successInfo = new SuccessInfo(false, message, null, null);
|
||||
try {
|
||||
getService().getTaggingService().updateTag(leaderboardName, raceColumnName, fleetName, tagToUpdate, tag,
|
||||
comment, imageURL, visibleForPublic);
|
||||
} catch (AuthorizationException e) {
|
||||
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "missingAuthorization"),
|
||||
null, null);
|
||||
} catch (IllegalArgumentException e) {
|
||||
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "invalidParameters"), null,
|
||||
null);
|
||||
} catch (NotRevokableException e) {
|
||||
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "tagNotRevokable"), null,
|
||||
null);
|
||||
} catch (RaceLogNotFoundException e) {
|
||||
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "raceLogNotFound"), null,
|
||||
null);
|
||||
} catch (ServiceNotFoundException e) {
|
||||
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "securityServiceNotFound"),
|
||||
null, null);
|
||||
} catch (TagAlreadyExistsException e) {
|
||||
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "tagAlreadyExists"), null,
|
||||
null);
|
||||
} catch (Exception e) {
|
||||
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "unknownError"), null,
|
||||
null);
|
||||
}
|
||||
return successInfo;
|
||||
}
|
||||
@@ -6504,19 +6555,39 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet
|
||||
@Override
|
||||
public List<TagDTO> getAllTags(String leaderboardName, String raceColumnName, String fleetName) {
|
||||
List<TagDTO> result = new ArrayList<TagDTO>();
|
||||
result.addAll(getService().getTaggingService().getPrivateTags(leaderboardName, raceColumnName, fleetName));
|
||||
result.addAll(getService().getTaggingService().getPublicTags(leaderboardName, raceColumnName, fleetName));
|
||||
try {
|
||||
result.addAll(getService().getTaggingService().getPublicTags(leaderboardName, raceColumnName, fleetName));
|
||||
} catch (RaceLogNotFoundException e) {
|
||||
// do nothing and try to return as much tags as possible (private tags)
|
||||
}
|
||||
try {
|
||||
result.addAll(getService().getTaggingService().getPrivateTags(leaderboardName, raceColumnName, fleetName));
|
||||
} catch (ServiceNotFoundException e) {
|
||||
// do nothing and try to return as much tags as possible (public tags)
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TagDTO> getPublicTags(String leaderboardName, String raceColumnName, String fleetName) {
|
||||
return getService().getTaggingService().getPublicTags(leaderboardName, raceColumnName, fleetName);
|
||||
List<TagDTO> result = new ArrayList<TagDTO>();
|
||||
try {
|
||||
result.addAll(getService().getTaggingService().getPublicTags(leaderboardName, raceColumnName, fleetName));
|
||||
} catch (RaceLogNotFoundException e) {
|
||||
// do nothing as method will always return at least an empty list
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TagDTO> getPrivateTags(String leaderboardName, String raceColumnName, String fleetName) {
|
||||
return getService().getTaggingService().getPrivateTags(leaderboardName, raceColumnName, fleetName);
|
||||
List<TagDTO> result = new ArrayList<TagDTO>();
|
||||
try {
|
||||
result.addAll(getService().getTaggingService().getPrivateTags(leaderboardName, raceColumnName, fleetName));
|
||||
} catch (ServiceNotFoundException e) {
|
||||
// do nothing as method will always return at least an empty list
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+6
-9
@@ -4,12 +4,9 @@ slicingTimeRangeOutOfBounds=The TimeRange to slice is not part of the race
|
||||
slicingCouldNotObtainRace=Could not obtain sliced race
|
||||
slicingError=Error slicing race
|
||||
unknownError=Unknown error
|
||||
notLoggedIn=You are not logged in
|
||||
missingPermissions=Missing permissions
|
||||
securityServiceNotFound=Security service not found
|
||||
racelogNotFound=Racelog not found
|
||||
tagNotRevokable=This tag cannot be revoked
|
||||
tagAlreadyExists=Tag does already exist, duplicated tags are not allowed
|
||||
tagAlreadyRemoved=Tag cannot be removed twice!
|
||||
tagNotEmpty=Tag may not be empty
|
||||
timepointNotEmpty=Timepoint may not be empty
|
||||
missingAuthorization=You are not logged in or missing the required permission!
|
||||
securityServiceNotFound=Security service not found!
|
||||
raceLogNotFound=Racelog not found!
|
||||
tagNotRevokable=This tag cannot be revoked!
|
||||
tagAlreadyExists=Tag does already exist, duplicated tags are not allowed!
|
||||
invalidParameters=One of the given parameters does not have a valid value!
|
||||
|
||||
+7
-10
@@ -3,13 +3,10 @@ slicingRaceColumnAlreadyUsedThe=Der Rennspaltenname ist in der Regatta bereits v
|
||||
slicingTimeRangeOutOfBounds=Die angegebene Zeitspanne ist ausserhalb des Rennens
|
||||
slicingCouldNotObtainRace=Das geschnittene Rennen konnte nicht gefunden werden
|
||||
slicingError=Fehler beim Schneiden des Rennens
|
||||
unknownError=Unbekannter Fehler
|
||||
notLoggedIn=Du bist nicht eingeloggt
|
||||
missingPermissions=Fehlende Berechtigung
|
||||
securityServiceNotFound=Sicherheits-Service konnte nicht gefunden werden
|
||||
racelogNotFound=Racelog konnte nicht gefunden werden
|
||||
tagNotRevokable=Dieser Tag ist nicht umkehrbar
|
||||
tagAlreadyExists=Dieser Tag existiert bereits
|
||||
tagAlreadyRemoved=Dieser Tag wurde bereits geloescht
|
||||
tagNotEmpty=Der Tag darf nicht leer sein
|
||||
timepointNotEmpty=Der Zeitpunkt darf nicht leer sein
|
||||
unknownError=Unbekannter Fehler!
|
||||
missingAuthorization=Du bist nicht eingeloggt oder dir fehlen die benoetigten Informationen!
|
||||
securityServiceNotFound=Sicherheits-Service konnte nicht gefunden werden!
|
||||
raceLogNotFound=Racelog konnte nicht gefunden werden!
|
||||
tagNotRevokable=Dieser Tag ist nicht umkehrbar!
|
||||
tagAlreadyExists=Dieser Tag existiert bereits!
|
||||
invalidParameters=Einer der Parameter hat einen ungueltigen Wert!
|
||||
|
||||
+69
-53
@@ -21,10 +21,14 @@ import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import org.apache.shiro.authz.AuthorizationException;
|
||||
import org.json.simple.JSONArray;
|
||||
|
||||
import com.sap.sailing.domain.common.abstractlog.NotRevokableException;
|
||||
import com.sap.sailing.domain.common.dto.TagDTO;
|
||||
import com.sap.sailing.domain.common.racelog.RaceLogServletConstants;
|
||||
import com.sap.sailing.domain.common.tagging.RaceLogNotFoundException;
|
||||
import com.sap.sailing.domain.common.tagging.TagAlreadyExistsException;
|
||||
import com.sap.sailing.server.gateway.jaxrs.AbstractSailingServerResource;
|
||||
import com.sap.sailing.server.tagging.TagDTODeSerializer;
|
||||
import com.sap.sailing.server.tagging.TaggingService;
|
||||
@@ -68,32 +72,31 @@ public class TagsResource extends AbstractSailingServerResource {
|
||||
@PathParam(RaceLogServletConstants.PARAMS_RACE_COLUMN_NAME) String raceColumnName,
|
||||
@PathParam(RaceLogServletConstants.PARAMS_RACE_FLEET_NAME) String fleetName,
|
||||
@DefaultValue("both") @QueryParam("visibility") String visibility) {
|
||||
|
||||
boolean lookForPublic = visibility.equalsIgnoreCase("both") || visibility.equalsIgnoreCase("public");
|
||||
boolean lookForPrivate = visibility.equalsIgnoreCase("both") || visibility.equalsIgnoreCase("private");
|
||||
|
||||
Response response;
|
||||
TaggingService taggingService = getService().getTaggingService();
|
||||
if (taggingService != null) {
|
||||
List<TagDTO> tags = new ArrayList<TagDTO>();
|
||||
|
||||
final TaggingService taggingService = getService().getTaggingService();
|
||||
final List<TagDTO> tags = new ArrayList<TagDTO>();
|
||||
final boolean lookForPublic = visibility.equalsIgnoreCase("both") || visibility.equalsIgnoreCase("public");
|
||||
final boolean lookForPrivate = visibility.equalsIgnoreCase("both") || visibility.equalsIgnoreCase("private");
|
||||
try {
|
||||
if (lookForPublic) {
|
||||
Util.addAll(taggingService.getPublicTags(leaderboardName, raceColumnName, fleetName), tags);
|
||||
}
|
||||
|
||||
if (lookForPrivate) {
|
||||
Util.addAll(taggingService.getPrivateTags(leaderboardName, raceColumnName, fleetName), tags);
|
||||
try {
|
||||
Util.addAll(taggingService.getPrivateTags(leaderboardName, raceColumnName, fleetName), tags);
|
||||
} catch (AuthorizationException e) {
|
||||
// do nothing when user is not logged in
|
||||
}
|
||||
}
|
||||
|
||||
// remove revoked tags from result
|
||||
tags.removeIf(tag -> tag.getRevokedAt() != null && tag.getRevokedAt().asMillis() != 0);
|
||||
|
||||
JSONArray jsonTags = serializer.serialize(tags);
|
||||
response = Response.ok(jsonTags.toJSONString()).type(APPLICATION_JSON_UTF8).build();
|
||||
} else {
|
||||
response = Response.status(Status.INTERNAL_SERVER_ERROR).type(TEXT_PLAIN_UTF8)
|
||||
.entity("Tagging Service not found!").build();
|
||||
logger.warning("Tagging Service not found!");
|
||||
} catch (RaceLogNotFoundException e) {
|
||||
response = Response.status(Status.BAD_REQUEST).type(TEXT_PLAIN_UTF8).build();
|
||||
} catch (Exception e) {
|
||||
logger.warning("Could not load tags! " + e.getMessage());
|
||||
response = Response.status(Status.INTERNAL_SERVER_ERROR).type(TEXT_PLAIN_UTF8).build();
|
||||
}
|
||||
return response;
|
||||
}
|
||||
@@ -106,11 +109,12 @@ public class TagsResource extends AbstractSailingServerResource {
|
||||
* @param visible
|
||||
* default is <code>false</code>
|
||||
*
|
||||
* @return status 201 (created) if creation was successful, otherwise 400 (bad request)
|
||||
* @return status 201 (created) if creation was successful, otherwise 400 (bad request) 401 (unauthorized) or 500
|
||||
* (internal server error)
|
||||
* @see TaggingService#addTag(String, String, String, String, String, String, boolean, TimePoint)
|
||||
*/
|
||||
@POST
|
||||
@Produces({ APPLICATION_JSON_UTF8, TEXT_PLAIN_UTF8 })
|
||||
@Produces({ TEXT_PLAIN_UTF8 })
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
public Response createTag(@Context UriInfo uriInfo,
|
||||
@PathParam(RaceLogServletConstants.PARAMS_LEADERBOARD_NAME) String leaderboardName,
|
||||
@@ -119,15 +123,18 @@ public class TagsResource extends AbstractSailingServerResource {
|
||||
@FormParam("comment") String comment, @FormParam("image") String imageURL,
|
||||
@FormParam("public") boolean visibleForPublic, @FormParam("raceTimepoint") long raceTimepoint) {
|
||||
Response response;
|
||||
TaggingService taggingService = getService().getTaggingService();
|
||||
boolean successful = taggingService.addTag(leaderboardName, raceColumnName, fleetName, tag, comment, imageURL,
|
||||
visibleForPublic, new MillisecondsTimePoint(raceTimepoint));
|
||||
if (successful) {
|
||||
final TaggingService taggingService = getService().getTaggingService();
|
||||
try {
|
||||
taggingService.addTag(leaderboardName, raceColumnName, fleetName, tag, comment, imageURL, visibleForPublic,
|
||||
new MillisecondsTimePoint(raceTimepoint));
|
||||
response = Response.created(uriInfo.getRequestUri()).build();
|
||||
} else {
|
||||
String errorMessage = taggingService.getLastErrorCode().getMessage();
|
||||
response = Response.status(Status.BAD_REQUEST).type(TEXT_PLAIN_UTF8).entity(errorMessage).build();
|
||||
logger.warning("Could not save tag! " + errorMessage);
|
||||
} catch (IllegalArgumentException | RaceLogNotFoundException | TagAlreadyExistsException e) {
|
||||
response = Response.status(Status.BAD_REQUEST).type(TEXT_PLAIN_UTF8).build();
|
||||
} catch (AuthorizationException e) {
|
||||
response = Response.status(Status.UNAUTHORIZED).type(TEXT_PLAIN_UTF8).build();
|
||||
} catch (Exception e) {
|
||||
logger.warning("Could not save tag! " + e.getMessage());
|
||||
response = Response.status(Status.INTERNAL_SERVER_ERROR).type(TEXT_PLAIN_UTF8).build();
|
||||
}
|
||||
return response;
|
||||
}
|
||||
@@ -135,12 +142,13 @@ public class TagsResource extends AbstractSailingServerResource {
|
||||
/**
|
||||
* Removes tag given as json string.
|
||||
*
|
||||
* @return status 204 (no content) if deletion was successful, otherwise 400 (bad request)
|
||||
* @return status 204 (no content) if deletion was successful, otherwise 400 (bad request), 401 (unauthorized) or
|
||||
* 500 (internal server error)
|
||||
* @see TagDTO
|
||||
* @see TaggingService#removeTag(String, String, String, TagDTO)
|
||||
*/
|
||||
@DELETE
|
||||
@Produces({ APPLICATION_JSON_UTF8, TEXT_PLAIN_UTF8 })
|
||||
@Produces({ TEXT_PLAIN_UTF8 })
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
public Response deleteTag(@PathParam(RaceLogServletConstants.PARAMS_LEADERBOARD_NAME) String leaderboardName,
|
||||
@PathParam(RaceLogServletConstants.PARAMS_RACE_COLUMN_NAME) String raceColumnName,
|
||||
@@ -149,13 +157,16 @@ public class TagsResource extends AbstractSailingServerResource {
|
||||
Response response;
|
||||
TagDTO tagToRemove = serializer.deserializeTag(tagJson);
|
||||
TaggingService taggingService = getService().getTaggingService();
|
||||
boolean successful = taggingService.removeTag(leaderboardName, raceColumnName, fleetName, tagToRemove);
|
||||
if (successful) {
|
||||
try {
|
||||
taggingService.removeTag(leaderboardName, raceColumnName, fleetName, tagToRemove);
|
||||
response = Response.noContent().build();
|
||||
} else {
|
||||
String errorMessage = taggingService.getLastErrorCode().getMessage();
|
||||
response = Response.status(Status.BAD_REQUEST).type(TEXT_PLAIN_UTF8).entity(errorMessage).build();
|
||||
logger.warning("Could not remove tag! " + errorMessage);
|
||||
} catch (IllegalArgumentException | NotRevokableException | RaceLogNotFoundException e) {
|
||||
response = Response.status(Status.BAD_REQUEST).type(TEXT_PLAIN_UTF8).build();
|
||||
} catch (AuthorizationException e) {
|
||||
response = Response.status(Status.UNAUTHORIZED).type(TEXT_PLAIN_UTF8).build();
|
||||
} catch (Exception e) {
|
||||
logger.warning("Could not remove tag! " + e.getMessage());
|
||||
response = Response.status(Status.INTERNAL_SERVER_ERROR).type(TEXT_PLAIN_UTF8).build();
|
||||
}
|
||||
return response;
|
||||
}
|
||||
@@ -168,12 +179,13 @@ public class TagsResource extends AbstractSailingServerResource {
|
||||
* @param tag
|
||||
* may not be empty
|
||||
*
|
||||
* @return status 204 (no content) if update was successful, otherwise 400 (bad request)
|
||||
* @return status 204 (no content) if update was successful, otherwise 400 (bad request), 401 (unauthorized) or 500
|
||||
* (internal server error)
|
||||
* @see TagDTO
|
||||
* @see TaggingService#updateTag(String, String, String, TagDTO, String, String, String, boolean)
|
||||
*/
|
||||
@PUT
|
||||
@Produces({ APPLICATION_JSON_UTF8, TEXT_PLAIN_UTF8 })
|
||||
@Produces({ TEXT_PLAIN_UTF8 })
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
public Response updateTag(@PathParam(RaceLogServletConstants.PARAMS_LEADERBOARD_NAME) String leaderboardName,
|
||||
@PathParam(RaceLogServletConstants.PARAMS_RACE_COLUMN_NAME) String raceColumnName,
|
||||
@@ -182,28 +194,32 @@ public class TagsResource extends AbstractSailingServerResource {
|
||||
@FormParam("comment") String commentParam, @FormParam("image") String imageURLParam,
|
||||
@FormParam("public") String visibleForPublicParam) {
|
||||
Response response;
|
||||
boolean successful = true;
|
||||
TagDTO tagToUpdate = serializer.deserializeTag(tagJson);
|
||||
TaggingService taggingService = getService().getTaggingService();
|
||||
final TagDTO tagToUpdate = serializer.deserializeTag(tagJson);
|
||||
final TaggingService taggingService = getService().getTaggingService();
|
||||
|
||||
// only call update method when any of the parameters needs to be changed
|
||||
if (tagParam != null || commentParam != null || imageURLParam != null || visibleForPublicParam != null) {
|
||||
// keep old values when no new values are provided
|
||||
String tag = tagParam == null ? tagToUpdate.getTag() : tagParam;
|
||||
String comment = commentParam == null ? tagToUpdate.getComment() : commentParam;
|
||||
String imageURL = imageURLParam == null ? tagToUpdate.getImageURL() : imageURLParam;
|
||||
boolean visibleForPublic = visibleForPublicParam == null ? tagToUpdate.isVisibleForPublic()
|
||||
: visibleForPublicParam.equalsIgnoreCase("true") ? true : false;
|
||||
|
||||
successful = taggingService.updateTag(leaderboardName, raceColumnName, fleetName, tagToUpdate, tag, comment,
|
||||
imageURL, visibleForPublic);
|
||||
}
|
||||
if (successful) {
|
||||
response = Response.noContent().build();
|
||||
String tag = (tagParam == null ? tagToUpdate.getTag() : tagParam);
|
||||
String comment = (commentParam == null ? tagToUpdate.getComment() : commentParam);
|
||||
String imageURL = (imageURLParam == null ? tagToUpdate.getImageURL() : imageURLParam);
|
||||
boolean visibleForPublic = (visibleForPublicParam == null ? tagToUpdate.isVisibleForPublic()
|
||||
: visibleForPublicParam.equalsIgnoreCase("true") ? true : false);
|
||||
try {
|
||||
taggingService.updateTag(leaderboardName, raceColumnName, fleetName, tagToUpdate, tag, comment,
|
||||
imageURL, visibleForPublic);
|
||||
response = Response.noContent().build();
|
||||
} catch (IllegalArgumentException | NotRevokableException | RaceLogNotFoundException
|
||||
| TagAlreadyExistsException e) {
|
||||
response = Response.status(Status.BAD_REQUEST).type(TEXT_PLAIN_UTF8).build();
|
||||
} catch (AuthorizationException e) {
|
||||
response = Response.status(Status.UNAUTHORIZED).type(TEXT_PLAIN_UTF8).build();
|
||||
} catch (Exception e) {
|
||||
logger.warning("Could not update tag! " + e.getMessage());
|
||||
response = Response.status(Status.INTERNAL_SERVER_ERROR).type(TEXT_PLAIN_UTF8).build();
|
||||
}
|
||||
} else {
|
||||
String errorMessage = taggingService.getLastErrorCode().getMessage();
|
||||
response = Response.status(Status.BAD_REQUEST).type(TEXT_PLAIN_UTF8).entity(errorMessage).build();
|
||||
logger.warning("Could not update tag! " + errorMessage);
|
||||
response = Response.noContent().build();
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
+61
-53
@@ -2,13 +2,18 @@ package com.sap.sailing.server.tagging;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.shiro.authz.AuthorizationException;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.abstractlog.NotRevokableException;
|
||||
import com.sap.sailing.domain.common.dto.TagDTO;
|
||||
import com.sap.sailing.domain.common.tagging.RaceLogNotFoundException;
|
||||
import com.sap.sailing.domain.common.tagging.ServiceNotFoundException;
|
||||
import com.sap.sailing.domain.common.tagging.TagAlreadyExistsException;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
// TODO: Replace error handling by throwing exceptions, see "topleveltranslations.json"
|
||||
// TODO: CommentTooLong
|
||||
// TODO: see "translation_v2.json" for new translation files
|
||||
// TODO: use document settings id for tags/tag-buttons/... as race identifier
|
||||
/**
|
||||
* This service is used to perform all CRUD operations on {@link TagDTO tags} and is used by the
|
||||
@@ -19,38 +24,6 @@ import com.sap.sse.common.TimePoint;
|
||||
*/
|
||||
public interface TaggingService {
|
||||
|
||||
/**
|
||||
* Enum used to identify issues.
|
||||
*/
|
||||
public enum ErrorCode {
|
||||
UNKNOWN_ERROR("unknownError", "Unknown error"),
|
||||
NOT_LOGGED_IN("notLoggedIn", "You are not logged in"),
|
||||
MISSING_PERMISSIONS("missingPermissions", "Missing permissions"),
|
||||
SECURITY_SERIVCE_NOT_FOUND("securityServiceNotFound", "Security service not found"),
|
||||
RACELOG_NOT_FOUND("racelogNotFound", "Racelog not found"),
|
||||
TAG_NOT_REVOKABLE("tagNotRevokable", "This tag cannot be revoked"),
|
||||
TAG_ALREADY_EXISTS("tagAlreadyExists", "Tag does already exist, duplicated tags are not allowed"),
|
||||
TAG_ALREADY_REMOVED("tagAlreadyRemoved", "Tag cannot be removed twice!"),
|
||||
TAG_NOT_EMPTY("tagNotEmpty", "Tag may not be empty"),
|
||||
TIMEPOINT_NOT_EMPTY("timepointNotEmpty", "Timepoint may not be empty");
|
||||
|
||||
private final String code;
|
||||
private final String message;
|
||||
|
||||
ErrorCode(String code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves given properties as tag for given race. Checks if all parameters are valid and all required parameters are
|
||||
* set.
|
||||
@@ -73,10 +46,21 @@ public interface TaggingService {
|
||||
* tag will be saved in {@link com.sap.sse.security.UserStore UserStore} (only visible for the creator)
|
||||
* @param raceTimepoint
|
||||
* timepoint in race when user created tag, must <b>NOT</b> be <code>null</code>
|
||||
* @return <code>true</code> if tag was saved successfully, otherwise <code>false</code>
|
||||
* @throws AuthorizationException
|
||||
* thrown if user is not logged in or is missing permissions
|
||||
* @throws IllegalArgumentException
|
||||
* thrown if one of the required parameters has an invalid value
|
||||
* @throws RaceLogNotFoundException
|
||||
* thrown if racelog cannot be found (e.g. when <code>leaderboardName</code>,
|
||||
* <code>raceColumnName</code> or <code>fleetName</code> are missing)
|
||||
* @throws ServiceNotFoundException
|
||||
* thrown if security service cannot be found
|
||||
* @throws TagAlreadyExistsException
|
||||
* thrown if tag already exists
|
||||
*/
|
||||
boolean addTag(String leaderboardName, String raceColumnName, String fleetName, String tag, String comment,
|
||||
String imageURL, boolean visibleForPublic, TimePoint raceTimepoint);
|
||||
void addTag(String leaderboardName, String raceColumnName, String fleetName, String tag, String comment,
|
||||
String imageURL, boolean visibleForPublic, TimePoint raceTimepoint) throws AuthorizationException,
|
||||
IllegalArgumentException, RaceLogNotFoundException, ServiceNotFoundException, TagAlreadyExistsException;
|
||||
|
||||
/**
|
||||
* Removes public {@link TagDTO tag} from {@link com.sap.sailing.domain.abstractlog.race.RaceLog RaceLog} and
|
||||
@@ -90,9 +74,21 @@ public interface TaggingService {
|
||||
* required to identify {@link RaceLog}, must <b>NOT</b> be <code>null</code>
|
||||
* @param tag
|
||||
* tag to remove
|
||||
* @return <code>true</code> if tag was removed successfully, otherwise <code>false</code>
|
||||
* @throws AuthorizationException
|
||||
* thrown if user is not logged in or is missing permissions
|
||||
* @throws IllegalArgumentException
|
||||
* thrown if one of the required parameters has an invalid value
|
||||
* @throws NotRevokableException
|
||||
* thrown if tag is public and not revokable from racelog
|
||||
* @throws RaceLogNotFoundException
|
||||
* thrown if racelog cannot be found (e.g. when <code>leaderboardName</code>,
|
||||
* <code>raceColumnName</code> or <code>fleetName</code> are missing)
|
||||
* @throws ServiceNotFoundException
|
||||
* thrown if security service cannot be found
|
||||
*/
|
||||
boolean removeTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tag);
|
||||
void removeTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tag)
|
||||
throws AuthorizationException, IllegalArgumentException, NotRevokableException, RaceLogNotFoundException,
|
||||
ServiceNotFoundException;
|
||||
|
||||
/**
|
||||
* Updates given <code>tagToUpdate</code> with the given parameters <code>tag</code>, <code>comment</code>,
|
||||
@@ -114,10 +110,24 @@ public interface TaggingService {
|
||||
* new iamge URL
|
||||
* @param visibleForPublic
|
||||
* new privacy status
|
||||
* @return <code>true</code> if tag was updated successfully, otherwise <code>false</code>
|
||||
* @throws AuthorizationException
|
||||
* thrown if user is not logged in or is missing permissions
|
||||
* @throws IllegalArgumentException
|
||||
* thrown if one of the required parameters has an invalid value
|
||||
* @throws NotRevokableException
|
||||
* thrown if tag is public and not revokable from racelog
|
||||
* @throws TagAlreadyExistsException
|
||||
* thrown if tag already exists
|
||||
* @throws RaceLogNotFoundException
|
||||
* thrown if racelog cannot be found (e.g. when <code>leaderboardName</code>,
|
||||
* <code>raceColumnName</code> or <code>fleetName</code> are missing)
|
||||
* @throws ServiceNotFoundException
|
||||
* thrown if security service cannot be found
|
||||
*/
|
||||
boolean updateTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tagToUpdate, String tag,
|
||||
String comment, String imageURL, boolean visibleForPublic);
|
||||
void updateTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tagToUpdate, String tag,
|
||||
String comment, String imageURL, boolean visibleForPublic)
|
||||
throws AuthorizationException, IllegalArgumentException, NotRevokableException, RaceLogNotFoundException,
|
||||
ServiceNotFoundException, TagAlreadyExistsException;
|
||||
|
||||
/**
|
||||
* Returns all public tags for the specified race.
|
||||
@@ -130,8 +140,12 @@ public interface TaggingService {
|
||||
* required to identify {@link RaceLog}, must <b>NOT</b> be <code>null</code>
|
||||
* @return list of {@link TagDTO tags}, empty list in case an error occurs or there are no tags available but
|
||||
* <b>never null</b>!
|
||||
* @throws RaceLogNotFoundException
|
||||
* thrown if racelog cannot be found (e.g. when <code>leaderboardName</code>,
|
||||
* <code>raceColumnName</code> or <code>fleetName</code> are missing)
|
||||
*/
|
||||
List<TagDTO> getPublicTags(String leaderboardName, String raceColumnName, String fleetName);
|
||||
List<TagDTO> getPublicTags(String leaderboardName, String raceColumnName, String fleetName)
|
||||
throws RaceLogNotFoundException;
|
||||
|
||||
/**
|
||||
* Returns all public tags since the given <code>searchSinceTimePoint</code> for the specified race.
|
||||
@@ -156,15 +170,9 @@ public interface TaggingService {
|
||||
* required to identify {@link RaceLog}, must <b>NOT</b> be <code>null</code>
|
||||
* @return list of {@link TagDTO tags}, empty list in case an error occurs or there are no tags available but
|
||||
* <b>never null</b>!
|
||||
* @throws ServiceNotFoundException
|
||||
* thrown if security service cannot be found
|
||||
*/
|
||||
List<TagDTO> getPrivateTags(String leaderboardName, String raceColumnName, String fleetName);
|
||||
|
||||
/**
|
||||
* Returns the last error code of the current user. Needs to be converted into error message to display this message
|
||||
* to the user.
|
||||
*
|
||||
* @return last {@link ErrorCode error code} which occured if error is known, otherwise
|
||||
* {@link ErrorCode#UNKNOWN_ERROR unknown error}
|
||||
*/
|
||||
ErrorCode getLastErrorCode();
|
||||
List<TagDTO> getPrivateTags(String leaderboardName, String raceColumnName, String fleetName)
|
||||
throws ServiceNotFoundException;
|
||||
}
|
||||
|
||||
+155
-220
@@ -1,9 +1,7 @@
|
||||
package com.sap.sailing.server.tagging;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authz.AuthorizationException;
|
||||
@@ -19,6 +17,9 @@ import com.sap.sailing.domain.common.abstractlog.NotRevokableException;
|
||||
import com.sap.sailing.domain.common.dto.TagDTO;
|
||||
import com.sap.sailing.domain.common.security.Permission;
|
||||
import com.sap.sailing.domain.common.security.Permission.Mode;
|
||||
import com.sap.sailing.domain.common.tagging.RaceLogNotFoundException;
|
||||
import com.sap.sailing.domain.common.tagging.ServiceNotFoundException;
|
||||
import com.sap.sailing.domain.common.tagging.TagAlreadyExistsException;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
@@ -30,255 +31,203 @@ public class TaggingServiceImpl implements TaggingService {
|
||||
|
||||
private final RacingEventService racingService;
|
||||
private final TagDTODeSerializer serializer;
|
||||
private final Map<Subject, ErrorCode> lastErrorCodes;
|
||||
|
||||
public TaggingServiceImpl(RacingEventService racingService) {
|
||||
this.racingService = racingService;
|
||||
serializer = new TagDTODeSerializer();
|
||||
lastErrorCodes = new HashMap<Subject, ErrorCode>();
|
||||
}
|
||||
|
||||
private void setLastErrorCode(ErrorCode errorCode) {
|
||||
lastErrorCodes.put(SecurityUtils.getSubject(), errorCode);
|
||||
}
|
||||
|
||||
private String getCurrentUsername() {
|
||||
String result = null;
|
||||
/**
|
||||
* Returns current username.
|
||||
*
|
||||
* @throws AuthorizationException
|
||||
* @return username of current user
|
||||
*/
|
||||
private String getCurrentUsername() throws AuthorizationException {
|
||||
Object principal = SecurityUtils.getSubject().getPrincipal();
|
||||
if (principal != null) {
|
||||
result = principal.toString();
|
||||
} else {
|
||||
setLastErrorCode(ErrorCode.NOT_LOGGED_IN);
|
||||
if (principal == null) {
|
||||
throw new AuthorizationException();
|
||||
}
|
||||
return result;
|
||||
return principal.toString();
|
||||
}
|
||||
|
||||
private SecurityService getSecurityService() {
|
||||
/**
|
||||
* Returns instance of {@link SecurityService} to access the user store.
|
||||
*
|
||||
* @return instance of {@link SecurityService}
|
||||
* @throws ServiceNotFoundException
|
||||
*/
|
||||
private SecurityService getSecurityService() throws ServiceNotFoundException {
|
||||
SecurityService securityService = Activator.getSecurityService();
|
||||
if (securityService == null) {
|
||||
setLastErrorCode(ErrorCode.SECURITY_SERIVCE_NOT_FOUND);
|
||||
throw new ServiceNotFoundException("Security service not found!");
|
||||
}
|
||||
return securityService;
|
||||
}
|
||||
|
||||
private boolean addPublicTag(String leaderboardName, String raceColumnName, String fleetName, String tag,
|
||||
String comment, String imageURL, TimePoint raceTimepoint) {
|
||||
boolean successful = true;
|
||||
try {
|
||||
// TODO: As soon as permission-vertical branch got merged into master, apply
|
||||
// new permission system at this permission check (see bug 4104, comment 9)
|
||||
// functionality: Check if user has the permission to add RaceLogEvents to RaceLog.
|
||||
SecurityUtils.getSubject().checkPermission(
|
||||
Permission.LEADERBOARD.getStringPermissionForObjects(Mode.UPDATE, leaderboardName));
|
||||
RaceLog raceLog = racingService.getRaceLog(leaderboardName, raceColumnName, fleetName);
|
||||
if (raceLog == null) {
|
||||
setLastErrorCode(ErrorCode.RACELOG_NOT_FOUND);
|
||||
successful = false;
|
||||
} else {
|
||||
// check if tag already exists
|
||||
boolean alreadyExists = false;
|
||||
List<TagDTO> publicTags = getPublicTags(leaderboardName, raceColumnName, fleetName);
|
||||
for (TagDTO publicTag : publicTags) {
|
||||
// ignore revoked tags as TagDTO.equals() does ignore revokedAt timepoint
|
||||
if (publicTag.getRevokedAt() == null && publicTag.equals(tag, comment, imageURL,
|
||||
true, racingService.getServerAuthor().getName(), raceTimepoint)) {
|
||||
alreadyExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (alreadyExists) {
|
||||
setLastErrorCode(ErrorCode.TAG_ALREADY_EXISTS);
|
||||
successful = false;
|
||||
} else {
|
||||
raceLog.add(new RaceLogTagEventImpl(tag, comment, imageURL, raceTimepoint,
|
||||
racingService.getServerAuthor(), raceLog.getCurrentPassId()));
|
||||
}
|
||||
}
|
||||
} catch (AuthorizationException e) {
|
||||
setLastErrorCode(ErrorCode.MISSING_PERMISSIONS);
|
||||
successful = false;
|
||||
}
|
||||
return successful;
|
||||
}
|
||||
|
||||
private boolean addPrivateTag(String leaderboardName, String raceColumnName, String fleetName, String tag,
|
||||
String comment, String imageURL, TimePoint raceTimepoint) {
|
||||
boolean successful = true;
|
||||
SecurityService securityService = Activator.getSecurityService();
|
||||
if (securityService == null) {
|
||||
setLastErrorCode(ErrorCode.SECURITY_SERIVCE_NOT_FOUND);
|
||||
successful = false;
|
||||
} else {
|
||||
Subject subject = SecurityUtils.getSubject();
|
||||
if (subject.getPrincipal() != null) {
|
||||
String username = subject.getPrincipal().toString();
|
||||
TagDTODeSerializer serializer = new TagDTODeSerializer();
|
||||
String key = serializer.generateUniqueKey(leaderboardName, raceColumnName, fleetName);
|
||||
String privateTagsJson = securityService.getPreference(username, key);
|
||||
List<TagDTO> privateTags = serializer.deserializeTags(privateTagsJson);
|
||||
TagDTO tagToAdd = new TagDTO(tag, comment, imageURL, false, username, raceTimepoint,
|
||||
MillisecondsTimePoint.now());
|
||||
if (privateTags.contains(tagToAdd)) {
|
||||
setLastErrorCode(ErrorCode.TAG_ALREADY_EXISTS);
|
||||
successful = false;
|
||||
} else {
|
||||
privateTags.add(tagToAdd);
|
||||
securityService.setPreference(username, key, serializer.serializeTags(privateTags));
|
||||
}
|
||||
} else {
|
||||
setLastErrorCode(ErrorCode.NOT_LOGGED_IN);
|
||||
successful = false;
|
||||
}
|
||||
}
|
||||
return successful;
|
||||
}
|
||||
|
||||
private boolean removePublicTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tag) {
|
||||
boolean successful = true;
|
||||
private void addPublicTag(String leaderboardName, String raceColumnName, String fleetName, String tag,
|
||||
String comment, String imageURL, TimePoint raceTimepoint)
|
||||
throws RaceLogNotFoundException, TagAlreadyExistsException {
|
||||
// TODO: As soon as permission-vertical branch got merged into master, apply
|
||||
// new permission system at this permission check (see bug 4104, comment 9)
|
||||
// functionality: Check if user has the permission to add RaceLogEvents to RaceLog.
|
||||
SecurityUtils.getSubject()
|
||||
.checkPermission(Permission.LEADERBOARD.getStringPermissionForObjects(Mode.UPDATE, leaderboardName));
|
||||
RaceLog raceLog = racingService.getRaceLog(leaderboardName, raceColumnName, fleetName);
|
||||
if (raceLog == null) {
|
||||
setLastErrorCode(ErrorCode.RACELOG_NOT_FOUND);
|
||||
successful = false;
|
||||
} else {
|
||||
ReadonlyRaceState raceState = ReadonlyRaceStateImpl.getOrCreate(racingService, raceLog);
|
||||
Iterable<RaceLogTagEvent> foundTagEvents = raceState.getTagEvents();
|
||||
for (RaceLogTagEvent tagEvent : foundTagEvents) {
|
||||
if (tagEvent.getRevokedAt() != null) {
|
||||
continue;
|
||||
} else if (tagEvent.getTag().equals(tag.getTag()) && tagEvent.getComment().equals(tag.getComment())
|
||||
&& tagEvent.getImageURL().equals(tag.getImageURL())
|
||||
&& tagEvent.getUsername().equals(tag.getUsername())
|
||||
&& tagEvent.getLogicalTimePoint().equals(tag.getRaceTimepoint())) {
|
||||
|
||||
try {
|
||||
// TODO: As soon as permission-vertical branch got merged into master, apply
|
||||
// new permission system at this permission check (see bug 4104, comment 9)
|
||||
// functionality: Check if user has the permission to delete tag from RaceLog (same user or
|
||||
// admin).
|
||||
Subject subject = SecurityUtils.getSubject();
|
||||
subject.checkPermission(
|
||||
Permission.LEADERBOARD.getStringPermissionForObjects(Mode.UPDATE, leaderboardName));
|
||||
if ((subject.getPrincipal() != null && subject.getPrincipal().equals(tag.getUsername()))
|
||||
|| subject.hasRole("admin")) {
|
||||
raceLog.revokeEvent(tagEvent.getAuthor(), tagEvent, "Revoked");
|
||||
} else {
|
||||
setLastErrorCode(ErrorCode.MISSING_PERMISSIONS);
|
||||
successful = false;
|
||||
}
|
||||
} catch (AuthorizationException e) {
|
||||
setLastErrorCode(ErrorCode.MISSING_PERMISSIONS);
|
||||
successful = false;
|
||||
} catch (NotRevokableException e) {
|
||||
setLastErrorCode(ErrorCode.TAG_NOT_REVOKABLE);
|
||||
successful = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
throw new RaceLogNotFoundException();
|
||||
}
|
||||
// check if tag already exists
|
||||
List<TagDTO> publicTags = getPublicTags(leaderboardName, raceColumnName, fleetName);
|
||||
for (TagDTO publicTag : publicTags) {
|
||||
// ignore revoked tags as TagDTO.equals() does ignore revokedAt timepoint
|
||||
if (publicTag.getRevokedAt() == null && publicTag.equals(tag, comment, imageURL, true,
|
||||
racingService.getServerAuthor().getName(), raceTimepoint)) {
|
||||
throw new TagAlreadyExistsException();
|
||||
}
|
||||
}
|
||||
return successful;
|
||||
raceLog.add(new RaceLogTagEventImpl(tag, comment, imageURL, raceTimepoint, racingService.getServerAuthor(),
|
||||
raceLog.getCurrentPassId()));
|
||||
}
|
||||
|
||||
private boolean removePrivateTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tag) {
|
||||
boolean successful = true;
|
||||
String username = getCurrentUsername();
|
||||
if (username == null) {
|
||||
setLastErrorCode(ErrorCode.NOT_LOGGED_IN);
|
||||
successful = false;
|
||||
} else {
|
||||
List<TagDTO> privateTags = getPrivateTags(leaderboardName, raceColumnName, fleetName);
|
||||
privateTags.remove(tag);
|
||||
SecurityService securityService = getSecurityService();
|
||||
String key = serializer.generateUniqueKey(leaderboardName, raceColumnName, fleetName);
|
||||
// error code will be set during collection of required data
|
||||
if (username != null && securityService != null && key != null) {
|
||||
if (privateTags.isEmpty()) {
|
||||
securityService.unsetPreference(username, key);
|
||||
} else {
|
||||
securityService.setPreference(username, key, serializer.serializeTags(privateTags));
|
||||
private void addPrivateTag(String leaderboardName, String raceColumnName, String fleetName, String tag,
|
||||
String comment, String imageURL, TimePoint raceTimepoint)
|
||||
throws AuthorizationException, ServiceNotFoundException, TagAlreadyExistsException {
|
||||
SecurityService securityService = Activator.getSecurityService();
|
||||
if (securityService == null) {
|
||||
throw new ServiceNotFoundException("Security service not found!");
|
||||
}
|
||||
Subject subject = SecurityUtils.getSubject();
|
||||
if (subject.getPrincipal() == null) {
|
||||
throw new AuthorizationException();
|
||||
}
|
||||
String username = subject.getPrincipal().toString();
|
||||
TagDTODeSerializer serializer = new TagDTODeSerializer();
|
||||
String key = serializer.generateUniqueKey(leaderboardName, raceColumnName, fleetName);
|
||||
String privateTagsJson = securityService.getPreference(username, key);
|
||||
List<TagDTO> privateTags = serializer.deserializeTags(privateTagsJson);
|
||||
TagDTO tagToAdd = new TagDTO(tag, comment, imageURL, false, username, raceTimepoint,
|
||||
MillisecondsTimePoint.now());
|
||||
if (privateTags.contains(tagToAdd)) {
|
||||
throw new TagAlreadyExistsException();
|
||||
}
|
||||
privateTags.add(tagToAdd);
|
||||
securityService.setPreference(username, key, serializer.serializeTags(privateTags));
|
||||
}
|
||||
|
||||
private void removePublicTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tag)
|
||||
throws AuthorizationException, NotRevokableException, RaceLogNotFoundException {
|
||||
RaceLog raceLog = racingService.getRaceLog(leaderboardName, raceColumnName, fleetName);
|
||||
if (raceLog == null) {
|
||||
throw new RaceLogNotFoundException();
|
||||
}
|
||||
ReadonlyRaceState raceState = ReadonlyRaceStateImpl.getOrCreate(racingService, raceLog);
|
||||
Iterable<RaceLogTagEvent> foundTagEvents = raceState.getTagEvents();
|
||||
for (RaceLogTagEvent tagEvent : foundTagEvents) {
|
||||
if (tagEvent.getRevokedAt() != null) {
|
||||
continue;
|
||||
} else if (tagEvent.getTag().equals(tag.getTag()) && tagEvent.getComment().equals(tag.getComment())
|
||||
&& tagEvent.getImageURL().equals(tag.getImageURL())
|
||||
&& tagEvent.getUsername().equals(tag.getUsername())
|
||||
&& tagEvent.getLogicalTimePoint().equals(tag.getRaceTimepoint())) {
|
||||
|
||||
// TODO: As soon as permission-vertical branch got merged into master, apply
|
||||
// new permission system at this permission check (see bug 4104, comment 9)
|
||||
// functionality: Check if user has the permission to delete tag from RaceLog (same user or
|
||||
// admin).
|
||||
Subject subject = SecurityUtils.getSubject();
|
||||
subject.checkPermission(
|
||||
Permission.LEADERBOARD.getStringPermissionForObjects(Mode.UPDATE, leaderboardName));
|
||||
if (!(subject.getPrincipal() != null && subject.getPrincipal().equals(tag.getUsername()))
|
||||
|| subject.hasRole("admin")) {
|
||||
throw new AuthorizationException();
|
||||
}
|
||||
raceLog.revokeEvent(tagEvent.getAuthor(), tagEvent, "Revoked");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void removePrivateTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tag)
|
||||
throws AuthorizationException, ServiceNotFoundException {
|
||||
String username = getCurrentUsername();
|
||||
List<TagDTO> privateTags = getPrivateTags(leaderboardName, raceColumnName, fleetName);
|
||||
privateTags.remove(tag);
|
||||
SecurityService securityService = getSecurityService();
|
||||
String key = serializer.generateUniqueKey(leaderboardName, raceColumnName, fleetName);
|
||||
// error code will be set during collection of required data
|
||||
if (username != null && securityService != null && key != null) {
|
||||
if (privateTags.isEmpty()) {
|
||||
securityService.unsetPreference(username, key);
|
||||
} else {
|
||||
securityService.setPreference(username, key, serializer.serializeTags(privateTags));
|
||||
}
|
||||
}
|
||||
return successful;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addTag(String leaderboardName, String raceColumnName, String fleetName, String tag, String comment,
|
||||
String imageURL, boolean visibleForPublic, TimePoint raceTimepoint) {
|
||||
boolean successful;
|
||||
public void addTag(String leaderboardName, String raceColumnName, String fleetName, String tag, String comment,
|
||||
String imageURL, boolean visibleForPublic, TimePoint raceTimepoint) throws AuthorizationException,
|
||||
IllegalArgumentException, RaceLogNotFoundException, ServiceNotFoundException, TagAlreadyExistsException {
|
||||
// prefill optional parameters
|
||||
comment = comment == null ? "" : comment;
|
||||
imageURL = imageURL == null ? "" : imageURL;
|
||||
|
||||
// check all parameters for validity
|
||||
if (tag == null || tag.isEmpty()) {
|
||||
setLastErrorCode(ErrorCode.TAG_NOT_EMPTY);
|
||||
successful = false;
|
||||
} else if (raceTimepoint == null || raceTimepoint.asMillis() == 0) {
|
||||
throw new IllegalArgumentException("Tag may not be empty!");
|
||||
}
|
||||
if (raceTimepoint == null || raceTimepoint.asMillis() == 0) {
|
||||
// TODO: Check if timepoint is near start/end of race (+/- x%)
|
||||
setLastErrorCode(ErrorCode.TIMEPOINT_NOT_EMPTY);
|
||||
successful = false;
|
||||
throw new IllegalArgumentException("Timepoint may not be empty!");
|
||||
}
|
||||
if (visibleForPublic) {
|
||||
addPublicTag(leaderboardName, raceColumnName, fleetName, tag, comment, imageURL, raceTimepoint);
|
||||
} else {
|
||||
// all parameters are valid => save tag
|
||||
if (visibleForPublic) {
|
||||
successful = addPublicTag(leaderboardName, raceColumnName, fleetName, tag, comment, imageURL,
|
||||
raceTimepoint);
|
||||
} else {
|
||||
successful = addPrivateTag(leaderboardName, raceColumnName, fleetName, tag, comment, imageURL,
|
||||
raceTimepoint);
|
||||
}
|
||||
addPrivateTag(leaderboardName, raceColumnName, fleetName, tag, comment, imageURL, raceTimepoint);
|
||||
}
|
||||
return successful;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tag) {
|
||||
boolean successful = true;
|
||||
// check all parameters for validity
|
||||
public void removeTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tag)
|
||||
throws AuthorizationException, IllegalArgumentException, NotRevokableException, RaceLogNotFoundException,
|
||||
ServiceNotFoundException {
|
||||
if (tag == null) {
|
||||
setLastErrorCode(ErrorCode.TAG_NOT_EMPTY);
|
||||
successful = false;
|
||||
throw new IllegalArgumentException("Tag may not be empty!");
|
||||
}
|
||||
if (tag.isVisibleForPublic()) {
|
||||
removePublicTag(leaderboardName, raceColumnName, fleetName, tag);
|
||||
} else {
|
||||
// all parameters are valid => remove tag
|
||||
if (tag.isVisibleForPublic()) {
|
||||
successful = removePublicTag(leaderboardName, raceColumnName, fleetName, tag);
|
||||
} else {
|
||||
successful = removePrivateTag(leaderboardName, raceColumnName, fleetName, tag);
|
||||
}
|
||||
removePrivateTag(leaderboardName, raceColumnName, fleetName, tag);
|
||||
}
|
||||
return successful;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tagToUpdate,
|
||||
String tag, String comment, String imageURL, boolean visibleForPublic) {
|
||||
boolean successful = true;
|
||||
public void updateTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tagToUpdate,
|
||||
String tag, String comment, String imageURL, boolean visibleForPublic)
|
||||
throws AuthorizationException, IllegalArgumentException, NotRevokableException, RaceLogNotFoundException,
|
||||
ServiceNotFoundException, TagAlreadyExistsException {
|
||||
String username = getCurrentUsername();
|
||||
if (username != null && tagToUpdate.getUsername().equals(username)) {
|
||||
if (removeTag(leaderboardName, raceColumnName, fleetName, tagToUpdate)) {
|
||||
successful = addTag(leaderboardName, raceColumnName, fleetName, tag, comment, imageURL,
|
||||
visibleForPublic, tagToUpdate.getRaceTimepoint());
|
||||
} else {
|
||||
successful = false;
|
||||
}
|
||||
removeTag(leaderboardName, raceColumnName, fleetName, tagToUpdate);
|
||||
addTag(leaderboardName, raceColumnName, fleetName, tag, comment, imageURL, visibleForPublic,
|
||||
tagToUpdate.getRaceTimepoint());
|
||||
|
||||
}
|
||||
return successful;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TagDTO> getPublicTags(String leaderboardName, String raceColumnName, String fleetName) {
|
||||
public List<TagDTO> getPublicTags(String leaderboardName, String raceColumnName, String fleetName)
|
||||
throws RaceLogNotFoundException {
|
||||
final List<TagDTO> result = new ArrayList<TagDTO>();
|
||||
RaceLog raceLog = racingService.getRaceLog(leaderboardName, raceColumnName, fleetName);
|
||||
if (raceLog == null) {
|
||||
setLastErrorCode(ErrorCode.RACELOG_NOT_FOUND);
|
||||
} else {
|
||||
ReadonlyRaceState raceState = ReadonlyRaceStateImpl.getOrCreate(racingService, raceLog);
|
||||
Iterable<RaceLogTagEvent> foundTagEvents = raceState.getTagEvents();
|
||||
for (RaceLogTagEvent tagEvent : foundTagEvents) {
|
||||
result.add(new TagDTO(tagEvent.getTag(), tagEvent.getComment(), tagEvent.getImageURL(),
|
||||
true, tagEvent.getUsername(), tagEvent.getLogicalTimePoint(), tagEvent.getCreatedAt(),
|
||||
tagEvent.getRevokedAt()));
|
||||
}
|
||||
throw new RaceLogNotFoundException();
|
||||
}
|
||||
ReadonlyRaceState raceState = ReadonlyRaceStateImpl.getOrCreate(racingService, raceLog);
|
||||
Iterable<RaceLogTagEvent> foundTagEvents = raceState.getTagEvents();
|
||||
for (RaceLogTagEvent tagEvent : foundTagEvents) {
|
||||
result.add(new TagDTO(tagEvent.getTag(), tagEvent.getComment(), tagEvent.getImageURL(), true,
|
||||
tagEvent.getUsername(), tagEvent.getLogicalTimePoint(), tagEvent.getCreatedAt(),
|
||||
tagEvent.getRevokedAt()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -297,8 +246,8 @@ public class TaggingServiceImpl implements TaggingService {
|
||||
&& tagEvent.getCreatedAt().after(searchSince))
|
||||
|| (searchSince != null && tagEvent.getRevokedAt() != null
|
||||
&& tagEvent.getRevokedAt().after(searchSince))) {
|
||||
result.add(new TagDTO(tagEvent.getTag(), tagEvent.getComment(), tagEvent.getImageURL(),
|
||||
true, tagEvent.getUsername(), tagEvent.getLogicalTimePoint(), tagEvent.getCreatedAt(),
|
||||
result.add(new TagDTO(tagEvent.getTag(), tagEvent.getComment(), tagEvent.getImageURL(), true,
|
||||
tagEvent.getUsername(), tagEvent.getLogicalTimePoint(), tagEvent.getCreatedAt(),
|
||||
tagEvent.getRevokedAt()));
|
||||
}
|
||||
}
|
||||
@@ -307,27 +256,13 @@ public class TaggingServiceImpl implements TaggingService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TagDTO> getPrivateTags(String leaderboardName, String raceColumnName, String fleetName) {
|
||||
public List<TagDTO> getPrivateTags(String leaderboardName, String raceColumnName, String fleetName)
|
||||
throws AuthorizationException, ServiceNotFoundException {
|
||||
final List<TagDTO> result = new ArrayList<TagDTO>();
|
||||
SecurityService securityService = getSecurityService();
|
||||
if (securityService != null) {
|
||||
String username = getCurrentUsername();
|
||||
if (username != null) {
|
||||
String key = serializer.generateUniqueKey(leaderboardName, raceColumnName, fleetName);
|
||||
String privateTagsJson = securityService.getPreference(username, key);
|
||||
List<TagDTO> privateTags = serializer.deserializeTags(privateTagsJson);
|
||||
result.addAll(privateTags);
|
||||
}
|
||||
}
|
||||
String key = serializer.generateUniqueKey(leaderboardName, raceColumnName, fleetName);
|
||||
String privateTagsJson = getSecurityService().getPreference(getCurrentUsername(), key);
|
||||
List<TagDTO> privateTags = serializer.deserializeTags(privateTagsJson);
|
||||
result.addAll(privateTags);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorCode getLastErrorCode() {
|
||||
ErrorCode lastErrorCode = lastErrorCodes.get(SecurityUtils.getSubject());
|
||||
if (lastErrorCode == null) {
|
||||
lastErrorCode = ErrorCode.UNKNOWN_ERROR;
|
||||
}
|
||||
return lastErrorCode;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user