rsanchez
2014-12-17 8200793f22c0ec9fc1ab9026406fe4d3a8cbaab7
#2205 feature - Added support for name or reference and email in license
requests
5 files modified
changed files
securis/pom.xml patch | view | blame | history
securis/src/main/java/net/curisit/securis/db/License.java patch | view | blame | history
securis/src/main/java/net/curisit/securis/services/ApiResource.java patch | view | blame | history
securis/src/main/java/net/curisit/securis/services/LicenseResource.java patch | view | blame | history
securis/src/main/webapp/js/licenses.js patch | view | blame | history
securis/pom.xml
....@@ -45,7 +45,7 @@
4545 <dependency>
4646 <groupId>net.curisit</groupId>
4747 <artifactId>securis-client</artifactId>
48
- <version>1.0.3-SNAPSHOT</version>
48
+ <version>1.0.4-SNAPSHOT</version>
4949 </dependency>
5050 <dependency>
5151 <groupId>org.hibernate</groupId>
securis/src/main/java/net/curisit/securis/db/License.java
....@@ -18,7 +18,6 @@
1818 import javax.persistence.NamedQueries;
1919 import javax.persistence.NamedQuery;
2020 import javax.persistence.NoResultException;
21
-import javax.persistence.NonUniqueResultException;
2221 import javax.persistence.OneToMany;
2322 import javax.persistence.Table;
2423 import javax.persistence.TypedQuery;
....@@ -29,7 +28,6 @@
2928 import net.curisit.securis.db.listeners.CreationTimestampListener;
3029 import net.curisit.securis.db.listeners.ModificationTimestampListener;
3130 import net.curisit.securis.services.exception.SeCurisServiceException;
32
-import net.curisit.securis.services.exception.SeCurisServiceException.ErrorCodes;
3331
3432 import org.apache.logging.log4j.LogManager;
3533 import org.apache.logging.log4j.Logger;
....@@ -59,7 +57,9 @@
5957 @NamedQuery(name = "last-code-suffix-used-in-pack", query = "SELECT max(l.codeSuffix) FROM License l where l.pack.id = :packId"),
6058 @NamedQuery(name = "list-licenses-by-pack", query = "SELECT l FROM License l where l.pack.id = :packId"),
6159 @NamedQuery(name = "list-licenses-by-req-data", query = "SELECT l FROM License l where l.reqDataHash = :hash"),
62
- @NamedQuery(name = "list-active-licenses-by-req-data", query = "SELECT l FROM License l where l.reqDataHash = :hash and l.status in ('AC', 'PA')")
60
+ @NamedQuery(name = "list-active-licenses-by-req-data", query = "SELECT l FROM License l where l.reqDataHash = :hash and l.status in ('AC', 'PA')"),
61
+ @NamedQuery(name = "list-valid-licenses-by-req-data", query = "SELECT l FROM License l where l.reqDataHash = :hash and l.status in ('RE', 'AC', 'PA')")
62
+
6363 })
6464 public class License implements CreationTimestampEntity, ModificationTimestampEntity, Serializable {
6565
....@@ -369,15 +369,47 @@
369369 }
370370 }
371371
372
- public static License findLicenseByRequestData(String requestData, EntityManager em) throws SeCurisServiceException {
372
+ /**
373
+ * Return licenses with status: REquested, ACtive, Pre-Active for a given
374
+ * request data
375
+ *
376
+ * @param requestData
377
+ * @param em
378
+ * @return
379
+ * @throws SeCurisServiceException
380
+ */
381
+ public static License findValidLicenseByRequestData(String requestData, EntityManager em) throws SeCurisServiceException {
382
+ TypedQuery<License> query = em.createNamedQuery("list-valid-licenses-by-req-data", License.class);
383
+ query.setParameter("hash", BlockedRequest.generateHash(requestData));
384
+ try {
385
+ List<License> list = query.getResultList();
386
+ if (list.size() == 0) {
387
+ return null;
388
+ }
389
+ if (list.size() > 1) {
390
+ LOG.error("There are more than 1 active or requested license for request data: {}\nHash: {}", requestData,
391
+ BlockedRequest.generateHash(requestData));
392
+ }
393
+ return list.get(0);
394
+ } catch (NoResultException e) {
395
+ // There is no license for request data
396
+ return null;
397
+ }
398
+ }
399
+
400
+ public static License findActiveLicenseByRequestData(String requestData, EntityManager em) throws SeCurisServiceException {
373401 TypedQuery<License> query = em.createNamedQuery("list-active-licenses-by-req-data", License.class);
374402 query.setParameter("hash", BlockedRequest.generateHash(requestData));
375403 try {
376
- return query.getSingleResult();
377
- } catch (NonUniqueResultException e) {
378
- LOG.error("There are more than 1 active license for request data: {}\nHash: {}", requestData, BlockedRequest.generateHash(requestData));
379
- throw new SeCurisServiceException(ErrorCodes.DUPLICATED_REQUEST_DATA, "There are more than 1 active license for request data hash: "
380
- + BlockedRequest.generateHash(requestData));
404
+ List<License> list = query.getResultList();
405
+ if (list.size() == 0) {
406
+ return null;
407
+ }
408
+ if (list.size() > 1) {
409
+ LOG.error("There are more than 1 active license for request data: {}\nHash: {}", requestData,
410
+ BlockedRequest.generateHash(requestData));
411
+ }
412
+ return list.get(0);
381413 } catch (NoResultException e) {
382414 // There is no license for request data
383415 return null;
securis/src/main/java/net/curisit/securis/services/ApiResource.java
....@@ -9,6 +9,7 @@
99 import javax.persistence.EntityManager;
1010 import javax.ws.rs.Consumes;
1111 import javax.ws.rs.GET;
12
+import javax.ws.rs.HeaderParam;
1213 import javax.ws.rs.POST;
1314 import javax.ws.rs.Path;
1415 import javax.ws.rs.Produces;
....@@ -120,11 +121,10 @@
120121 MediaType.APPLICATION_JSON
121122 })
122123 @Transactional
123
- public Response createFromRequest(RequestBean request, @Context BasicSecurityContext bsc) throws IOException, SeCurisServiceException,
124
- SeCurisException {
124
+ public Response createFromRequest(RequestBean request, @HeaderParam(LicenseManager.HEADER_LICENSE_NAME_OR_REFERENCE) String nameOrReference,
125
+ @HeaderParam(LicenseManager.HEADER_LICENSE_EMAIL) String userEmail) throws IOException, SeCurisServiceException, SeCurisException {
125126 LOG.info("Request to get license: {}", request);
126
-
127
- SignedLicenseBean lic = createLicense(request, emProvider.get(), false);
127
+ SignedLicenseBean lic = createLicense(request, emProvider.get(), false, nameOrReference, userEmail);
128128
129129 return Response.ok(lic).build();
130130 }
....@@ -148,8 +148,9 @@
148148 })
149149 @Transactional
150150 @SuppressWarnings("unchecked")
151
- public Response createFromRequestFile(MultipartFormDataInput mpfdi, @Context BasicSecurityContext bsc) throws IOException,
152
- SeCurisServiceException, SeCurisException {
151
+ public Response createFromRequestFile(MultipartFormDataInput mpfdi,
152
+ @HeaderParam(LicenseManager.HEADER_LICENSE_NAME_OR_REFERENCE) String nameOrReference,
153
+ @HeaderParam(LicenseManager.HEADER_LICENSE_EMAIL) String userEmail) throws IOException, SeCurisServiceException, SeCurisException {
153154 RequestBean req = new RequestBean();
154155 req.setPackCode(mpfdi.getFormDataPart("packCode", String.class, null));
155156 req.setLicenseTypeCode(mpfdi.getFormDataPart("licenseTypeCode", String.class, null));
....@@ -159,7 +160,7 @@
159160 req.setMacAddresses(mpfdi.getFormDataPart("macAddresses", List.class, null));
160161 req.setOsName(mpfdi.getFormDataPart("osName", String.class, null));
161162
162
- return createFromRequest(req, bsc);
163
+ return createFromRequest(req, nameOrReference, userEmail);
163164 }
164165
165166 /**
....@@ -194,7 +195,7 @@
194195 throw new SeCurisServiceException(ErrorCodes.LICENSE_NOT_READY_FOR_RENEW, "Only licenses with status 'Active' can be renew");
195196 }
196197
197
- SignedLicenseBean signedLic = createLicense(previousLic, em, true);
198
+ SignedLicenseBean signedLic = renewLicense(previousLic, em);
198199
199200 return Response.ok(signedLic).build();
200201 }
....@@ -273,7 +274,11 @@
273274 throw new SeCurisServiceException(ErrorCodes.LICENSE_NOT_READY_FOR_RENEW, "The license is still valid, not ready for renew");
274275 }
275276
276
- return createFromRequest(lic, bsc);
277
+ return renewFromPreviousLicense(lic, bsc);
278
+ }
279
+
280
+ private SignedLicenseBean renewLicense(RequestBean req, EntityManager em) throws SeCurisServiceException {
281
+ return createLicense(req, em, true, null, null);
277282 }
278283
279284 /**
....@@ -286,7 +291,8 @@
286291 * @return
287292 * @throws SeCurisServiceException
288293 */
289
- private SignedLicenseBean createLicense(RequestBean req, EntityManager em, boolean renew) throws SeCurisServiceException {
294
+ private SignedLicenseBean createLicense(RequestBean req, EntityManager em, boolean renew, String nameOrReference, String email)
295
+ throws SeCurisServiceException {
290296 LicenseBean previousLicenseBean = null;
291297 License lic = null;
292298 if (renew) {
....@@ -295,14 +301,25 @@
295301 if (lic.getStatus() != LicenseStatus.ACTIVE && lic.getStatus() != LicenseStatus.PRE_ACTIVE) {
296302 throw new SeCurisServiceException(ErrorCodes.INVALID_DATA, "The current license has been cancelled");
297303 }
298
- } else {
299
- lic = new License();
300304 }
301305
302306 if (!renew) {
303
- License existingLicense = License.findLicenseByRequestData(lic.getRequestData(), em);
304
- if (existingLicense != null) {
305
- throw new SeCurisServiceException(ErrorCodes.DUPLICATED_REQUEST_DATA, "There is already an active license for current request data");
307
+ try {
308
+ lic = License.findValidLicenseByRequestData(JsonUtils.toJSON(req), em);
309
+ } catch (SeCurisException e1) {
310
+ throw new SeCurisServiceException(ErrorCodes.INVALID_FORMAT, "Request sent is not valid");
311
+ }
312
+ if (lic != null) {
313
+ try {
314
+ if (lic.getStatus() == LicenseStatus.ACTIVE || lic.getStatus() == LicenseStatus.PRE_ACTIVE) {
315
+ return JsonUtils.json2object(lic.getLicenseData(), SignedLicenseBean.class);
316
+ }
317
+ } catch (SeCurisException e) {
318
+ throw new SeCurisServiceException(ErrorCodes.INVALID_FORMAT, "Error trying to get the license bean from license code: "
319
+ + lic.getCode());
320
+ }
321
+ } else {
322
+ lic = new License();
306323 }
307324 }
308325 Pack pack = em.createNamedQuery("pack-by-code", Pack.class).setParameter("code", req.getPackCode()).getSingleResult();
....@@ -310,11 +327,15 @@
310327 if (!renew && pack.getNumAvailables() <= 0) {
311328 throw new SeCurisServiceException(ErrorCodes.NO_AVAILABLE_LICENSES, "The current pack has no licenses availables");
312329 }
330
+ if (!renew && lic.getStatus() == LicenseStatus.REQUESTED && !pack.isLicensePreactivation()) {
331
+ throw new SeCurisServiceException(ErrorCodes.NO_AVAILABLE_LICENSES, "Current pack doesn't allow license preactivation");
332
+ }
333
+
313334 SignedLicenseBean signedLicense;
314335 try {
315336 String licCode;
316
- if (renew) {
317
- licCode = previousLicenseBean.getLicenseCode();
337
+ if (renew || lic.getStatus() == LicenseStatus.REQUESTED) {
338
+ licCode = lic.getCode();
318339 } else {
319340 licCode = LicUtils.getLicenseCode(pack.getCode(), licenseHelper.getNextCodeSuffix(pack.getId(), em));
320341 }
....@@ -340,23 +361,35 @@
340361 lic.setModificationTimestamp(new Date());
341362 lic.setExpirationDate(signedLicense.getExpirationDate());
342363 User user = em.find(User.class, CLIENT_USERNAME);
343
- if (!renew) {
344
-
364
+ if (!renew && lic.getStatus() != LicenseStatus.REQUESTED) {
345365 lic.setPack(pack);
346366 lic.setCreatedBy(user);
347367 lic.setCreationTimestamp(new Date());
348
- lic.setStatus(LicenseStatus.PRE_ACTIVE);
368
+ if (pack.isLicensePreactivation()) {
369
+ lic.setStatus(LicenseStatus.PRE_ACTIVE);
370
+ } else {
371
+ lic.setStatus(LicenseStatus.REQUESTED);
372
+ }
349373 lic.setCode(signedLicense.getLicenseCode());
350374 lic.setCodeSuffix(LicUtils.getLicenseCodeSuffix(signedLicense.getLicenseCode()));
375
+ lic.setEmail(email);
376
+ lic.setFullName(nameOrReference);
351377 em.persist(lic);
352378 em.persist(licenseHelper.createLicenseHistoryAction(lic, user, LicenseHistory.Actions.CREATE));
353
- if (lic.getStatus() == LicenseStatus.ACTIVE) {
379
+ if (pack.isLicensePreactivation()) {
354380 em.persist(licenseHelper.createLicenseHistoryAction(lic, user, LicenseHistory.Actions.PRE_ACTIVATE, "Pre-activated on creation"));
381
+ } else {
382
+ LOG.warn("License ({}) created, but the pack doesn't allow preactivation", lic.getCode());
383
+ throw new SeCurisServiceException(ErrorCodes.NO_AVAILABLE_LICENSES, "Current pack doesn't allow license preactivation");
355384 }
356385 } else {
357
- lic.setStatus(LicenseStatus.ACTIVE);
386
+ lic.setStatus(renew ? LicenseStatus.ACTIVE : LicenseStatus.PRE_ACTIVE);
358387 em.merge(lic);
359
- em.persist(licenseHelper.createLicenseHistoryAction(lic, user, LicenseHistory.Actions.RENEW));
388
+ if (renew) {
389
+ em.persist(licenseHelper.createLicenseHistoryAction(lic, user, LicenseHistory.Actions.RENEW));
390
+ } else {
391
+ em.persist(licenseHelper.createLicenseHistoryAction(lic, user, LicenseHistory.Actions.PRE_ACTIVATE, "Pre-activated after request"));
392
+ }
360393 }
361394
362395 return signedLicense;
securis/src/main/java/net/curisit/securis/services/LicenseResource.java
....@@ -213,7 +213,7 @@
213213
214214 validateRequestData(lic.getPack(), lic.getRequestData());
215215
216
- License existingLicense = License.findLicenseByRequestData(lic.getRequestData(), em);
216
+ License existingLicense = License.findActiveLicenseByRequestData(lic.getRequestData(), em);
217217 if (existingLicense != null && existingLicense.getStatus() == LicenseStatus.ACTIVE) {
218218 throw new SeCurisServiceException(ErrorCodes.NO_AVAILABLE_LICENSES, "The pack has not available licenses");
219219 }
....@@ -379,7 +379,7 @@
379379 User createdBy = userHelper.getUser(bsc.getUserPrincipal().getName(), em);
380380
381381 if (lic.getRequestData() != null) {
382
- License existingLicense = License.findLicenseByRequestData(lic.getRequestData(), em);
382
+ License existingLicense = License.findActiveLicenseByRequestData(lic.getRequestData(), em);
383383 if (existingLicense != null) {
384384 throw new SeCurisServiceException(ErrorCodes.DUPLICATED_REQUEST_DATA, "There is already an active license for current request data");
385385 }
securis/src/main/webapp/js/licenses.js
....@@ -32,6 +32,7 @@
3232 * copy them for simplicity, this info won't change easily
3333 */
3434 var PACK_ACTIONS_BY_STATUS = {
35
+ edit: [PACK_STATUS.CREATED, PACK_STATUS.EXPIRED, PACK_STATUS.ONHOLD, PACK_STATUS.ACTIVE],
3536 activate: [PACK_STATUS.CREATED, PACK_STATUS.EXPIRED, PACK_STATUS.ONHOLD],
3637 putonhold: [PACK_STATUS.ACTIVE],
3738 cancel: [PACK_STATUS.EXPIRED, PACK_STATUS.ONHOLD, PACK_STATUS.ACTIVE],
....@@ -169,6 +170,7 @@
169170 * we copy them for simplicity, this info won't change easily
170171 */
171172 var LIC_ACTIONS_BY_STATUS = {
173
+ edit: [LIC_STATUS.REQUESTED, LIC_STATUS.EXPIRED, LIC_STATUS.PREACTIVE, LIC_STATUS.ACTIVE, LIC_STATUS.CANCELLED, LIC_STATUS.BLOCKED],
172174 add_request: [LIC_STATUS.CREATED],
173175 activate: [LIC_STATUS.CREATED, LIC_STATUS.REQUESTED, LIC_STATUS.PREACTIVE],
174176 send: [LIC_STATUS.ACTIVE, LIC_STATUS.PREACTIVE],