Cette classe gère les informations d'activation, y compris l'analyse des données d'activation à partir d'un fichier XML existant l'émission de requêtes HTTP au serveur de contenu pour obtenir des informations d'autorisation de base et le stockage des informations d'activation dans le système de fichiers sous forme de fichier XML.
This commit is contained in:
656
src/main/java/common/Activation.java
Normal file
656
src/main/java/common/Activation.java
Normal file
@@ -0,0 +1,656 @@
|
|||||||
|
package common;
|
||||||
|
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
import javax.xml.xpath.XPath;
|
||||||
|
import javax.xml.xpath.XPathConstants;
|
||||||
|
import javax.xml.xpath.XPathExpressionException;
|
||||||
|
import javax.xml.xpath.XPathFactory;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads, writes and maintains data contained in the activation.xml file, or alternative file
|
||||||
|
*/
|
||||||
|
public class Activation
|
||||||
|
{
|
||||||
|
public static final String HOBBES_DEFAULT_VERSION = "10.0.4";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumeration for the type of operating system we're running on.
|
||||||
|
*/
|
||||||
|
public enum OS { WINDOWS, LINUX, MAC, UNKNOWN }
|
||||||
|
|
||||||
|
private final Logger LOGGER = Logger.getLogger( Activation.class.getName() );
|
||||||
|
public HttpUtils httpUtils;
|
||||||
|
protected Path activationFile;
|
||||||
|
protected boolean hasActivationToken = false;
|
||||||
|
|
||||||
|
// properties stored in the activationServiceInfo, credentials and activationToken nodes.
|
||||||
|
protected HashMap<String, String> properties = new HashMap<>();
|
||||||
|
Set<String> operatorURLList = new LinkedHashSet<>();
|
||||||
|
Map<String, String> licenseServiceCertificates = new HashMap<>();
|
||||||
|
|
||||||
|
// XPath factory and XPath instance for parsing
|
||||||
|
private final XPathFactory xpathFactory = XPathFactory.newInstance();
|
||||||
|
private final XPath xpath = xpathFactory.newXPath();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor which loads an existing activation file.
|
||||||
|
*
|
||||||
|
* @param activationFilePath path to the activation.xml file
|
||||||
|
* @param logLevel the initial logging level for this class
|
||||||
|
**/
|
||||||
|
public Activation( Path activationFilePath, HttpUtils httpUtils, Level logLevel )
|
||||||
|
{
|
||||||
|
LOGGER.setLevel( logLevel );
|
||||||
|
this.activationFile = activationFilePath;
|
||||||
|
this.httpUtils = httpUtils;
|
||||||
|
|
||||||
|
// Try to parse existing activation file, don't throw an exception on failure
|
||||||
|
if (null != activationFilePath && Files.exists( activationFilePath ))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
parseActivationFile( false );
|
||||||
|
}
|
||||||
|
catch (GourouException ignore){}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static factory method to create a Activation instance, possibly initializing data
|
||||||
|
* from a file. If the properties cannot be initialized from the file, this
|
||||||
|
* will contact the Adobe server for initialization and authorization info.
|
||||||
|
* If initialization from the network occurs, the activation file will be
|
||||||
|
* written to the file system.
|
||||||
|
*
|
||||||
|
* @param activationFilePath The path for activation file. This needs to be the full file
|
||||||
|
* path in case the name of the activation file was changed by the command line,
|
||||||
|
* @param ACSServer The ACS server URL (used for default activation file creation if needed).
|
||||||
|
* @return A new or existing Activation instance.
|
||||||
|
* <br/><br/>
|
||||||
|
* TODO: should this be replaced with a constructor?
|
||||||
|
*/
|
||||||
|
public static Activation createActivation( Path activationFilePath, String ACSServer, HttpUtils httpUtils, Level logLevel )
|
||||||
|
throws IOException, GourouException, ParserConfigurationException, SAXException
|
||||||
|
{
|
||||||
|
// start by ensuring the directory path exists; probably unnecessary??
|
||||||
|
Path dirPath = activationFilePath.getParent();
|
||||||
|
|
||||||
|
if (!Files.exists( dirPath ))
|
||||||
|
{
|
||||||
|
Files.createDirectories( dirPath );
|
||||||
|
}
|
||||||
|
|
||||||
|
// This constructor parses the activation file, if it exists. No exception is thrown
|
||||||
|
// on parsing failure. No attempt is made to initialize the activation via the internet.
|
||||||
|
Activation activation = new Activation( activationFilePath, httpUtils, logLevel );
|
||||||
|
|
||||||
|
// if parsing failed, checkActivationInfo might access the Adobe server
|
||||||
|
boolean doUpdate = activation.checkActivationInfo( ACSServer );
|
||||||
|
|
||||||
|
if (activation.checkAuthCert())
|
||||||
|
{
|
||||||
|
doUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doUpdate)
|
||||||
|
{
|
||||||
|
activation.updateActivationFile();
|
||||||
|
}
|
||||||
|
return activation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves an indicator of the operating system we're running on.
|
||||||
|
*
|
||||||
|
* @return an Activation.OS enumeration
|
||||||
|
*/
|
||||||
|
public static OS getOS()
|
||||||
|
{
|
||||||
|
String osName = System.getProperty( "os.name" );
|
||||||
|
if (osName.toLowerCase().contains( "windows" ))
|
||||||
|
{
|
||||||
|
return OS.WINDOWS;
|
||||||
|
}
|
||||||
|
else if (osName.toLowerCase().contains( "linux" ))
|
||||||
|
{
|
||||||
|
return OS.LINUX;
|
||||||
|
}
|
||||||
|
else if (osName.toLowerCase().contains( "mac os x" ) || osName.toLowerCase().contains( "macos" ))
|
||||||
|
{
|
||||||
|
return OS.MAC;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return OS.UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the default Adept directory.
|
||||||
|
*
|
||||||
|
* @return The default Adept directory path.
|
||||||
|
*/
|
||||||
|
public static String getDefaultAdeptDir()
|
||||||
|
{
|
||||||
|
String homeDir = System.getProperty( "user.home" );
|
||||||
|
if (homeDir != null && !homeDir.isEmpty())
|
||||||
|
{
|
||||||
|
// Using Paths.get for platform-independent path construction
|
||||||
|
if (getOS() == OS.MAC)
|
||||||
|
{
|
||||||
|
return Paths.get( homeDir, "/Library/Application Support/Adobe/Digital Editions").toString();
|
||||||
|
}
|
||||||
|
return Paths.get( homeDir, ".config", "jadept" ).toString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Fallback for environments without user.home, similar to LOCAL_ADEPT_DIR
|
||||||
|
Logger logger = Logger.getLogger( Activation.class.getName() );
|
||||||
|
logger.log( Level.WARNING, "user.home not found, using local adept directory." );
|
||||||
|
return ".";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the "credentials" DOM element and store the properties
|
||||||
|
*
|
||||||
|
* @param credentialsEl The DOM Element containing 5 or 6 properties
|
||||||
|
*/
|
||||||
|
public void storeCredentials( Element credentialsEl )
|
||||||
|
{
|
||||||
|
parseActivationInfo( credentialsEl );
|
||||||
|
// Handle username and login method from credentials
|
||||||
|
NodeList nameNodes = credentialsEl.getElementsByTagName( "username" );
|
||||||
|
Element usernameNode = (Element) nameNodes.item( 0 );
|
||||||
|
if (usernameNode != null)
|
||||||
|
{
|
||||||
|
String method = usernameNode.getAttribute( "method" );
|
||||||
|
properties.put( "method", method );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parse the activationToken DOM Element and store the enclosed 6 properties
|
||||||
|
*
|
||||||
|
* @param activationEl see description
|
||||||
|
*/
|
||||||
|
public void updateActivationTokenData( Element activationEl )
|
||||||
|
{
|
||||||
|
hasActivationToken = parseActivationInfo( activationEl );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLogLevel( Level newLevel )
|
||||||
|
{
|
||||||
|
LOGGER.setLevel( newLevel );
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean parseActivationInfo( Node activationInfo )
|
||||||
|
{
|
||||||
|
NodeList nodes = activationInfo.getChildNodes();
|
||||||
|
for (int i = 0; i < nodes.getLength(); i++)
|
||||||
|
{
|
||||||
|
Node node = nodes.item( i );
|
||||||
|
if (node instanceof Element)
|
||||||
|
{ // store the key values without prefixes
|
||||||
|
String tag = node.getLocalName();
|
||||||
|
if (null == tag)
|
||||||
|
{
|
||||||
|
tag = ((Element) node).getTagName();
|
||||||
|
}
|
||||||
|
properties.put( tag, node.getTextContent() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Document parseActivationDocument( Document activationDoc, boolean throwOnFailure )
|
||||||
|
throws XPathExpressionException
|
||||||
|
{
|
||||||
|
Element activationInfo = activationDoc.getDocumentElement();
|
||||||
|
if (!activationInfo.getTagName().contains( "activationInfo" ))
|
||||||
|
{
|
||||||
|
// if the document node is not "activationInfo", find that node in the document.
|
||||||
|
// should never happen.
|
||||||
|
activationInfo = (Element) xpath
|
||||||
|
.evaluate( "activationInfo",
|
||||||
|
activationDoc.getDocumentElement(), XPathConstants.NODE );
|
||||||
|
}
|
||||||
|
activationInfo.normalize();
|
||||||
|
Node node = XmlUtils.getNode( activationDoc, "//adept:activationServiceInfo", false );
|
||||||
|
parseActivationInfo( node ); // This method will populate the userName property, but not the method attribute
|
||||||
|
|
||||||
|
xpath.setNamespaceContext( new XmlUtils.AdeptNamespaceContext( activationDoc ) );
|
||||||
|
|
||||||
|
// Extract credential elements using XPath
|
||||||
|
node = XmlUtils.getNode( activationDoc, "//adept:credentials", false );
|
||||||
|
if (null != node)
|
||||||
|
{
|
||||||
|
parseActivationInfo( node );
|
||||||
|
|
||||||
|
// Handle username and login method from credentials
|
||||||
|
Element usernameNode = (Element) xpath.evaluate( "//adept:username", activationDoc, XPathConstants.NODE );
|
||||||
|
if (usernameNode != null)
|
||||||
|
{
|
||||||
|
String method = usernameNode.getAttribute( "method" );
|
||||||
|
properties.put( "method", method );
|
||||||
|
}
|
||||||
|
else if (throwOnFailure)
|
||||||
|
{
|
||||||
|
throw new GourouException( "Invalid activation file: adept:username node not found." );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ("anonymous".equals( getLoginMethod() ))
|
||||||
|
{
|
||||||
|
properties.put( "username", "anonymous" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Extract activationToken data using XPath
|
||||||
|
node = XmlUtils.getNode( activationDoc, "//adept:activationToken", false );
|
||||||
|
if (null != node)
|
||||||
|
{
|
||||||
|
hasActivationToken = parseActivationInfo( node );
|
||||||
|
}
|
||||||
|
// Populate licenseServiceCertificates map
|
||||||
|
NodeList licenseServiceNodes = (NodeList) xpath.evaluate(
|
||||||
|
"//adept:licenseServices/adept:licenseServiceInfo", activationDoc, XPathConstants.NODESET );
|
||||||
|
for (int i = 0; i < licenseServiceNodes.getLength(); i++)
|
||||||
|
{
|
||||||
|
Element serviceInfoNode = (Element) licenseServiceNodes.item( i );
|
||||||
|
String url = XmlUtils.getChildElementText( serviceInfoNode, "adept:licenseURL", false );
|
||||||
|
String certificate = XmlUtils.getChildElementText( serviceInfoNode, "adept:certificate", false );
|
||||||
|
if (!url.isEmpty())
|
||||||
|
{
|
||||||
|
licenseServiceCertificates.put( url.trim(), certificate );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node = XmlUtils.getNode( activationDoc, "//adept:operatorURLList", false );
|
||||||
|
if (null != node)
|
||||||
|
{
|
||||||
|
// We don't save the user id, because it is just a repetition
|
||||||
|
licenseServiceNodes = (NodeList) xpath.evaluate( "//adept:operatorURL", activationDoc,
|
||||||
|
XPathConstants.NODESET );
|
||||||
|
for (int i = 0; i < licenseServiceNodes.getLength(); i++)
|
||||||
|
{
|
||||||
|
Element serviceInfoNode = (Element) licenseServiceNodes.item( i );
|
||||||
|
String url = serviceInfoNode.getTextContent();
|
||||||
|
if (!url.isEmpty())
|
||||||
|
{
|
||||||
|
operatorURLList.add( url.trim() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return activationDoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the activation.xml file and populates user properties
|
||||||
|
*
|
||||||
|
* @param throwOnFailure if false, an exception will not be thrown if parsing fails.
|
||||||
|
* @return the parsed activation XML Document
|
||||||
|
* @throws GourouException only when throwOnFailure is true.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("UnusedReturnValue")
|
||||||
|
protected Document parseActivationFile( boolean throwOnFailure )
|
||||||
|
throws GourouException
|
||||||
|
{
|
||||||
|
LOGGER.log( Level.FINE, "DEBUG: Parse activation file " + activationFile );
|
||||||
|
|
||||||
|
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
||||||
|
docFactory.setNamespaceAware( true ); // Important for XPath with namespaces
|
||||||
|
DocumentBuilder docBuilder;
|
||||||
|
Document activationDoc = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
docBuilder = docFactory.newDocumentBuilder();
|
||||||
|
activationDoc = docBuilder.parse( activationFile.toFile() );
|
||||||
|
return parseActivationDocument( activationDoc, throwOnFailure );
|
||||||
|
}
|
||||||
|
catch (ParserConfigurationException e)
|
||||||
|
{
|
||||||
|
if (throwOnFailure)
|
||||||
|
{
|
||||||
|
throw new GourouException( "XML Parser configuration error: " + e.getMessage() );
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
catch (SAXException | IOException | XPathExpressionException e)
|
||||||
|
{
|
||||||
|
if (throwOnFailure)
|
||||||
|
{
|
||||||
|
throw new GourouException( "Invalid activation file: " + e.getMessage() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return activationDoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ** Getters and setters ** */
|
||||||
|
public Path getActivationDirPath()
|
||||||
|
{
|
||||||
|
if (null != activationFile)
|
||||||
|
{
|
||||||
|
return activationFile.getParent();
|
||||||
|
}
|
||||||
|
return Paths.get( "" ).toAbsolutePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-- ActivationNode --//
|
||||||
|
public String getActivationURL()
|
||||||
|
{
|
||||||
|
return properties.get( "activationURL" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthURL()
|
||||||
|
{
|
||||||
|
return properties.getOrDefault( "authURL", "https://adeactivate.adobe.com/adept" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserInfoURL()
|
||||||
|
{
|
||||||
|
return properties.get( "userInfoURL" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCertificate()
|
||||||
|
{
|
||||||
|
return properties.get( "certificate" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthenticationCertificate()
|
||||||
|
{
|
||||||
|
return properties.get( "authenticationCertificate" );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-- Credentials node --//
|
||||||
|
// In XML this is known as "user"
|
||||||
|
public String getUUID()
|
||||||
|
{
|
||||||
|
return properties.get( "user" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername()
|
||||||
|
{
|
||||||
|
String username = properties.get( "username" );
|
||||||
|
if (null == username || username.isBlank())
|
||||||
|
{
|
||||||
|
return properties.get( "method" );
|
||||||
|
}
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPKCS12()
|
||||||
|
{
|
||||||
|
return properties.get( "pkcs12" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLicenseCertificate()
|
||||||
|
{
|
||||||
|
return properties.get( "licenseCertificate" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrivateLicenseKey()
|
||||||
|
{
|
||||||
|
return properties.get( "privateLicenseKey" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLoginMethod()
|
||||||
|
{
|
||||||
|
return properties.getOrDefault( "method", "anonymous" );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-- Activation Token node --//
|
||||||
|
public String getDeviceFingerprint()
|
||||||
|
{
|
||||||
|
return properties.get( "fingerprint" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDeviceUUID()
|
||||||
|
{
|
||||||
|
return properties.get( "device" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDeviceType()
|
||||||
|
{
|
||||||
|
return properties.get( "deviceType" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getLicenseServices()
|
||||||
|
{
|
||||||
|
return licenseServiceCertificates;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getSignature()
|
||||||
|
{
|
||||||
|
return properties.get( "signature" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a license certificate associated with a specific URL
|
||||||
|
*
|
||||||
|
* @param url see description
|
||||||
|
* @return The associated license certificate
|
||||||
|
*/
|
||||||
|
public String getLicenseServiceCertificate( String url )
|
||||||
|
{
|
||||||
|
return licenseServiceCertificates.getOrDefault( url.trim(), "" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getOperatorList()
|
||||||
|
{
|
||||||
|
return operatorURLList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the activation.xml file to the appropriate folder based on the properties
|
||||||
|
* stored in memory
|
||||||
|
*
|
||||||
|
* @throws ParserConfigurationException if the document cannot be created
|
||||||
|
* @throws IOException if the activation file cannot be created or written.
|
||||||
|
*/
|
||||||
|
public void updateActivationFile()
|
||||||
|
throws ParserConfigurationException, IOException
|
||||||
|
{
|
||||||
|
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
||||||
|
docFactory.setNamespaceAware( true );
|
||||||
|
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
|
||||||
|
|
||||||
|
LOGGER.log( Level.FINEST, "DEBUG: Creating new activation" );
|
||||||
|
|
||||||
|
Document activationDoc = docBuilder.newDocument();
|
||||||
|
// Create XML declaration - handled by Transformer by default
|
||||||
|
Element activationInfo = activationDoc.createElementNS( XmlUtils.ADOBE_ADEPT_NS, "activationInfo" );
|
||||||
|
activationDoc.appendChild( activationInfo );
|
||||||
|
|
||||||
|
// Create and populate activationServiceInfo Element
|
||||||
|
// When writing this node to XML, be sure and do it in this order
|
||||||
|
Element activationServiceInfo = activationDoc
|
||||||
|
.createElementNS( XmlUtils.ADOBE_ADEPT_NS, "adept:activationServiceInfo" );
|
||||||
|
activationInfo.appendChild( activationServiceInfo );
|
||||||
|
XmlUtils.appendTextElem( activationServiceInfo, "adept:authURL", getAuthURL() );
|
||||||
|
XmlUtils.appendTextElem( activationServiceInfo, "adept:userInfoURL", getUserInfoURL() );
|
||||||
|
XmlUtils.appendTextElem( activationServiceInfo, "adept:activationURL", getActivationURL() );
|
||||||
|
XmlUtils.appendTextElem( activationServiceInfo, "adept:certificate", getCertificate() );
|
||||||
|
XmlUtils.appendTextElem( activationServiceInfo, "adept:authenticationCertificate",
|
||||||
|
getAuthenticationCertificate() );
|
||||||
|
|
||||||
|
// Create and populate credentials Element
|
||||||
|
Element credentialsEl = activationDoc
|
||||||
|
.createElementNS( XmlUtils.ADOBE_ADEPT_NS, "adept:credentials" );
|
||||||
|
activationInfo.appendChild( credentialsEl );
|
||||||
|
XmlUtils.appendTextElem( credentialsEl, "adept:user", getUUID() );
|
||||||
|
Element nameEl = activationDoc.createElementNS( XmlUtils.ADOBE_ADEPT_NS, "adept:username" );
|
||||||
|
credentialsEl.appendChild( nameEl );
|
||||||
|
if (!getLoginMethod().equals( "anonymous" ))
|
||||||
|
{
|
||||||
|
nameEl.setTextContent( getUsername() );
|
||||||
|
}
|
||||||
|
nameEl.setAttribute( "method", getLoginMethod() );
|
||||||
|
XmlUtils.appendTextElem( credentialsEl, "adept:pkcs12", getPKCS12() );
|
||||||
|
XmlUtils.appendTextElem( credentialsEl, "adept:licenseCertificate", getLicenseCertificate() );
|
||||||
|
XmlUtils.appendTextElem( credentialsEl, "adept:privateLicenseKey", getPrivateLicenseKey() );
|
||||||
|
XmlUtils.appendTextElem( credentialsEl, "adept:authenticationCertificate",
|
||||||
|
getAuthenticationCertificate() );
|
||||||
|
|
||||||
|
// Create and populate activationToken Element, without namespace
|
||||||
|
if (hasActivationToken)
|
||||||
|
{
|
||||||
|
credentialsEl = activationDoc
|
||||||
|
.createElement( "activationToken" );
|
||||||
|
activationInfo.appendChild( credentialsEl );
|
||||||
|
XmlUtils.appendTextElem( credentialsEl, "device", getDeviceUUID() );
|
||||||
|
XmlUtils.appendTextElem( credentialsEl, "fingerprint", getDeviceFingerprint() );
|
||||||
|
XmlUtils.appendTextElem( credentialsEl, "deviceType", getDeviceType() );
|
||||||
|
XmlUtils.appendTextElem( credentialsEl, "activationURL", getActivationURL() );
|
||||||
|
XmlUtils.appendTextElem( credentialsEl, "user", getUUID() );
|
||||||
|
XmlUtils.appendTextElem( credentialsEl, "signature", getSignature() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create and populate licenseServices Element
|
||||||
|
if (!licenseServiceCertificates.isEmpty())
|
||||||
|
{
|
||||||
|
Element licenseServicesNode = activationDoc
|
||||||
|
.createElementNS( XmlUtils.ADOBE_ADEPT_NS,
|
||||||
|
"adept:licenseServices" );
|
||||||
|
activationInfo.appendChild( licenseServicesNode );
|
||||||
|
licenseServiceCertificates.forEach( ( licenseURL, certificate ) -> {
|
||||||
|
Element licenseServiceInfo = activationDoc.
|
||||||
|
createElementNS( XmlUtils.ADOBE_ADEPT_NS, "adept:licenseServiceInfo" );
|
||||||
|
XmlUtils.appendTextElem( licenseServiceInfo, "adept:licenseURL", licenseURL );
|
||||||
|
XmlUtils.appendTextElem( licenseServiceInfo, "adept:certificate", certificate );
|
||||||
|
licenseServicesNode.appendChild( licenseServiceInfo );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create and populate operatorURL list
|
||||||
|
if (!operatorURLList.isEmpty())
|
||||||
|
{
|
||||||
|
Element operatorURLListNode = activationDoc
|
||||||
|
.createElementNS( XmlUtils.ADOBE_ADEPT_NS, "adept:operatorURLList" );
|
||||||
|
activationInfo.appendChild( operatorURLListNode );
|
||||||
|
// add the user id, just to match the linux code.
|
||||||
|
XmlUtils.appendTextElem( operatorURLListNode, "adept:user", getUUID() );
|
||||||
|
operatorURLList.forEach( operatorURL -> XmlUtils
|
||||||
|
.appendTextElem( operatorURLListNode, "adept:operatorURL", operatorURL ) );
|
||||||
|
}
|
||||||
|
updateActivationFile( activationDoc, activationFile );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the activation file on disk with the content of the provided document.
|
||||||
|
*
|
||||||
|
* @param doc The XML document to write to the activation file.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("UnusedReturnValue")
|
||||||
|
private String updateActivationFile( Document doc, Path activationFile )
|
||||||
|
throws IOException, GourouException
|
||||||
|
{
|
||||||
|
String xmlStr = XmlUtils.docToString( doc, false );
|
||||||
|
LOGGER.log( Level.FINE, "DEBUG: Update Activation file:\n" + xmlStr );
|
||||||
|
Files.writeString( activationFile, xmlStr );
|
||||||
|
return xmlStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checks the stored activation info to see if it's already stored. If not, request
|
||||||
|
* the properties from Adobe via HTTP
|
||||||
|
*
|
||||||
|
* @param ACSServer The URL of the Adobe Content Service
|
||||||
|
* @return true if the info was updated from the internet, false if it's already in memory.
|
||||||
|
* If false, no need to update the activation file in the file system.
|
||||||
|
*
|
||||||
|
* @throws ParserConfigurationException, IOException, SAXException if an
|
||||||
|
* error occurs while parsing a new activation info {@link Document}
|
||||||
|
*/
|
||||||
|
boolean checkActivationInfo( String ACSServer )
|
||||||
|
throws ParserConfigurationException, IOException, SAXException
|
||||||
|
{
|
||||||
|
if (properties.size() < 3)
|
||||||
|
{
|
||||||
|
// fetch the activationInfo from the Adobe Content Service server
|
||||||
|
LOGGER.log( Level.FINEST, "DEBUG: Creating new activation" );
|
||||||
|
|
||||||
|
// Get activationServiceInfo from content server
|
||||||
|
if (ACSServer == null || ACSServer.isEmpty())
|
||||||
|
{ // use default value
|
||||||
|
ACSServer = "https://adeactivate.adobe.com/adept"; // ACS_SERVER
|
||||||
|
}
|
||||||
|
String activationURL = ACSServer + "/ActivationServiceInfo";
|
||||||
|
Document docActivationServiceInfo = httpUtils
|
||||||
|
.sendHTTPRequestForXML( activationURL, null, null, null, false );
|
||||||
|
|
||||||
|
Element docRoot = docActivationServiceInfo.getDocumentElement();
|
||||||
|
parseActivationInfo( docRoot );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOGGER.log( Level.FINE, "DEBUG: Read previous activation configuration" );
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checks the stored authentication info to see if it's already stored. If not, requests
|
||||||
|
* the properties from Adobe via HTTP
|
||||||
|
*
|
||||||
|
* @return true if the info was updated from the internet, false if it's already in memory.
|
||||||
|
* If false, no need to update the activation file in the file system.
|
||||||
|
*/
|
||||||
|
public boolean checkAuthCert()
|
||||||
|
throws GourouException, IOException, ParserConfigurationException, SAXException
|
||||||
|
{
|
||||||
|
// Check for the existence of an authentication certificate
|
||||||
|
String authenticationCertificate = getAuthenticationCertificate();
|
||||||
|
if (null == authenticationCertificate
|
||||||
|
|| authenticationCertificate.isEmpty())
|
||||||
|
{
|
||||||
|
// No authentication certificate stored, get it from Adobe
|
||||||
|
LOGGER.log( Level.FINEST, "DEBUG: Creating new activation, authentication part" );
|
||||||
|
|
||||||
|
String authenticationURL = getAuthURL();
|
||||||
|
// There will be no authentication URL if checkActivationInfo was not called first.
|
||||||
|
if (null == authenticationURL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
authenticationURL = authenticationURL.trim() + "/AuthenticationServiceInfo";
|
||||||
|
|
||||||
|
Document docAuthenticationServiceInfo = httpUtils
|
||||||
|
.sendHTTPRequestForXML( authenticationURL, null, null,
|
||||||
|
null, false );
|
||||||
|
authenticationCertificate = XmlUtils
|
||||||
|
.extractTextElem( docAuthenticationServiceInfo, "//adept:certificate", true );
|
||||||
|
|
||||||
|
properties.put( "authenticationCertificate", authenticationCertificate );
|
||||||
|
String activationURL = XmlUtils
|
||||||
|
.extractTextElem( docAuthenticationServiceInfo, "//adept:authURL", true );
|
||||||
|
properties.put( "activationURL", activationURL );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// unnecessary method, used for testing.
|
||||||
|
public int getPropertiesSize()
|
||||||
|
{
|
||||||
|
return properties.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user