package net.curisit.securis.services; import java.io.IOException; import java.util.Date; import java.util.List; import javax.inject.Inject; import javax.inject.Provider; import javax.persistence.EntityManager; import javax.persistence.TypedQuery; import javax.ws.rs.Consumes; 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.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import net.curisit.integrity.commons.JsonUtils; import net.curisit.integrity.commons.Utils; import net.curisit.integrity.exception.CurisException; import net.curisit.securis.DefaultExceptionHandler; import net.curisit.securis.db.License; import net.curisit.securis.db.Pack; import net.curisit.securis.db.User; import net.curisit.securis.security.BasicSecurityContext; import net.curisit.securis.security.Securable; import net.curisit.securis.utils.TokenHelper; import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.inject.persist.Transactional; /** * License resource, this service will provide methods to create, modify and delete licenses * * @author roberto */ @Path("/license") public class LicenseResource { private static final Logger log = LoggerFactory.getLogger(LicenseResource.class); @Inject TokenHelper tokenHelper; @Inject Provider emProvider; public LicenseResource() { } /** * * @return the server version in format majorVersion.minorVersion */ @GET @Path("/") @Securable @Produces( { MediaType.APPLICATION_JSON }) public Response index(@QueryParam("packId") Integer packId, @Context BasicSecurityContext bsc) { log.info("Getting licenses list "); EntityManager em = emProvider.get(); if (!bsc.isUserInRole(BasicSecurityContext.ROL_ADMIN)) { Pack pack = em.find(Pack.class, packId); if (pack == null) return Response.ok().build(); if (!bsc.getOrganizationsIds().contains(pack.getOrganization().getId())) { log.error("Pack with id {} not accesible by user {}", pack, bsc.getUserPrincipal()); return Response.status(Status.UNAUTHORIZED).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Unathorized access to pack licenses").build(); } } TypedQuery q = em.createNamedQuery("list-licenses-by-pack", License.class); q.setParameter("packId", packId); List list = q.getResultList(); return Response.ok(list).build(); } /** * * @return the server version in format majorVersion.minorVersion */ @GET @Path("/{licId}") @Securable @Produces( { MediaType.APPLICATION_JSON }) public Response get(@PathParam("licId") Integer licId, @Context BasicSecurityContext bsc) { log.info("Getting organization data for id: {}: ", licId); if (licId == null || licId.equals("")) { log.error("License ID is mandatory"); return Response.status(Status.NOT_FOUND).build(); } EntityManager em = emProvider.get(); License lic = em.find(License.class, licId); if (lic == null) { log.error("License with id {} not found in DB", licId); return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "License not found for ID: " + licId).build(); } if (!bsc.isUserInRole(BasicSecurityContext.ROL_ADMIN)) { if (!bsc.getOrganizationsIds().contains(lic.getPack().getOrganization().getId())) { log.error("License with id {} is not accesible by user {}", licId, bsc.getUserPrincipal()); return Response.status(Status.UNAUTHORIZED).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Unathorized access to license data").build(); } } return Response.ok(lic).build(); } @POST @Path("/") @Consumes(MediaType.APPLICATION_JSON) @Securable @Produces( { MediaType.APPLICATION_JSON }) @Transactional public Response create(License lic, @Context BasicSecurityContext bsc) { log.info("Creating new license from create()"); EntityManager em = emProvider.get(); Pack pack = null; if (lic.getPackId() != null) { pack = em.find(Pack.class, lic.getPackId()); if (pack == null) { log.error("License pack with id {} not found in DB", lic.getPackId()); return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "License's pack not found with ID: " + lic.getPackId()).build(); } else { if (!bsc.isUserInRole(BasicSecurityContext.ROL_ADMIN)) { if (!bsc.getOrganizationsIds().contains(pack.getOrganization().getId())) { log.error("License for pack with id {} can not be created by user {}", pack.getId(), bsc.getUserPrincipal()); return Response.status(Status.UNAUTHORIZED).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Unathorized action on pack license").build(); } } } } try { User createdBy = getUser(bsc.getUserPrincipal().getName(), em); lic.setCreatedBy(createdBy); } catch (CurisException ex) { String createdByUsername = lic.getCreatedById(); log.error("License created by user with id {} not found in DB", createdByUsername); return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "License's created by user not found with ID: " + createdByUsername).build(); } // ODO: Manage status if request data is set lic.setCanceledBy(null); lic.setStatus(License.Status.CREATED); lic.setCreationTimestamp(new Date()); lic.setModificationTimestamp(lic.getCreationTimestamp()); em.persist(lic); return Response.ok(lic).build(); } @POST @Path("/") @Consumes(MediaType.MULTIPART_FORM_DATA) @Securable @Produces( { MediaType.APPLICATION_JSON }) @Transactional public Response createWithFile(MultipartFormDataInput mpfdi, @Context BasicSecurityContext bsc) throws IOException { License lic = new License(); lic.setCode(mpfdi.getFormDataPart("code", String.class, null)); lic.setRequestData(mpfdi.getFormDataPart("request_data", String.class, null)); lic.setPackId(mpfdi.getFormDataPart("pack_id", Integer.class, null)); lic.setFullName(mpfdi.getFormDataPart("full_name", String.class, null)); lic.setEmail(mpfdi.getFormDataPart("email", String.class, null)); lic.setComments(mpfdi.getFormDataPart("comments", String.class, null)); try { log.info("File content: {}", lic.getRequestData()); log.info("License read from multipart: {}", JsonUtils.toJSON(lic)); } catch (CurisException e) { // TODO Auto-generated catch block e.printStackTrace(); } return create(lic, bsc); } private User getUser(String username, EntityManager em) throws CurisException { User user = null; if (username != null) { user = em.find(User.class, username); if (user == null) { throw new CurisException("User not found"); } } return user; } @PUT @POST @Path("/{licId}") @Securable @Transactional @Consumes(MediaType.APPLICATION_JSON) @Produces( { MediaType.APPLICATION_JSON }) public Response modify(License lic, @PathParam("licId") Integer licId, @Context BasicSecurityContext bsc) { log.info("Modifying organization with id: {}", licId); EntityManager em = emProvider.get(); // Pack pack = null; // if (lic.getPackId() != null) { // pack = em.find(Pack.class, lic.getPackId()); // if (pack == null) { // log.error("License pack with id {} not found in DB", lic.getPackId()); // return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "License's pack not found with ID: " + lic.getPackId()).build(); // } else { // if (!bsc.isUserInRole(BasicSecurityContext.ROL_ADMIN)) { // if (!bsc.getOrganizationsIds().contains(pack.getOrganization().getId())) { // log.error("License for pack with id {} can not be modified by user {}", pack.getId(), bsc.getUserPrincipal()); // return Response.status(Status.UNAUTHORIZED).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Unathorized action on pack license").build(); // } // } // } // } User createdBy = null; try { createdBy = getUser(lic.getCreatedById(), em); } catch (CurisException ex) { String createdByUsername = lic.getCreatedById(); log.error("License created by user with id {} not found in DB", createdByUsername); return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "License's created by user not found with ID: " + createdByUsername).build(); } User canceledBy = null; try { canceledBy = getUser(lic.getCanceledById(), em); } catch (CurisException ex) { String canceledByUsername = lic.getCreatedById(); log.error("License canceled by user with id {} not found in DB", canceledByUsername); return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "License's canceled by user not found with ID: " + canceledByUsername).build(); } License currentLicense = em.find(License.class, lic.getId()); if (currentLicense == null) { log.error("License with id {} not found in DB", licId); return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "License not found for ID: " + licId).build(); } if (!bsc.isUserInRole(BasicSecurityContext.ROL_ADMIN)) { if (!bsc.getOrganizationsIds().contains(lic.getPack().getOrganization().getId())) { log.error("License with id {} is not accesible by user {}", licId, bsc.getUserPrincipal()); return Response.status(Status.UNAUTHORIZED).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Unathorized access to license data").build(); } } // TODO: set status based in current one and dates ? use custom actions ? currentLicense.setCreatedBy(createdBy); currentLicense.setCanceledBy(canceledBy); // currentLicense.setPack(pack); currentLicense.setCode(lic.getCode()); currentLicense.setFullName(lic.getFullName()); currentLicense.setEmail(lic.getEmail()); currentLicense.setRequestData(lic.getRequestData()); currentLicense.setModificationTimestamp(new Date()); em.persist(currentLicense); return Response.ok(currentLicense).build(); } @DELETE @Path("/{licId}") @Transactional @Securable @Produces( { MediaType.APPLICATION_JSON }) public Response delete(@PathParam("licId") String licId, @Context BasicSecurityContext bsc) { log.info("Deleting license with id: {}", licId); EntityManager em = emProvider.get(); License lic = em.find(License.class, Integer.parseInt(licId)); if (lic == null) { log.error("License with id {} can not be deleted, It was not found in DB", licId); return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "License was not found, ID: " + licId).build(); } if (!bsc.isUserInRole(BasicSecurityContext.ROL_ADMIN)) { if (!bsc.getOrganizationsIds().contains(lic.getPack().getOrganization().getId())) { log.error("License with id {} is not accesible by user {}", licId, bsc.getUserPrincipal()); return Response.status(Status.UNAUTHORIZED).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Unathorized access to license data").build(); } } if (lic.getStatus() != License.Status.CANCELED || lic.getStatus() != License.Status.CREATED) { log.error("License {} can not be deleted with status {}", lic.getCode(), lic.getStatus()); return Response.status(Status.FORBIDDEN).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "License can not be deleted in current status").build(); } em.remove(lic); return Response.ok(Utils.createMap("success", true, "id", licId)).build(); } }