/* * Copyright @ 2013 CurisTEC, S.A.S. All Rights Reserved. */ package net.curisit.securis.services; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import jakarta.annotation.security.RolesAllowed; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; import jakarta.persistence.TypedQuery; import jakarta.servlet.http.HttpServletRequest; import jakarta.ws.rs.Consumes; import jakarta.ws.rs.DELETE; import jakarta.ws.rs.GET; import jakarta.ws.rs.HeaderParam; import jakarta.ws.rs.POST; import jakarta.ws.rs.PUT; import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.Context; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import net.curisit.integrity.commons.Utils; import net.curisit.securis.DefaultExceptionHandler; import net.curisit.securis.db.Application; import net.curisit.securis.db.ApplicationMetadata; import net.curisit.securis.db.User.Rol; import net.curisit.securis.ioc.EnsureTransaction; import net.curisit.securis.security.BasicSecurityContext; import net.curisit.securis.security.Securable; import net.curisit.securis.services.exception.SeCurisServiceException; import net.curisit.securis.services.exception.SeCurisServiceException.ErrorCodes; import net.curisit.securis.services.helpers.MetadataHelper; import net.curisit.securis.utils.TokenHelper; /** * ApplicationResource *
* REST endpoints to list, fetch, create, update and delete {@link Application}s. * Security: *
* Constructor */ public ApplicationResource() {} /** * index
* List applications visible to the current user.
*
* @param bsc security context
* @return 200 with list (possibly empty) or 200 empty if user has no app scope
*/
@GET
@Path("/")
@Produces({ MediaType.APPLICATION_JSON })
@Securable
public Response index(@Context BasicSecurityContext bsc) {
LOG.info("Getting applications list ");
em.clear();
TypedQuery
* Fetch a single application by ID.
*
* @param appid string ID
* @return 200 + entity or 404 if not found
* @throws SeCurisServiceException when ID is invalid or not found
*/
@GET
@Path("/{appid}")
@Produces({ MediaType.APPLICATION_JSON })
@Securable
public Response get(@PathParam("appid") String appid) throws SeCurisServiceException {
LOG.info("Getting application data for id: {}: ", appid);
if (appid == null || "".equals(appid)) {
LOG.error("Application ID is mandatory");
return Response.status(Status.NOT_FOUND).build();
}
em.clear();
Application app = null;
try {
LOG.info("READY to GET app: {}", appid);
app = em.find(Application.class, Integer.parseInt(appid));
} catch (Exception e) {
LOG.info("ERROR GETTING app: {}", e);
}
if (app == null) {
LOG.error("Application with id {} not found in DB", appid);
throw new SeCurisServiceException(ErrorCodes.NOT_FOUND, "Application not found with ID: " + appid);
}
return Response.ok(app).build();
}
/**
* create
* Create a new application with optional metadata entries.
*
* @param app application payload
* @param token auth token (audited externally)
* @return 200 + persisted entity
*/
@POST
@Path("/")
@Consumes(MediaType.APPLICATION_JSON)
@Produces({ MediaType.APPLICATION_JSON })
@EnsureTransaction
@Securable(roles = Rol.ADMIN)
@RolesAllowed(BasicSecurityContext.ROL_ADMIN)
public Response create(Application app, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) {
LOG.info("Creating new application");
app.setCreationTimestamp(new Date());
em.persist(app);
if (app.getApplicationMetadata() != null) {
for (ApplicationMetadata md : app.getApplicationMetadata()) {
md.setApplication(app);
md.setCreationTimestamp(new Date());
em.persist(md);
}
}
LOG.info("Creating application ({}) with date: {}", app.getId(), app.getCreationTimestamp());
return Response.ok(app).build();
}
/**
* modify
* Update core fields and reconcile metadata set:
*
* Build a map from metadata key → entity for fast reconciliation.
*
* @param applicationMetadata
* @return mapMD
*/
private Map
* Delete an application by ID.
* Note: deletion is not allowed if there are dependent entities (enforced by DB/cascade).
*
*
* @param appid path ID
* @param app new state
*/
@PUT
@POST
@Path("/{appid}")
@EnsureTransaction
@Consumes(MediaType.APPLICATION_JSON)
@Produces({ MediaType.APPLICATION_JSON })
@Securable(roles = Rol.ADMIN)
@RolesAllowed(BasicSecurityContext.ROL_ADMIN)
public Response modify(Application app, @PathParam("appid") String appid, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) {
LOG.info("Modifying application with id: {}", appid);
Application currentapp = em.find(Application.class, Integer.parseInt(appid));
if (currentapp == null) {
LOG.error("Application with id {} not found in DB", appid);
return Response.status(Status.NOT_FOUND)
.header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Application not found with ID: " + appid)
.build();
}
currentapp.setCode(app.getCode());
currentapp.setName(app.getName());
currentapp.setLicenseFilename(app.getLicenseFilename());
currentapp.setDescription(app.getDescription());
Set