From c2cf57687d1d61fd476659bc5bead0592143a5c6 Mon Sep 17 00:00:00 2001
From: Roberto Sánchez <roberto.sanchez@curisit.net>
Date: Fri, 17 Jan 2014 18:50:27 +0000
Subject: [PATCH] #395 feature - Added remaining resources to REST API in Licenses management

---
 securis/src/main/java/net/curisit/securis/db/License.java                    |    6 
 securis/src/main/java/net/curisit/securis/services/SecurityInterceptor.java  |   26 +-
 securis/src/main/java/net/curisit/securis/services/ApiResource.java          |   49 ++++++
 securis/src/main/java/net/curisit/securis/utils/TokenHelper.java             |    2 
 securis/src/main/java/net/curisit/securis/ioc/RequestsModule.java            |    6 
 securis/src/main/java/net/curisit/securis/services/LicenseResource.java      |  216 +++++++++++++++++++++++++++
 securis/src/main/java/net/curisit/securis/services/BasicServices.java        |    3 
 securis/src/main/java/net/curisit/securis/services/OrganizationResource.java |    2 
 securis/src/main/java/net/curisit/securis/services/PackResource.java         |  160 ++++++++++++++++++++
 9 files changed, 452 insertions(+), 18 deletions(-)

diff --git a/securis/src/main/java/net/curisit/securis/db/License.java b/securis/src/main/java/net/curisit/securis/db/License.java
index 6ef4659..5ab3b78 100644
--- a/securis/src/main/java/net/curisit/securis/db/License.java
+++ b/securis/src/main/java/net/curisit/securis/db/License.java
@@ -145,17 +145,17 @@
 	}
 
 	@JsonProperty("pack_code")
