package net.curisit.securis.services; import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.annotation.security.RolesAllowed; import javax.inject.Inject; import javax.inject.Provider; import javax.persistence.EntityManager; import javax.persistence.TypedQuery; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; 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.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.Utils; import net.curisit.securis.DefaultExceptionHandler; import net.curisit.securis.db.Organization; 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.spi.ResteasyProviderFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.inject.persist.Transactional; /** * Organization resource, this service will provide methods to create, modify and delete organizations * * @author roberto */ @Path("/organization") public class OrganizationResource { private static final Logger log = LoggerFactory.getLogger(OrganizationResource.class); @Inject private Provider emProvider; public OrganizationResource() { } /** * * @return the server version in format majorVersion.minorVersion */ @GET @Path("/") @Produces( { MediaType.APPLICATION_JSON }) @Securable // @RolesAllowed(SecurityContextWrapper.ROL_ADVANCE) public Response index(@Context BasicSecurityContext bsc) { log.info("Getting organizations list "); // log.info("User orgs: {}", request.getAttribute("oser_orgs")); BasicSecurityContext bsc2 = ResteasyProviderFactory.getContextData(BasicSecurityContext.class); log.info("bsc: {}", bsc); log.info("bsc2: {}", bsc2); // log.info("securityContext: {}", scw); log.info("securityContext ROL_ADMIN?: {}", bsc.isUserInRole(BasicSecurityContext.ROL_ADMIN)); EntityManager em = emProvider.get(); TypedQuery q; if (bsc.isUserInRole(BasicSecurityContext.ROL_ADMIN)) { log.info("GEtting all orgs for user: " + bsc.getUserPrincipal()); q = em.createNamedQuery("list-organizations", Organization.class); } else { q = em.createNamedQuery("list-organizations", Organization.class); // if (securityContext.getOrganizationsIds() == null) // Response.ok().build(); // log.info("Getting only {} orgs for user: {}", securityContext.getOrganizationsIds(), securityContext.getUserPrincipal()); // q = em.createNamedQuery("list-organizations-by-ids", Organization.class); // q.setParameter("list_ids", securityContext.getOrganizationsIds()); } List list = q.getResultList(); return Response.ok(list).build(); } /** * * @return the server version in format majorVersion.minorVersion */ @GET @Path("/{orgid}") @Produces( { MediaType.APPLICATION_JSON }) @Securable public Response get(@PathParam("orgid") String orgid, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) { log.info("Getting organization data for id: {}: ", orgid); if (orgid == null || orgid.equals("")) { log.error("Organization ID is mandatory"); return Response.status(Status.NOT_FOUND).build(); } // if (!securityContext.isOrgAccesible(Integer.parseInt(orgid))) { // log.error("Organization with id {} not accessible for user: {}", orgid, securityContext.getUserPrincipal()); // return Response.status(Status.UNAUTHORIZED).build(); // } EntityManager em = emProvider.get(); Organization org = em.find(Organization.class, Integer.parseInt(orgid)); if (org == null) { log.error("Organization with id {} not found in DB", orgid); return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Organization not found, id: " + orgid).build(); } return Response.ok(org).build(); } private boolean isCyclicalRelationship(int currentId, Organization parent) { while (parent != null) { if (parent.getId() == currentId) return true; parent = parent.getParentOrganization(); } return false; } @POST @Path("/") @Consumes(MediaType.APPLICATION_JSON) @Produces( { MediaType.APPLICATION_JSON }) @Transactional @Securable @RolesAllowed(BasicSecurityContext.ROL_ADMIN) public Response create(Organization org, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) { log.info("Creating new organization"); EntityManager em = emProvider.get(); Organization parentOrg = null; if (org.getParentOrgId() != null) { parentOrg = em.find(Organization.class, org.getParentOrgId()); if (parentOrg == null) { log.error("Organization parent with id {} not found in DB", org.getParentOrgId()); return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Organization's parent not found with ID: " + org.getParentOrgId()).build(); } } List users = null; List usersIds = org.getUsersIds(); if (usersIds != null && usersIds.size() > 0) { users = new ArrayList<>(); for (String username : usersIds) { User user = em.find(User.class, username); if (user == null) { log.error("Organization user with id {} not found in DB", username); return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Organization's user not found with ID: " + username).build(); } users.add(user); } } org.setUsers(users); org.setParentOrganization(parentOrg); org.setCreationTimestamp(new Date()); em.persist(org); return Response.ok(org).build(); } @PUT @POST @Path("/{orgid}") @Transactional @Consumes(MediaType.APPLICATION_JSON) @Produces( { MediaType.APPLICATION_JSON }) @Securable @RolesAllowed(BasicSecurityContext.ROL_ADMIN) public Response modify(Organization org, @PathParam("orgid") String orgid, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) { log.info("Modifying organization with id: {}", orgid); EntityManager em = emProvider.get(); Organization currentOrg = em.find(Organization.class, Integer.parseInt(orgid)); if (currentOrg == null) { log.error("Organization with id {} not found in DB", orgid); return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Organization not found with ID: " + orgid).build(); } Organization parentOrg = null; if (org.getParentOrgId() != null) { parentOrg = em.find(Organization.class, org.getParentOrgId()); if (parentOrg == null) { log.error("Organization parent with id {} not found in DB", org.getParentOrgId()); return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Organization's parent not found with ID: " + org.getParentOrgId()).build(); } if (isCyclicalRelationship(currentOrg.getId(), parentOrg)) { log.error("Organization parent generate a cyclical relationship, parent id {}, current id: {}", org.getParentOrgId(), currentOrg.getId()); return Response.status(Status.FORBIDDEN).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Cyclical relationships are not allowed, please change the parent organization, current Parent: " + parentOrg.getName()).build(); } } List users = null; List usersIds = org.getUsersIds(); if (usersIds != null && usersIds.size() > 0) { users = new ArrayList<>(); for (String username : usersIds) { User user = em.find(User.class, username); if (user == null) { log.error("Organization user with id '{}' not found in DB", username); return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Organization's user not found with ID: " + username).build(); } users.add(user); } } currentOrg.setUsers(users); currentOrg.setParentOrganization(parentOrg); currentOrg.setCode(org.getCode()); currentOrg.setName(org.getName()); currentOrg.setDescription(org.getDescription()); em.persist(currentOrg); return Response.ok(currentOrg).build(); } @DELETE @Path("/{orgid}") @Transactional @Produces( { MediaType.APPLICATION_JSON }) @Securable @RolesAllowed(BasicSecurityContext.ROL_ADMIN) public Response delete(@PathParam("orgid") String orgid, @Context HttpServletRequest request) { log.info("Deleting organization with id: {}", orgid); EntityManager em = emProvider.get(); Organization org = em.find(Organization.class, Integer.parseInt(orgid)); if (org == null) { log.error("Organization with id {} can not be deleted, It was not found in DB", orgid); return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Organization was not found, ID: " + orgid).build(); } if (org.getChildOrganizations() != null && org.getChildOrganizations().size() > 0) { log.error("Organization has children and can not be deleted, ID: " + orgid); return Response.status(Status.FORBIDDEN).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Organization has children and can not be deleted, ID: " + orgid).build(); } em.remove(org); return Response.ok(Utils.createMap("success", true, "id", orgid)).build(); } }