package fi.otavanopisto.muikku.plugins.communicator.rest; import java.util.List; import javax.ejb.Stateful; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import fi.otavanopisto.muikku.model.users.UserEntity; import fi.otavanopisto.muikku.plugin.PluginRESTService; import fi.otavanopisto.muikku.plugins.communicator.CommunicatorController; import fi.otavanopisto.muikku.plugins.communicator.CommunicatorFolderType; import fi.otavanopisto.muikku.plugins.communicator.model.CommunicatorLabel; import fi.otavanopisto.muikku.plugins.communicator.model.CommunicatorMessage; import fi.otavanopisto.muikku.plugins.communicator.model.CommunicatorMessageId; import fi.otavanopisto.muikku.plugins.communicator.model.CommunicatorMessageIdLabel; import fi.otavanopisto.muikku.plugins.communicator.model.CommunicatorUserLabel; import fi.otavanopisto.muikku.servlet.BaseUrl; import fi.otavanopisto.muikku.session.SessionController; import fi.otavanopisto.security.AuthorizationException; import fi.otavanopisto.security.rest.RESTPermit; import fi.otavanopisto.security.rest.RESTPermit.Handling; @Path("/communicator") @RequestScoped @Stateful @Produces ("application/json") public class CommunicatorLabelRESTService extends PluginRESTService { private static final long serialVersionUID = 6680345677459264564L; @Inject @BaseUrl private String baseUrl; @Inject private SessionController sessionController; @Inject private CommunicatorController communicatorController; @Inject private CommunicatorRESTModels restModels; @GET @Path ("/messages/{COMMUNICATORMESSAGEID}/labels") @RESTPermit(handling = Handling.INLINE, requireLoggedIn = true) public Response listMessageIdLabels( @PathParam ("COMMUNICATORMESSAGEID") Long communicatorMessageId) throws AuthorizationException { CommunicatorMessageId messageId = communicatorController.findCommunicatorMessageId(communicatorMessageId); // Lists only labels of logged user so we can consider this safe UserEntity userEntity = sessionController.getLoggedUserEntity(); List<CommunicatorMessageIdLabel> labels = communicatorController.listMessageIdLabelsByUserEntity(userEntity, messageId); return Response.ok( restModels.restLabel(labels) ).build(); } @POST @Path ("/messages/{COMMUNICATORMESSAGEID}/labels") @RESTPermit(handling = Handling.INLINE, requireLoggedIn = true) public Response createMessageIdLabel( @PathParam ("COMMUNICATORMESSAGEID") Long communicatorMessageId, CommunicatorMessageIdLabelRESTModel newLabel) throws AuthorizationException { CommunicatorMessageId messageId = communicatorController.findCommunicatorMessageId(communicatorMessageId); UserEntity userEntity = sessionController.getLoggedUserEntity(); CommunicatorLabel label = communicatorController.findUserLabelById(newLabel.getLabelId()); if ((label != null) && canAccessLabel(userEntity, label)) { CommunicatorMessageIdLabel userLabel = communicatorController.findMessageIdLabel(userEntity, messageId, label); if (userLabel == null) { userLabel = communicatorController.createMessageIdLabel(userEntity, messageId, label); return Response.ok( restModels.restLabel(userLabel) ).build(); } else { return Response.status(Status.BAD_REQUEST).build(); } } else { return Response.status(Status.NOT_FOUND).build(); } } @GET @Path ("/messages/{COMMUNICATORMESSAGEID}/labels/{LABELID}") @RESTPermit(handling = Handling.INLINE, requireLoggedIn = true) public Response getMessageIdLabel( @PathParam ("COMMUNICATORMESSAGEID") Long communicatorMessageId, @PathParam ("LABELID") Long labelId ) throws AuthorizationException { CommunicatorMessageIdLabel label = communicatorController.findMessageIdLabelById(labelId); UserEntity userEntity = sessionController.getLoggedUserEntity(); if (!canAccessLabel(userEntity, label.getLabel())) { return Response.status(Status.FORBIDDEN).build(); } return Response.ok( restModels.restLabel(label) ).build(); } @DELETE @Path ("/messages/{COMMUNICATORMESSAGEID}/labels/{LABELID}") @RESTPermit(handling = Handling.INLINE, requireLoggedIn = true) public Response deleteUserLabel( @PathParam ("COMMUNICATORMESSAGEID") Long communicatorMessageId, @PathParam ("LABELID") Long userLabelId) throws AuthorizationException { CommunicatorMessageIdLabel label = communicatorController.findMessageIdLabelById(userLabelId); UserEntity userEntity = sessionController.getLoggedUserEntity(); if (!canAccessLabel(userEntity, label.getLabel())) { return Response.status(Status.FORBIDDEN).build(); } communicatorController.delete(label); return Response.noContent().build(); } @GET @Path ("/userLabels") @RESTPermit(handling = Handling.INLINE, requireLoggedIn = true) public Response listUserLabels() throws AuthorizationException { UserEntity userEntity = sessionController.getLoggedUserEntity(); // Lists only labels of logged user so we can consider this safe List<CommunicatorUserLabel> userLabels = communicatorController.listUserLabelsByUserEntity(userEntity); return Response.ok( restModels.restUserLabel(userLabels) ).build(); } @POST @Path ("/userLabels") @RESTPermit(handling = Handling.INLINE, requireLoggedIn = true) public Response createUserLabel(CommunicatorUserLabelRESTModel newUserLabel) throws AuthorizationException { UserEntity userEntity = sessionController.getLoggedUserEntity(); // Creates only labels for logged user so we can consider this safe CommunicatorUserLabel userLabel = communicatorController.createUserLabel(newUserLabel.getName(), newUserLabel.getColor(), userEntity); return Response.ok( restModels.restUserLabel(userLabel) ).build(); } @GET @Path ("/userLabels/{USERLABELID}") @RESTPermit(handling = Handling.INLINE, requireLoggedIn = true) public Response getUserLabel( @PathParam ("USERLABELID") Long userLabelId ) throws AuthorizationException { UserEntity userEntity = sessionController.getLoggedUserEntity(); CommunicatorUserLabel userLabel = communicatorController.findUserLabelById(userLabelId); if ((userLabel != null) && canAccessLabel(userEntity, userLabel)) { return Response.ok( restModels.restUserLabel(userLabel) ).build(); } else { return Response.status(Status.NOT_FOUND).build(); } } @DELETE @Path ("/userLabels/{USERLABELID}") @RESTPermit(handling = Handling.INLINE, requireLoggedIn = true) public Response deleteUserLabel( @PathParam ("USERLABELID") Long userLabelId ) throws AuthorizationException { UserEntity userEntity = sessionController.getLoggedUserEntity(); CommunicatorUserLabel userLabel = communicatorController.findUserLabelById(userLabelId); if ((userLabel != null) && canAccessLabel(userEntity, userLabel)) { communicatorController.delete(userLabel); return Response.noContent().build(); } else { return Response.status(Status.NOT_FOUND).build(); } } @PUT @Path ("/userLabels/{USERLABELID}") @RESTPermit(handling = Handling.INLINE, requireLoggedIn = true) public Response editUserLabel( @PathParam ("USERLABELID") Long userLabelId, CommunicatorUserLabelRESTModel updatedUserLabel ) throws AuthorizationException { if (!updatedUserLabel.getId().equals(userLabelId)) { return Response.status(Response.Status.BAD_REQUEST).entity("Id is immutable").build(); } UserEntity userEntity = sessionController.getLoggedUserEntity(); CommunicatorUserLabel userLabel = communicatorController.findUserLabelById(userLabelId); if ((userLabel != null) && canAccessLabel(userEntity, userLabel)) { CommunicatorUserLabel editedUserLabel = communicatorController.updateUserLabel(userLabel, updatedUserLabel.getName(), updatedUserLabel.getColor()); return Response.ok( restModels.restUserLabel(editedUserLabel) ).build(); } else { return Response.status(Status.NOT_FOUND).build(); } } @GET @Path ("/userLabels/{USERLABELID}/messages/{COMMUNICATORMESSAGEID}") @RESTPermit(handling = Handling.INLINE, requireLoggedIn = true) public Response listUserUnreadCommunicatorMessagesByMessageId( @PathParam ("USERLABELID") Long userLabelId, @PathParam ("COMMUNICATORMESSAGEID") Long communicatorMessageId) { UserEntity userEntity = sessionController.getLoggedUserEntity(); CommunicatorUserLabel userLabel = communicatorController.findUserLabelById(userLabelId); if ((userLabel != null) && canAccessLabel(userEntity, userLabel)) { CommunicatorMessageId threadId = communicatorController.findCommunicatorMessageId(communicatorMessageId); List<CommunicatorMessage> receivedItems = communicatorController.listMessagesByMessageId(userEntity, threadId, false); List<CommunicatorMessageIdLabel> labels = communicatorController.listMessageIdLabelsByUserEntity(userEntity, threadId); List<CommunicatorMessageIdLabelRESTModel> restLabels = restModels.restLabel(labels); CommunicatorMessageId olderThread = communicatorController.findOlderThreadId(userEntity, threadId, CommunicatorFolderType.LABEL, userLabel); CommunicatorMessageId newerThread = communicatorController.findNewerThreadId(userEntity, threadId, CommunicatorFolderType.LABEL, userLabel); return Response.ok( restModels.restThreadViewModel(receivedItems, olderThread, newerThread, restLabels) ).build(); } else { return Response.status(Status.NOT_FOUND).build(); } } private boolean canAccessLabel(UserEntity userEntity, CommunicatorLabel label) { if (label instanceof CommunicatorUserLabel) { // No access if not logged in if (userEntity == null) return false; CommunicatorUserLabel userLabel = (CommunicatorUserLabel) label; return userEntity.getId().equals(userLabel.getUserEntity()); } return false; } }