-	public String getLicenseTypcode() {
+	public String getPackCode() {
 		return pack == null ? null : pack.getCode();
 	}
 
 	@JsonProperty("pack_id")
-	public Integer getOrgId() {
+	public Integer getPackId() {
 		return pack == null ? null : pack.getId();
 	}
 
 	@JsonProperty("pack_id")
-	public void setOrgId(Integer idPack) {
+	public void setPackId(Integer idPack) {
 		if (idPack == null) {
 			pack = null;
 		} else {
diff --git a/securis/src/main/java/net/curisit/securis/ioc/RequestsModule.java b/securis/src/main/java/net/curisit/securis/ioc/RequestsModule.java
index 366b85d..4059219 100644
--- a/securis/src/main/java/net/curisit/securis/ioc/RequestsModule.java
+++ b/securis/src/main/java/net/curisit/securis/ioc/RequestsModule.java
@@ -1,10 +1,13 @@
 package net.curisit.securis.ioc;
 
+import net.curisit.securis.services.ApiResource;
 import net.curisit.securis.services.ApplicationResource;
 import net.curisit.securis.services.BasicServices;
+import net.curisit.securis.services.LicenseResource;
 import net.curisit.securis.services.LicenseServices;
 import net.curisit.securis.services.LicenseTypeResource;
 import net.curisit.securis.services.OrganizationResource;
+import net.curisit.securis.services.PackResource;
 import net.curisit.securis.services.SecurityInterceptor;
 import net.curisit.securis.services.UserResource;
 
@@ -29,6 +32,9 @@
 		bind(ApplicationResource.class);
 		bind(LicenseTypeResource.class);
 		bind(OrganizationResource.class);
+		bind(ApiResource.class);
+		bind(LicenseResource.class);
+		bind(PackResource.class);
 	}
 
 	@Provides
diff --git a/securis/src/main/java/net/curisit/securis/services/ApiResource.java b/securis/src/main/java/net/curisit/securis/services/ApiResource.java
new file mode 100644
index 0000000..bb85548
--- /dev/null
+++ b/securis/src/main/java/net/curisit/securis/services/ApiResource.java
@@ -0,0 +1,49 @@
+package net.curisit.securis.services;
+
+import javax.inject.Inject;
+import javax.inject.Provider;
+import javax.persistence.EntityManager;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import net.curisit.securis.utils.TokenHelper;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * External API to be accessed by third parties
+ * 
+ * @author roberto <roberto.sanchez@curisit.net>
+ */
+@Path("/api")
+public class ApiResource {
+
+	@SuppressWarnings("unused")
+	private static final Logger log = LoggerFactory.getLogger(ApiResource.class);
+
+	@Inject
+	TokenHelper tokenHelper;
+
+	@Inject
+	Provider<EntityManager> emProvider;
+
+	public ApiResource() {
+	}
+
+	/**
+	 * 
+	 * @return Simple text message to check API status
+	 */
+	@GET
+	@Path("/")
+	@Produces(
+		{ MediaType.TEXT_PLAIN })
+	public Response index() {
+		return Response.ok("SeCuris API").build();
+	}
+
+}
diff --git a/securis/src/main/java/net/curisit/securis/services/BasicServices.java b/securis/src/main/java/net/curisit/securis/services/BasicServices.java
index ef66c32..e1a7a77 100644
--- a/securis/src/main/java/net/curisit/securis/services/BasicServices.java
+++ b/securis/src/main/java/net/curisit/securis/services/BasicServices.java
@@ -21,7 +21,6 @@
 import javax.ws.rs.core.UriBuilder;
 
 import net.curisit.integrity.commons.Utils;
-import net.curisit.securis.db.User;
 import net.curisit.securis.utils.TokenHelper;
 
 import org.slf4j.Logger;
@@ -88,7 +87,7 @@
 	 * @return
 	 */
 	@GET
-	@Securable(roles = User.Rol.ADMIN)
+	@Securable()
 	@Path("/check")
 	@Produces(
 		{ MediaType.APPLICATION_JSON })
diff --git a/securis/src/main/java/net/curisit/securis/services/LicenseResource.java b/securis/src/main/java/net/curisit/securis/services/LicenseResource.java
new file mode 100644
index 0000000..0e25467
--- /dev/null
+++ b/securis/src/main/java/net/curisit/securis/services/LicenseResource.java
@@ -0,0 +1,216 @@
+package net.curisit.securis.services;
+
+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.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.integrity.exception.CurisException;
+import net.curisit.securis.SecurisErrorHandler;
+import net.curisit.securis.db.License;
+import net.curisit.securis.db.Pack;
+import net.curisit.securis.db.User;
+import net.curisit.securis.utils.TokenHelper;
+
+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 <roberto.sanchez@curisit.net>
+ */
+@Path("/organization")
+public class LicenseResource {
+
+	private static final Logger log = LoggerFactory.getLogger(LicenseResource.class);
+
+	@Inject
+	TokenHelper tokenHelper;
+
+	@Inject
+	Provider<EntityManager> emProvider;
+
+	public LicenseResource() {
+	}
+
+	/**
+	 * 
+	 * @return the server version in format majorVersion.minorVersion
+	 */
+	@GET
+	@Path("/")
+	@Produces(
+		{ MediaType.APPLICATION_JSON })
+	public Response index() {
+		log.info("Getting licenses list ");
+
+		EntityManager em = emProvider.get();
+		TypedQuery<License> q = em.createNamedQuery("list-licenses-by-pack", License.class);
+
+		List<License> list = q.getResultList();
+
+		return Response.ok(list).build();
+	}
+
+	/**
+	 * 
+	 * @return the server version in format majorVersion.minorVersion
+	 */
+	@GET
+	@Path("/{licId}")
+	@Produces(
+		{ MediaType.APPLICATION_JSON })
+	public Response get(@PathParam("licId") String licId, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) {
+		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 lt = em.find(License.class, Integer.parseInt(licId));
+		if (lt == null) {
+			log.error("License with id {} not found in DB", licId);
+			return Response.status(Status.NOT_FOUND).build();
+		}
+		return Response.ok(lt).build();
+	}
+
+	@POST
+	@Path("/")
+	@Consumes(MediaType.APPLICATION_JSON)
+	@Produces(
+		{ MediaType.APPLICATION_JSON })
+	@Transactional
+	public Response create(License lic, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) {
+		log.info("Creating new organization");
+		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(SecurisErrorHandler.HEADER_ERROR_MESSAGE, "License's pack not found with ID: " + lic.getPackId()).build();
+			}
+		}
+
+		try {
+			User createdBy = getUser(lic.getCreatedById(), 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(SecurisErrorHandler.HEADER_ERROR_MESSAGE, "License's created by user not found with ID: " + createdByUsername).build();
+		}
+
+		try {
+			User canceledBy = getUser(lic.getCanceledById(), em);
+			lic.setCanceledBy(canceledBy);
+		} 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(SecurisErrorHandler.HEADER_ERROR_MESSAGE, "License's canceled by user not found with ID: " + canceledByUsername).build();
+		}
+
+		lic.setCreationTimestamp(new Date());
+		em.persist(lic);
+
+		return Response.ok(lic).build();
+	}
+
+	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}")
+	@Transactional
+	@Consumes(MediaType.APPLICATION_JSON)
+	@Produces(
+		{ MediaType.APPLICATION_JSON })
+	public Response modify(License lic, @PathParam("licId") String licId, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) {
+		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(SecurisErrorHandler.HEADER_ERROR_MESSAGE, "License's pack not found with ID: " + lic.getPackId()).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(SecurisErrorHandler.HEADER_ERROR_MESSAGE, "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(SecurisErrorHandler.HEADER_ERROR_MESSAGE, "License's canceled by user not found with ID: " + canceledByUsername).build();
+		}
+
+		lic.setCreatedBy(createdBy);
+		lic.setCanceledBy(canceledBy);
+		lic.setPack(pack);
+		em.persist(lic);
+
+		return Response.ok(lic).build();
+	}
+
+	@DELETE
+	@Path("/{licId}")
+	@Transactional
+	@Produces(
+		{ MediaType.APPLICATION_JSON })
+	public Response delete(@PathParam("licId") String licId, @Context HttpServletRequest request) {
+		log.info("Deleting license with id: {}", licId);
+		EntityManager em = emProvider.get();
+		License org = em.find(License.class, Integer.parseInt(licId));
+		if (org == null) {
+			log.error("License with id {} can not be deleted, It was not found in DB", licId);
+			return Response.status(Status.NOT_FOUND).header(SecurisErrorHandler.HEADER_ERROR_MESSAGE, "License was not found, ID: " + licId).build();
+		}
+
+		em.remove(org);
+		return Response.ok(Utils.createMap("success", true, "id", licId)).build();
+	}
+
+}
diff --git a/securis/src/main/java/net/curisit/securis/services/OrganizationResource.java b/securis/src/main/java/net/curisit/securis/services/OrganizationResource.java
index a7cbbcf..71b5441 100644
--- a/securis/src/main/java/net/curisit/securis/services/OrganizationResource.java
+++ b/securis/src/main/java/net/curisit/securis/services/OrganizationResource.java
@@ -202,7 +202,7 @@
 	@Produces(
 		{ MediaType.APPLICATION_JSON })
 	public Response delete(@PathParam("orgid") String orgid, @Context HttpServletRequest request) {
-		log.info("Deleting app with id: {}", orgid);
+		log.info("Deleting organization with id: {}", orgid);
 		EntityManager em = emProvider.get();
 		Organization org = em.find(Organization.class, Integer.parseInt(orgid));
 		if (org == null) {
diff --git a/securis/src/main/java/net/curisit/securis/services/PackResource.java b/securis/src/main/java/net/curisit/securis/services/PackResource.java
new file mode 100644
index 0000000..75ff497
--- /dev/null
+++ b/securis/src/main/java/net/curisit/securis/services/PackResource.java
@@ -0,0 +1,160 @@
+package net.curisit.securis.services;
+
+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.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.integrity.exception.CurisException;
+import net.curisit.securis.SecurisErrorHandler;
+import net.curisit.securis.db.Pack;
+import net.curisit.securis.db.User;
+import net.curisit.securis.utils.TokenHelper;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.persist.Transactional;
+
+/**
+ * Pack resource, this service will provide methods to create, modify and delete packs
+ * 
+ * @author roberto <roberto.sanchez@curisit.net>
+ */
+@Path("/pack")
+public class PackResource {
+
+	private static final Logger log = LoggerFactory.getLogger(PackResource.class);
+
+	@Inject
+	TokenHelper tokenHelper;
+
+	@Inject
+	Provider<EntityManager> emProvider;
+
+	public PackResource() {
+	}
+
+	/**
+	 * 
+	 * @return the server version in format majorVersion.minorVersion
+	 */
+	@GET
+	@Path("/")
+	@Produces(
+		{ MediaType.APPLICATION_JSON })
+	public Response index() {
+		log.info("Getting packs list ");
+
+		EntityManager em = emProvider.get();
+		TypedQuery<Pack> q = em.createNamedQuery("list-packs-by-orgs", Pack.class);
+
+		List<Pack> list = q.getResultList();
+
+		return Response.ok(list).build();
+	}
+
+	/**
+	 * 
+	 * @return the server version in format majorVersion.minorVersion
+	 */
+	@GET
+	@Path("/{packId}")
+	@Produces(
+		{ MediaType.APPLICATION_JSON })
+	public Response get(@PathParam("packId") String packId, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) {
+		log.info("Getting pack data for id: {}: ", packId);
+		if (packId == null || packId.equals("")) {
+			log.error("Pack ID is mandatory");
+			return Response.status(Status.NOT_FOUND).build();
+		}
+
+		EntityManager em = emProvider.get();
+		Pack lt = em.find(Pack.class, Integer.parseInt(packId));
+		if (lt == null) {
+			log.error("Pack with id {} not found in DB", packId);
+			return Response.status(Status.NOT_FOUND).build();
+		}
+		return Response.ok(lt).build();
+	}
+
+	@POST
+	@Path("/")
+	@Consumes(MediaType.APPLICATION_JSON)
+	@Produces(
+		{ MediaType.APPLICATION_JSON })
+	@Transactional
+	public Response create(Pack pack, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) {
+		log.info("Creating new pack");
+		EntityManager em = emProvider.get();
+
+		pack.setCreationTimestamp(new Date());
+		em.persist(pack);
+
+		return Response.ok(pack).build();
+	}
+
+	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("/{packId}")
+	@Transactional
+	@Consumes(MediaType.APPLICATION_JSON)
+	@Produces(
+		{ MediaType.APPLICATION_JSON })
+	public Response modify(Pack pack, @PathParam("packId") String packId, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) {
+		log.info("Modifying pack with id: {}", packId);
+		EntityManager em = emProvider.get();
+
+		em.persist(pack);
+
+		return Response.ok(pack).build();
+	}
+
+	@DELETE
+	@Path("/{packId}")
+	@Transactional
+	@Produces(
+		{ MediaType.APPLICATION_JSON })
+	public Response delete(@PathParam("packId") String packId, @Context HttpServletRequest request) {
+		log.info("Deleting pack with id: {}", packId);
+		EntityManager em = emProvider.get();
+		Pack org = em.find(Pack.class, Integer.parseInt(packId));
+		if (org == null) {
+			log.error("Pack with id {} can not be deleted, It was not found in DB", packId);
+			return Response.status(Status.NOT_FOUND).header(SecurisErrorHandler.HEADER_ERROR_MESSAGE, "Pack was not found, ID: " + packId).build();
+		}
+
+		em.remove(org);
+		return Response.ok(Utils.createMap("success", true, "id", packId)).build();
+	}
+
+}
diff --git a/securis/src/main/java/net/curisit/securis/services/SecurityInterceptor.java b/securis/src/main/java/net/curisit/securis/services/SecurityInterceptor.java
index 0516435..ca84402 100644
--- a/securis/src/main/java/net/curisit/securis/services/SecurityInterceptor.java
+++ b/securis/src/main/java/net/curisit/securis/services/SecurityInterceptor.java
@@ -40,31 +40,33 @@
 
 	@Override
 	public void filter(ContainerRequestContext containerRequestContext) throws IOException {
-		log.info("filter using REST interceptor, method: {}", containerRequestContext.getMethod());
-
-		log.info("filter using REST interceptor, ResourceMethodInvoker: {}", containerRequestContext.getProperty("org.jboss.resteasy.core.ResourceMethodInvoker"));
 		ResourceMethodInvoker methodInvoker = (ResourceMethodInvoker) containerRequestContext.getProperty("org.jboss.resteasy.core.ResourceMethodInvoker");
 		Method method = methodInvoker.getMethod();
 
 		if (!method.isAnnotationPresent(Securable.class))
 			return;
 		String token = servletRequest.getHeader(TokenHelper.TOKEN_HEADER_PÀRAM);
-		if (token == null || !tokenHelper.isTokenValid(token))
+		if (token == null || !tokenHelper.isTokenValid(token)) {
+			log.info("Access denied to '{}', Token not valid.", servletRequest.getPathInfo());
 			containerRequestContext.abortWith(Response.status(Status.UNAUTHORIZED).build());
-		Securable sec = method.getAnnotation(Securable.class);
+		} else {
+			Securable sec = method.getAnnotation(Securable.class);
 
-		// If roles == 0 we only need to validate the token
-		if (sec.roles() != 0) {
-			String username = tokenHelper.extractUserFromToken(token);
-			int userRoles = getUserRoles(username);
-			if ((sec.roles() & userRoles) == 0) {
-				log.info("User {} has no necessary role to access url: {}", username, servletRequest.getPathInfo());
-				containerRequestContext.abortWith(Response.status(Status.UNAUTHORIZED).build());
+			// If roles == 0 we only need to validate the token
+			if (sec.roles() != 0) {
+				String username = tokenHelper.extractUserFromToken(token);
+				int userRoles = getUserRoles(username);
+				if ((sec.roles() & userRoles) == 0) {
+					log.info("User {} has no necessary role to access url: {}", username, servletRequest.getPathInfo());
+					containerRequestContext.abortWith(Response.status(Status.UNAUTHORIZED).build());
+				}
 			}
 		}
 	}
 
 	private int getUserRoles(String username) {
+		if (username == null)
+			return 0;
 		Integer userRoles = cache.get("roles_" + username, Integer.class);
 		if (userRoles == null) {
 			EntityManager em = emProvider.get();
diff --git a/securis/src/main/java/net/curisit/securis/utils/TokenHelper.java b/securis/src/main/java/net/curisit/securis/utils/TokenHelper.java
index b7d82de..19a1e9a 100644
--- a/securis/src/main/java/net/curisit/securis/utils/TokenHelper.java
+++ b/securis/src/main/java/net/curisit/securis/utils/TokenHelper.java
@@ -101,6 +101,8 @@
 
 	public String extractUserFromToken(String token) {
 		try {
+			if (token == null)
+				return null;
 			String tokenDecoded = new String(Base64.decode(token));
 			String[] parts = StringUtils.split(tokenDecoded, ' ');
 			if (parts == null || parts.length < 3)

--
Gitblit v1.3.2