From 94c288b4f8d353c44b64e40c0863c7fce6782293 Mon Sep 17 00:00:00 2001
From: rsanchez <rsanchez@curisit.net>
Date: Thu, 24 Sep 2015 17:26:14 +0000
Subject: [PATCH] #2756 fix - chnaged API to allow activation by code and other UI changes
---
securis/src/main/java/net/curisit/securis/services/ApiResource.java | 219 +++++++++++++++++++++---------
securis/src/main/java/net/curisit/securis/ioc/RequestsInterceptor.java | 6
securis/src/main/java/net/curisit/securis/db/Application.java | 9 +
securis/src/main/webapp/js/catalogs.json | 6
securis/src/main/java/net/curisit/securis/services/BasicServices.java | 6
securis/src/main/java/net/curisit/securis/services/ApplicationResource.java | 1
securis/src/main/java/net/curisit/securis/db/License.java | 33 ++++
securis/src/main/webapp/licenses.html | 38 +++-
securis/pom.xml | 4
securis/src/main/java/net/curisit/securis/services/helpers/LicenseHelper.java | 3
securis/src/main/java/net/curisit/securis/utils/TokenHelper.java | 22 ++
securis/src/main/java/net/curisit/securis/services/LicenseResource.java | 12 +
securis/src/main/webapp/js/licenses.js | 20 ++
securis/src/main/resources/db/schema.sql | 2
14 files changed, 286 insertions(+), 95 deletions(-)
diff --git a/securis/pom.xml b/securis/pom.xml
index 74efe79..d6a4847 100644
--- a/securis/pom.xml
+++ b/securis/pom.xml
@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>net.curisit</groupId>
<artifactId>securis-server</artifactId>
- <version>1.0.2</version>
+ <version>1.1.1</version>
<name>SeCuris</name>
<description>CurisTEC Server Licenses</description>
<dependencies>
@@ -51,7 +51,7 @@
<dependency>
<groupId>net.curisit</groupId>
<artifactId>securis-client</artifactId>
- <version>1.0.6-SNAPSHOT</version>
+ <version>1.1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
diff --git a/securis/src/main/java/net/curisit/securis/db/Application.java b/securis/src/main/java/net/curisit/securis/db/Application.java
index 6bf6ba8..f7f546d 100644
--- a/securis/src/main/java/net/curisit/securis/db/Application.java
+++ b/securis/src/main/java/net/curisit/securis/db/Application.java
@@ -46,6 +46,7 @@
@GeneratedValue
private Integer id;
+ private String code;
private String name;
private String description;
@@ -139,4 +140,12 @@
public void setLicenseTypes(Set<LicenseType> licenseTypes) {
this.licenseTypes = licenseTypes;
}
+
+ public String getCode() {
+ return code;
+ }
+
+ public void setCode(String code) {
+ this.code = code;
+ }
}
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 6c0ec5b..fcaec12 100644
--- a/securis/src/main/java/net/curisit/securis/db/License.java
+++ b/securis/src/main/java/net/curisit/securis/db/License.java
@@ -54,6 +54,7 @@
@JsonIgnoreProperties(ignoreUnknown = true)
@NamedQueries({
@NamedQuery(name = "license-by-code", query = "SELECT l FROM License l where l.code = :code"),
+ @NamedQuery(name = "license-by-activation-code", query = "SELECT l FROM License l where l.activationCode = :activationCode"),
@NamedQuery(name = "last-code-suffix-used-in-pack", query = "SELECT max(l.codeSuffix) FROM License l where l.pack.id = :packId"),
@NamedQuery(name = "list-licenses-by-pack", query = "SELECT l FROM License l where l.pack.id = :packId"),
@NamedQuery(name = "list-licenses-by-req-data", query = "SELECT l FROM License l where l.reqDataHash = :hash"),
@@ -72,6 +73,10 @@
private int id;
private String code;
+
+ @Column(name = "activation_code")
+ @JsonProperty("activation_code")
+ private String activationCode;
@Column(name = "code_suffix")
@JsonProperty("code_suffix")
@@ -397,6 +402,26 @@
}
}
+ /**
+ * Return licenses with status: REquested, ACtive, Pre-Active for a given
+ * request data
+ *
+ * @param requestData
+ * @param em
+ * @return
+ * @throws SeCurisServiceException
+ */
+ public static License findLicenseByActivationCode(String activationCode, EntityManager em) throws SeCurisServiceException {
+ TypedQuery<License> query = em.createNamedQuery("license-by-activation-code", License.class);
+ query.setParameter("activationCode", activationCode);
+ try {
+ return query.getSingleResult();
+ } catch (NoResultException e) {
+ // There is no license for request data
+ return null;
+ }
+ }
+
public static License findActiveLicenseByRequestData(String requestData, EntityManager em) throws SeCurisServiceException {
TypedQuery<License> query = em.createNamedQuery("list-active-licenses-by-req-data", License.class);
query.setParameter("hash", BlockedRequest.generateHash(requestData));
@@ -435,4 +460,12 @@
this.codeSuffix = codeSuffix;
}
+ public String getActivationCode() {
+ return activationCode;
+ }
+
+ public void setActivationCode(String activationCode) {
+ this.activationCode = activationCode;
+ }
+
}
diff --git a/securis/src/main/java/net/curisit/securis/ioc/RequestsInterceptor.java b/securis/src/main/java/net/curisit/securis/ioc/RequestsInterceptor.java
index 6a74d4d..63f42b5 100644
--- a/securis/src/main/java/net/curisit/securis/ioc/RequestsInterceptor.java
+++ b/securis/src/main/java/net/curisit/securis/ioc/RequestsInterceptor.java
@@ -143,8 +143,10 @@
if (user != null) {
userRoles = 0;
List<Integer> roles = user.getRoles();
- for (Integer rol : roles) {
- userRoles += rol;
+ if (roles != null) {
+ for (Integer rol : roles) {
+ userRoles += rol;
+ }
}
// We store user roles in cache only for one hour
cache.set("roles_" + username, userRoles, 3600);
diff --git a/securis/src/main/java/net/curisit/securis/services/ApiResource.java b/securis/src/main/java/net/curisit/securis/services/ApiResource.java
index 743be97..20fe504 100644
--- a/securis/src/main/java/net/curisit/securis/services/ApiResource.java
+++ b/securis/src/main/java/net/curisit/securis/services/ApiResource.java
@@ -68,7 +68,7 @@
@Inject
LicenseGenerator licenseGenerator;
- private static final String CLIENT_USERNAME = "_client";
+ public static final String API_CLIENT_USERNAME = "_client";
public ApiResource() {
}
@@ -115,7 +115,7 @@
@POST
@Path("/request")
@Consumes(MediaType.APPLICATION_JSON)
- // TODO: Enable this: @Securable
+ @Securable
@Produces({
MediaType.APPLICATION_JSON
})
@@ -123,7 +123,7 @@
public Response createFromRequest(RequestBean request, @HeaderParam(LicenseManager.HEADER_LICENSE_NAME_OR_REFERENCE) String nameOrReference,
@HeaderParam(LicenseManager.HEADER_LICENSE_EMAIL) String userEmail) throws IOException, SeCurisServiceException, SeCurisException {
LOG.info("Request to get license: {}", request);
- SignedLicenseBean lic = createLicense(request, em, false, nameOrReference, userEmail);
+ SignedLicenseBean lic = createLicense(request, em, nameOrReference, userEmail);
return Response.ok(lic).build();
}
@@ -151,6 +151,8 @@
@HeaderParam(LicenseManager.HEADER_LICENSE_NAME_OR_REFERENCE) String nameOrReference,
@HeaderParam(LicenseManager.HEADER_LICENSE_EMAIL) String userEmail) throws IOException, SeCurisServiceException, SeCurisException {
RequestBean req = new RequestBean();
+ req.setAppCode(mpfdi.getFormDataPart("appCode", String.class, null));
+ req.setActivationCode(mpfdi.getFormDataPart("activationCode", String.class, null));
req.setPackCode(mpfdi.getFormDataPart("packCode", String.class, null));
req.setLicenseTypeCode(mpfdi.getFormDataPart("licenseTypeCode", String.class, null));
req.setCustomerCode(mpfdi.getFormDataPart("customerCode", String.class, null));
@@ -175,7 +177,7 @@
@POST
@Path("/renew")
@Consumes(MediaType.APPLICATION_JSON)
- // TODO: Enable this: @Securable
+ @Securable
@Produces({
MediaType.APPLICATION_JSON
})
@@ -214,7 +216,7 @@
@POST
@Path("/validate")
@Consumes(MediaType.APPLICATION_JSON)
- // TODO: Enable this: @Securable
+ @Securable
@Produces({
MediaType.APPLICATION_JSON
})
@@ -226,7 +228,6 @@
throw new SeCurisServiceException(ErrorCodes.LICENSE_IS_EXPIRED, "The license is expired");
}
- // EntityManager em = emProvider.get();
try {
SignatureHelper.getInstance().validateSignature(currentLic);
} catch (SeCurisException ex) {
@@ -261,6 +262,8 @@
SeCurisServiceException, SeCurisException {
LicenseBean lic = new LicenseBean();
+ lic.setAppCode(mpfdi.getFormDataPart("appCode", String.class, null));
+ lic.setActivationCode(mpfdi.getFormDataPart("activationName", String.class, null));
lic.setAppName(mpfdi.getFormDataPart("appName", String.class, null));
lic.setArch(mpfdi.getFormDataPart("arch", String.class, null));
lic.setCrcLogo(mpfdi.getFormDataPart("crcLogo", String.class, null));
@@ -279,7 +282,7 @@
}
private SignedLicenseBean renewLicense(RequestBean req, EntityManager em) throws SeCurisServiceException {
- return createLicense(req, em, true, null, null);
+ return renewLicense(req, em);
}
/**
@@ -292,16 +295,38 @@
* @return
* @throws SeCurisServiceException
*/
- private SignedLicenseBean createLicense(RequestBean req, EntityManager em, boolean renew, String nameOrReference, String email)
- throws SeCurisServiceException {
- LicenseBean previousLicenseBean = null;
+ private SignedLicenseBean createLicense(RequestBean req, EntityManager em, String nameOrReference, String email) throws SeCurisServiceException {
License lic = null;
- if (renew) {
- previousLicenseBean = (LicenseBean) req;
- lic = License.findLicenseByCode(previousLicenseBean.getLicenseCode(), em);
- if (lic.getStatus() != LicenseStatus.ACTIVE && lic.getStatus() != LicenseStatus.PRE_ACTIVE) {
- throw new SeCurisServiceException(ErrorCodes.INVALID_DATA, "The current license has been cancelled");
+
+ if (req.getActivationCode() != null) {
+ lic = License.findLicenseByActivationCode(req.getActivationCode(), em);
+ if (lic == null) {
+ throw new SeCurisServiceException(ErrorCodes.INVALID_DATA, "The given activation code is invalid: " + req.getActivationCode());
}
+ if (lic.getStatus() == LicenseStatus.ACTIVE) {
+ RequestBean initialRequest;
+ try {
+ initialRequest = JsonUtils.json2object(lic.getRequestData(), RequestBean.class);
+ if (!req.match(initialRequest)) {
+ throw new SeCurisServiceException(ErrorCodes.INVALID_DATA, "There is already an active license for given activation code: "
+ + req.getActivationCode());
+ } else {
+ return JsonUtils.json2object(lic.getLicenseData(), SignedLicenseBean.class);
+ }
+ } catch (SeCurisException e) {
+ LOG.error("Error getting existing license", e);
+ throw new SeCurisServiceException(ErrorCodes.INVALID_FORMAT, "Original request is wrong");
+ }
+ } else {
+ if (req.getAppCode() != null && !req.getAppCode().equals(lic.getPack().getLicenseType().getApplication().getCode())) {
+ LOG.error("Activation code {} belongs to app: {} but was sent by: {}", req.getActivationCode(), lic.getPack().getLicenseType()
+ .getApplication().getCode(), req.getAppCode());
+ throw new SeCurisServiceException(ErrorCodes.INVALID_DATA, "The given activation code belongs to a different application: "
+ + req.getActivationCode());
+ }
+ }
+ // We validate if the HW is the same, otherwise an error is
+ // thrown
} else {
try {
lic = License.findValidLicenseByRequestData(JsonUtils.toJSON(req), em);
@@ -321,40 +346,126 @@
lic = new License();
}
}
+
Pack pack;
- try {
- pack = em.createNamedQuery("pack-by-code", Pack.class).setParameter("code", req.getPackCode()).getSingleResult();
- } catch (NoResultException e) {
- throw new SeCurisServiceException(ErrorCodes.NOT_FOUND, "No pack found for code: " + req.getPackCode());
- }
+ if (lic.getActivationCode() == null) {
+ try {
+ pack = em.createNamedQuery("pack-by-code", Pack.class).setParameter("code", req.getPackCode()).getSingleResult();
+ } catch (NoResultException e) {
+ throw new SeCurisServiceException(ErrorCodes.NOT_FOUND, "No pack found for code: " + req.getPackCode());
+ }
- if (!renew && pack.getNumAvailables() <= 0) {
- throw new SeCurisServiceException(ErrorCodes.NO_AVAILABLE_LICENSES, "The current pack has no licenses availables");
- }
- if (!renew && lic.getStatus() == LicenseStatus.REQUESTED && !pack.isLicensePreactivation()) {
- throw new SeCurisServiceException(ErrorCodes.NO_AVAILABLE_LICENSES, "Current pack doesn't allow license preactivation");
- }
+ if (pack.getNumAvailables() <= 0) {
+ throw new SeCurisServiceException(ErrorCodes.NO_AVAILABLE_LICENSES, "The current pack has no licenses availables");
+ }
+ if (lic.getStatus() == LicenseStatus.REQUESTED && !pack.isLicensePreactivation()) {
+ throw new SeCurisServiceException(ErrorCodes.NO_AVAILABLE_LICENSES, "Current pack doesn't allow license preactivation");
+ }
- if (!req.getCustomerCode().equals(pack.getOrganization().getCode())) {
- throw new SeCurisServiceException(ErrorCodes.INVALID_LICENSE_REQUEST_DATA, "Customer code is not valid: " + req.getCustomerCode());
- }
+ if (!req.getCustomerCode().equals(pack.getOrganization().getCode())) {
+ throw new SeCurisServiceException(ErrorCodes.INVALID_LICENSE_REQUEST_DATA, "Customer code is not valid: " + req.getCustomerCode());
+ }
- if (!req.getLicenseTypeCode().equals(pack.getLicenseTypeCode())) {
- throw new SeCurisServiceException(ErrorCodes.INVALID_LICENSE_REQUEST_DATA, "License type code is not valid: " + req.getLicenseTypeCode());
+ if (!req.getLicenseTypeCode().equals(pack.getLicenseTypeCode())) {
+ throw new SeCurisServiceException(ErrorCodes.INVALID_LICENSE_REQUEST_DATA, "License type code is not valid: "
+ + req.getLicenseTypeCode());
+ }
+ } else {
+ pack = lic.getPack();
}
-
SignedLicenseBean signedLicense;
try {
String licCode;
- if (renew || lic.getStatus() == LicenseStatus.REQUESTED) {
- licCode = lic.getCode();
- } else {
+ if (lic.getCode() == null) {
licCode = LicUtils.getLicenseCode(pack.getCode(), licenseHelper.getNextCodeSuffix(pack.getId(), em));
+ } else {
+ licCode = lic.getCode();
}
- Date expirationDate = licenseHelper.getExpirationDateFromPack(pack, !renew);
+ Date expirationDate = licenseHelper.getExpirationDateFromPack(pack, lic.getActivationCode() == null);
LicenseBean lb = licenseGenerator.generateLicense(req, licenseHelper.extractPackMetadata(pack.getMetadata()), expirationDate, licCode,
pack.getAppName());
+ signedLicense = new SignedLicenseBean(lb);
+ } catch (SeCurisException e) {
+ throw new SeCurisServiceException(ErrorCodes.INVALID_LICENSE_REQUEST_DATA, "Error generating license: " + e.toString());
+ }
+ try {
+ lic.setRequestData(JsonUtils.toJSON(req));
+ if (BlockedRequest.isRequestBlocked(lic.getRequestData(), em)) {
+ throw new SeCurisServiceException(ErrorCodes.BLOCKED_REQUEST_DATA, "Given request data is blocked and cannot be activated");
+ }
+ lic.setLicenseData(JsonUtils.toJSON(signedLicense));
+ } catch (SeCurisException e) {
+ LOG.error("Error generating license JSON", e);
+ throw new SeCurisServiceException(ErrorCodes.INVALID_FORMAT, "Error generating license JSON");
+ }
+
+ lic.setModificationTimestamp(new Date());
+ lic.setExpirationDate(signedLicense.getExpirationDate());
+ User user = em.find(User.class, API_CLIENT_USERNAME);
+ if (lic.getStatus() != LicenseStatus.REQUESTED) {
+ lic.setPack(pack);
+ lic.setCreatedBy(user);
+ lic.setCreationTimestamp(new Date());
+ if (lic.getActivationCode() != null) {
+ lic.setStatus(LicenseStatus.ACTIVE);
+ } else {
+ lic.setStatus(pack.isLicensePreactivation() ? LicenseStatus.PRE_ACTIVE : LicenseStatus.REQUESTED);
+ }
+ lic.setCode(signedLicense.getLicenseCode());
+ lic.setCodeSuffix(LicUtils.getLicenseCodeSuffix(signedLicense.getLicenseCode()));
+ if (lic.getEmail() == null || "".equals(lic.getEmail())) {
+ lic.setEmail(email);
+ }
+ if (lic.getFullName() == null || "".equals(lic.getFullName())) {
+ lic.setFullName(nameOrReference);
+ }
+ em.persist(lic);
+ em.persist(licenseHelper.createLicenseHistoryAction(lic, user, LicenseHistory.Actions.CREATE));
+ if (lic.getActivationCode() != null) {
+ em.persist(licenseHelper.createLicenseHistoryAction(lic, user, LicenseHistory.Actions.ACTIVATE, "Activated by code on creation"));
+ } else {
+ if (pack.isLicensePreactivation()) {
+ em.persist(licenseHelper.createLicenseHistoryAction(lic, user, LicenseHistory.Actions.PRE_ACTIVATE, "Pre-activated on creation"));
+ } else {
+ LOG.warn("License ({}) created, but the pack doesn't allow preactivation", lic.getCode());
+ throw new SeCurisServiceException(ErrorCodes.NO_AVAILABLE_LICENSES, "Current pack doesn't allow license preactivation");
+ }
+ }
+ } else {
+ lic.setStatus(LicenseStatus.PRE_ACTIVE);
+ em.merge(lic);
+ em.persist(licenseHelper.createLicenseHistoryAction(lic, user, LicenseHistory.Actions.PRE_ACTIVATE, "Pre-activated after request"));
+ }
+
+ return signedLicense;
+ }
+
+ /**
+ * Creates a new signed license from request data or from previous license
+ * if It's a renew
+ *
+ * @param req
+ * @param em
+ * @param renew
+ * @return
+ * @throws SeCurisServiceException
+ */
+ private SignedLicenseBean renewLicense(LicenseBean previousLicenseBean, EntityManager em) throws SeCurisServiceException {
+
+ License lic = License.findLicenseByCode(previousLicenseBean.getLicenseCode(), em);
+ if (lic.getStatus() != LicenseStatus.ACTIVE && lic.getStatus() != LicenseStatus.PRE_ACTIVE) {
+ throw new SeCurisServiceException(ErrorCodes.INVALID_DATA, "The current license has been cancelled");
+ }
+
+ Pack pack = lic.getPack();
+ SignedLicenseBean signedLicense;
+ try {
+ String licCode = lic.getCode();
+ Date expirationDate = licenseHelper.getExpirationDateFromPack(pack, false);
+
+ LicenseBean lb = licenseGenerator.generateLicense(previousLicenseBean, licenseHelper.extractPackMetadata(pack.getMetadata()),
+ expirationDate, licCode, pack.getAppName());
signedLicense = new SignedLicenseBean(lb);
} catch (SeCurisException e) {
throw new SeCurisServiceException(ErrorCodes.INVALID_LICENSE_REQUEST_DATA, "Error generating license: " + e.toString());
@@ -372,37 +483,11 @@
lic.setModificationTimestamp(new Date());
lic.setExpirationDate(signedLicense.getExpirationDate());
- User user = em.find(User.class, CLIENT_USERNAME);
- if (!renew && lic.getStatus() != LicenseStatus.REQUESTED) {
- lic.setPack(pack);
- lic.setCreatedBy(user);
- lic.setCreationTimestamp(new Date());
- if (pack.isLicensePreactivation()) {
- lic.setStatus(LicenseStatus.PRE_ACTIVE);
- } else {
- lic.setStatus(LicenseStatus.REQUESTED);
- }
- lic.setCode(signedLicense.getLicenseCode());
- lic.setCodeSuffix(LicUtils.getLicenseCodeSuffix(signedLicense.getLicenseCode()));
- lic.setEmail(email);
- lic.setFullName(nameOrReference);
- em.persist(lic);
- em.persist(licenseHelper.createLicenseHistoryAction(lic, user, LicenseHistory.Actions.CREATE));
- if (pack.isLicensePreactivation()) {
- em.persist(licenseHelper.createLicenseHistoryAction(lic, user, LicenseHistory.Actions.PRE_ACTIVATE, "Pre-activated on creation"));
- } else {
- LOG.warn("License ({}) created, but the pack doesn't allow preactivation", lic.getCode());
- throw new SeCurisServiceException(ErrorCodes.NO_AVAILABLE_LICENSES, "Current pack doesn't allow license preactivation");
- }
- } else {
- lic.setStatus(renew ? LicenseStatus.ACTIVE : LicenseStatus.PRE_ACTIVE);
- em.merge(lic);
- if (renew) {
- em.persist(licenseHelper.createLicenseHistoryAction(lic, user, LicenseHistory.Actions.RENEW));
- } else {
- em.persist(licenseHelper.createLicenseHistoryAction(lic, user, LicenseHistory.Actions.PRE_ACTIVATE, "Pre-activated after request"));
- }
- }
+ User user = em.find(User.class, API_CLIENT_USERNAME);
+
+ lic.setStatus(LicenseStatus.ACTIVE);
+ em.merge(lic);
+ em.persist(licenseHelper.createLicenseHistoryAction(lic, user, LicenseHistory.Actions.RENEW));
return signedLicense;
}
diff --git a/securis/src/main/java/net/curisit/securis/services/ApplicationResource.java b/securis/src/main/java/net/curisit/securis/services/ApplicationResource.java
index e9b5551..5ce62d6 100644
--- a/securis/src/main/java/net/curisit/securis/services/ApplicationResource.java
+++ b/securis/src/main/java/net/curisit/securis/services/ApplicationResource.java
@@ -161,6 +161,7 @@
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());
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 1b7a494..d1bba29 100644
--- a/securis/src/main/java/net/curisit/securis/services/BasicServices.java
+++ b/securis/src/main/java/net/curisit/securis/services/BasicServices.java
@@ -73,14 +73,8 @@
MediaType.APPLICATION_JSON
})
public Response login(@FormParam("username") String user, @FormParam("password") String password, @Context HttpServletRequest request) {
- LOG.info("index session: " + request.getSession());
- LOG.info("user: {}, pass: {}", user, password);
LOG.info("is user in role: {} == {} ? ", "advance", request.isUserInRole("advance"));
- if ("no".equals(password)) {
- // TODO: Code to text exception handling
- return Response.status(Status.UNAUTHORIZED).build();
- }
String tokenAuth = tokenHelper.generateToken(user);
return Response.ok(Utils.createMap("success", true, "token", tokenAuth)).build();
}
diff --git a/securis/src/main/java/net/curisit/securis/services/LicenseResource.java b/securis/src/main/java/net/curisit/securis/services/LicenseResource.java
index 3abb26f..fc57a2f 100644
--- a/securis/src/main/java/net/curisit/securis/services/LicenseResource.java
+++ b/securis/src/main/java/net/curisit/securis/services/LicenseResource.java
@@ -209,7 +209,7 @@
License existingLicense = License.findActiveLicenseByRequestData(lic.getRequestData(), em);
if (existingLicense != null && existingLicense.getStatus() == LicenseStatus.ACTIVE) {
- throw new SeCurisServiceException(ErrorCodes.NO_AVAILABLE_LICENSES, "The pack has not available licenses");
+ throw new SeCurisServiceException(ErrorCodes.NO_AVAILABLE_LICENSES, "An active license already exists for the given request data");
}
lic.setStatus(LicenseStatus.ACTIVE);
@@ -347,9 +347,19 @@
if (checkIfCodeExists(lic.getCode(), em)) {
throw new SeCurisServiceException(ErrorCodes.INVALID_DATA, "The license code is already used in an existing license");
}
+ if (lic.getActivationCode() == null) {
+ throw new SeCurisServiceException(ErrorCodes.INVALID_DATA, "The activation code is mandatory");
+ }
+ License existingLic = License.findLicenseByActivationCode(lic.getActivationCode(), em);
+ if (existingLic != null) {
+ throw new SeCurisServiceException(ErrorCodes.INVALID_DATA, "The activation code is already used in: " + existingLic.getCode());
+ }
if (!LicUtils.checkValidLicenseCodeCrc(lic.getCode())) {
throw new SeCurisServiceException(ErrorCodes.INVALID_DATA, "The license code is not valid");
}
+ if (!Utils.isValidEmail(lic.getEmail())) {
+ throw new SeCurisServiceException(ErrorCodes.INVALID_DATA, "The user email should be a valid email");
+ }
Pack pack = null;
if (lic.getPackId() != null) {
diff --git a/securis/src/main/java/net/curisit/securis/services/helpers/LicenseHelper.java b/securis/src/main/java/net/curisit/securis/services/helpers/LicenseHelper.java
index 039eb03..512957b 100644
--- a/securis/src/main/java/net/curisit/securis/services/helpers/LicenseHelper.java
+++ b/securis/src/main/java/net/curisit/securis/services/helpers/LicenseHelper.java
@@ -125,6 +125,9 @@
if (isPreActivation) {
validPeriod = pack.getPreactivationValidPeriod() * MS_PER_DAY;
} else {
+ if (pack.getRenewValidPeriod() <= 0) {
+ return pack.getEndValidDate();
+ }
validPeriod = pack.getRenewValidPeriod() * MS_PER_DAY;
}
Date expirationDate = new Date(new Date().getTime() + validPeriod);
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 824dc51..72289c8 100644
--- a/securis/src/main/java/net/curisit/securis/utils/TokenHelper.java
+++ b/securis/src/main/java/net/curisit/securis/utils/TokenHelper.java
@@ -11,6 +11,7 @@
import javax.inject.Inject;
import net.curisit.integrity.commons.Utils;
+import net.curisit.securis.services.ApiResource;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
@@ -42,8 +43,12 @@
* @return
*/
public String generateToken(String user) {
+
+ return generateToken(user, new Date());
+ }
+
+ public String generateToken(String user, Date date) {
try {
- Date date = new Date();
String secret = generateSecret(user, date);
StringBuffer sb = new StringBuffer();
sb.append(secret);
@@ -58,7 +63,6 @@
LOG.error("Error generating SHA-256 hash", e);
}
return null;
-
}
private String generateSecret(String user, Date date) throws UnsupportedEncodingException, NoSuchAlgorithmException {
@@ -90,9 +94,11 @@
String secret = parts[0];
String user = parts[1];
Date date = Utils.toDateFromIso(parts[2]);
- if (new Date().after(new Date(date.getTime() + VALID_TOKEN_PERIOD * 60 * 60 * 1000))) {
- return false;
- }
+ if (date.getTime() > 0 || !user.equals(ApiResource.API_CLIENT_USERNAME)) {
+ if (new Date().after(new Date(date.getTime() + VALID_TOKEN_PERIOD * 60 * 60 * 1000))) {
+ return false;
+ }
+ } // else: It's a securis-client API call
String newSecret = generateSecret(user, date);
return newSecret.equals(secret);
} catch (IOException e) {
@@ -136,4 +142,10 @@
return null;
}
+ public static void main(String[] args) {
+ // client token:
+ // OTk3ODRiMzY5NzQ5MWI5NmYyZGQyODRiYjY2ZTU2YzdmMTZjYzM3YTY3N2ExM2M3ODI2MjU5ZTMzOTIyYjUzNSBfY2xpZW50IDE5NzAtMDEtMDFUMDA6NTk6NTkuOTk5KzAxMDA=
+ // OTk3ODRiMzY5NzQ5MWI5NmYyZGQyODRiYjY2ZTU2YzdmMTZjYzM3YTY3N2ExM2M3ODI2MjU5ZTMzOTIyYjUzNSBfY2xpZW50IDE5NzAtMDEtMDFUMDA6NTk6NTkuOTk5KzAxMDA=
+ System.out.print("client token: " + new TokenHelper().generateToken("_client", new Date(-1)));
+ }
}
diff --git a/securis/src/main/resources/db/schema.sql b/securis/src/main/resources/db/schema.sql
index 9dd74ed..61e8b7d 100644
--- a/securis/src/main/resources/db/schema.sql
+++ b/securis/src/main/resources/db/schema.sql
@@ -23,6 +23,7 @@
drop table IF EXISTS application;
CREATE TABLE IF NOT EXISTS application (
id INT NOT NULL auto_increment,
+ code VARCHAR(4) NOT NULL ,
name VARCHAR(45) NOT NULL ,
license_filename VARCHAR(100) NOT NULL ,
description VARCHAR(500) NULL ,
@@ -105,6 +106,7 @@
CREATE TABLE IF NOT EXISTS license (
id INT NOT NULL auto_increment,
code VARCHAR(100) NOT NULL ,
+ activation_code VARCHAR(100) NULL ,
code_suffix INT NULL ,
request_data VARCHAR(1024) NULL ,
request_data_hash VARCHAR(64) NULL ,
diff --git a/securis/src/main/webapp/js/catalogs.json b/securis/src/main/webapp/js/catalogs.json
index ccb1948..77bf78a 100644
--- a/securis/src/main/webapp/js/catalogs.json
+++ b/securis/src/main/webapp/js/catalogs.json
@@ -10,6 +10,12 @@
"autogenerate" : true,
"readOnly" : true
}, {
+ "name" : "code",
+ "display" : "Code",
+ "type" : "string",
+ "maxlength" : 4,
+ "mandatory" : true
+ }, {
"name" : "name",
"display" : "Name",
"type" : "string",
diff --git a/securis/src/main/webapp/js/licenses.js b/securis/src/main/webapp/js/licenses.js
index 712f7e8..fc4faed 100644
--- a/securis/src/main/webapp/js/licenses.js
+++ b/securis/src/main/webapp/js/licenses.js
@@ -724,7 +724,10 @@
email: true
}
$scope.maxlength = {
+ activation_code: 36,
code: 50,
+ full_name: 100,
+ email: 100,
request_data: 500,
comments: 1024
}
@@ -787,7 +790,8 @@
$scope.isNew = true;
$scope.showForm = true;
$scope.license = {
- pack_id: $scope.currentPack.id
+ pack_id: $scope.currentPack.id,
+ activation_code: $scope.createUUID()
}
Packs.nextliccode($scope.currentPack.id, function(data) {
console.log('New code: ' + data);
@@ -797,12 +801,26 @@
$('#licenseForm * #email').focus();
}, 0);
}
+ $scope.createUUID = function () {
+ // http://www.ietf.org/rfc/rfc4122.txt
+ var s = new Array(36);
+ var hexDigits = "0123456789abcdef";
+ for (var i = 0; i < 36; i++) {
+ s[i] = hexDigits.substr(Math.random() * 0x10 | 0, 1);
+ }
+ s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
+ s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
+ s[8] = s[13] = s[18] = s[23] = "-";
+ var uuid = s.join("");
+ return uuid;
+ }
$scope.editLicense = function(selectedlicense) {
$scope.isNew = false;
$scope.showForm = true;
$scope.license = selectedlicense;
$scope.license.status_name = Licenses.getStatusName($scope.license.status);
+ $scope.license.activation_code = $scope.license.activation_code || $scope.createUUID();
setTimeout(function() {
$('#licenseForm * #code').focus();
diff --git a/securis/src/main/webapp/licenses.html b/securis/src/main/webapp/licenses.html
index db2eb06..f8394b7 100644
--- a/securis/src/main/webapp/licenses.html
+++ b/securis/src/main/webapp/licenses.html
@@ -56,7 +56,7 @@
ng-show="packForm.code.$invalid">
<span class="glyphicon glyphicon-warning-sign"></span> <span
ng-show="packForm.code.$error.maxlength"
- ng-bind="maxlengthErrorMsg('Code', maxlength.code)"></span> <span
+ ng-bind="maxLengthErrorMsg('Code', maxlength.code)"></span> <span
ng-show="packForm.code.$error.required"
ng-bind="mandatoryFieldErrorMsg('Code')"></span>
</div>
@@ -103,7 +103,7 @@
ng-show="packForm.num_licenses.$invalid">
<span class="glyphicon glyphicon-warning-sign"></span> <span
ng-show="packForm.num_licenses.$error.maxlength"
- ng-bind="maxlengthErrorMsg('Num. Licenses', maxlength.num_licenses)"></span>
+ ng-bind="maxLengthErrorMsg('Num. Licenses', maxlength.num_licenses)"></span>
<span ng-show="packForm.num_licenses.$error.required"
ng-bind="mandatoryFieldErrorMsg('Num. Licenses')"></span>
</div>
@@ -190,7 +190,7 @@
i18n>Period for renew (days)</label>
<div class="col-md-8">
<input type="number" id="renew_valid_period" name="renew_valid_period"
- min="1" class="form-control" ng-model="pack.renew_valid_period"
+ min="0" class="form-control" ng-model="pack.renew_valid_period"
ng-required="true" />
<div class="alert inline-alert alert-warning"
ng-show="packForm.renew_valid_period.$invalid">
@@ -215,7 +215,7 @@
ng-show="packForm.comments.$invalid">
<span class="glyphicon glyphicon-warning-sign"></span> <span
ng-show="packForm.comments.$error.maxlength"
- ng-bind="maxlengthErrorMsg('Comments', maxlength.comments)"></span>
+ ng-bind="maxLengthErrorMsg('Comments', maxlength.comments)"></span>
<span ng-show="packForm.comments.$error.required"
ng-bind="mandatoryFieldErrorMsg('comments')"></span>
</div>
@@ -415,9 +415,25 @@
ng-show="licenseForm.code.$invalid">
<span class="glyphicon glyphicon-warning-sign"></span> <span
ng-show="licenseForm.code.$error.maxlength"
- ng-bind="maxlengthErrorMsg('Code', maxlength.code)"></span> <span
+ ng-bind="maxLengthErrorMsg('Code', maxlength.code)"></span> <span
ng-show="licenseForm.code.$error.required"
ng-bind="mandatoryFieldErrorMsg('Code')"></span>
+ </div>
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-md-3 control-label" for="activation_code" i18n>Activation code</label>
+ <div class="col-md-8">
+ <input type="string" id="activation_code" name="activation_code" placeholder=""
+ class="form-control" ng-model="license.activation_code" readonly
+ ng-required="mandatory.activation_code" ng-maxlength="{{maxlength.activation_code}}" />
+ <div class="alert inline-alert alert-warning"
+ ng-show="licenseForm.activation_code.$invalid">
+ <span class="glyphicon glyphicon-warning-sign"></span> <span
+ ng-show="licenseForm.activation_code.$error.maxlength"
+ ng-bind="maxLengthErrorMsg('Activation code', maxlength.activation_code)"></span> <span
+ ng-show="licenseForm.activation_code.$error.required"
+ ng-bind="mandatoryFieldErrorMsg('Activation code')"></span>
</div>
</div>
</div>
@@ -442,12 +458,12 @@
<div class="col-md-8">
<input type="string" id="full_name" name="full_name"
placeholder="" class="form-control" ng-model="license.full_name"
- ng-required="mandatory.full_name" />
+ ng-required="mandatory.full_name" ng-maxlength="{{maxlength.full_name}}" />
<div class="alert inline-alert alert-warning"
ng-show="licenseForm.full_name.$invalid">
<span class="glyphicon glyphicon-warning-sign"></span> <span
ng-show="licenseForm.full_name.$error.maxlength"
- ng-bind="maxlengthErrorMsg('User full name', maxlength.full_name)"></span>
+ ng-bind="maxLengthErrorMsg('User full name', maxlength.full_name)"></span>
<span ng-show="licenseForm.full_name.$error.required"
ng-bind="mandatoryFieldErrorMsg('User full name')"></span>
</div>
@@ -460,14 +476,14 @@
<div class="col-md-8">
<input type="email" id="email" name="email" placeholder=""
class="form-control" ng-model="license.email"
- ng-required="mandatory.email" />
+ ng-required="mandatory.email" ng-maxlength="{{maxlength.email}}" />
<div class="alert inline-alert alert-warning"
ng-show="licenseForm.email.$invalid">
<span class="glyphicon glyphicon-warning-sign"></span> <span
ng-show="licenseForm.email.$error.email"
ng-bind="'Please, write a valid email address'"></span> <span
ng-show="licenseForm.email.$error.maxlength"
- ng-bind="maxlengthErrorMsg('User email', maxlength.email)"></span>
+ ng-bind="maxLengthErrorMsg('User email', maxlength.email)"></span>
<span ng-show="licenseForm.email.$error.required"
ng-bind="mandatoryFieldErrorMsg('User email')"></span>
</div>
@@ -490,7 +506,7 @@
<span class="glyphicon glyphicon-warning-sign">
<span
ng-show="licenseForm.request_data.$error.maxlength"
- ng-bind="maxlengthErrorMsg('Request data', maxlength.request_data)"></span>
+ ng-bind="maxLengthErrorMsg('Request data', maxlength.request_data)"></span>
<span ng-show="licenseForm.request_data.$error.required"
ng-bind="mandatoryFieldErrorMsg('Request data')"></span>
</span>
@@ -514,7 +530,7 @@
ng-show="licenseForm.comments.$invalid">
<span class="glyphicon glyphicon-warning-sign"></span> <span
ng-show="licenseForm.comments.$error.maxlength"
- ng-bind="maxlengthErrorMsg('Comments', maxlength.comments)"></span>
+ ng-bind="maxLengthErrorMsg('Comments', maxlength.comments)"></span>
<span ng-show="licenseForm.comments.$error.required"
ng-bind="mandatoryFieldErrorMsg('comments')"></span>
</div>
--
Gitblit v1.3.2