| .. | .. |
|---|
| 45 | 45 | import net.curisit.securis.db.LicenseStatus; |
|---|
| 46 | 46 | import net.curisit.securis.db.Pack; |
|---|
| 47 | 47 | import net.curisit.securis.db.PackMetadata; |
|---|
| 48 | +import net.curisit.securis.db.PackStatus; |
|---|
| 48 | 49 | import net.curisit.securis.db.User; |
|---|
| 49 | 50 | import net.curisit.securis.security.BasicSecurityContext; |
|---|
| 50 | 51 | import net.curisit.securis.security.Securable; |
|---|
| .. | .. |
|---|
| 56 | 57 | import net.curisit.securis.utils.TokenHelper; |
|---|
| 57 | 58 | |
|---|
| 58 | 59 | import org.apache.commons.io.IOUtils; |
|---|
| 60 | +import org.apache.commons.lang3.ObjectUtils; |
|---|
| 59 | 61 | import org.apache.logging.log4j.LogManager; |
|---|
| 60 | 62 | import org.apache.logging.log4j.Logger; |
|---|
| 61 | 63 | |
|---|
| .. | .. |
|---|
| 158 | 160 | } |
|---|
| 159 | 161 | if (License.Status.isActionValid(License.Action.DOWNLOAD, lic.getStatus())) { |
|---|
| 160 | 162 | LOG.error("License with id {} is not active, so It can not downloaded", licId, bsc.getUserPrincipal()); |
|---|
| 161 | | - throw new SeCurisServiceException(Status.FORBIDDEN.getStatusCode(), "License is not active, so It can not be downloaded"); |
|---|
| 163 | + throw new SeCurisServiceException(ErrorCodes.WRONG_STATUS, "License is not active, so It can not be downloaded"); |
|---|
| 162 | 164 | } |
|---|
| 163 | 165 | em.persist(createLicenseHistoryAction(lic, getUser(bsc, em), LicenseHistory.Actions.DOWNLOAD)); |
|---|
| 164 | 166 | return Response |
|---|
| .. | .. |
|---|
| 193 | 195 | LOG.error("License with id {} can not be activated from current license status", licId); |
|---|
| 194 | 196 | throw new SeCurisServiceException(Status.FORBIDDEN.getStatusCode(), "License with id " + licId |
|---|
| 195 | 197 | + " can not be activated from the current license status"); |
|---|
| 198 | + } |
|---|
| 199 | + validateRequestData(lic.getPack(), lic.getRequestData()); |
|---|
| 200 | + |
|---|
| 201 | + License existingLicense = License.findLicenseByRequestData(lic.getRequestData(), em); |
|---|
| 202 | + if (existingLicense != null) { |
|---|
| 203 | + return Response.status(DefaultExceptionHandler.DEFAULT_APP_ERROR_STATUS_CODE) |
|---|
| 204 | + .header(DefaultExceptionHandler.ERROR_CODE_MESSAGE_HEADER, ErrorCodes.DUPLICATED_REQUEST_DATA) |
|---|
| 205 | + .header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "There is already an active license for current request data") |
|---|
| 206 | + .type(MediaType.APPLICATION_JSON).entity(existingLicense).build(); |
|---|
| 196 | 207 | } |
|---|
| 197 | 208 | |
|---|
| 198 | 209 | lic.setStatus(LicenseStatus.ACTIVE); |
|---|
| .. | .. |
|---|
| 291 | 302 | } |
|---|
| 292 | 303 | |
|---|
| 293 | 304 | lic.setStatus(LicenseStatus.CANCELLED); |
|---|
| 305 | + lic.setCancelledById(bsc.getUserPrincipal().getName()); |
|---|
| 294 | 306 | lic.setModificationTimestamp(new Date()); |
|---|
| 295 | 307 | em.persist(lic); |
|---|
| 296 | 308 | |
|---|
| 297 | | - em.persist(createLicenseHistoryAction(lic, getUser(bsc, em), LicenseHistory.Actions.CANCEL, "Cancelation reason: " + reason)); |
|---|
| 309 | + em.persist(createLicenseHistoryAction(lic, getUser(bsc, em), LicenseHistory.Actions.CANCEL, "Cancellation reason: " + reason)); |
|---|
| 298 | 310 | return Response.ok(lic).build(); |
|---|
| 299 | 311 | } |
|---|
| 300 | 312 | |
|---|
| .. | .. |
|---|
| 321 | 333 | LOG.error("License for pack with id {} can not be created by user {}", pack.getId(), bsc.getUserPrincipal()); |
|---|
| 322 | 334 | throw new SeCurisServiceException(ErrorCodes.UNAUTHORIZED_ACCESS, "Unathorized action on pack license"); |
|---|
| 323 | 335 | } |
|---|
| 336 | + if (pack.getStatus() != PackStatus.ACTIVE) { |
|---|
| 337 | + LOG.error("Current pack, {}, is not active so licenses cannot be created", pack.getId()); |
|---|
| 338 | + throw new SeCurisServiceException(ErrorCodes.WRONG_STATUS, "Current pack is not active so licenses cannot be created"); |
|---|
| 339 | + } |
|---|
| 324 | 340 | } |
|---|
| 325 | 341 | |
|---|
| 326 | 342 | User createdBy = getUser(bsc.getUserPrincipal().getName(), em); |
|---|
| 327 | 343 | |
|---|
| 328 | 344 | if (lic.getRequestData() != null) { |
|---|
| 345 | + License existingLicense = License.findLicenseByRequestData(lic.getRequestData(), em); |
|---|
| 346 | + if (existingLicense != null) { |
|---|
| 347 | + return Response.status(DefaultExceptionHandler.DEFAULT_APP_ERROR_STATUS_CODE) |
|---|
| 348 | + .header(DefaultExceptionHandler.ERROR_CODE_MESSAGE_HEADER, ErrorCodes.DUPLICATED_REQUEST_DATA) |
|---|
| 349 | + .header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "There is already an active license for current request data") |
|---|
| 350 | + .type(MediaType.APPLICATION_JSON).entity(existingLicense).build(); |
|---|
| 351 | + } |
|---|
| 329 | 352 | SignedLicenseBean signedLicense = generateLicense(lic, em); |
|---|
| 330 | 353 | // If user provide a request data the license status is passed |
|---|
| 331 | 354 | // directly to ACTIVE |
|---|
| .. | .. |
|---|
| 338 | 361 | lic.setLicenseData(JsonUtils.toJSON(signedLicense)); |
|---|
| 339 | 362 | } catch (SeCurisException e) { |
|---|
| 340 | 363 | LOG.error("Error generaing license JSON", e); |
|---|
| 341 | | - throw new SeCurisServiceException(ErrorCodes.INVALID_FORMAT, "Error generaing license JSON"); |
|---|
| 364 | + throw new SeCurisServiceException(ErrorCodes.INVALID_FORMAT, "Error generating license JSON"); |
|---|
| 342 | 365 | } |
|---|
| 343 | 366 | } else { |
|---|
| 344 | 367 | lic.setStatus(LicenseStatus.CREATED); |
|---|
| .. | .. |
|---|
| 387 | 410 | * @throws SeCurisServiceException |
|---|
| 388 | 411 | */ |
|---|
| 389 | 412 | private RequestBean validateRequestData(Pack pack, String requestData) throws SeCurisServiceException { |
|---|
| 413 | + if (requestData == null) { |
|---|
| 414 | + throw new SeCurisServiceException(ErrorCodes.INVALID_REQUEST_DATA, "Request data is empty"); |
|---|
| 415 | + } |
|---|
| 390 | 416 | RequestBean rb = null; |
|---|
| 391 | 417 | try { |
|---|
| 392 | 418 | rb = JsonUtils.json2object(requestData, RequestBean.class); |
|---|
| .. | .. |
|---|
| 422 | 448 | EntityManager em = emProvider.get(); |
|---|
| 423 | 449 | |
|---|
| 424 | 450 | License currentLicense = getCurrentLicense(licId, bsc, em); |
|---|
| 425 | | - |
|---|
| 426 | | - currentLicense.setCode(lic.getCode()); |
|---|
| 451 | + currentLicense.setComments(lic.getComments()); |
|---|
| 427 | 452 | currentLicense.setFullName(lic.getFullName()); |
|---|
| 428 | 453 | currentLicense.setEmail(lic.getEmail()); |
|---|
| 429 | | - if (lic.getRequestData() != null && currentLicense.getStatus() == LicenseStatus.CREATED) { |
|---|
| 430 | | - SignedLicenseBean signedLicense = generateLicense(lic, em); |
|---|
| 431 | | - lic.setStatus(LicenseStatus.ACTIVE); |
|---|
| 432 | | - try { |
|---|
| 433 | | - // Next line is necessary to normalize the String that contains |
|---|
| 434 | | - // the request. |
|---|
| 435 | | - lic.setRequestData(JsonUtils.toJSON((RequestBean) signedLicense)); |
|---|
| 436 | | - if (BlockedRequest.isRequestBlocked(lic.getRequestData(), em)) { |
|---|
| 437 | | - throw new SeCurisServiceException(ErrorCodes.BLOCKED_REQUEST_DATA, "Given request data is blocked and cannot be activate"); |
|---|
| 454 | + |
|---|
| 455 | + if (currentLicense.getStatus() == LicenseStatus.CREATED && !ObjectUtils.equals(currentLicense.getReqDataHash(), lic.getReqDataHash())) { |
|---|
| 456 | + if (lic.getRequestData() != null) { |
|---|
| 457 | + SignedLicenseBean signedLicense = generateLicense(lic, em); |
|---|
| 458 | + try { |
|---|
| 459 | + // Next line is necessary to normalize the String that |
|---|
| 460 | + // contains |
|---|
| 461 | + // the request. |
|---|
| 462 | + lic.setRequestData(JsonUtils.toJSON((RequestBean) signedLicense)); |
|---|
| 463 | + if (BlockedRequest.isRequestBlocked(lic.getRequestData(), em)) { |
|---|
| 464 | + throw new SeCurisServiceException(ErrorCodes.BLOCKED_REQUEST_DATA, "Given request data is blocked and cannot be used again"); |
|---|
| 465 | + } |
|---|
| 466 | + lic.setLicenseData(JsonUtils.toJSON(signedLicense)); |
|---|
| 467 | + } catch (SeCurisException e) { |
|---|
| 468 | + LOG.error("Error generaing license JSON", e); |
|---|
| 469 | + throw new SeCurisServiceException(ErrorCodes.INVALID_FORMAT, "Error generaing license JSON"); |
|---|
| 438 | 470 | } |
|---|
| 439 | | - lic.setLicenseData(JsonUtils.toJSON(signedLicense)); |
|---|
| 440 | | - } catch (SeCurisException e) { |
|---|
| 441 | | - LOG.error("Error generaing license JSON", e); |
|---|
| 442 | | - throw new SeCurisServiceException(ErrorCodes.INVALID_FORMAT, "Error generaing license JSON"); |
|---|
| 471 | + } else { |
|---|
| 472 | + // This set method could pass a null value |
|---|
| 473 | + currentLicense.setRequestData(null); |
|---|
| 443 | 474 | } |
|---|
| 444 | | - currentLicense.setRequestData(lic.getRequestData()); |
|---|
| 445 | 475 | } |
|---|
| 476 | + |
|---|
| 446 | 477 | currentLicense.setModificationTimestamp(new Date()); |
|---|
| 447 | 478 | em.persist(currentLicense); |
|---|
| 448 | 479 | em.persist(createLicenseHistoryAction(lic, getUser(bsc, em), LicenseHistory.Actions.MODIFY)); |
|---|
| .. | .. |
|---|
| 462 | 493 | EntityManager em = emProvider.get(); |
|---|
| 463 | 494 | License lic = getCurrentLicense(licId, bsc, em); |
|---|
| 464 | 495 | |
|---|
| 465 | | - if (lic.getStatus() != LicenseStatus.CANCELLED || lic.getStatus() != LicenseStatus.CREATED) { |
|---|
| 496 | + if (License.Status.isActionValid(License.Action.DELETE, lic.getStatus())) { |
|---|
| 466 | 497 | LOG.error("License {} can not be deleted with status {}", lic.getCode(), lic.getStatus()); |
|---|
| 467 | | - return Response.status(Status.FORBIDDEN) |
|---|
| 468 | | - .header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "License can not be deleted in current status").build(); |
|---|
| 498 | + throw new SeCurisServiceException(ErrorCodes.WRONG_STATUS, "License can not be deleted in current status: " + lic.getStatus().name()); |
|---|
| 499 | + } |
|---|
| 500 | + if (lic.getStatus() == LicenseStatus.CANCELLED) { |
|---|
| 501 | + // If license is removed and it's blocked then the blocked request |
|---|
| 502 | + // should be removed, that is, |
|---|
| 503 | + // the license deletion will unblock the request data |
|---|
| 504 | + TypedQuery<License> query = em.createNamedQuery("list-licenses-by-req-data", License.class); |
|---|
| 505 | + query.setParameter("hash", lic.getReqDataHash()); |
|---|
| 506 | + List<License> list = query.getResultList(); |
|---|
| 507 | + if (list == null || list.size() == 0) { |
|---|
| 508 | + BlockedRequest br = em.find(BlockedRequest.class, lic.getReqDataHash()); |
|---|
| 509 | + if (br != null) { |
|---|
| 510 | + em.remove(br); |
|---|
| 511 | + } |
|---|
| 512 | + } |
|---|
| 469 | 513 | } |
|---|
| 470 | 514 | |
|---|
| 471 | 515 | em.remove(lic); |
|---|
| 472 | 516 | return Response.ok(Utils.createMap("success", true, "id", licId)).build(); |
|---|
| 473 | 517 | } |
|---|
| 474 | 518 | |
|---|
| 475 | | - @DELETE |
|---|
| 519 | + @POST |
|---|
| 476 | 520 | @Path("/{licId}/block") |
|---|
| 477 | 521 | @Transactional |
|---|
| 478 | 522 | @Securable |
|---|
| .. | .. |
|---|
| 484 | 528 | EntityManager em = emProvider.get(); |
|---|
| 485 | 529 | License lic = getCurrentLicense(licId, bsc, em); |
|---|
| 486 | 530 | |
|---|
| 487 | | - if (lic.getStatus() != LicenseStatus.CANCELLED) { |
|---|
| 531 | + if (!License.Status.isActionValid(License.Action.BLOCK, lic.getStatus())) { |
|---|
| 488 | 532 | LOG.error("License can only be blocked in CANCELLED status, current: {}", lic.getStatus().name()); |
|---|
| 489 | 533 | throw new SeCurisServiceException(ErrorCodes.WRONG_STATUS, "License can only be blocked in CANCELLED status"); |
|---|
| 490 | 534 | } |
|---|
| .. | .. |
|---|
| 502 | 546 | return Response.ok(Utils.createMap("success", true, "id", licId)).build(); |
|---|
| 503 | 547 | } |
|---|
| 504 | 548 | |
|---|
| 549 | + @POST |
|---|
| 550 | + @Path("/{licId}/unblock") |
|---|
| 551 | + @Transactional |
|---|
| 552 | + @Securable |
|---|
| 553 | + @Produces({ |
|---|
| 554 | + MediaType.APPLICATION_JSON |
|---|
| 555 | + }) |
|---|
| 556 | + public Response unblock(@PathParam("licId") Integer licId, @Context BasicSecurityContext bsc) throws SeCurisServiceException { |
|---|
| 557 | + LOG.info("Unblocking license with id: {}", licId); |
|---|
| 558 | + EntityManager em = emProvider.get(); |
|---|
| 559 | + License lic = getCurrentLicense(licId, bsc, em); |
|---|
| 560 | + |
|---|
| 561 | + if (BlockedRequest.isRequestBlocked(lic.getRequestData(), em)) { |
|---|
| 562 | + BlockedRequest blockedReq = em.find(BlockedRequest.class, lic.getReqDataHash()); |
|---|
| 563 | + em.remove(blockedReq); |
|---|
| 564 | + em.persist(createLicenseHistoryAction(lic, getUser(bsc, em), LicenseHistory.Actions.UNBLOCK)); |
|---|
| 565 | + } else { |
|---|
| 566 | + LOG.info("Request data for license {} is NOT blocked", licId); |
|---|
| 567 | + } |
|---|
| 568 | + |
|---|
| 569 | + return Response.ok(Utils.createMap("success", true, "id", licId)).build(); |
|---|
| 570 | + } |
|---|
| 571 | + |
|---|
| 505 | 572 | private License getCurrentLicense(Integer licId, BasicSecurityContext bsc, EntityManager em) throws SeCurisServiceException { |
|---|
| 506 | 573 | if (licId == null || "".equals(licId)) { |
|---|
| 507 | 574 | LOG.error("License ID is mandatory"); |
|---|