Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement License Activation Functionality #6

Merged
merged 5 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 23 additions & 5 deletions includes/RestApi/Controllers/PLSController.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,21 @@ class PLSController extends \WP_REST_Controller {
*/
protected $rest_base = 'license';

/**
* Instance of the PLSUtility class.
*
* @var PLSUtility
*/
protected $pls_utility;

/**
* Constructor for the PLSController class.
*/
public function __construct() {
// Instantiate PLSUtility for license handling
$this->pls_utility = new PLSUtility();
}

/**
* Registers the routes for the objects of the controller.
*/
Expand Down Expand Up @@ -93,7 +108,8 @@ public function get_args() {
public function create_license( $request ) {
$plugin_slug = sanitize_text_field( $request->get_param( 'pluginSlug' ) );

$response = PLSUtility::provision_license( $plugin_slug );
// Use the instance of PLSUtility to provision a new license
$response = $this->pls_utility->provision_license( $plugin_slug );

if ( is_wp_error( $response ) ) {
return new \WP_REST_Response(
Expand All @@ -115,9 +131,10 @@ public function create_license( $request ) {
* @return \WP_REST_Response|\WP_Error
*/
public function get_license_status( $request ) {
$plugin_slug = sanitize_text_field( $request->get_param( 'plugin_slug' ) );
$plugin_slug = sanitize_text_field( $request->get_param( 'pluginSlug' ) );

$license_status = PLSUtility::retrieve_license_status( $plugin_slug );
// Use the instance of PLSUtility to retrieve license status
$license_status = $this->pls_utility->retrieve_license_status( $plugin_slug );
if ( is_wp_error( $license_status ) ) {
return new \WP_REST_Response(
array(
Expand All @@ -138,9 +155,10 @@ public function get_license_status( $request ) {
* @return \WP_REST_Response|WP_Error
*/
public function activate_license( $request ) {
$plugin_slug = sanitize_text_field( $request->get_param( 'plugin_slug' ) );
$plugin_slug = sanitize_text_field( $request->get_param( 'pluginSlug' ) );

$activation_result = PLSUtility::activate_license( $plugin_slug );
// Use the instance of PLSUtility to activate the license
$activation_result = $this->pls_utility->activate_license( $plugin_slug );
if ( is_wp_error( $activation_result ) ) {
return new \WP_REST_Response(
array(
Expand Down
243 changes: 214 additions & 29 deletions includes/Utilities/PLSUtility.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,92 @@

namespace NewfoldLabs\WP\Module\PLS\Utilities;

use NewfoldLabs\WP\Module\Data\Helpers\Encryption;

/**
* Class PLSUtility
*
* Provides utility functions for handling license operations.
*/
class PLSUtility {

/**
* The base URL for the Hiive PLS API.
*
* @var string
*/
private $base_url;

/**
* Option name for storing license data as an associative array in WordPress options.
*
* @var string
*/
private $license_data_option_name = 'nfd_module_pls_license_data';

/**
* Constructor for PLSUtility.
*/
public function __construct() {
// Define the base URL for the API if not already defined.
if ( ! defined( 'NFD_PLS_URL' ) ) {
define( 'NFD_PLS_URL', 'https://licensing.hiive.cloud' );
}
$this->base_url = constant( 'NFD_PLS_URL' );
}

/**
* Stores license data with encryption.
*
* @param array $license_data The license data to be encrypted and stored.
*/
public function store_license_data( $license_data ) {
$encryption = new Encryption();

// Encrypt the license data before storing it in WordPress options
$encrypted_data = $encryption->encrypt( wp_json_encode( $license_data ) );

// Save the encrypted license data to the WordPress options table
update_option( $this->license_data_option_name, $encrypted_data );
}

/**
* Retrieves license data with decryption.
*
* @return array|false The decrypted license data, or false on failure.
*/
public function retrieve_license_data() {
$encryption = new Encryption();

// Retrieve the encrypted license data from the WordPress options table
$encrypted_data = get_option( $this->license_data_option_name );
if ( ! $encrypted_data ) {
return false;
}

// Decrypt the license data
$decrypted_data = $encryption->decrypt( $encrypted_data );
if ( ! $decrypted_data ) {
return false;
}

// Return the decrypted data as an associative array
return json_decode( $decrypted_data, true );
}

/**
* Provisions a new license via the Hiive PLS API using the plugin slug.
* If the license is already stored in the WordPress option, it returns the stored license.
* If the license is already stored in the WordPress option, it returns the stored data.
*
* @param string $plugin_slug The plugin slug.
*
* @return array|WP_Error License data or WP_Error on failure.
*/
public static function provision_license( $plugin_slug ) {
// Retrieve the stored license data from the WordPress option.
$option_name = 'nfd_module_pls_license_data_' . $plugin_slug;
$license_data = get_option( $option_name );

// Check if the license data already exists in the options.
// TODO: Update this to store only the license ID in the appropriate plugin option once the Hiive API is ready and can store the download URL as well.
if ( $license_data ) {
return json_decode( $license_data, true );
public function provision_license( $plugin_slug ) {
// Retrieve existing license data for the plugin if available
$license_data_store = $this->retrieve_license_data();
if ( isset( $license_data_store[ $plugin_slug ] ) ) {
return $license_data_store[ $plugin_slug ];
}

// If no license is found, proceed with an API request to provision a new license.
Expand All @@ -34,23 +96,33 @@ public static function provision_license( $plugin_slug ) {
'pluginSlug' => $plugin_slug,
);

// Send the API request to provision a license
$hiive_request = new HiiveUtility( $endpoint, $body, 'POST' );
$response = $hiive_request->send_request();
if ( is_wp_error( $response ) ) {
return $response;
}

// Parse the response from the API
$response_body = json_decode( $response, true );
// Check if the response contains the necessary license ID and download URL.
if ( isset( $response_body['license_id'], $response_body['download_url'] ) ) {
if ( isset(
$response_body['download_url'],
$response_body['storage_key'],
$response_body['storage_method'],
$response_body['license_id'],
$response_body['basename']
) ) {
$license_data = array(
'licenseId' => $response_body['license_id'],
'downloadUrl' => $response_body['download_url'],
'storageMethod' => 'wp_option',
'storageKey' => $option_name,
'storageKey' => $response_body['storage_key'],
'storageMethod' => $response_body['storage_method'],
'licenseId' => $response_body['license_id'],
'basename' => $response_body['basename'],
);

update_option( $option_name, wp_json_encode( $license_data ) );
// Add the new license data to the license data store and save it
$license_data_store[ $plugin_slug ] = $license_data;
$this->store_license_data( $license_data_store );

return $license_data;
}
Expand All @@ -62,31 +134,144 @@ public static function provision_license( $plugin_slug ) {
}

/**
* Retrieves the license status by plugin slug via the Hiive PLS API.
* Activates a license by plugin slug via the Hiive PLS API.
*
* @param string $plugin_slug The plugin slug.
*
* @return string|WP_Error The license status or WP_Error on failure.
* @return array|WP_Error License status or WP_Error on failure.
*/
public static function retrieve_license_status( $plugin_slug ) {
// TODO: Replace this dummy method with an actual API call to Hiive to retrieve the license status.
$statuses = array( 'active', 'new', 'expired', 'not_generated' );
$random_status = $statuses[ array_rand( $statuses ) ];
public function activate_license( $plugin_slug ) {
// Retrieve the stored license data for the plugin
$license_data_store = $this->retrieve_license_data();
if ( ! isset( $license_data_store[ $plugin_slug ] ) ) {
return new \WP_Error(
'nfd_pls_error',
__( 'No license data found for the specified plugin slug.', 'wp-module-pls' )
);
}

$license_data = $license_data_store[ $plugin_slug ];
if ( ! isset( $license_data['storageKey'], $license_data['licenseId'] ) ) {
return new \WP_Error(
'nfd_pls_error',
__( 'Missing storageKey or licenseId in stored license data.', 'wp-module-pls' )
);
}

$storage_key = $license_data['storageKey'];
$license_id = $license_data['licenseId'];

// Retrieve domain name and email from WordPress database
$domain_name = get_home_url();
$email = get_option( 'admin_email' );

return $random_status;
// Create the body for the API request, including domain name and email
$body = array(
'domain_name' => $domain_name,
'email' => $email,
);
$endpoint = "{$this->base_url}/license/{$license_id}/activate";

// Send the request to activate the license
$response = wp_remote_post(
$endpoint,
array(
'body' => wp_json_encode( $body ),
'headers' => array( 'Content-Type' => 'application/json' ),
'timeout' => 30,
)
);
if ( is_wp_error( $response ) ) {
return $response;
}

$response_code = wp_remote_retrieve_response_code( $response );
if ( $response_code < 200 || $response_code >= 300 ) {
$response_body = wp_remote_retrieve_body( $response );
return new \WP_Error(
'nfd_pls_error',
__( 'API returned a non-success status code: ', 'wp-module-pls' ) . $response_code
);
}

// Parse the response to check for activation key
$response_body = wp_remote_retrieve_body( $response );
$response_data = json_decode( $response_body, true );
if ( isset( $response_data['data']['activation_key'] ) ) {
// Store the activation key in the WordPress options table
update_option( $storage_key, $response_data['data']['activation_key'] );

return $response_data;
}

return new \WP_Error(
'nfd_pls_error',
__( 'Unexpected response format from the API.', 'wp-module-pls' )
);
}

/**
* Activates a license by plugin slug via the Hiive PLS API.
* Retrieves the license status by plugin slug via the Hiive PLS API.
*
* @param string $plugin_slug The plugin slug.
*
* @return array|WP_Error License status or WP_Error on failure.
* @return string|WP_Error The license status or WP_Error on failure.
*/
public static function activate_license( $plugin_slug ) {
// TODO: Replace this dummy method with an actual API call to Hiive to activate the license.
return array(
'status' => 'active',
public function retrieve_license_status( $plugin_slug ) {
// Retrieve the stored license data for the plugin
$license_data_store = $this->retrieve_license_data();

if ( ! isset( $license_data_store[ $plugin_slug ] ) ) {
return new \WP_Error(
'nfd_pls_error',
__( 'No license data found for the specified plugin slug.', 'wp-module-pls' )
);
}

$license_data = $license_data_store[ $plugin_slug ];
$storage_key = $license_data['storageKey'] ?? null;

if ( ! $storage_key ) {
return new \WP_Error(
'nfd_pls_error',
__( 'Missing storageKey in stored license data.', 'wp-module-pls' )
);
}

// Retrieve the license ID from the option stored under storageKey.
$license_id = get_option( $storage_key );

if ( ! $license_id ) {
return new \WP_Error(
'nfd_pls_error',
__( 'No license ID found for the specified storage key.', 'wp-module-pls' )
);
}

// Send request to retrieve the license status from the API
$endpoint = "{$this->base_url}/license/{$license_id}/status";
$response = wp_remote_get( $endpoint, array( 'timeout' => 30 ) );

// Check for errors in the request
if ( is_wp_error( $response ) ) {
return $response;
}

$response_code = wp_remote_retrieve_response_code( $response );
if ( $response_code < 200 || $response_code >= 300 ) {
return new \WP_Error(
'nfd_pls_error',
__( 'API returned a non-success status code: ', 'wp-module-pls' ) . $response_code
);
}

// Parse the response to get the license status
$response_body = wp_remote_retrieve_body( $response );
$response_data = json_decode( $response_body, true );

return $response_data['status'] ?? new \WP_Error(
'nfd_pls_error',
__( 'Unexpected response format from the API.', 'wp-module-pls' )
);
}
}
Loading