Merge pull request #1041 from mailpoet/access_control
Allows granular control of access to various parts of the plugin [MAILPOET-1057] [MAILPOET-1048]
This commit is contained in:
@ -1,11 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\API;
|
||||
|
||||
use MailPoet\Config\AccessControl;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class API {
|
||||
static function JSON() {
|
||||
return new \MailPoet\API\JSON\API();
|
||||
static function JSON(AccessControl $access_control) {
|
||||
return new \MailPoet\API\JSON\API($access_control);
|
||||
}
|
||||
|
||||
static function MP($version) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace MailPoet\API\JSON;
|
||||
|
||||
use MailPoet\Config\Env;
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\Util\Helpers;
|
||||
use MailPoet\Util\Security;
|
||||
use MailPoet\WP\Hooks;
|
||||
@ -19,9 +19,11 @@ class API {
|
||||
private $_available_api_versions = array(
|
||||
'v1'
|
||||
);
|
||||
private $access_control;
|
||||
const CURRENT_VERSION = 'v1';
|
||||
|
||||
function __construct() {
|
||||
function __construct(AccessControl $access_control) {
|
||||
$this->access_control = $access_control;
|
||||
foreach($this->_available_api_versions as $available_api_version) {
|
||||
$this->addEndpointNamespace(
|
||||
sprintf('%s\%s', __NAMESPACE__, $available_api_version),
|
||||
@ -130,17 +132,11 @@ class API {
|
||||
|
||||
// check the accessibility of the requested endpoint's action
|
||||
// by default, an endpoint's action is considered "private"
|
||||
$permissions = $endpoint->permissions;
|
||||
if(array_key_exists($this->_request_method, $permissions) === false ||
|
||||
$permissions[$this->_request_method] !== Access::ALL
|
||||
) {
|
||||
if($this->checkPermissions() === false) {
|
||||
$error_message = __('You do not have the required permissions.', 'mailpoet');
|
||||
$error_response = $this->createErrorResponse(Error::FORBIDDEN, $error_message, Response::STATUS_FORBIDDEN);
|
||||
return $error_response;
|
||||
}
|
||||
if(!$this->validatePermissions($this->_request_method, $endpoint->permissions)) {
|
||||
$error_message = __('You do not have the required permissions.', 'mailpoet');
|
||||
$error_response = $this->createErrorResponse(Error::FORBIDDEN, $error_message, Response::STATUS_FORBIDDEN);
|
||||
return $error_response;
|
||||
}
|
||||
|
||||
$response = $endpoint->{$this->_request_method}($this->_request_data);
|
||||
return $response;
|
||||
} catch(\Exception $e) {
|
||||
@ -150,8 +146,11 @@ class API {
|
||||
}
|
||||
}
|
||||
|
||||
function checkPermissions() {
|
||||
return current_user_can(Env::$required_permission);
|
||||
function validatePermissions($request_method, $permissions) {
|
||||
// validate method permission if defined, otherwise validate global permission
|
||||
return(!empty($permissions['methods'][$request_method])) ?
|
||||
$this->access_control->validatePermission($permissions['methods'][$request_method]) :
|
||||
$this->access_control->validatePermission($permissions['global']);
|
||||
}
|
||||
|
||||
function checkToken() {
|
||||
|
@ -1,12 +0,0 @@
|
||||
<?php
|
||||
namespace MailPoet\API\JSON;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
final class Access {
|
||||
const ALL = 'all';
|
||||
|
||||
private function __construct() {
|
||||
|
||||
}
|
||||
}
|
@ -1,11 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\API\JSON;
|
||||
|
||||
use MailPoet\Config\AccessControl;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
abstract class Endpoint {
|
||||
|
||||
public $permissions = array();
|
||||
public $permissions = array(
|
||||
'global' => array(AccessControl::PERMISSION_MANAGE_SETTINGS),
|
||||
'methods' => array()
|
||||
);
|
||||
|
||||
function successResponse(
|
||||
$data = array(), $meta = array(), $status = Response::STATUS_OK
|
||||
@ -18,7 +23,7 @@ abstract class Endpoint {
|
||||
) {
|
||||
if(empty($errors)) {
|
||||
$errors = array(
|
||||
Error::UNKNOWN => __('An unknown error occurred.', 'mailpoet')
|
||||
Error::UNKNOWN => __('An unknown error occurred.', 'mailpoet')
|
||||
);
|
||||
}
|
||||
return new ErrorResponse($errors, $meta, $status);
|
||||
|
@ -1,12 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\API\JSON\v1;
|
||||
|
||||
use MailPoet\API\JSON\Endpoint as APIEndpoint;
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\WP\Posts as WPPosts;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class AutomatedLatestContent extends APIEndpoint {
|
||||
public $ALC;
|
||||
public $permissions = array(
|
||||
'global' => AccessControl::PERMISSION_MANAGE_EMAILS
|
||||
);
|
||||
|
||||
function __construct() {
|
||||
$this->ALC = new \MailPoet\Newsletter\AutomatedLatestContent();
|
||||
|
@ -1,12 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\API\JSON\v1;
|
||||
|
||||
use MailPoet\API\JSON\Endpoint as APIEndpoint;
|
||||
use MailPoet\API\JSON\Error as APIError;
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\Models\CustomField;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class CustomFields extends APIEndpoint {
|
||||
public $permissions = array(
|
||||
'global' => AccessControl::PERMISSION_MANAGE_FORMS
|
||||
);
|
||||
|
||||
function getAll() {
|
||||
$collection = CustomField::orderByAsc('created_at')->findMany();
|
||||
$custom_fields = array_map(function($custom_field) {
|
||||
|
@ -1,17 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\API\JSON\v1;
|
||||
|
||||
use MailPoet\API\JSON\Endpoint as APIEndpoint;
|
||||
use MailPoet\API\JSON\Error as APIError;
|
||||
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\Form\Renderer as FormRenderer;
|
||||
use MailPoet\Form\Util;
|
||||
use MailPoet\Listing;
|
||||
use MailPoet\Models\Form;
|
||||
use MailPoet\Models\StatisticsForms;
|
||||
use MailPoet\Form\Renderer as FormRenderer;
|
||||
use MailPoet\Listing;
|
||||
use MailPoet\Form\Util;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Forms extends APIEndpoint {
|
||||
public $permissions = array(
|
||||
'global' => AccessControl::PERMISSION_MANAGE_FORMS
|
||||
);
|
||||
|
||||
function get($data = array()) {
|
||||
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||
$form = Form::findOne($id);
|
||||
|
@ -1,13 +1,19 @@
|
||||
<?php
|
||||
namespace MailPoet\API\JSON\v1;
|
||||
use MailPoet\API\JSON\Endpoint as APIEndpoint;
|
||||
|
||||
use MailPoet\Subscribers\ImportExport\Import\MailChimp;
|
||||
namespace MailPoet\API\JSON\v1;
|
||||
|
||||
use MailPoet\API\JSON\Endpoint as APIEndpoint;
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\Models\Segment;
|
||||
use MailPoet\Subscribers\ImportExport\Import\MailChimp;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class ImportExport extends APIEndpoint {
|
||||
public $permissions = array(
|
||||
'global' => AccessControl::PERMISSION_MANAGE_SUBSCRIBERS
|
||||
);
|
||||
|
||||
function getMailChimpLists($data) {
|
||||
try {
|
||||
$mailChimp = new MailChimp($data['api_key']);
|
||||
|
@ -1,10 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\API\JSON\v1;
|
||||
|
||||
use MailPoet\API\JSON\Endpoint as APIEndpoint;
|
||||
use MailPoet\Config\AccessControl;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class MP2Migrator extends APIEndpoint {
|
||||
public $permissions = array(
|
||||
'global' => AccessControl::PERMISSION_MANAGE_SETTINGS
|
||||
);
|
||||
|
||||
public function __construct() {
|
||||
$this->MP2Migrator = new \MailPoet\Config\MP2Migrator();
|
||||
|
@ -1,12 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\API\JSON\v1;
|
||||
|
||||
use MailPoet\API\JSON\Endpoint as APIEndpoint;
|
||||
use MailPoet\API\JSON\Error as APIError;
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\Mailer\MailerLog;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Mailer extends APIEndpoint {
|
||||
public $permissions = array(
|
||||
'global' => AccessControl::PERMISSION_MANAGE_EMAILS
|
||||
);
|
||||
|
||||
function send($data = array()) {
|
||||
try {
|
||||
$mailer = new \MailPoet\Mailer\Mailer(
|
||||
|
@ -1,13 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\API\JSON\v1;
|
||||
|
||||
use MailPoet\API\JSON\Endpoint as APIEndpoint;
|
||||
use MailPoet\API\JSON\Error as APIError;
|
||||
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\Models\NewsletterTemplate;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class NewsletterTemplates extends APIEndpoint {
|
||||
public $permissions = array(
|
||||
'global' => AccessControl::PERMISSION_MANAGE_EMAILS
|
||||
);
|
||||
|
||||
function get($data = array()) {
|
||||
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||
$template = NewsletterTemplate::findOne($id);
|
||||
|
@ -1,17 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\API\JSON\v1;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use MailPoet\API\JSON\Endpoint as APIEndpoint;
|
||||
use MailPoet\API\JSON\Error as APIError;
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\Listing;
|
||||
use MailPoet\Models\Newsletter;
|
||||
use MailPoet\Models\NewsletterOption;
|
||||
use MailPoet\Models\NewsletterOptionField;
|
||||
use MailPoet\Models\NewsletterSegment;
|
||||
use MailPoet\Models\NewsletterTemplate;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\Models\Newsletter;
|
||||
use MailPoet\Models\NewsletterTemplate;
|
||||
use MailPoet\Models\NewsletterSegment;
|
||||
use MailPoet\Models\NewsletterOptionField;
|
||||
use MailPoet\Models\NewsletterOption;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Newsletter\Renderer\Renderer;
|
||||
use MailPoet\Newsletter\Scheduler\Scheduler;
|
||||
@ -23,6 +25,10 @@ if(!defined('ABSPATH')) exit;
|
||||
require_once(ABSPATH . 'wp-includes/pluggable.php');
|
||||
|
||||
class Newsletters extends APIEndpoint {
|
||||
public $permissions = array(
|
||||
'global' => AccessControl::PERMISSION_MANAGE_EMAILS
|
||||
);
|
||||
|
||||
function get($data = array()) {
|
||||
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||
$newsletter = Newsletter::findOne($id);
|
||||
|
@ -1,15 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\API\JSON\v1;
|
||||
|
||||
use MailPoet\API\JSON\Endpoint as APIEndpoint;
|
||||
use MailPoet\API\JSON\Error as APIError;
|
||||
|
||||
use MailPoet\Models\Segment;
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\Listing;
|
||||
use MailPoet\Models\Segment;
|
||||
use MailPoet\Segments\WP;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Segments extends APIEndpoint {
|
||||
public $permissions = array(
|
||||
'global' => AccessControl::PERMISSION_MANAGE_SEGMENTS
|
||||
);
|
||||
|
||||
function get($data = array()) {
|
||||
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||
$segment = Segment::findOne($id);
|
||||
|
@ -1,18 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\API\JSON\v1;
|
||||
|
||||
use MailPoet\API\JSON\Endpoint as APIEndpoint;
|
||||
use MailPoet\API\JSON\Error as APIError;
|
||||
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\Mailer\Mailer;
|
||||
use MailPoet\Models\Newsletter;
|
||||
use MailPoet\Models\SendingQueue as SendingQueueModel;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Newsletter\Scheduler\Scheduler;
|
||||
use MailPoet\Models\SendingQueue as SendingQueueModel;
|
||||
use MailPoet\Util\Helpers;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class SendingQueue extends APIEndpoint {
|
||||
public $permissions = array(
|
||||
'global' => AccessControl::PERMISSION_MANAGE_EMAILS
|
||||
);
|
||||
|
||||
function add($data = array()) {
|
||||
$newsletter_id = (isset($data['newsletter_id'])
|
||||
? (int)$data['newsletter_id']
|
||||
|
@ -1,11 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\API\JSON\v1;
|
||||
|
||||
use MailPoet\API\JSON\Endpoint as APIEndpoint;
|
||||
use MailPoet\API\JSON\Error as APIError;
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\Config\Installer;
|
||||
use MailPoet\Services\Bridge;
|
||||
use MailPoet\Util\License\License;
|
||||
use MailPoet\WP\DateTime;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
@ -13,6 +14,9 @@ if(!defined('ABSPATH')) exit;
|
||||
class Services extends APIEndpoint {
|
||||
public $bridge;
|
||||
public $date_time;
|
||||
public $permissions = array(
|
||||
'global' => AccessControl::PERMISSION_MANAGE_SETTINGS
|
||||
);
|
||||
|
||||
function __construct() {
|
||||
$this->bridge = new Bridge();
|
||||
|
@ -1,24 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\API\JSON\v1;
|
||||
|
||||
use MailPoet\API\JSON\Endpoint as APIEndpoint;
|
||||
use MailPoet\API\JSON\Error as APIError;
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\Services\Bridge;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Settings extends APIEndpoint {
|
||||
public $permissions = array(
|
||||
'global' => AccessControl::PERMISSION_MANAGE_SETTINGS
|
||||
);
|
||||
|
||||
function get() {
|
||||
return $this->successResponse(Setting::getAll());
|
||||
}
|
||||
|
||||
function set($settings = array()) {
|
||||
if(empty($settings)) {
|
||||
return $this->badRequest(array(
|
||||
APIError::BAD_REQUEST =>
|
||||
__('You have not specified any settings to be saved.', 'mailpoet')
|
||||
));
|
||||
return $this->badRequest(
|
||||
array(
|
||||
APIError::BAD_REQUEST =>
|
||||
__('You have not specified any settings to be saved.', 'mailpoet')
|
||||
));
|
||||
} else {
|
||||
foreach($settings as $name => $value) {
|
||||
Setting::setValue($name, $value);
|
||||
|
@ -1,13 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\API\JSON\v1;
|
||||
|
||||
use MailPoet\API\JSON\Endpoint as APIEndpoint;
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\Config\Activator;
|
||||
use MailPoet\WP\Hooks;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Setup extends APIEndpoint {
|
||||
public $permissions = array(
|
||||
'global' => AccessControl::PERMISSION_MANAGE_SETTINGS
|
||||
);
|
||||
|
||||
function reset() {
|
||||
try {
|
||||
$activator = new Activator();
|
||||
|
@ -1,21 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\API\JSON\v1;
|
||||
|
||||
use MailPoet\API\JSON\Endpoint as APIEndpoint;
|
||||
use MailPoet\API\JSON\Error as APIError;
|
||||
use MailPoet\API\JSON\Access as APIAccess;
|
||||
|
||||
use MailPoet\Form\Util\FieldNameObfuscator;
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\Listing;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Form\Util\FieldNameObfuscator;
|
||||
use MailPoet\Models\Form;
|
||||
use MailPoet\Models\StatisticsForms;
|
||||
use MailPoet\Models\Subscriber;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Subscribers extends APIEndpoint {
|
||||
|
||||
public $permissions = array(
|
||||
'subscribe' => APIAccess::ALL
|
||||
'global' => AccessControl::PERMISSION_MANAGE_SUBSCRIBERS,
|
||||
'methods' => array('subscribe' => AccessControl::NO_ACCESS_RESTRICTION)
|
||||
);
|
||||
|
||||
function get($data = array()) {
|
||||
|
104
lib/Config/AccessControl.php
Normal file
104
lib/Config/AccessControl.php
Normal file
@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Config;
|
||||
|
||||
use MailPoet\WP\Hooks as WPHooks;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
require_once(ABSPATH . 'wp-includes/pluggable.php');
|
||||
|
||||
class AccessControl {
|
||||
const PERMISSION_ACCESS_PLUGIN_ADMIN = 'access_plugin_admin';
|
||||
const PERMISSION_MANAGE_SETTINGS = 'manage_settings';
|
||||
const PERMISSION_MANAGE_EMAILS = 'manage_emails';
|
||||
const PERMISSION_MANAGE_SUBSCRIBERS = 'manage_subscribers';
|
||||
const PERMISSION_MANAGE_FORMS = 'manage_forms';
|
||||
const PERMISSION_MANAGE_SEGMENTS = 'manage_segments';
|
||||
const PERMISSION_UPDATE_PLUGIN = 'update_plugin';
|
||||
const NO_ACCESS_RESTRICTION = 'no_access_restriction';
|
||||
|
||||
public $permissions;
|
||||
public $current_user_roles;
|
||||
public $user_capabilities;
|
||||
|
||||
function __construct() {
|
||||
$this->permissions = $this->getDefaultPermissions();
|
||||
$this->user_roles = $this->getUserRoles();
|
||||
$this->user_capabilities = $this->getUserCapabilities();
|
||||
}
|
||||
|
||||
private function getDefaultPermissions() {
|
||||
return array(
|
||||
self::PERMISSION_ACCESS_PLUGIN_ADMIN => WPHooks::applyFilters(
|
||||
'mailpoet_permission_access_plugin_admin',
|
||||
array(
|
||||
'administrator',
|
||||
'editor'
|
||||
)
|
||||
),
|
||||
self::PERMISSION_MANAGE_SETTINGS => WPHooks::applyFilters(
|
||||
'mailpoet_permission_manage_settings',
|
||||
array(
|
||||
'administrator'
|
||||
)
|
||||
),
|
||||
self::PERMISSION_MANAGE_EMAILS => WPHooks::applyFilters(
|
||||
'mailpoet_permission_manage_emails',
|
||||
array(
|
||||
'administrator',
|
||||
'editor'
|
||||
)
|
||||
),
|
||||
self::PERMISSION_MANAGE_SUBSCRIBERS => WPHooks::applyFilters(
|
||||
'mailpoet_permission_manage_subscribers',
|
||||
array(
|
||||
'administrator'
|
||||
)
|
||||
),
|
||||
self::PERMISSION_MANAGE_FORMS => WPHooks::applyFilters(
|
||||
'mailpoet_permission_manage_forms',
|
||||
array(
|
||||
'administrator'
|
||||
)
|
||||
),
|
||||
self::PERMISSION_MANAGE_SEGMENTS => WPHooks::applyFilters(
|
||||
'mailpoet_permission_manage_segments',
|
||||
array(
|
||||
'administrator'
|
||||
)
|
||||
),
|
||||
self::PERMISSION_UPDATE_PLUGIN => WPHooks::applyFilters(
|
||||
'mailpoet_permission_update_plugin',
|
||||
array(
|
||||
'administrator'
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
function getUserRoles() {
|
||||
$user = wp_get_current_user();
|
||||
return $user->roles;
|
||||
}
|
||||
|
||||
function getUserCapabilities() {
|
||||
$user = wp_get_current_user();
|
||||
return array_keys($user->allcaps);
|
||||
}
|
||||
|
||||
function getUserFirstCapability() {
|
||||
return (!empty($this->user_capabilities)) ?
|
||||
$this->user_capabilities[0] :
|
||||
null;
|
||||
}
|
||||
|
||||
function validatePermission($permission) {
|
||||
if($permission === self::NO_ACCESS_RESTRICTION) return true;
|
||||
if(empty($this->permissions[$permission])) return false;
|
||||
$permitted_roles = array_intersect(
|
||||
$this->user_roles,
|
||||
$this->permissions[$permission]
|
||||
);
|
||||
return (!empty($permitted_roles));
|
||||
}
|
||||
}
|
@ -1,10 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Config;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Activator {
|
||||
static function activate() {
|
||||
function activate() {
|
||||
$migrator = new Migrator();
|
||||
$migrator->up();
|
||||
|
||||
@ -14,7 +15,7 @@ class Activator {
|
||||
update_option('mailpoet_db_version', Env::$version);
|
||||
}
|
||||
|
||||
static function deactivate() {
|
||||
function deactivate() {
|
||||
$migrator = new Migrator();
|
||||
$migrator->down();
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Config;
|
||||
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\Util\Url;
|
||||
|
||||
class Changelog {
|
||||
function __construct() {
|
||||
}
|
||||
|
||||
function init() {
|
||||
$doing_ajax = (bool)(defined('DOING_AJAX') && DOING_AJAX);
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Config;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
@ -31,7 +32,6 @@ class Env {
|
||||
static $db_collation;
|
||||
static $db_charset_collate;
|
||||
static $db_timezone_offset;
|
||||
static $required_permission = 'manage_options';
|
||||
|
||||
static function init($file, $version) {
|
||||
global $wpdb;
|
||||
|
@ -13,17 +13,18 @@ if(!defined('ABSPATH')) exit;
|
||||
require_once(ABSPATH . 'wp-admin/includes/plugin.php');
|
||||
|
||||
class Initializer {
|
||||
|
||||
const UNABLE_TO_CONNECT = 'Unable to connect to the database (the database is unable to open a file or folder), the connection is likely not configured correctly. Please read our [link] Knowledge Base article [/link] for steps how to resolve it.';
|
||||
const SOLVE_DB_ISSUE_URL = 'http://beta.docs.mailpoet.com/article/200-solving-database-connection-issues';
|
||||
|
||||
protected $plugin_initialized = false;
|
||||
private $access_control;
|
||||
|
||||
function __construct($params = array(
|
||||
'file' => '',
|
||||
'version' => '1.0.0'
|
||||
)) {
|
||||
Env::init($params['file'], $params['version']);
|
||||
$this->access_control = new AccessControl();
|
||||
}
|
||||
|
||||
function init() {
|
||||
@ -135,7 +136,11 @@ class Initializer {
|
||||
|
||||
// if current db version and plugin version differ
|
||||
if(version_compare($current_db_version, Env::$version) !== 0) {
|
||||
Activator::activate();
|
||||
if(!$this->access_control->validatePermission(AccessControl::PERMISSION_UPDATE_PLUGIN)) {
|
||||
throw new \Exception(__('You do not have permission to activate/deactivate MailPoet plugin.', 'mailpoet'));
|
||||
}
|
||||
$activator = new Activator();
|
||||
$activator->activate();
|
||||
}
|
||||
}
|
||||
|
||||
@ -185,7 +190,7 @@ class Initializer {
|
||||
}
|
||||
|
||||
function setupMenu() {
|
||||
$menu = new Menu($this->renderer, Env::$assets_url);
|
||||
$menu = new Menu($this->renderer, Env::$assets_url, $this->access_control);
|
||||
$menu->init();
|
||||
}
|
||||
|
||||
@ -218,11 +223,11 @@ class Initializer {
|
||||
}
|
||||
|
||||
function setupJSONAPI() {
|
||||
API\API::JSON()->init();
|
||||
API\API::JSON($this->access_control)->init();
|
||||
}
|
||||
|
||||
function setupRouter() {
|
||||
$router = new Router\Router();
|
||||
$router = new Router\Router($this->access_control);
|
||||
$router->init();
|
||||
}
|
||||
|
||||
@ -246,7 +251,7 @@ class Initializer {
|
||||
function handleFailedInitialization($exception) {
|
||||
// Check if we are able to add pages at this point
|
||||
if(function_exists('wp_get_current_user')) {
|
||||
Menu::addErrorPage();
|
||||
Menu::addErrorPage($this->access_control);
|
||||
}
|
||||
return WPNotice::displayError($exception);
|
||||
}
|
||||
|
@ -187,8 +187,9 @@ class MP2Migrator {
|
||||
*
|
||||
*/
|
||||
private function eraseMP3Data() {
|
||||
Activator::deactivate();
|
||||
Activator::activate();
|
||||
$activator = new Activator();
|
||||
$activator->deactivate();
|
||||
$activator->activate();
|
||||
|
||||
$this->deleteSegments();
|
||||
$this->resetMigrationCounters();
|
||||
|
@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Config;
|
||||
|
||||
use MailPoet\Cron\CronTrigger;
|
||||
@ -25,9 +26,18 @@ use MailPoet\WP\Readme;
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Menu {
|
||||
function __construct($renderer, $assets_url) {
|
||||
const MAIN_PAGE_SLUG = 'mailpoet-newsletters';
|
||||
|
||||
public $renderer;
|
||||
public $assets_url;
|
||||
private $access_control;
|
||||
private $subscribers_over_limit;
|
||||
|
||||
function __construct($renderer, $assets_url, AccessControl $access_control) {
|
||||
$this->renderer = $renderer;
|
||||
$this->assets_url = $assets_url;
|
||||
$this->access_control = $access_control;
|
||||
$this->user_capability = $this->access_control->getUserFirstCapability();
|
||||
$subscribers_feature = new SubscribersFeature();
|
||||
$this->subscribers_over_limit = $subscribers_feature->check();
|
||||
$this->checkMailPoetAPIKey();
|
||||
@ -45,134 +55,204 @@ class Menu {
|
||||
}
|
||||
|
||||
function setup() {
|
||||
if(!$this->access_control->validatePermission(AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN)) return;
|
||||
if(self::isOnMailPoetAdminPage()) {
|
||||
do_action('mailpoet_conflict_resolver_styles');
|
||||
do_action('mailpoet_conflict_resolver_scripts');
|
||||
}
|
||||
|
||||
$main_page_slug = 'mailpoet-newsletters';
|
||||
|
||||
// Main page
|
||||
add_menu_page(
|
||||
'MailPoet',
|
||||
'MailPoet',
|
||||
Env::$required_permission,
|
||||
$main_page_slug,
|
||||
$this->user_capability,
|
||||
self::MAIN_PAGE_SLUG,
|
||||
null,
|
||||
$this->assets_url . '/img/menu_icon.png',
|
||||
30
|
||||
);
|
||||
|
||||
$newsletters_page = add_submenu_page(
|
||||
$main_page_slug,
|
||||
$this->setPageTitle(__('Emails', 'mailpoet')),
|
||||
__('Emails', 'mailpoet'),
|
||||
Env::$required_permission,
|
||||
$main_page_slug,
|
||||
array(
|
||||
$this,
|
||||
'newsletters'
|
||||
)
|
||||
);
|
||||
// Emails page
|
||||
if($this->access_control->validatePermission(AccessControl::PERMISSION_MANAGE_EMAILS)) {
|
||||
$newsletters_page = add_submenu_page(
|
||||
self::MAIN_PAGE_SLUG,
|
||||
$this->setPageTitle(__('Emails', 'mailpoet')),
|
||||
__('Emails', 'mailpoet'),
|
||||
$this->user_capability,
|
||||
self::MAIN_PAGE_SLUG,
|
||||
array(
|
||||
$this,
|
||||
'newsletters'
|
||||
)
|
||||
);
|
||||
|
||||
// add limit per page to screen options
|
||||
add_action('load-' . $newsletters_page, function() {
|
||||
add_screen_option('per_page', array(
|
||||
'label' => _x(
|
||||
'Number of newsletters per page',
|
||||
'newsletters per page (screen options)',
|
||||
'mailpoet'
|
||||
),
|
||||
'option' => 'mailpoet_newsletters_per_page'
|
||||
));
|
||||
});
|
||||
// add limit per page to screen options
|
||||
add_action('load-' . $newsletters_page, function() {
|
||||
add_screen_option('per_page', array(
|
||||
'label' => _x(
|
||||
'Number of newsletters per page',
|
||||
'newsletters per page (screen options)',
|
||||
'mailpoet'
|
||||
),
|
||||
'option' => 'mailpoet_newsletters_per_page'
|
||||
));
|
||||
});
|
||||
|
||||
$forms_page = add_submenu_page(
|
||||
$main_page_slug,
|
||||
$this->setPageTitle(__('Forms', 'mailpoet')),
|
||||
__('Forms', 'mailpoet'),
|
||||
Env::$required_permission,
|
||||
'mailpoet-forms',
|
||||
array(
|
||||
$this,
|
||||
'forms'
|
||||
)
|
||||
);
|
||||
// add limit per page to screen options
|
||||
add_action('load-' . $forms_page, function() {
|
||||
add_screen_option('per_page', array(
|
||||
'label' => _x(
|
||||
'Number of forms per page',
|
||||
'forms per page (screen options)',
|
||||
'mailpoet'
|
||||
),
|
||||
'option' => 'mailpoet_forms_per_page'
|
||||
));
|
||||
});
|
||||
// newsletter editor
|
||||
add_submenu_page(
|
||||
true,
|
||||
$this->setPageTitle(__('Newsletter', 'mailpoet')),
|
||||
__('Newsletter Editor', 'mailpoet'),
|
||||
$this->user_capability,
|
||||
'mailpoet-newsletter-editor',
|
||||
array(
|
||||
$this,
|
||||
'newletterEditor'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$subscribers_page = add_submenu_page(
|
||||
$main_page_slug,
|
||||
$this->setPageTitle(__('Subscribers', 'mailpoet')),
|
||||
__('Subscribers', 'mailpoet'),
|
||||
Env::$required_permission,
|
||||
'mailpoet-subscribers',
|
||||
array(
|
||||
$this,
|
||||
'subscribers'
|
||||
)
|
||||
);
|
||||
// add limit per page to screen options
|
||||
add_action('load-' . $subscribers_page, function() {
|
||||
add_screen_option('per_page', array(
|
||||
'label' => _x(
|
||||
'Number of subscribers per page',
|
||||
'subscribers per page (screen options)',
|
||||
'mailpoet'
|
||||
),
|
||||
'option' => 'mailpoet_subscribers_per_page'
|
||||
));
|
||||
});
|
||||
// Forms page
|
||||
if($this->access_control->validatePermission(AccessControl::PERMISSION_MANAGE_FORMS)) {
|
||||
$forms_page = add_submenu_page(
|
||||
self::MAIN_PAGE_SLUG,
|
||||
$this->setPageTitle(__('Forms', 'mailpoet')),
|
||||
__('Forms', 'mailpoet'),
|
||||
$this->user_capability,
|
||||
'mailpoet-forms',
|
||||
array(
|
||||
$this,
|
||||
'forms'
|
||||
)
|
||||
);
|
||||
|
||||
$segments_page = add_submenu_page(
|
||||
$main_page_slug,
|
||||
$this->setPageTitle(__('Lists', 'mailpoet')),
|
||||
__('Lists', 'mailpoet'),
|
||||
Env::$required_permission,
|
||||
'mailpoet-segments',
|
||||
array(
|
||||
$this,
|
||||
'segments'
|
||||
)
|
||||
);
|
||||
// add limit per page to screen options
|
||||
add_action('load-' . $forms_page, function() {
|
||||
add_screen_option('per_page', array(
|
||||
'label' => _x(
|
||||
'Number of forms per page',
|
||||
'forms per page (screen options)',
|
||||
'mailpoet'
|
||||
),
|
||||
'option' => 'mailpoet_forms_per_page'
|
||||
));
|
||||
});
|
||||
|
||||
// add limit per page to screen options
|
||||
add_action('load-' . $segments_page, function() {
|
||||
add_screen_option('per_page', array(
|
||||
'label' => _x(
|
||||
'Number of segments per page',
|
||||
'segments per page (screen options)',
|
||||
'mailpoet'
|
||||
),
|
||||
'option' => 'mailpoet_segments_per_page'
|
||||
));
|
||||
});
|
||||
// form editor
|
||||
add_submenu_page(
|
||||
true,
|
||||
$this->setPageTitle(__('Form Editor', 'mailpoet')),
|
||||
__('Form Editor', 'mailpoet'),
|
||||
$this->user_capability,
|
||||
'mailpoet-form-editor',
|
||||
array(
|
||||
$this,
|
||||
'formEditor'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Subscribers page
|
||||
if($this->access_control->validatePermission(AccessControl::PERMISSION_MANAGE_SUBSCRIBERS)) {
|
||||
$subscribers_page = add_submenu_page(
|
||||
self::MAIN_PAGE_SLUG,
|
||||
$this->setPageTitle(__('Subscribers', 'mailpoet')),
|
||||
__('Subscribers', 'mailpoet'),
|
||||
$this->user_capability,
|
||||
'mailpoet-subscribers',
|
||||
array(
|
||||
$this,
|
||||
'subscribers'
|
||||
)
|
||||
);
|
||||
|
||||
// add limit per page to screen options
|
||||
add_action('load-' . $subscribers_page, function() {
|
||||
add_screen_option('per_page', array(
|
||||
'label' => _x(
|
||||
'Number of subscribers per page',
|
||||
'subscribers per page (screen options)',
|
||||
'mailpoet'
|
||||
),
|
||||
'option' => 'mailpoet_subscribers_per_page'
|
||||
));
|
||||
});
|
||||
|
||||
// import
|
||||
add_submenu_page(
|
||||
'admin.php?page=mailpoet-subscribers',
|
||||
$this->setPageTitle(__('Import', 'mailpoet')),
|
||||
__('Import', 'mailpoet'),
|
||||
$this->user_capability,
|
||||
'mailpoet-import',
|
||||
array(
|
||||
$this,
|
||||
'import'
|
||||
)
|
||||
);
|
||||
|
||||
// export
|
||||
add_submenu_page(
|
||||
true,
|
||||
$this->setPageTitle(__('Export', 'mailpoet')),
|
||||
__('Export', 'mailpoet'),
|
||||
$this->user_capability,
|
||||
'mailpoet-export',
|
||||
array(
|
||||
$this,
|
||||
'export'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Segments page
|
||||
if($this->access_control->validatePermission(AccessControl::PERMISSION_MANAGE_SEGMENTS)) {
|
||||
$segments_page = add_submenu_page(
|
||||
self::MAIN_PAGE_SLUG,
|
||||
$this->setPageTitle(__('Lists', 'mailpoet')),
|
||||
__('Lists', 'mailpoet'),
|
||||
$this->user_capability,
|
||||
'mailpoet-segments',
|
||||
array(
|
||||
$this,
|
||||
'segments'
|
||||
)
|
||||
);
|
||||
|
||||
// add limit per page to screen options
|
||||
add_action('load-' . $segments_page, function() {
|
||||
add_screen_option('per_page', array(
|
||||
'label' => _x(
|
||||
'Number of segments per page',
|
||||
'segments per page (screen options)',
|
||||
'mailpoet'
|
||||
),
|
||||
'option' => 'mailpoet_segments_per_page'
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
// Settings page
|
||||
if($this->access_control->validatePermission(AccessControl::PERMISSION_MANAGE_SETTINGS)) {
|
||||
add_submenu_page(
|
||||
self::MAIN_PAGE_SLUG,
|
||||
$this->setPageTitle(__('Settings', 'mailpoet')),
|
||||
__('Settings', 'mailpoet'),
|
||||
$this->user_capability,
|
||||
'mailpoet-settings',
|
||||
array(
|
||||
$this,
|
||||
'settings'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Help page
|
||||
add_submenu_page(
|
||||
$main_page_slug,
|
||||
$this->setPageTitle(__('Settings', 'mailpoet')),
|
||||
__('Settings', 'mailpoet'),
|
||||
Env::$required_permission,
|
||||
'mailpoet-settings',
|
||||
array(
|
||||
$this,
|
||||
'settings'
|
||||
)
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
$main_page_slug,
|
||||
self::MAIN_PAGE_SLUG,
|
||||
$this->setPageTitle(__('Help', 'mailpoet')),
|
||||
__('Help', 'mailpoet'),
|
||||
Env::$required_permission,
|
||||
$this->user_capability,
|
||||
'mailpoet-help',
|
||||
array(
|
||||
$this,
|
||||
@ -180,12 +260,13 @@ class Menu {
|
||||
)
|
||||
);
|
||||
|
||||
// Premium page
|
||||
// Only show this page in menu if the Premium plugin is not activated
|
||||
add_submenu_page(
|
||||
License::getLicense() ? true : $main_page_slug,
|
||||
License::getLicense() ? true : self::MAIN_PAGE_SLUG,
|
||||
$this->setPageTitle(__('Premium', 'mailpoet')),
|
||||
__('Premium', 'mailpoet'),
|
||||
Env::$required_permission,
|
||||
$this->user_capability,
|
||||
'mailpoet-premium',
|
||||
array(
|
||||
$this,
|
||||
@ -193,35 +274,12 @@ class Menu {
|
||||
)
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
'admin.php?page=mailpoet-subscribers',
|
||||
$this->setPageTitle(__('Import', 'mailpoet')),
|
||||
__('Import', 'mailpoet'),
|
||||
Env::$required_permission,
|
||||
'mailpoet-import',
|
||||
array(
|
||||
$this,
|
||||
'import'
|
||||
)
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
true,
|
||||
$this->setPageTitle(__('Export', 'mailpoet')),
|
||||
__('Export', 'mailpoet'),
|
||||
Env::$required_permission,
|
||||
'mailpoet-export',
|
||||
array(
|
||||
$this,
|
||||
'export'
|
||||
)
|
||||
);
|
||||
|
||||
// Welcome page
|
||||
add_submenu_page(
|
||||
true,
|
||||
$this->setPageTitle(__('Welcome', 'mailpoet')),
|
||||
__('Welcome', 'mailpoet'),
|
||||
Env::$required_permission,
|
||||
$this->user_capability,
|
||||
'mailpoet-welcome',
|
||||
array(
|
||||
$this,
|
||||
@ -229,23 +287,12 @@ class Menu {
|
||||
)
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
true,
|
||||
$this->setPageTitle(__('Migration', 'mailpoet')),
|
||||
'',
|
||||
Env::$required_permission,
|
||||
'mailpoet-migration',
|
||||
array(
|
||||
$this,
|
||||
'migration'
|
||||
)
|
||||
);
|
||||
|
||||
// Update page
|
||||
add_submenu_page(
|
||||
true,
|
||||
$this->setPageTitle(__('Update', 'mailpoet')),
|
||||
__('Update', 'mailpoet'),
|
||||
Env::$required_permission,
|
||||
$this->user_capability,
|
||||
'mailpoet-update',
|
||||
array(
|
||||
$this,
|
||||
@ -253,27 +300,16 @@ class Menu {
|
||||
)
|
||||
);
|
||||
|
||||
// Migration page
|
||||
add_submenu_page(
|
||||
true,
|
||||
$this->setPageTitle(__('Form Editor', 'mailpoet')),
|
||||
__('Form Editor', 'mailpoet'),
|
||||
Env::$required_permission,
|
||||
'mailpoet-form-editor',
|
||||
$this->setPageTitle(__('Migration', 'mailpoet')),
|
||||
'',
|
||||
$this->user_capability,
|
||||
'mailpoet-migration',
|
||||
array(
|
||||
$this,
|
||||
'formEditor'
|
||||
)
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
true,
|
||||
$this->setPageTitle(__('Newsletter', 'mailpoet')),
|
||||
__('Newsletter Editor', 'mailpoet'),
|
||||
Env::$required_permission,
|
||||
'mailpoet-newsletter-editor',
|
||||
array(
|
||||
$this,
|
||||
'newletterEditor'
|
||||
'migration'
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -293,20 +329,20 @@ class Menu {
|
||||
or
|
||||
strpos($redirect_url, 'mailpoet') === false
|
||||
) {
|
||||
$redirect_url = admin_url('admin.php?page=mailpoet-newsletters');
|
||||
$redirect_url = admin_url('admin.php?page=' . self::MAIN_PAGE_SLUG);
|
||||
}
|
||||
|
||||
$data = array(
|
||||
'settings' => Setting::getAll(),
|
||||
'current_user' => wp_get_current_user(),
|
||||
'redirect_url' => $redirect_url,
|
||||
'sub_menu' => 'mailpoet-newsletters'
|
||||
'sub_menu' => self::MAIN_PAGE_SLUG
|
||||
);
|
||||
$this->displayPage('welcome.html', $data);
|
||||
}
|
||||
|
||||
function migration() {
|
||||
$mp2_migrator = new MP2Migrator();
|
||||
$mp2_migrator = new MP2Migrator($this->access_control);
|
||||
$mp2_migrator->init();
|
||||
$data = array(
|
||||
'log_file_url' => $mp2_migrator->log_file_url,
|
||||
@ -328,14 +364,14 @@ class Menu {
|
||||
or
|
||||
strpos($redirect_url, 'mailpoet') === false
|
||||
) {
|
||||
$redirect_url = admin_url('admin.php?page=mailpoet-newsletters');
|
||||
$redirect_url = admin_url('admin.php?page=' . self::MAIN_PAGE_SLUG);
|
||||
}
|
||||
|
||||
$data = array(
|
||||
'settings' => Setting::getAll(),
|
||||
'current_user' => wp_get_current_user(),
|
||||
'redirect_url' => $redirect_url,
|
||||
'sub_menu' => 'mailpoet-newsletters'
|
||||
'sub_menu' => self::MAIN_PAGE_SLUG
|
||||
);
|
||||
|
||||
$readme_file = Env::$path . '/readme.txt';
|
||||
@ -352,7 +388,7 @@ class Menu {
|
||||
function premium() {
|
||||
$data = array(
|
||||
'subscriber_count' => Subscriber::getTotalSubscribers(),
|
||||
'sub_menu' => 'mailpoet-newsletters'
|
||||
'sub_menu' => self::MAIN_PAGE_SLUG
|
||||
);
|
||||
|
||||
$this->displayPage('premium.html', $data);
|
||||
@ -505,7 +541,7 @@ class Menu {
|
||||
'shortcodes' => ShortcodesHelper::getShortcodes(),
|
||||
'settings' => Setting::getAll(),
|
||||
'current_wp_user' => Subscriber::getCurrentWPUser(),
|
||||
'sub_menu' => 'mailpoet-newsletters'
|
||||
'sub_menu' => self::MAIN_PAGE_SLUG
|
||||
);
|
||||
wp_enqueue_media();
|
||||
wp_enqueue_script('tinymce-wplink', includes_url('js/tinymce/plugins/wplink/plugin.js'));
|
||||
@ -597,13 +633,13 @@ class Menu {
|
||||
* This error page is used when the initialization is failed
|
||||
* to display admin notices only
|
||||
*/
|
||||
static function addErrorPage() {
|
||||
static function addErrorPage(AccessControl $access_control) {
|
||||
if(!self::isOnMailPoetAdminPage()) {
|
||||
return false;
|
||||
}
|
||||
// Check if page already exists
|
||||
if(get_plugin_page_hook($_REQUEST['page'], '')
|
||||
|| get_plugin_page_hook($_REQUEST['page'], 'mailpoet-newsletters')
|
||||
|| get_plugin_page_hook($_REQUEST['page'], self::MAIN_PAGE_SLUG)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
@ -611,9 +647,12 @@ class Menu {
|
||||
true,
|
||||
'MailPoet',
|
||||
'MailPoet',
|
||||
Env::$required_permission,
|
||||
$access_control->getUserFirstCapability(),
|
||||
$_REQUEST['page'],
|
||||
array(__CLASS__, 'errorPageCallback')
|
||||
array(
|
||||
__CLASS__,
|
||||
'errorPageCallback'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@ -624,7 +663,7 @@ class Menu {
|
||||
function checkMailPoetAPIKey(ServicesChecker $checker = null) {
|
||||
if(self::isOnMailPoetAdminPage()) {
|
||||
$show_notices = isset($_REQUEST['page'])
|
||||
&& stripos($_REQUEST['page'], 'mailpoet-newsletters') === false;
|
||||
&& stripos($_REQUEST['page'], self::MAIN_PAGE_SLUG) === false;
|
||||
$checker = $checker ?: new ServicesChecker();
|
||||
$this->mp_api_key_valid = $checker->isMailPoetAPIKeyValid($show_notices);
|
||||
}
|
||||
@ -633,7 +672,7 @@ class Menu {
|
||||
function checkPremiumKey(ServicesChecker $checker = null) {
|
||||
if(self::isOnMailPoetAdminPage()) {
|
||||
$show_notices = isset($_REQUEST['page'])
|
||||
&& stripos($_REQUEST['page'], 'mailpoet-newsletters') === false;
|
||||
&& stripos($_REQUEST['page'], self::MAIN_PAGE_SLUG) === false;
|
||||
$checker = $checker ?: new ServicesChecker();
|
||||
$this->premium_key_valid = $checker->isPremiumKeyValid($show_notices);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
namespace MailPoet\Form;
|
||||
|
||||
use MailPoet\API\JSON\API;
|
||||
use MailPoet\Config\Renderer;
|
||||
use MailPoet\Config\Renderer as ConfigRenderer;
|
||||
use MailPoet\Form\Renderer as FormRenderer;
|
||||
use MailPoet\Models\Form;
|
||||
use MailPoet\Util\Security;
|
||||
@ -174,7 +174,7 @@ class Widget extends \WP_Widget {
|
||||
$data['api_version'] = API::CURRENT_VERSION;
|
||||
|
||||
// render form
|
||||
$renderer = new Renderer();
|
||||
$renderer = new ConfigRenderer();
|
||||
try {
|
||||
$output = $renderer->render('form/widget.html', $data);
|
||||
$output = do_shortcode($output);
|
||||
|
@ -1,6 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Router\Endpoints;
|
||||
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\Cron\CronHelper;
|
||||
use MailPoet\Cron\Daemon;
|
||||
|
||||
@ -17,6 +19,9 @@ class CronDaemon {
|
||||
self::ACTION_PING_RESPONSE
|
||||
);
|
||||
public $data;
|
||||
public $permissions = array(
|
||||
'global' => AccessControl::NO_ACCESS_RESTRICTION
|
||||
);
|
||||
|
||||
function __construct($data) {
|
||||
$this->data = $data;
|
||||
|
@ -1,6 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Router\Endpoints;
|
||||
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\Subscription as UserSubscription;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
@ -16,6 +18,9 @@ class Subscription {
|
||||
self::ACTION_UNSUBSCRIBE
|
||||
);
|
||||
public $data;
|
||||
public $permissions = array(
|
||||
'global' => AccessControl::NO_ACCESS_RESTRICTION
|
||||
);
|
||||
|
||||
function __construct($data) {
|
||||
$this->data = $data;
|
||||
|
@ -1,6 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Router\Endpoints;
|
||||
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\Models\Newsletter;
|
||||
use MailPoet\Models\NewsletterLink;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
@ -20,6 +22,9 @@ class Track {
|
||||
self::ACTION_OPEN
|
||||
);
|
||||
public $data;
|
||||
public $permissions = array(
|
||||
'global' => AccessControl::NO_ACCESS_RESTRICTION
|
||||
);
|
||||
|
||||
function __construct($data) {
|
||||
$this->data = $this->_processTrackData($data);
|
||||
@ -38,8 +43,8 @@ class Track {
|
||||
function _processTrackData($data) {
|
||||
$data = (object)Links::transformUrlDataObject($data);
|
||||
if(empty($data->queue_id) ||
|
||||
empty($data->subscriber_id) ||
|
||||
empty($data->subscriber_token)
|
||||
empty($data->subscriber_id) ||
|
||||
empty($data->subscriber_token)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Router\Endpoints;
|
||||
|
||||
use MailPoet\Config\Env;
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\Models\Newsletter;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Models\Subscriber;
|
||||
@ -17,8 +18,12 @@ class ViewInBrowser {
|
||||
const ACTION_VIEW = 'view';
|
||||
public $allowed_actions = array(self::ACTION_VIEW);
|
||||
public $data;
|
||||
public $permissions = array(
|
||||
'global' => AccessControl::NO_ACCESS_RESTRICTION
|
||||
);
|
||||
|
||||
function __construct($data) {
|
||||
function __construct($data, AccessControl $access_control) {
|
||||
$this->access_control = $access_control;
|
||||
$this->data = $this->_processBrowserPreviewData($data);
|
||||
}
|
||||
|
||||
@ -69,8 +74,8 @@ class ViewInBrowser {
|
||||
$data->queue = false;
|
||||
}
|
||||
|
||||
// allow users with 'manage_options' permission to preview any newsletter
|
||||
if(!empty($data->preview) && current_user_can(Env::$required_permission)
|
||||
// allow users with permission to manage emails to preview any newsletter
|
||||
if(!empty($data->preview) && $this->access_control->validatePermission(AccessControl::PERMISSION_MANAGE_EMAILS)
|
||||
) return $data;
|
||||
|
||||
// allow others to preview newsletters only when newsletter hash is defined
|
||||
|
@ -1,6 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Router;
|
||||
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\Util\Helpers;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
@ -12,19 +14,21 @@ class Router {
|
||||
public $data;
|
||||
const NAME = 'mailpoet_router';
|
||||
const RESPONSE_ERROR = 404;
|
||||
const RESPONE_FORBIDDEN = 403;
|
||||
|
||||
function __construct($api_data = false) {
|
||||
function __construct(AccessControl $access_control, $api_data = false) {
|
||||
$api_data = ($api_data) ? $api_data : $_GET;
|
||||
$this->api_request = isset($api_data[self::NAME]);
|
||||
$this->endpoint = isset($api_data['endpoint']) ?
|
||||
Helpers::underscoreToCamelCase($api_data['endpoint']) :
|
||||
false;
|
||||
$this->action = isset($api_data['action']) ?
|
||||
$this->endpoint_action = isset($api_data['action']) ?
|
||||
Helpers::underscoreToCamelCase($api_data['action']) :
|
||||
false;
|
||||
$this->data = isset($api_data['data']) ?
|
||||
self::decodeRequestData($api_data['data']) :
|
||||
false;
|
||||
$this->access_control = $access_control;
|
||||
}
|
||||
|
||||
function init() {
|
||||
@ -33,15 +37,18 @@ class Router {
|
||||
if(!$this->endpoint || !class_exists($endpoint_class)) {
|
||||
return $this->terminateRequest(self::RESPONSE_ERROR, __('Invalid router endpoint', 'mailpoet'));
|
||||
}
|
||||
$endpoint = new $endpoint_class($this->data);
|
||||
if(!method_exists($endpoint, $this->action) || !in_array($this->action, $endpoint->allowed_actions)) {
|
||||
$endpoint = new $endpoint_class($this->data, $this->access_control);
|
||||
if(!method_exists($endpoint, $this->endpoint_action) || !in_array($this->endpoint_action, $endpoint->allowed_actions)) {
|
||||
return $this->terminateRequest(self::RESPONSE_ERROR, __('Invalid router endpoint action', 'mailpoet'));
|
||||
}
|
||||
if(!$this->validatePermissions($this->endpoint_action, $endpoint->permissions)) {
|
||||
return $this->terminateRequest(self::RESPONE_FORBIDDEN, __('You do not have the required permissions.', 'mailpoet'));
|
||||
}
|
||||
do_action('mailpoet_conflict_resolver_router_url_query_parameters');
|
||||
return call_user_func(
|
||||
array(
|
||||
$endpoint,
|
||||
$this->action
|
||||
$this->endpoint_action
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -74,4 +81,11 @@ class Router {
|
||||
status_header($code, $message);
|
||||
exit;
|
||||
}
|
||||
|
||||
function validatePermissions($endpoint_action, $permissions) {
|
||||
// validate action permission if defined, otherwise validate global permission
|
||||
return(!empty($permissions['actions'][$endpoint_action])) ?
|
||||
$this->access_control->validatePermission($permissions['actions'][$endpoint_action]) :
|
||||
$this->access_control->validatePermission($permissions['global']);
|
||||
}
|
||||
}
|
@ -2,14 +2,15 @@
|
||||
|
||||
namespace MailPoet\Subscription;
|
||||
|
||||
use MailPoet\API\JSON\API;
|
||||
use MailPoet\API\API as API;
|
||||
use MailPoet\API\JSON\Response as APIResponse;
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\Util\Url as UrlHelper;
|
||||
|
||||
class Form {
|
||||
static function onSubmit($request_data = false) {
|
||||
$request_data = ($request_data) ? $request_data : $_REQUEST;
|
||||
$api = new API();
|
||||
$api = API::JSON(new AccessControl());
|
||||
$api->setRequestData($request_data);
|
||||
$form_id = (!empty($request_data['data']['form_id'])) ? (int)$request_data['data']['form_id'] : false;
|
||||
$response = $api->processRoute();
|
||||
|
@ -2,10 +2,11 @@
|
||||
namespace MailPoet\Test\API;
|
||||
|
||||
use MailPoet\API\API;
|
||||
use MailPoet\Config\AccessControl;
|
||||
|
||||
class APITest extends \MailPoetTest {
|
||||
function testItCallsJSONAPI() {
|
||||
expect(API::JSON())->isInstanceOf('MailPoet\API\JSON\API');
|
||||
expect(API::JSON(new AccessControl()))->isInstanceOf('MailPoet\API\JSON\API');
|
||||
}
|
||||
|
||||
function testItCallsMPAPI() {
|
||||
|
@ -1,13 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Test\API\JSON;
|
||||
|
||||
use Codeception\Util\Stub;
|
||||
use MailPoet\API\JSON\API;
|
||||
use MailPoet\API\JSON\SuccessResponse;
|
||||
use Helper\WordPressHooks as WPHooksHelper;
|
||||
use MailPoet\API\API;
|
||||
use MailPoet\API\JSON\API as JSONAPI;
|
||||
use MailPoet\API\JSON\Response;
|
||||
use MailPoet\API\JSON\Response as APIResponse;
|
||||
use MailPoet\API\JSON\SuccessResponse;
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\WP\Hooks;
|
||||
|
||||
// required to be able to use wp_delete_user()
|
||||
require_once(ABSPATH.'wp-admin/includes/user.php');
|
||||
require_once(ABSPATH . 'wp-admin/includes/user.php');
|
||||
require_once('APITestNamespacedEndpointStubV1.php');
|
||||
require_once('APITestNamespacedEndpointStubV2.php');
|
||||
|
||||
@ -22,30 +28,16 @@ class APITest extends \MailPoetTest {
|
||||
} else {
|
||||
$this->wp_user_id = $wp_user_id;
|
||||
}
|
||||
|
||||
$this->api = new API();
|
||||
}
|
||||
|
||||
function testItChecksPermissions() {
|
||||
// logged out user
|
||||
expect($this->api->checkPermissions())->false();
|
||||
|
||||
// give administrator role to wp user
|
||||
$wp_user = get_user_by('id', $this->wp_user_id);
|
||||
$wp_user->add_role('administrator');
|
||||
wp_set_current_user($wp_user->ID, $wp_user->user_login);
|
||||
|
||||
// administrator should have permission
|
||||
expect($this->api->checkPermissions())->true();
|
||||
$this->api = API::JSON(new AccessControl());
|
||||
}
|
||||
|
||||
function testItCallsAPISetupAction() {
|
||||
$called = false;
|
||||
add_action(
|
||||
Hooks::addAction(
|
||||
'mailpoet_api_setup',
|
||||
function ($api) use (&$called) {
|
||||
function($api) use (&$called) {
|
||||
$called = true;
|
||||
expect($api instanceof API)->true();
|
||||
expect($api instanceof JSONAPI)->true();
|
||||
}
|
||||
);
|
||||
$api = Stub::makeEmptyExcept(
|
||||
@ -136,11 +128,101 @@ class APITest extends \MailPoetTest {
|
||||
);
|
||||
$this->api->setRequestData($data);
|
||||
$response = $this->api->processRoute();
|
||||
|
||||
expect($response->getData()['data'])->equals($data['api_version']);
|
||||
}
|
||||
|
||||
function testItValidatesPermissionBeforeProcessingEndpointMethod() {
|
||||
$namespace = array(
|
||||
'name' => 'MailPoet\API\JSON\v1',
|
||||
'version' => 'v1'
|
||||
);
|
||||
$data = array(
|
||||
'endpoint' => 'a_p_i_test_namespaced_endpoint_stub_v1',
|
||||
'method' => 'restricted',
|
||||
'api_version' => 'v1',
|
||||
'data' => array('test' => 'data')
|
||||
);
|
||||
$access_control = new AccessControl();
|
||||
$access_control->user_roles = $access_control->permissions[AccessControl::PERMISSION_MANAGE_SETTINGS];
|
||||
$api = Stub::make(
|
||||
new \MailPoet\API\JSON\API($access_control),
|
||||
array(
|
||||
'validatePermissions' => function($method, $permissions) use ($data) {
|
||||
expect($method)->equals($data['method']);
|
||||
expect($permissions)->equals(
|
||||
array(
|
||||
'global' => AccessControl::NO_ACCESS_RESTRICTION,
|
||||
'methods' => array(
|
||||
'test' => AccessControl::NO_ACCESS_RESTRICTION,
|
||||
'restricted' => AccessControl::PERMISSION_MANAGE_SETTINGS
|
||||
)
|
||||
)
|
||||
);
|
||||
return true;
|
||||
}
|
||||
)
|
||||
);
|
||||
$api->addEndpointNamespace($namespace['name'], $namespace['version']);
|
||||
$api->setRequestData($data);
|
||||
$response = $api->processRoute();
|
||||
expect($response->getData()['data'])->equals($data['data']);
|
||||
}
|
||||
|
||||
function testItReturnsForbiddenResponseWhenPermissionFailsValidation() {
|
||||
$namespace = array(
|
||||
'name' => 'MailPoet\API\JSON\v1',
|
||||
'version' => 'v1'
|
||||
);
|
||||
$data = array(
|
||||
'endpoint' => 'a_p_i_test_namespaced_endpoint_stub_v1',
|
||||
'method' => 'restricted',
|
||||
'api_version' => 'v1',
|
||||
'data' => array('test' => 'data')
|
||||
);
|
||||
$access_control = new AccessControl();
|
||||
$access_control->user_roles = array();
|
||||
$api = new \MailPoet\API\JSON\API($access_control);
|
||||
$api->addEndpointNamespace($namespace['name'], $namespace['version']);
|
||||
$api->setRequestData($data);
|
||||
$response = $api->processRoute();
|
||||
expect($response->status)->equals(Response::STATUS_FORBIDDEN);
|
||||
}
|
||||
|
||||
function testItValidatesGlobalPermission() {
|
||||
$access_control = new AccessControl();
|
||||
$permissions = array(
|
||||
'global' => AccessControl::PERMISSION_MANAGE_SETTINGS,
|
||||
);
|
||||
|
||||
$access_control->user_roles = array();
|
||||
$api = new JSONAPI($access_control);
|
||||
expect($api->validatePermissions(null, $permissions))->false();
|
||||
|
||||
$access_control->user_roles = $access_control->permissions[AccessControl::PERMISSION_MANAGE_SETTINGS];
|
||||
$api = new JSONAPI($access_control);
|
||||
expect($api->validatePermissions(null, $permissions))->true();
|
||||
}
|
||||
|
||||
function testItValidatesEndpointMethodPermission() {
|
||||
$access_control = new AccessControl();
|
||||
$permissions = array(
|
||||
'global' => null,
|
||||
'methods' => array(
|
||||
'test' => AccessControl::PERMISSION_MANAGE_SETTINGS
|
||||
)
|
||||
);
|
||||
|
||||
$access_control->user_roles = array();
|
||||
$api = new JSONAPI($access_control);
|
||||
expect($api->validatePermissions('test', $permissions))->false();
|
||||
|
||||
$access_control->user_roles = $access_control->permissions[AccessControl::PERMISSION_MANAGE_SETTINGS];
|
||||
$api = new JSONAPI($access_control);
|
||||
expect($api->validatePermissions('test', $permissions))->true();
|
||||
}
|
||||
|
||||
function _after() {
|
||||
WPHooksHelper::releaseAllHooks();
|
||||
wp_delete_user($this->wp_user_id);
|
||||
}
|
||||
}
|
@ -3,16 +3,24 @@
|
||||
namespace MailPoet\API\JSON\v1;
|
||||
|
||||
use MailPoet\API\JSON\Endpoint as APIEndpoint;
|
||||
use MailPoet\API\JSON\Access as APIAccess;
|
||||
use MailPoet\Config\AccessControl;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class APITestNamespacedEndpointStubV1 extends APIEndpoint {
|
||||
public $permissions = array(
|
||||
'test' => APIAccess::ALL
|
||||
'global' => AccessControl::NO_ACCESS_RESTRICTION,
|
||||
'methods' => array(
|
||||
'test' => AccessControl::NO_ACCESS_RESTRICTION,
|
||||
'restricted' => AccessControl::PERMISSION_MANAGE_SETTINGS
|
||||
)
|
||||
);
|
||||
|
||||
function test($data) {
|
||||
return $this->successResponse($data);
|
||||
}
|
||||
|
||||
function restricted($data) {
|
||||
return $this->successResponse($data);
|
||||
}
|
||||
}
|
||||
|
@ -2,14 +2,17 @@
|
||||
|
||||
namespace MailPoet\API\JSON\v2;
|
||||
|
||||
use MailPoet\API\JSON\Access as APIAccess;
|
||||
use MailPoet\API\JSON\Endpoint as APIEndpoint;
|
||||
use MailPoet\Config\AccessControl;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class APITestNamespacedEndpointStubV2 extends APIEndpoint {
|
||||
public $permissions = array(
|
||||
'testVersion' => APIAccess::ALL
|
||||
'global' => AccessControl::NO_ACCESS_RESTRICTION,
|
||||
'methods' => array(
|
||||
'test' => AccessControl::NO_ACCESS_RESTRICTION
|
||||
)
|
||||
);
|
||||
|
||||
function testVersion() {
|
||||
|
115
tests/unit/Config/AccessControlTest.php
Normal file
115
tests/unit/Config/AccessControlTest.php
Normal file
@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Test\Config;
|
||||
|
||||
use Helper\WordPressHooks as WPHooksHelper;
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\WP\Hooks;
|
||||
|
||||
class AccessControlTest extends \MailPoetTest {
|
||||
function testItSetsDefaultPermissionsUponInitialization() {
|
||||
$default_permissions = array(
|
||||
AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN => array(
|
||||
'administrator',
|
||||
'editor'
|
||||
),
|
||||
AccessControl::PERMISSION_MANAGE_SETTINGS => array(
|
||||
'administrator'
|
||||
),
|
||||
AccessControl::PERMISSION_MANAGE_EMAILS => array(
|
||||
'administrator',
|
||||
'editor'
|
||||
),
|
||||
AccessControl::PERMISSION_MANAGE_SUBSCRIBERS => array(
|
||||
'administrator'
|
||||
),
|
||||
AccessControl::PERMISSION_MANAGE_FORMS => array(
|
||||
'administrator'
|
||||
),
|
||||
AccessControl::PERMISSION_MANAGE_SEGMENTS => array(
|
||||
'administrator'
|
||||
),
|
||||
AccessControl::PERMISSION_UPDATE_PLUGIN => array(
|
||||
'administrator'
|
||||
)
|
||||
);
|
||||
$access_control = new AccessControl();
|
||||
expect($access_control->permissions)->equals($default_permissions);
|
||||
}
|
||||
|
||||
function testItAllowsSettingCustomPermissions() {
|
||||
Hooks::addFilter(
|
||||
'mailpoet_permission_access_plugin_admin',
|
||||
function() {
|
||||
return array('custom_access_plugin_admin_role');
|
||||
}
|
||||
);
|
||||
Hooks::addFilter(
|
||||
'mailpoet_permission_manage_settings',
|
||||
function() {
|
||||
return array('custom_manage_settings_role');
|
||||
}
|
||||
);
|
||||
Hooks::addFilter(
|
||||
'mailpoet_permission_manage_emails',
|
||||
function() {
|
||||
return array('custom_manage_emails_role');
|
||||
}
|
||||
);
|
||||
Hooks::addFilter(
|
||||
'mailpoet_permission_manage_subscribers',
|
||||
function() {
|
||||
return array('custom_manage_subscribers_role');
|
||||
}
|
||||
);
|
||||
Hooks::addFilter(
|
||||
'mailpoet_permission_manage_forms',
|
||||
function() {
|
||||
return array('custom_manage_forms_role');
|
||||
}
|
||||
);
|
||||
Hooks::addFilter(
|
||||
'mailpoet_permission_manage_segments',
|
||||
function() {
|
||||
return array('custom_manage_segments_role');
|
||||
}
|
||||
);
|
||||
Hooks::addFilter(
|
||||
'mailpoet_permission_update_plugin',
|
||||
function() {
|
||||
return array('custom_update_plugin_role');
|
||||
}
|
||||
);
|
||||
|
||||
$access_control = new AccessControl();
|
||||
expect($access_control->permissions)->equals(
|
||||
array(
|
||||
AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN => array(
|
||||
'custom_access_plugin_admin_role'
|
||||
),
|
||||
AccessControl::PERMISSION_MANAGE_SETTINGS => array(
|
||||
'custom_manage_settings_role'
|
||||
),
|
||||
AccessControl::PERMISSION_MANAGE_EMAILS => array(
|
||||
'custom_manage_emails_role'
|
||||
),
|
||||
AccessControl::PERMISSION_MANAGE_SUBSCRIBERS => array(
|
||||
'custom_manage_subscribers_role'
|
||||
),
|
||||
AccessControl::PERMISSION_MANAGE_FORMS => array(
|
||||
'custom_manage_forms_role'
|
||||
),
|
||||
AccessControl::PERMISSION_MANAGE_SEGMENTS => array(
|
||||
'custom_manage_segments_role'
|
||||
),
|
||||
AccessControl::PERMISSION_UPDATE_PLUGIN => array(
|
||||
'custom_update_plugin_role'
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function _after() {
|
||||
WPHooksHelper::releaseAllHooks();
|
||||
}
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Test\Config;
|
||||
|
||||
use Codeception\Util\Stub;
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\Config\Menu;
|
||||
use MailPoet\Config\Renderer;
|
||||
use MailPoet\Config\ServicesChecker;
|
||||
@ -39,7 +41,7 @@ class MenuTest extends \MailPoetTest {
|
||||
function testItChecksMailpoetAPIKey() {
|
||||
$renderer = Stub::make(new Renderer());
|
||||
$assets_url = '';
|
||||
$menu = new Menu($renderer, $assets_url);
|
||||
$menu = new Menu($renderer, $assets_url, new AccessControl());
|
||||
|
||||
$_REQUEST['page'] = 'mailpoet-newsletters';
|
||||
$checker = Stub::make(
|
||||
@ -62,7 +64,7 @@ class MenuTest extends \MailPoetTest {
|
||||
function testItChecksPremiumKey() {
|
||||
$renderer = Stub::make(new Renderer());
|
||||
$assets_url = '';
|
||||
$menu = new Menu($renderer, $assets_url);
|
||||
$menu = new Menu($renderer, $assets_url, new AccessControl());
|
||||
|
||||
$_REQUEST['page'] = 'mailpoet-newsletters';
|
||||
$checker = Stub::make(
|
||||
|
@ -1,7 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Test\Router\Endpoints;
|
||||
|
||||
use Codeception\Util\Stub;
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\Models\Newsletter;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Models\Subscriber;
|
||||
@ -33,7 +35,7 @@ class ViewInBrowserTest extends \MailPoetTest {
|
||||
'preview' => false
|
||||
);
|
||||
// instantiate class
|
||||
$this->view_in_browser = new ViewInBrowser($this->browser_preview_data);
|
||||
$this->view_in_browser = new ViewInBrowser($this->browser_preview_data, new AccessControl());
|
||||
}
|
||||
|
||||
function testItAbortsWhenBrowserPreviewDataIsMissing() {
|
||||
@ -123,6 +125,7 @@ class ViewInBrowserTest extends \MailPoetTest {
|
||||
}
|
||||
|
||||
function testItDoesNotRequireWpAdministratorToBeOnProcessedListWhenPreviewIsEnabled() {
|
||||
$view_in_browser = $this->view_in_browser;
|
||||
$data = (object)array_merge(
|
||||
$this->browser_preview_data,
|
||||
array(
|
||||
@ -132,19 +135,25 @@ class ViewInBrowserTest extends \MailPoetTest {
|
||||
)
|
||||
);
|
||||
$data->preview = true;
|
||||
|
||||
// when WP user is not logged, false should be returned
|
||||
expect($this->view_in_browser->_validateBrowserPreviewData($data))->false();
|
||||
expect($view_in_browser->_validateBrowserPreviewData($data))->false();
|
||||
|
||||
// when WP user is logged in but does not have 'manage options' permission, false should be returned
|
||||
wp_set_current_user(1);
|
||||
$wp_user = wp_get_current_user();
|
||||
$wp_user->remove_role('administrator');
|
||||
$view_in_browser->access_control = new AccessControl();
|
||||
expect($this->view_in_browser->_validateBrowserPreviewData($data))->false();
|
||||
|
||||
// when WP user is logged and has 'manage options' permission, data should be returned
|
||||
$wp_user->add_role('administrator');
|
||||
expect($this->view_in_browser->_validateBrowserPreviewData($data))->equals($data);
|
||||
$view_in_browser->access_control = new AccessControl();
|
||||
expect($view_in_browser->_validateBrowserPreviewData($data))->equals($data);
|
||||
}
|
||||
|
||||
function testItSetsSubscriberToLoggedInWPUserWhenPreviewIsEnabled() {
|
||||
$view_in_browser = $this->view_in_browser;
|
||||
$data = (object)array_merge(
|
||||
$this->browser_preview_data,
|
||||
array(
|
||||
@ -155,7 +164,8 @@ class ViewInBrowserTest extends \MailPoetTest {
|
||||
);
|
||||
$data->preview = true;
|
||||
wp_set_current_user(1);
|
||||
$result = $this->view_in_browser->_validateBrowserPreviewData($data);
|
||||
$view_in_browser->access_control = new AccessControl();
|
||||
$result = $view_in_browser->_validateBrowserPreviewData($data);
|
||||
expect($result->subscriber->id)->equals(1);
|
||||
}
|
||||
|
||||
|
@ -1,24 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Test\Router;
|
||||
|
||||
use Codeception\Util\Stub;
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\Router\Router;
|
||||
|
||||
require_once('RouterTestMockEndpoint.php');
|
||||
|
||||
class RouterTest extends \MailPoetTest {
|
||||
public $access_control;
|
||||
public $router_data;
|
||||
public $router;
|
||||
|
||||
function __construct() {
|
||||
parent::__construct();
|
||||
function _before() {
|
||||
$this->router_data = array(
|
||||
Router::NAME => '',
|
||||
'endpoint' => 'router_test_mock_endpoint',
|
||||
'action' => 'test',
|
||||
'data' => base64_encode(json_encode(array('data' => 'dummy data')))
|
||||
);
|
||||
$this->router = new Router($this->router_data);
|
||||
$this->access_control = new AccessControl();
|
||||
$this->router = new Router($this->access_control, $this->router_data);
|
||||
}
|
||||
|
||||
function testItCanGetAPIDataFromGetRequest() {
|
||||
@ -26,10 +28,10 @@ class RouterTest extends \MailPoetTest {
|
||||
$url = 'http://example.com/?' . Router::NAME . '&endpoint=view_in_browser&action=view&data='
|
||||
. base64_encode(json_encode($data));
|
||||
parse_str(parse_url($url, PHP_URL_QUERY), $_GET);
|
||||
$router = new Router();
|
||||
$router = new Router($this->access_control);
|
||||
expect($router->api_request)->equals(true);
|
||||
expect($router->endpoint)->equals('viewInBrowser');
|
||||
expect($router->action)->equals('view');
|
||||
expect($router->endpoint_action)->equals('view');
|
||||
expect($router->data)->equals($data);
|
||||
}
|
||||
|
||||
@ -37,8 +39,8 @@ class RouterTest extends \MailPoetTest {
|
||||
$router_data = $this->router_data;
|
||||
unset($router_data[Router::NAME]);
|
||||
$router = Stub::construct(
|
||||
new Router(),
|
||||
array($router_data)
|
||||
'\MailPoet\Router\Router',
|
||||
array($this->access_control, $router_data)
|
||||
);
|
||||
$result = $router->init();
|
||||
expect($result)->null();
|
||||
@ -48,8 +50,8 @@ class RouterTest extends \MailPoetTest {
|
||||
$router_data = $this->router_data;
|
||||
$router_data['endpoint'] = 'invalid_endpoint';
|
||||
$router = Stub::construct(
|
||||
new Router(),
|
||||
array($router_data),
|
||||
'\MailPoet\Router\Router',
|
||||
array($this->access_control, $router_data),
|
||||
array(
|
||||
'terminateRequest' => function($code, $error) {
|
||||
return array(
|
||||
@ -72,8 +74,8 @@ class RouterTest extends \MailPoetTest {
|
||||
$router_data = $this->router_data;
|
||||
$router_data['action'] = 'invalid_action';
|
||||
$router = Stub::construct(
|
||||
new Router(),
|
||||
array($router_data),
|
||||
'\MailPoet\Router\Router',
|
||||
array($this->access_control, $router_data),
|
||||
array(
|
||||
'terminateRequest' => function($code, $error) {
|
||||
return array(
|
||||
@ -92,6 +94,87 @@ class RouterTest extends \MailPoetTest {
|
||||
);
|
||||
}
|
||||
|
||||
function testItValidatesGlobalPermission() {
|
||||
$access_control = new AccessControl();
|
||||
$router = $this->router;
|
||||
|
||||
$permissions = array(
|
||||
'global' => AccessControl::PERMISSION_MANAGE_SETTINGS,
|
||||
);
|
||||
$access_control->user_roles = array();
|
||||
$router->access_control = $access_control;
|
||||
expect($router->validatePermissions(null, $permissions))->false();
|
||||
|
||||
$access_control->user_roles = $access_control->permissions[AccessControl::PERMISSION_MANAGE_SETTINGS];
|
||||
$router->access_control = $access_control;
|
||||
expect($router->validatePermissions(null, $permissions))->true();
|
||||
}
|
||||
|
||||
function testItValidatesEndpointActionPermission() {
|
||||
$access_control = new AccessControl();
|
||||
$router = $this->router;
|
||||
|
||||
$permissions = array(
|
||||
'global' => null,
|
||||
'actions' => array(
|
||||
'test' => AccessControl::PERMISSION_MANAGE_SETTINGS
|
||||
)
|
||||
);
|
||||
|
||||
$access_control->user_roles = array();
|
||||
$router->access_control = $access_control;
|
||||
expect($router->validatePermissions('test', $permissions))->false();
|
||||
|
||||
$access_control->user_roles = $access_control->permissions[AccessControl::PERMISSION_MANAGE_SETTINGS];
|
||||
$router->access_control = $access_control;
|
||||
expect($router->validatePermissions('test', $permissions))->true();
|
||||
}
|
||||
|
||||
function testItValidatesPermissionBeforeProcessingEndpointAction() {
|
||||
$router = Stub::construct(
|
||||
'\MailPoet\Router\Router',
|
||||
array($this->access_control, $this->router_data),
|
||||
array(
|
||||
'validatePermissions' => function($action, $permissions) {
|
||||
expect($action)->equals($this->router_data['action']);
|
||||
expect($permissions)->equals(
|
||||
array(
|
||||
'global' => AccessControl::NO_ACCESS_RESTRICTION
|
||||
)
|
||||
);
|
||||
return true;
|
||||
}
|
||||
)
|
||||
);
|
||||
$result = $router->init();
|
||||
expect($result)->equals(
|
||||
array('data' => 'dummy data')
|
||||
);
|
||||
}
|
||||
|
||||
function testItReturnsForbiddenResponseWhenPermissionFailsValidation() {
|
||||
$router = Stub::construct(
|
||||
'\MailPoet\Router\Router',
|
||||
array($this->access_control, $this->router_data),
|
||||
array(
|
||||
'validatePermissions' => false,
|
||||
'terminateRequest' => function($code, $error) {
|
||||
return array(
|
||||
$code,
|
||||
$error
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
$result = $router->init();
|
||||
expect($result)->equals(
|
||||
array(
|
||||
403,
|
||||
'You do not have the required permissions.'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function testItCallsEndpointAction() {
|
||||
$data = array('data' => 'dummy data');
|
||||
$result = $this->router->init();
|
||||
@ -99,8 +182,7 @@ class RouterTest extends \MailPoetTest {
|
||||
}
|
||||
|
||||
function testItExecutesUrlParameterConflictResolverAction() {
|
||||
$data = array('data' => 'dummy data');
|
||||
$result = $this->router->init();
|
||||
$this->router->init();
|
||||
expect((boolean)did_action('mailpoet_conflict_resolver_router_url_query_parameters'))->true();
|
||||
}
|
||||
|
||||
|
@ -2,12 +2,17 @@
|
||||
|
||||
namespace MailPoet\Router\Endpoints;
|
||||
|
||||
use MailPoet\Config\AccessControl;
|
||||
|
||||
class RouterTestMockEndpoint {
|
||||
const ACTION_TEST = 'test';
|
||||
public $allowed_actions = array(
|
||||
self::ACTION_TEST
|
||||
);
|
||||
public $data;
|
||||
public $permissions = array(
|
||||
'global' => AccessControl::NO_ACCESS_RESTRICTION
|
||||
);
|
||||
|
||||
function __construct($data) {
|
||||
$this->data = $data;
|
||||
|
Reference in New Issue
Block a user