securis/src/main/java/net/curisit/securis/db/Application.java
.. .. @@ -4,6 +4,7 @@ 4 4 import java.util.Date; 5 5 import java.util.Set; 6 6 7 +import javax.persistence.CascadeType;7 8 import javax.persistence.Column; 8 9 import javax.persistence.Entity; 9 10 import javax.persistence.FetchType; .. .. @@ -56,7 +57,7 @@ 56 57 @OneToMany(fetch = FetchType.LAZY, mappedBy = "application") 57 58 private Set<LicenseType> licenseTypes; 58 59 59 - @OneToMany(fetch = FetchType.LAZY, mappedBy = "application")60 + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "application")60 61 private Set<ApplicationMetadata> metadata; 61 62 62 63 public Integer getId() { securis/src/main/java/net/curisit/securis/db/LicenseType.java
.. .. @@ -4,6 +4,7 @@ 4 4 import java.util.Date; 5 5 import java.util.Set; 6 6 7 +import javax.persistence.CascadeType;7 8 import javax.persistence.Column; 8 9 import javax.persistence.Entity; 9 10 import javax.persistence.FetchType; .. .. @@ -62,7 +63,7 @@ 62 63 @JoinColumn(name = "application_id") 63 64 private Application application; 64 65 65 - @OneToMany(fetch = FetchType.LAZY, mappedBy = "licenseType")66 + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "licenseType")66 67 private Set<LicenseTypeMetadata> metadata; 67 68 68 69 public Set<LicenseTypeMetadata> getMetadata() { securis/src/main/java/net/curisit/securis/db/Pack.java
.. .. @@ -99,7 +99,7 @@ 99 99 @JsonProperty("default_valid_period") 100 100 private Integer defaultValidPeriod; 101 101 102 - @OneToMany(fetch = FetchType.LAZY, mappedBy = "pack")102 + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "pack")103 103 private Set<PackMetadata> metadata; 104 104 105 105 public Integer getId() { .. .. @@ -317,6 +317,14 @@ 317 317 this.endValidDate = endValidDate; 318 318 } 319 319 320 + public Set<License> getLicenses() {321 + return licenses;322 + }323 +324 + public void setLicenses(Set<License> licenses) {325 + this.licenses = licenses;326 + }327 +320 328 @Override 321 329 public boolean equals(Object obj) { 322 330 if (!(obj instanceof Pack)) securis/src/main/java/net/curisit/securis/services/LicenseResource.java
.. .. @@ -1,7 +1,6 @@ 1 1 package net.curisit.securis.services; 2 2 3 3 import java.io.File; 4 -import java.io.FileWriter;5 4 import java.io.IOException; 6 5 import java.nio.file.Files; 7 6 import java.text.MessageFormat; .. .. @@ -51,6 +50,8 @@ 51 50 import net.curisit.securis.security.Securable; 52 51 import net.curisit.securis.services.exception.SeCurisServiceException; 53 52 import net.curisit.securis.services.exception.SeCurisServiceException.ErrorCodes; 53 +import net.curisit.securis.services.helpers.LicenseHelper;54 +import net.curisit.securis.services.helpers.UserHelper;54 55 import net.curisit.securis.utils.EmailManager; 55 56 import net.curisit.securis.utils.JsonUtils; 56 57 import net.curisit.securis.utils.Params; .. .. @@ -75,16 +76,22 @@ 75 76 private static final Logger LOG = LogManager.getLogger(LicenseResource.class); 76 77 77 78 @Inject 78 - TokenHelper tokenHelper;79 + private TokenHelper tokenHelper;79 80 80 81 @Inject 81 - EmailManager emailManager;82 + private EmailManager emailManager;82 83 83 84 @Inject 84 - Provider<EntityManager> emProvider;85 + private UserHelper userHelper;85 86 86 87 @Inject 87 - LicenseGenerator licenseGenerator;88 + private LicenseHelper licenseHelper;89 +90 + @Inject91 + private Provider<EntityManager> emProvider;92 +93 + @Inject94 + private LicenseGenerator licenseGenerator;88 95 89 96 /** 90 97 * .. .. @@ -162,7 +169,7 @@ 162 169 LOG.error("License with id {} is not active, so It can not downloaded", licId, bsc.getUserPrincipal()); 163 170 throw new SeCurisServiceException(ErrorCodes.WRONG_STATUS, "License is not active, so It can not be downloaded"); 164 171 } 165 - em.persist(createLicenseHistoryAction(lic, getUser(bsc, em), LicenseHistory.Actions.DOWNLOAD));172 + em.persist(licenseHelper.createLicenseHistoryAction(lic, userHelper.getUser(bsc, em), LicenseHistory.Actions.DOWNLOAD));166 173 return Response 167 174 .ok(lic.getLicenseData()) 168 175 .header("Content-Disposition", .. .. @@ -210,8 +217,8 @@ 210 217 lic.setModificationTimestamp(new Date()); 211 218 212 219 em.persist(lic); 213 - User user = getUser(bsc.getUserPrincipal().getName(), em);214 - em.persist(createLicenseHistoryAction(lic, user, LicenseHistory.Actions.ACTIVATE));220 + User user = userHelper.getUser(bsc.getUserPrincipal().getName(), em);221 + em.persist(licenseHelper.createLicenseHistoryAction(lic, user, LicenseHistory.Actions.ACTIVATE));215 222 return Response.ok(lic).build(); 216 223 } 217 224 .. .. @@ -243,12 +250,12 @@ 243 250 throw new SeCurisServiceException(Status.NOT_FOUND.getStatusCode(), "There is no license file available"); 244 251 } 245 252 246 - User user = getUser(bsc.getUserPrincipal().getName(), em);253 + User user = userHelper.getUser(bsc.getUserPrincipal().getName(), em);247 254 try { 248 255 String subject = MessageFormat.format(Params.get(Params.KEYS.EMAIL_LIC_DEFAULT_SUBJECT), lic.getPack().getAppName()); 249 256 String email_tpl = IOUtils.toString(this.getClass().getResourceAsStream("/lic_email_template.en")); 250 257 String body = MessageFormat.format(email_tpl, lic.getFullName(), app.getName()); 251 - licFile = createTemporaryLicenseFile(lic, app.getLicenseFilename());258 + licFile = licenseHelper.createTemporaryLicenseFile(lic, app.getLicenseFilename());252 259 253 260 emailManager.sendEmail(subject, body, lic.getEmail(), addCC ? user.getEmail() : null, licFile); 254 261 } catch (IOException e) { .. .. @@ -262,7 +269,7 @@ 262 269 263 270 lic.setModificationTimestamp(new Date()); 264 271 em.persist(lic); 265 - em.persist(createLicenseHistoryAction(lic, user, LicenseHistory.Actions.SEND, "Email sent to: " + lic.getEmail()));272 + em.persist(licenseHelper.createLicenseHistoryAction(lic, user, LicenseHistory.Actions.SEND, "Email sent to: " + lic.getEmail()));266 273 return Response.ok(lic).build(); 267 274 } 268 275 .. .. @@ -301,23 +308,8 @@ 301 308 + " can not be canceled without a reason"); 302 309 } 303 310 304 - lic.setStatus(LicenseStatus.CANCELLED);305 - lic.setCancelledById(bsc.getUserPrincipal().getName());306 - lic.setModificationTimestamp(new Date());307 - em.persist(lic);308 -309 - em.persist(createLicenseHistoryAction(lic, getUser(bsc, em), LicenseHistory.Actions.CANCEL, "Cancellation reason: " + reason));311 + licenseHelper.cancelLicense(lic, reason, bsc, em);310 312 return Response.ok(lic).build(); 311 - }312 -313 - /**314 - * Cancel the license315 - *316 - * @param lic317 - * @param em318 - */319 - public static void cancelLicense(License lic, EntityManager em) throws SeCurisServiceException {320 -321 313 } 322 314 323 315 @POST .. .. @@ -349,7 +341,7 @@ 349 341 } 350 342 } 351 343 352 - User createdBy = getUser(bsc.getUserPrincipal().getName(), em);344 + User createdBy = userHelper.getUser(bsc.getUserPrincipal().getName(), em);353 345 354 346 if (lic.getRequestData() != null) { 355 347 License existingLicense = License.findLicenseByRequestData(lic.getRequestData(), em); .. .. @@ -380,9 +372,9 @@ 380 372 lic.setCreationTimestamp(new Date()); 381 373 lic.setModificationTimestamp(lic.getCreationTimestamp()); 382 374 em.persist(lic); 383 - em.persist(createLicenseHistoryAction(lic, createdBy, LicenseHistory.Actions.CREATE));375 + em.persist(licenseHelper.createLicenseHistoryAction(lic, createdBy, LicenseHistory.Actions.CREATE));384 376 if (lic.getStatus() == LicenseStatus.ACTIVE) { 385 - em.persist(createLicenseHistoryAction(lic, createdBy, LicenseHistory.Actions.CREATE, "Activated on creation"));377 + em.persist(licenseHelper.createLicenseHistoryAction(lic, createdBy, LicenseHistory.Actions.CREATE, "Activated on creation"));386 378 } 387 379 388 380 return Response.ok(lic).build(); .. .. @@ -486,7 +478,7 @@ 486 478 487 479 currentLicense.setModificationTimestamp(new Date()); 488 480 em.persist(currentLicense); 489 - em.persist(createLicenseHistoryAction(lic, getUser(bsc, em), LicenseHistory.Actions.MODIFY));481 + em.persist(licenseHelper.createLicenseHistoryAction(lic, userHelper.getUser(bsc, em), LicenseHistory.Actions.MODIFY));490 482 491 483 return Response.ok(currentLicense).build(); 492 484 } .. .. @@ -547,12 +539,12 @@ 547 539 } 548 540 BlockedRequest blockedReq = new BlockedRequest(); 549 541 blockedReq.setCreationTimestamp(new Date()); 550 - blockedReq.setBlockedBy(getUser(bsc, em));542 + blockedReq.setBlockedBy(userHelper.getUser(bsc, em));551 543 blockedReq.setRequestData(lic.getRequestData()); 552 544 553 545 em.persist(blockedReq); 554 546 555 - em.persist(createLicenseHistoryAction(lic, getUser(bsc, em), LicenseHistory.Actions.BLOCK));547 + em.persist(licenseHelper.createLicenseHistoryAction(lic, userHelper.getUser(bsc, em), LicenseHistory.Actions.BLOCK));556 548 return Response.ok(Utils.createMap("success", true, "id", licId)).build(); 557 549 } 558 550 .. .. @@ -571,7 +563,7 @@ 571 563 if (BlockedRequest.isRequestBlocked(lic.getRequestData(), em)) { 572 564 BlockedRequest blockedReq = em.find(BlockedRequest.class, lic.getReqDataHash()); 573 565 em.remove(blockedReq); 574 - em.persist(createLicenseHistoryAction(lic, getUser(bsc, em), LicenseHistory.Actions.UNBLOCK));566 + em.persist(licenseHelper.createLicenseHistoryAction(lic, userHelper.getUser(bsc, em), LicenseHistory.Actions.UNBLOCK));575 567 } else { 576 568 LOG.info("Request data for license {} is NOT blocked", licId); 577 569 } .. .. @@ -595,43 +587,6 @@ 595 587 throw new SeCurisServiceException(Status.UNAUTHORIZED.getStatusCode(), "Unathorized access to license data"); 596 588 } 597 589 return lic; 598 - }599 -600 - private User getUser(BasicSecurityContext bsc, EntityManager em) throws SeCurisServiceException {601 - String username = bsc.getUserPrincipal().getName();602 - return getUser(username, em);603 - }604 -605 - private User getUser(String username, EntityManager em) throws SeCurisServiceException {606 - User user = null;607 - if (username != null) {608 - user = em.find(User.class, username);609 - if (user == null) {610 - throw new SeCurisServiceException(Status.NOT_FOUND.getStatusCode(), "User not found with username: " + username);611 - }612 - }613 - return user;614 - }615 -616 - private File createTemporaryLicenseFile(License lic, String licFileName) throws IOException {617 - File f = Files.createTempDirectory("securis-server").toFile();618 - f = new File(f, licFileName);619 - IOUtils.write(lic.getLicenseData(), new FileWriter(f));620 - return f;621 - }622 -623 - private LicenseHistory createLicenseHistoryAction(License lic, User user, String action, String comments) {624 - LicenseHistory lh = new LicenseHistory();625 - lh.setLicense(lic);626 - lh.setUser(user);627 - lh.setTimestamp(new Date());628 - lh.setAction(action);629 - lh.setComments(comments);630 - return lh;631 - }632 -633 - private LicenseHistory createLicenseHistoryAction(License lic, User user, String action) {634 - return createLicenseHistoryAction(lic, user, action, null);635 590 } 636 591 637 592 public static void main(String[] args) throws IOException { securis/src/main/java/net/curisit/securis/services/PackResource.java
.. .. @@ -12,6 +12,7 @@ 12 12 import javax.persistence.TypedQuery; 13 13 import javax.ws.rs.Consumes; 14 14 import javax.ws.rs.DELETE; 15 +import javax.ws.rs.FormParam;15 16 import javax.ws.rs.GET; 16 17 import javax.ws.rs.POST; 17 18 import javax.ws.rs.PUT; .. .. @@ -26,6 +27,8 @@ 26 27 import net.curisit.integrity.commons.Utils; 27 28 import net.curisit.securis.DefaultExceptionHandler; 28 29 import net.curisit.securis.SeCurisException; 30 +import net.curisit.securis.db.License;31 +import net.curisit.securis.db.LicenseStatus;29 32 import net.curisit.securis.db.LicenseType; 30 33 import net.curisit.securis.db.Organization; 31 34 import net.curisit.securis.db.Pack; .. .. @@ -36,6 +39,8 @@ 36 39 import net.curisit.securis.security.Securable; 37 40 import net.curisit.securis.services.exception.SeCurisServiceException; 38 41 import net.curisit.securis.services.exception.SeCurisServiceException.ErrorCodes; 42 +import net.curisit.securis.services.helpers.LicenseHelper;43 +import net.curisit.securis.services.helpers.UserHelper;39 44 import net.curisit.securis.utils.TokenHelper; 40 45 41 46 import org.apache.logging.log4j.LogManager; .. .. @@ -60,8 +65,11 @@ 60 65 @Inject 61 66 Provider<EntityManager> emProvider; 62 67 63 - public PackResource() {64 - }68 + @Inject69 + private UserHelper userHelper;70 +71 + @Inject72 + private LicenseHelper licenseHelper;65 73 66 74 /** 67 75 * .. .. @@ -297,8 +305,9 @@ 297 305 @Produces({ 298 306 MediaType.APPLICATION_JSON 299 307 }) 300 - public Response cancel(@PathParam("packId") Integer packId) throws SeCurisServiceException {301 - LOG.info("Putting On hold pack with id: {}", packId);308 + public Response cancel(@PathParam("packId") Integer packId, @FormParam("reason") String reason, @Context BasicSecurityContext bsc)309 + throws SeCurisServiceException {310 + LOG.info("Cancelling pack with id: {}", packId);302 311 EntityManager em = emProvider.get(); 303 312 304 313 Pack currentPack = em.find(Pack.class, packId); .. .. @@ -308,6 +317,12 @@ 308 317 throw new SeCurisServiceException(ErrorCodes.WRONG_STATUS, "Pack cannot be cancelled in status: " + currentPack.getStatus().name()); 309 318 } 310 319 320 + Set<License> licenses = currentPack.getLicenses();321 + for (License license : licenses) {322 + if (license.getStatus() == LicenseStatus.ACTIVE || license.getStatus() == LicenseStatus.PRE_ACTIVE) {323 + licenseHelper.cancelLicense(license, "Pack cancellation. " + reason, bsc, em);324 + }325 + }311 326 currentPack.setStatus(PackStatus.CANCELLED); 312 327 em.persist(currentPack); 313 328 .. .. @@ -334,7 +349,7 @@ 334 349 @Produces({ 335 350 MediaType.APPLICATION_JSON 336 351 }) 337 - public Response delete(@PathParam("packId") String packId) {352 + public Response delete(@PathParam("packId") String packId) throws SeCurisServiceException {338 353 LOG.info("Deleting pack with id: {}", packId); 339 354 EntityManager em = emProvider.get(); 340 355 Pack pack = em.find(Pack.class, Integer.parseInt(packId)); .. .. @@ -343,10 +358,14 @@ 343 358 return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Pack was not found, ID: " + packId) 344 359 .build(); 345 360 } 346 - if (pack.getMetadata() != null) {347 - for (PackMetadata md : pack.getMetadata()) {348 - em.remove(md);361 + // Pack metadata is removed in cascade automatically.362 +363 + Set<License> licenses = pack.getLicenses();364 + for (License license : licenses) {365 + if (license.getStatus() == LicenseStatus.ACTIVE || license.getStatus() == LicenseStatus.PRE_ACTIVE) {366 + throw new SeCurisServiceException(ErrorCodes.WRONG_STATUS, "An active license cannot be deleted. License code: " + license.getCode());349 367 } 368 + em.remove(license);350 369 } 351 370 352 371 em.remove(pack); securis/src/main/java/net/curisit/securis/services/helpers/LicenseHelper.java
.. .. @@ -0,0 +1,64 @@ 1 +package net.curisit.securis.services.helpers;2 +3 +import java.io.File;4 +import java.io.FileWriter;5 +import java.io.IOException;6 +import java.nio.file.Files;7 +import java.util.Date;8 +9 +import javax.inject.Inject;10 +import javax.inject.Singleton;11 +import javax.persistence.EntityManager;12 +13 +import net.curisit.securis.db.License;14 +import net.curisit.securis.db.LicenseHistory;15 +import net.curisit.securis.db.LicenseStatus;16 +import net.curisit.securis.db.User;17 +import net.curisit.securis.security.BasicSecurityContext;18 +import net.curisit.securis.services.exception.SeCurisServiceException;19 +20 +import org.apache.commons.io.IOUtils;21 +22 +@Singleton23 +public class LicenseHelper {24 +25 + @Inject26 + private UserHelper userHelper;27 +28 + /**29 + * Cancel the license30 + *31 + * @param lic32 + * @param em33 + */34 + public void cancelLicense(License lic, String reason, BasicSecurityContext bsc, EntityManager em) throws SeCurisServiceException {35 + lic.setStatus(LicenseStatus.CANCELLED);36 + lic.setCancelledById(bsc.getUserPrincipal().getName());37 + lic.setModificationTimestamp(new Date());38 + em.persist(lic);39 +40 + em.persist(createLicenseHistoryAction(lic, userHelper.getUser(bsc, em), LicenseHistory.Actions.CANCEL, "Cancellation reason: " + reason));41 +42 + }43 +44 + public LicenseHistory createLicenseHistoryAction(License lic, User user, String action, String comments) {45 + LicenseHistory lh = new LicenseHistory();46 + lh.setLicense(lic);47 + lh.setUser(user);48 + lh.setTimestamp(new Date());49 + lh.setAction(action);50 + lh.setComments(comments);51 + return lh;52 + }53 +54 + public LicenseHistory createLicenseHistoryAction(License lic, User user, String action) {55 + return createLicenseHistoryAction(lic, user, action, null);56 + }57 +58 + public File createTemporaryLicenseFile(License lic, String licFileName) throws IOException {59 + File f = Files.createTempDirectory("securis-server").toFile();60 + f = new File(f, licFileName);61 + IOUtils.write(lic.getLicenseData(), new FileWriter(f));62 + return f;63 + }64 +}securis/src/main/java/net/curisit/securis/services/helpers/UserHelper.java
.. .. @@ -0,0 +1,29 @@ 1 +package net.curisit.securis.services.helpers;2 +3 +import javax.inject.Singleton;4 +import javax.persistence.EntityManager;5 +import javax.ws.rs.core.Response.Status;6 +7 +import net.curisit.securis.db.User;8 +import net.curisit.securis.security.BasicSecurityContext;9 +import net.curisit.securis.services.exception.SeCurisServiceException;10 +11 +@Singleton12 +public class UserHelper {13 +14 + public User getUser(BasicSecurityContext bsc, EntityManager em) throws SeCurisServiceException {15 + String username = bsc.getUserPrincipal().getName();16 + return getUser(username, em);17 + }18 +19 + public User getUser(String username, EntityManager em) throws SeCurisServiceException {20 + User user = null;21 + if (username != null) {22 + user = em.find(User.class, username);23 + if (user == null) {24 + throw new SeCurisServiceException(Status.NOT_FOUND.getStatusCode(), "User not found with username: " + username);25 + }26 + }27 + return user;28 + }29 +}securis/src/main/resources/static/js/licenses.js
.. .. @@ -105,11 +105,12 @@ 105 105 var _error = _createErrorCallback(pack, $L.get('Put on hold'), _onerror); 106 106 packResource.putonhold({id: pack.id}, _success, _error); 107 107 } 108 - this.cancel = function(pack, _onsuccess, _onerror) {108 + this.cancel = function(pack, extra_data, _onsuccess, _onerror) {109 109 console.log('Cancellation on pack: ' + pack.id); 110 110 var _success = _createSuccessCallback($L.get('Cancellation'), $L.get("Pack '{0}' {1} successfully", pack.code, $L.get("cancelled")), _onsuccess); 111 111 var _error = _createErrorCallback(pack, $L.get('Cancellation'), _onerror); 112 - packResource.cancel({id: pack.id}, _success, _error);112 + var params = angular.extend({id: pack.id}, extra_data);113 + packResource.cancel(params, _success, _error);113 114 } 114 115 this.delete = function(pack, _onsuccess, _onerror) { 115 116 console.log('Delete on pack: ' + pack.id); .. .. @@ -334,10 +335,17 @@ 334 335 */ 335 336 $scope.execute = function(action, pack) { 336 337 var _execute = function(extra_data) { 337 - Packs[action](pack || $scope.pack, extra_data, function() {338 - if (!$scope.isNew) $scope.showForm = false;339 - $scope.packs = Packs.getPacksList();340 - });338 + if (extra_data) {339 + Packs[action](pack || $scope.pack, extra_data, function() {340 + if (!$scope.isNew) $scope.showForm = false;341 + $scope.packs = Packs.getPacksList();342 + });343 + } else {344 + Packs[action](pack || $scope.pack, function() {345 + if (!$scope.isNew) $scope.showForm = false;346 + $scope.packs = Packs.getPacksList();347 + });348 + }341 349 } 342 350 if (action === 'delete') { 343 351 BootstrapDialog.confirm($L.get("The pack '{0}' will be deleted, are you sure ?", $scope.pack.code), function(answer) { securis/src/main/resources/static/licenses.html
.. .. @@ -266,24 +266,6 @@ 266 266 </form> 267 267 </div> 268 268 269 -<div class="modal fade" id="cancellationReasonDialog" tabindex="-1" role="dialog" aria-labelledby="cancelDialogLabel" aria-hidden="true">270 - <div class="modal-dialog">271 - <div class="modal-content">272 - <div class="modal-header">273 - <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>274 - <h4 class="modal-title" id="cancelDialogLabel" i18n>Pack cancellation</h4>275 - </div>276 - <div class="modal-body">277 -278 - </div>279 - <div class="modal-footer">280 - <button type="button" class="btn btn-default" data-dismiss="modal" i18n>Close</button>281 - <button type="button" class="btn btn-primary" i18n>Cancel pack</button>282 - </div>283 - </div>284 - </div>285 -</div>286 -287 269 <div class="panel panel-default"> 288 270 <div class="panel-heading"> 289 271 Packs <span class="badge pull-right" ng-bind="packs.length || 0"></span> .. .. @@ -323,7 +305,6 @@ 323 305 </div> 324 306 325 307 </div> 326 - {{license | json}}327 308 <div id="licenses_section" class="col-md-6" 328 309 ng-controller="LicensesCtrl"> 329 310 <nav class="navbar navbar-default navbar-static-top"