package net.curisit.securis; import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.util.Date; import java.util.HashMap; import java.util.Map; import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import net.curisit.securis.ConnectionManager.Command; import net.curisit.securis.beans.LicenseBean; import net.curisit.securis.beans.RequestBean; import net.curisit.securis.beans.SignedLicenseBean; import net.curisit.securis.beans.StatusBean; import net.curisit.securis.utils.JsonUtils; import net.curisit.securis.utils.Params; import net.curisit.securis.utils.SignatureHelper; /** * Manage all licenses tasks, just like validation, renew, requesting, ... * * @author roberto */ public class LicenseManager { private static final Logger LOG = LogManager.getLogger(LicenseManager.class); private static LicenseManager singleton = new LicenseManager(); public static final String PING_MESSAGE = "SeCuris API OK"; public static final String HEADER_LICENSE_NAME_OR_REFERENCE = "X-SECURIS-LIC-NAMEREF"; public static final String HEADER_LICENSE_EMAIL = "X-SECURIS-LIC-EMAIL"; private LicenseManager() { } public static LicenseManager getInstance() { return singleton; } /** * Loads a license from file * * @param licFile * @return The license bean * @throws SeCurisException */ public LicenseBean load(File licFile) throws SeCurisException { LicenseBean licBean; try { licBean = JsonUtils.json2object(FileUtils.readFileToString(licFile), LicenseBean.class); } catch (IOException e) { throw new SeCurisException("Error getting license data from file: " + licFile, e); } return licBean; } /** * Validates the license stored in {@code licFile} and get the corresponding * LicenseBean *

* The validation includes: *

*

* * @param licFile * @return The license bean stored in file * @throws SeCurisException */ public LicenseBean validateLicense(File licFile) throws SeCurisException { return validateLicense(licFile, false); } /** * Validates the license stored in {@code licFile} and get the corresponding * LicenseBean. The License date is not validated *

* The validation includes: *

*

* * @param licFile * @return The license bean stored in file * @throws SeCurisException */ public LicenseBean validateLicense(File licFile, boolean excludeDateValidation) throws SeCurisException { LicenseBean licBean = load(licFile); SignatureHelper.getInstance().validateSignature(licBean); if (licBean.getActivationCode() != null) { LicenseValidator.getInstance().validateHW(licBean, Params.get(Params.KEYS.APPLICATION_CODE), licBean.getActivationCode()); } else { LicenseValidator.getInstance().validateHW(licBean, Params.get(Params.KEYS.LIC_TYPE_CODE, Params.get(Params.KEYS.APPLICATION_CODE)), Params.get(Params.KEYS.CUSTOMER_CODE), Params.get(Params.KEYS.PACK_CODE)); } LicenseValidator.getInstance().validateLogo(licBean); if (!excludeDateValidation) { if (new Date().after(licBean.getExpirationDate())) { throw new ExpiredLicenseException(); } } return licBean; } /** * Request to server for a valid license * * @return The license bean returned by the server * @throws SeCurisException */ public SignedLicenseBean requestLicense(String nameOrReference, String email) throws SeCurisException { RequestBean req = ReqGenerator.getInstance().createRequest(Params.get(Params.KEYS.LIC_TYPE_CODE, Params.get(Params.KEYS.APPLICATION_CODE)), Params.get(Params.KEYS.CUSTOMER_CODE), Params.get(Params.KEYS.PACK_CODE)); SignedLicenseBean lic = requestLicenseToServer(req, nameOrReference, email); return lic; } /** * Request to server for a valid license * * @return The license bean returned by the server * @throws SeCurisException */ public SignedLicenseBean requestLicense(String nameOrReference, String email, String activationCode) throws SeCurisException { RequestBean req = ReqGenerator.getInstance().createRequest(Params.get(Params.KEYS.APPLICATION_CODE), activationCode); SignedLicenseBean lic = requestLicenseToServer(req, nameOrReference, email); return lic; } /** * Request to server for a valid license * * @return The license bean returned by the server * @throws SeCurisException */ public SignedLicenseBean requestLicense(String activationCode) throws SeCurisException { return requestLicense(null, null, activationCode); } /** * Generate a license file using a {@link LicenseBean} * * @param license * @param file * @throws SeCurisException */ public void save(LicenseBean license, File file) throws SeCurisException { SignedLicenseBean signedLic = new SignedLicenseBean(license); save(signedLic, file); } /** * Generate a license file using a {@link LicenseBean} * * @param license * @param file * @throws SeCurisException */ public void save(SignedLicenseBean signedLic, File file) throws SeCurisException { byte[] json; try { json = JsonUtils.toPrettyJSON(signedLic).getBytes("utf-8"); Files.write(Paths.get(file.toURI()), json, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); } catch (UnsupportedEncodingException e) { LOG.error("Error creating json doc from license: " + signedLic, e); throw new SeCurisException("Error creating json doc from license: " + signedLic, e); } catch (IOException e) { LOG.error("Error creating license file: " + file, e); throw new SeCurisException("Error creating json doc from license: " + signedLic, e); } LOG.debug("License saved in {}", file); } private SignedLicenseBean requestLicenseToServer(RequestBean req, String nameOrReference, String email) throws SeCurisException { Map headers = new HashMap(); headers.put(HEADER_LICENSE_NAME_OR_REFERENCE, nameOrReference); headers.put(HEADER_LICENSE_EMAIL, email); SignedLicenseBean lic = ConnectionManager.getInstance().executePost(Command.CREATE_LIC, SignedLicenseBean.class, req, headers); return lic; } /** * Creates a new request file with current hardware in the File passed as * parameter * * @param outputRequestFile * File where the request data will be saved * @return The generated request bean * @throws SeCurisException */ public RequestBean createRequestFile(File outputRequestFile) throws SeCurisException { RequestBean req = ReqGenerator.getInstance().createRequest(Params.get(Params.KEYS.LIC_TYPE_CODE, Params.get(Params.KEYS.APPLICATION_CODE)), Params.get(Params.KEYS.CUSTOMER_CODE), Params.get(Params.KEYS.PACK_CODE)); ReqGenerator.getInstance().save(req, outputRequestFile); return req; } /** * Creates a new request file with current hardware in the File passed as * parameter * * @param outputRequestFile * File where the request data will be saved * @return The generated request bean * @throws SeCurisException */ public RequestBean createRequestFile(File outputRequestFile, String activationCode) throws SeCurisException { return createRequestFile(outputRequestFile, activationCode, null); } /** * Creates a new request file with current hardware in the File passed as * parameter * * @param outputRequestFile * File where the request data will be saved * * @param activationCode * Activation code provided be SeCurisadministrator * @param appCode * Application code to use, ignoring the code set in config file * @return The generated request bean * @throws SeCurisException */ public RequestBean createRequestFile(File outputRequestFile, String activationCode, String appCode) throws SeCurisException { if (appCode == null) { Params.get(Params.KEYS.APPLICATION_CODE); } RequestBean req = ReqGenerator.getInstance().createRequest(appCode, activationCode); ReqGenerator.getInstance().save(req, outputRequestFile); return req; } /** * Send the current license file to server, which is previously validated, * to get a renewed one if it is prepared in server side. * * @param licenseFile * Current and valid License file * @return New license bean if server creates a new one, otherwise the same * current License bean will be returned * @throws SeCurisException */ public SignedLicenseBean renew(File licenseFile) throws SeCurisException { LicenseBean lic = validateLicense(licenseFile, true); SignedLicenseBean newLic = ConnectionManager.getInstance().executePost(Command.RENEW_LIC, SignedLicenseBean.class, lic); return newLic; } /** * Check on SeCuris server if current license is still valid in server DB. * * @param licenseFile * @throws SeCurisException */ public void assertLicenseIsValid(File licenseFile) throws SeCurisException, IOException { LicenseBean lic = validateLicense(licenseFile); // We need to snd the signed version to validate signature on server ConnectionManager.getInstance().executePost(Command.VALIDATE, LicenseBean.class, new SignedLicenseBean(lic)); } public void testServer() throws SeCurisException { StatusBean status = ConnectionManager.getInstance().executeGet(Command.TEST, StatusBean.class); if (!PING_MESSAGE.equals(status.getMessage())) { throw new SeCurisException("SeCuris Server is not running in given URL"); } } public static void main(String[] args) throws SeCurisException { System.out.println("APPLICATION_CODE: " + Params.get(Params.KEYS.APPLICATION_CODE)); System.out.println("LICENSE_SERVER_URL: " + Params.get(Params.KEYS.LICENSE_SERVER_URL)); LicenseManager lm = LicenseManager.getInstance(); // LicenseBean lic = // lm.requestLicense("aaf88d6c-6622-492a-93ec-10f3d1dc7120"); LicenseBean lic = lm.requestLicense("Rob", "rsanchez@curisit.net"); System.out.println(lic.getLicenseCode() + " " + lic.getExpirationDate()); // LicenseBean lic = lm. } }