Filter for license provisioning

This commit adds a filter that will provision the API key. It only runs on WP.com sites with plugins.

[MAILPOET-5131]
This commit is contained in:
Brezo Cordero
2023-03-17 16:45:00 -05:00
committed by Aschepikov
parent 397232e932
commit fc8837e03c
5 changed files with 168 additions and 1 deletions

View File

@ -4,7 +4,9 @@ namespace MailPoet\API\JSON\v1;
use MailPoet\API\JSON\Endpoint as APIEndpoint;
use MailPoet\API\JSON\Error as APIError;
use MailPoet\API\JSON\ErrorResponse;
use MailPoet\API\JSON\Response;
use MailPoet\API\JSON\SuccessResponse;
use MailPoet\Config\AccessControl;
use MailPoet\Config\ServicesChecker;
use MailPoet\Cron\Workers\SubscribersEngagementScore;
@ -493,4 +495,24 @@ class Settings extends APIEndpoint {
'action' => 'reactivate',
];
}
/**
* Prepares the settings to set up MSS with the given key and calls the set method.
*
* @param string $apiKey
* @return ErrorResponse|SuccessResponse
*/
public function setupMSS(string $apiKey) {
$new_settings = [
'mta_group' => 'mailpoet',
'mta' => [
'method' => 'MailPoet',
'mailpoet_api_key' => $apiKey,
],
'signup_confirmation' => [
'enabled' => '1',
],
];
return $this->set($new_settings);
}
}

View File

@ -13,6 +13,7 @@ use MailPoet\Subscription\Form;
use MailPoet\Subscription\Manage;
use MailPoet\Subscription\Registration;
use MailPoet\WP\Functions as WPFunctions;
use MailPoet\WPCOM\DotcomLicenseProvisioner;
class Hooks {
/** @var Form */
@ -54,6 +55,9 @@ class Hooks {
/** @var SubscriberChangesNotifier */
private $subscriberChangesNotifier;
/** @var DotcomLicenseProvisioner */
private $dotcomLicenseProvisioner;
public function __construct(
Form $subscriptionForm,
Comment $subscriptionComment,
@ -67,7 +71,8 @@ class Hooks {
HooksWooCommerce $hooksWooCommerce,
SubscriberHandler $subscriberHandler,
SubscriberChangesNotifier $subscriberChangesNotifier,
WP $wpSegment
WP $wpSegment,
DotcomLicenseProvisioner $dotcomLicenseProvisioner
) {
$this->subscriptionForm = $subscriptionForm;
$this->subscriptionComment = $subscriptionComment;
@ -82,6 +87,7 @@ class Hooks {
$this->subscriberHandler = $subscriberHandler;
$this->hooksWooCommerce = $hooksWooCommerce;
$this->subscriberChangesNotifier = $subscriberChangesNotifier;
$this->dotcomLicenseProvisioner = $dotcomLicenseProvisioner;
}
public function init() {
@ -99,6 +105,7 @@ class Hooks {
$this->setupFooter();
$this->setupSettingsLinkInPluginPage();
$this->setupChangeNotifications();
$this->setupLicenseProvisioning();
}
public function initEarlyHooks() {
@ -475,4 +482,13 @@ class Hooks {
[$this->subscriberChangesNotifier, 'notify']
);
}
public function setupLicenseProvisioning(): void {
$this->wp->addFilter(
'wpcom_marketplace_webhook_response_mailpoet-business',
[$this->dotcomLicenseProvisioner, 'provisionLicense'],
10,
3
);
}
}

View File

@ -537,6 +537,8 @@ class ContainerConfigurator implements IContainerConfigurator {
$container->autowire(\MailPoet\WP\Emoji::class)->setPublic(true);
$container->autowire(\MailPoet\WP\Functions::class)->setPublic(true);
$container->autowire(\MailPoet\WP\AutocompletePostListLoader::class)->setPublic(true);
// WordPress.com
$container->autowire(\MailPoet\WPCOM\DotcomLicenseProvisioner::class)->setPublic(true);
// Third party classes
$container->autowire(\MailPoetVendor\CSS::class)->setClass(\MailPoetVendor\CSS::class)->setPublic(true);
$container->autowire(\MailPoetVendor\csstidy::class)->setClass(\MailPoetVendor\csstidy::class);

View File

@ -35,6 +35,7 @@ class LoggerFactory {
const TOPIC_API = 'api';
const TOPIC_TRACKING = 'tracking';
const TOPIC_COUPONS = 'coupons';
const TOPIC_PROVISIONING = 'provisioning';
/** @var LoggerFactory */
private static $instance;

View File

@ -0,0 +1,126 @@
<?php declare(strict_types = 1);
namespace MailPoet\WPCOM;
use MailPoet\API\JSON\ErrorResponse;
use MailPoet\API\JSON\v1\Services;
use MailPoet\API\JSON\v1\Settings;
use MailPoet\Logging\LoggerFactory;
use WP_Error;
/**
* This class is responsible for receiving and activating the license purchased from WP.com Marketplace.
*/
class DotcomLicenseProvisioner {
const EVENT_TYPE_PROVISION_LICENSE = 'provision_license';
/** @var LoggerFactory */
private $loggerFactory;
/** @var Settings */
private $settings;
/** @var Services */
private $services;
public function __construct(
LoggerFactory $loggerFactory,
Settings $settings,
Services $services
) {
$this->loggerFactory = $loggerFactory;
$this->settings = $settings;
$this->services = $services;
}
/**
* Returns true if in the context of WordPress.com Atomic platform.
*
* @return bool
*/
private function isAtomicPlatform(): bool {
return defined('IS_ATOMIC') && IS_ATOMIC && defined('ATOMIC_CLIENT_ID') && (ATOMIC_CLIENT_ID === '2');
}
/**
* Activates MSS and adds API key for subscriptions purchased from WP.com Marketplace.
*
* @param bool $result
* @param array $licensePayload
* @param string $eventType
* @return bool|WP_Error
*/
public function provisionLicense(bool $result, array $licensePayload, string $eventType) {
if (!$this->isAtomicPlatform() || $eventType !== self::EVENT_TYPE_PROVISION_LICENSE) {
return $result;
}
$apiKey = $this->getKeyFromPayload($licensePayload);
if (is_wp_error($apiKey)) {
$this->loggerFactory->getLogger(LoggerFactory::TOPIC_PROVISIONING)->error(
'key was not found in license payload');
return $apiKey;
}
return $this->activateMSS($apiKey);
}
/**
* Returns API key from license payload.
* @param array $licensePayload
* @return string|WP_Error
*/
private function getKeyFromPayload(array $licensePayload) {
if (isset($licensePayload['apiKey']) && is_string($licensePayload['apiKey'])) {
return $licensePayload['apiKey'];
}
return new WP_Error('invalid_license_payload', 'Invalid license payload: Missing API key.');
}
/**
* Saves the API key and activates MSS.
* @param string $apiKey
* @return true|WP_Error
*/
private function activateMSS(string $apiKey) {
$response = $this->settings->setupMSS($apiKey);
if ($response instanceof ErrorResponse) {
$this->loggerFactory->getLogger(LoggerFactory::TOPIC_PROVISIONING)->error(
'Setting sending method and key failed',
['$response' => $response]
);
return new WP_Error('Provisioning failed setting the data', $this->concatMessages($response));
}
// This is necessary if the key changed but the sending method was already set to MailPoet
$response = $this->services->refreshMSSKeyStatus();
if ($response instanceof ErrorResponse) {
$this->loggerFactory->getLogger(LoggerFactory::TOPIC_PROVISIONING)->error(
'Refreshing the key failed',
['$response' => $response]
);
return new WP_Error('Provisioning failed activating the data', $this->concatMessages($response));
}
$this->loggerFactory->getLogger(LoggerFactory::TOPIC_PROVISIONING)->info(
'License was provisioned'
);
return true;
}
private function concatMessages(ErrorResponse $response): string {
$data = $response->getData();
$result = '';
if (empty($data) || !isset($data['errors'])) {
return $result;
}
foreach ($data['errors'] as $error) {
$result .= $error['message'] . " ";
}
return $result;
}
}