Refactors AccessControl and passes it as dependency to JSON API and Menu

This commit is contained in:
Vlad
2017-08-14 11:28:31 -04:00
parent 51fbf29031
commit 2e5554a3af
12 changed files with 286 additions and 241 deletions

View File

@ -2,7 +2,6 @@
namespace MailPoet\API\JSON; namespace MailPoet\API\JSON;
use MailPoet\Config\AccessControl; use MailPoet\Config\AccessControl;
use MailPoet\Config\Env;
use MailPoet\Util\Helpers; use MailPoet\Util\Helpers;
use MailPoet\Util\Security; use MailPoet\Util\Security;
use MailPoet\WP\Hooks; use MailPoet\WP\Hooks;
@ -20,9 +19,11 @@ class API {
private $_available_api_versions = array( private $_available_api_versions = array(
'v1' 'v1'
); );
private $access_control;
const CURRENT_VERSION = 'v1'; const CURRENT_VERSION = 'v1';
function __construct() { function __construct() {
$this->access_control = new AccessControl();
foreach($this->_available_api_versions as $available_api_version) { foreach($this->_available_api_versions as $available_api_version) {
$this->addEndpointNamespace( $this->addEndpointNamespace(
sprintf('%s\%s', __NAMESPACE__, $available_api_version), sprintf('%s\%s', __NAMESPACE__, $available_api_version),
@ -127,7 +128,7 @@ class API {
throw new \Exception(__('Invalid API endpoint.', 'mailpoet')); throw new \Exception(__('Invalid API endpoint.', 'mailpoet'));
} }
$endpoint = new $this->_request_endpoint_class(); $endpoint = new $this->_request_endpoint_class($this->access_control);
// check the accessibility of the requested endpoint's action // check the accessibility of the requested endpoint's action
// by default, an endpoint's action is considered "private" // by default, an endpoint's action is considered "private"
@ -148,12 +149,12 @@ class API {
function validatePermissions($request_method, $permissions) { function validatePermissions($request_method, $permissions) {
// if method permission is defined, validate it // if method permission is defined, validate it
if (!empty($permissions['methods'][$request_method])) { if (!empty($permissions['methods'][$request_method])) {
return ($permissions['methods'][$request_method] === Access::ALL) ? return ($permissions['methods'][$request_method] === AccessControl::ACCESS_ALL) ?
true : true :
AccessControl::validatePermission($permissions['methods'][$request_method]); $this->access_control->validatePermission($permissions['methods'][$request_method]);
} }
// use global permission // use global permission
return AccessControl::validatePermission($permissions['global']); return $this->access_control->validatePermission($permissions['global']);
} }
function checkToken() { function checkToken() {

View File

@ -1,12 +0,0 @@
<?php
namespace MailPoet\API\JSON;
if(!defined('ABSPATH')) exit;
final class Access {
const ALL = 'all';
private function __construct() {
}
}

View File

@ -12,8 +12,9 @@ class MP2Migrator extends APIEndpoint {
'global' => AccessControl::PERMISSION_MANAGE_SETTINGS 'global' => AccessControl::PERMISSION_MANAGE_SETTINGS
); );
public function __construct() { public function __construct(AccessControl $access_control) {
$this->MP2Migrator = new \MailPoet\Config\MP2Migrator(); $this->access_control = $access_control;
$this->MP2Migrator = new \MailPoet\Config\MP2Migrator($this->access_control);
} }
/** /**

View File

@ -13,10 +13,15 @@ class Setup extends APIEndpoint {
public $permissions = array( public $permissions = array(
'global' => AccessControl::PERMISSION_MANAGE_SETTINGS 'global' => AccessControl::PERMISSION_MANAGE_SETTINGS
); );
private $access_control;
function __construct(AccessControl $access_control) {
$this->access_control = $access_control;
}
function reset() { function reset() {
try { try {
$activator = new Activator(); $activator = new Activator($this->access_control);
$activator->deactivate(); $activator->deactivate();
$activator->activate(); $activator->activate();
Hooks::doAction('mailpoet_setup_reset'); Hooks::doAction('mailpoet_setup_reset');

View File

@ -2,7 +2,6 @@
namespace MailPoet\API\JSON\v1; namespace MailPoet\API\JSON\v1;
use MailPoet\API\JSON\Access as APIAccess;
use MailPoet\API\JSON\Endpoint as APIEndpoint; use MailPoet\API\JSON\Endpoint as APIEndpoint;
use MailPoet\API\JSON\Error as APIError; use MailPoet\API\JSON\Error as APIError;
use MailPoet\Config\AccessControl; use MailPoet\Config\AccessControl;
@ -17,7 +16,7 @@ if(!defined('ABSPATH')) exit;
class Subscribers extends APIEndpoint { class Subscribers extends APIEndpoint {
public $permissions = array( public $permissions = array(
'global' => AccessControl::PERMISSION_MANAGE_SUBSCRIBERS, 'global' => AccessControl::PERMISSION_MANAGE_SUBSCRIBERS,
'methods' => array('subscribe' => APIAccess::ALL) 'methods' => array('subscribe' => AccessControl::ACCESS_ALL)
); );
function get($data = array()) { function get($data = array()) {

View File

@ -8,23 +8,26 @@ if(!defined('ABSPATH')) exit;
require_once(ABSPATH . 'wp-includes/pluggable.php'); require_once(ABSPATH . 'wp-includes/pluggable.php');
class AccessControl { class AccessControl {
static $permissions;
const PERMISSION_ACCESS_PLUGIN = 'access_plugin'; const PERMISSION_ACCESS_PLUGIN = 'access_plugin';
const PERMISSION_MANAGE_SETTINGS = 'manage_settings'; const PERMISSION_MANAGE_SETTINGS = 'manage_settings';
const PERMISSION_MANAGE_EMAILS = 'manage_emails'; const PERMISSION_MANAGE_EMAILS = 'manage_emails';
const PERMISSION_MANAGE_SUBSCRIBERS = 'manage_subscribers'; const PERMISSION_MANAGE_SUBSCRIBERS = 'manage_subscribers';
const PERMISSION_MANAGE_FORMS = 'manage_forms'; const PERMISSION_MANAGE_FORMS = 'manage_forms';
const PERMISSION_MANAGE_SEGMENTS = 'manage_segments'; const PERMISSION_MANAGE_SEGMENTS = 'manage_segments';
const PERMISSION_UPDATE_PLUGIN = 'update_plugin';
const ACCESS_ALL = 'All';
static function init($permissions = array()) { public $permissions;
self::setPermissions($permissions); public $current_user_roles;
public $user_capabilities;
function __construct() {
$this->permissions = $this->getDefaultPermissions();
$this->user_roles = $this->getUserRoles();
$this->user_capabilities = $this->getUserCapabilities();
} }
static function setPermissions($permissions = array()) { private function getDefaultPermissions() {
self::$permissions = ($permissions) ? $permissions : self::getPermissions();
}
static function getPermissions() {
return array( return array(
self::PERMISSION_ACCESS_PLUGIN => WPHooks::applyFilters( self::PERMISSION_ACCESS_PLUGIN => WPHooks::applyFilters(
'mailpoet_permission_access_plugin', 'mailpoet_permission_access_plugin',
@ -63,18 +66,31 @@ class AccessControl {
array( array(
'administrator' 'administrator'
) )
),
self::PERMISSION_UPDATE_PLUGIN => WPHooks::applyFilters(
'mailpoet_permission_update_plugin',
array(
'administrator'
) )
),
); );
} }
static function validatePermission($permission) { function getUserRoles() {
if(empty(self::$permissions)) self::init(); $user = wp_get_current_user();
if(empty(self::$permissions[$permission])) return false; return $user->roles;
$current_user = wp_get_current_user(); }
$current_user_roles = $current_user->roles;
function getUserCapabilities() {
$user = wp_get_current_user();
return array_keys($user->allcaps);
}
function validatePermission($permission) {
if(empty($this->permissions[$permission])) return false;
$permitted_roles = array_intersect( $permitted_roles = array_intersect(
$current_user_roles, $this->user_roles,
self::$permissions[$permission] $this->permissions[$permission]
); );
return (!empty($permitted_roles)); return (!empty($permitted_roles));
} }

View File

@ -5,13 +5,16 @@ namespace MailPoet\Config;
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;
class Activator { class Activator {
const REQUIRED_PERMISSION = AccessControl::PERMISSION_MANAGE_SETTINGS; private $access_control;
static function activate() { function __construct(AccessControl $access_control) {
self::validatePermission(); $this->access_control = $access_control;
if(!current_user_can(self::PERMISSION_ACTIVATE)) { if(!$this->access_control->validatePermission(AccessControl::PERMISSION_UPDATE_PLUGIN)) {
throw new \Exception('MaiLpoet ID must be greater than zero'); throw new \Exception(__('You do not have permission to activate/deactivate MailPoet plugin.', 'mailpoet'));
} }
}
function activate() {
$migrator = new Migrator(); $migrator = new Migrator();
$migrator->up(); $migrator->up();
@ -21,19 +24,8 @@ class Activator {
update_option('mailpoet_db_version', Env::$version); update_option('mailpoet_db_version', Env::$version);
} }
static function deactivate() { function deactivate() {
self::validatePermission();
$migrator = new Migrator(); $migrator = new Migrator();
$migrator->down(); $migrator->down();
} }
static function validatePermission() {
if(AccessControl::validatePermission(self::REQUIRED_PERMISSION)) return;
throw new \Exception(
sprintf(
__('MailPoet can only be activated/deactivated by a user with <strong>%s</strong> capability.', 'mailpoet'),
self::REQUIRED_PERMISSION
)
);
}
} }

View File

@ -4,7 +4,10 @@ use MailPoet\Models\Setting;
use MailPoet\Util\Url; use MailPoet\Util\Url;
class Changelog { class Changelog {
function __construct() { private $access_control;
function __construct(AccessControl $access_control) {
$this->access_control = $access_control;
} }
function init() { function init() {
@ -34,7 +37,7 @@ class Changelog {
$version = Setting::getValue('version', null); $version = Setting::getValue('version', null);
$redirect_url = null; $redirect_url = null;
$mp2_migrator = new MP2Migrator(); $mp2_migrator = new MP2Migrator($this->access_control);
if(!in_array($_GET['page'], array('mailpoet-migration', 'mailpoet-settings')) && $mp2_migrator->isMigrationStartedAndNotCompleted()) { if(!in_array($_GET['page'], array('mailpoet-migration', 'mailpoet-settings')) && $mp2_migrator->isMigrationStartedAndNotCompleted()) {
// Force the redirection if the migration has started but is not completed // Force the redirection if the migration has started but is not completed
$redirect_url = admin_url('admin.php?page=mailpoet-migration'); $redirect_url = admin_url('admin.php?page=mailpoet-migration');

View File

@ -13,18 +13,18 @@ if(!defined('ABSPATH')) exit;
require_once(ABSPATH . 'wp-admin/includes/plugin.php'); require_once(ABSPATH . 'wp-admin/includes/plugin.php');
class Initializer { 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 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'; const SOLVE_DB_ISSUE_URL = 'http://beta.docs.mailpoet.com/article/200-solving-database-connection-issues';
protected $plugin_initialized = false; protected $plugin_initialized = false;
private $access_control;
function __construct($params = array( function __construct($params = array(
'file' => '', 'file' => '',
'version' => '1.0.0' 'version' => '1.0.0'
)) { )) {
Env::init($params['file'], $params['version']); Env::init($params['file'], $params['version']);
AccessControl::init(); $this->access_control = new AccessControl();
} }
function init() { function init() {
@ -136,7 +136,8 @@ class Initializer {
// if current db version and plugin version differ // if current db version and plugin version differ
if(version_compare($current_db_version, Env::$version) !== 0) { if(version_compare($current_db_version, Env::$version) !== 0) {
Activator::activate(); $activator = new Activator($this->access_control);
$activator->activate();
} }
} }
@ -186,12 +187,12 @@ class Initializer {
} }
function setupMenu() { function setupMenu() {
$menu = new Menu($this->renderer, Env::$assets_url); $menu = new Menu($this->renderer, Env::$assets_url, $this->access_control);
$menu->init(); $menu->init();
} }
function setupChangelog() { function setupChangelog() {
$changelog = new Changelog(); $changelog = new Changelog($this->access_control);
$changelog->init(); $changelog->init();
} }
@ -247,7 +248,7 @@ class Initializer {
function handleFailedInitialization($exception) { function handleFailedInitialization($exception) {
// Check if we are able to add pages at this point // Check if we are able to add pages at this point
if(function_exists('wp_get_current_user')) { if(function_exists('wp_get_current_user')) {
Menu::addErrorPage(); Menu::addErrorPage($this->access_control);
} }
return WPNotice::displayError($exception); return WPNotice::displayError($exception);
} }

View File

@ -19,17 +19,19 @@ class MP2Migrator {
const CHUNK_SIZE = 10; // To import the data by batch const CHUNK_SIZE = 10; // To import the data by batch
private $log_file; private $log_file;
private $access_control;
public $log_file_url; public $log_file_url;
public $progressbar; public $progressbar;
private $segments_mapping = array(); // Mapping between old and new segment IDs private $segments_mapping = array(); // Mapping between old and new segment IDs
private $wp_users_segment; private $wp_users_segment;
public function __construct() { public function __construct(AccessControl $access_control) {
$this->defineMP2Tables(); $this->defineMP2Tables();
$log_filename = 'mp2migration.log'; $log_filename = 'mp2migration.log';
$this->log_file = Env::$temp_path . '/' . $log_filename; $this->log_file = Env::$temp_path . '/' . $log_filename;
$this->log_file_url = Env::$temp_url . '/' . $log_filename; $this->log_file_url = Env::$temp_url . '/' . $log_filename;
$this->progressbar = new ProgressBar('mp2migration'); $this->progressbar = new ProgressBar('mp2migration');
$this->access_control = $access_control;
} }
private function defineMP2Tables() { private function defineMP2Tables() {
@ -187,8 +189,9 @@ class MP2Migrator {
* *
*/ */
private function eraseMP3Data() { private function eraseMP3Data() {
Activator::deactivate(); $activator = new Activator($this->access_control);
Activator::activate(); $activator->deactivate();
$activator->activate();
$this->deleteSegments(); $this->deleteSegments();
$this->resetMigrationCounters(); $this->resetMigrationCounters();

View File

@ -26,9 +26,18 @@ use MailPoet\WP\Readme;
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;
class Menu { 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->renderer = $renderer;
$this->assets_url = $assets_url; $this->assets_url = $assets_url;
$this->access_control = $access_control;
$this->user_capability = $this->access_control->user_capabilities[0];
$subscribers_feature = new SubscribersFeature(); $subscribers_feature = new SubscribersFeature();
$this->subscribers_over_limit = $subscribers_feature->check(); $this->subscribers_over_limit = $subscribers_feature->check();
$this->checkMailPoetAPIKey(); $this->checkMailPoetAPIKey();
@ -46,30 +55,31 @@ class Menu {
} }
function setup() { function setup() {
if(!AccessControl::validatePermission('access_plugin')) return; if(!$this->access_control->validatePermission(AccessControl::PERMISSION_ACCESS_PLUGIN)) return;
if(self::isOnMailPoetAdminPage()) { if(self::isOnMailPoetAdminPage()) {
do_action('mailpoet_conflict_resolver_styles'); do_action('mailpoet_conflict_resolver_styles');
do_action('mailpoet_conflict_resolver_scripts'); do_action('mailpoet_conflict_resolver_scripts');
} }
$main_page_slug = 'mailpoet-newsletters'; // Main page
add_menu_page( add_menu_page(
'MailPoet', 'MailPoet',
'MailPoet', 'MailPoet',
AccessControl::validatePermission(AccessControl::PERMISSION_ACCESS_PLUGIN), $this->user_capability,
$main_page_slug, self::MAIN_PAGE_SLUG,
null, null,
$this->assets_url . '/img/menu_icon.png', $this->assets_url . '/img/menu_icon.png',
30 30
); );
// Emails page
if ($this->access_control->validatePermission(AccessControl::PERMISSION_MANAGE_EMAILS)) {
$newsletters_page = add_submenu_page( $newsletters_page = add_submenu_page(
$main_page_slug, self::MAIN_PAGE_SLUG,
$this->setPageTitle(__('Emails', 'mailpoet')), $this->setPageTitle(__('Emails', 'mailpoet')),
__('Emails', 'mailpoet'), __('Emails', 'mailpoet'),
AccessControl::validatePermission(AccessControl::PERMISSION_MANAGE_EMAILS), $this->user_capability,
$main_page_slug, self::MAIN_PAGE_SLUG,
array( array(
$this, $this,
'newsletters' 'newsletters'
@ -88,17 +98,34 @@ class Menu {
)); ));
}); });
// newsletter editor
add_submenu_page(
true,
$this->setPageTitle(__('Newsletter', 'mailpoet')),
__('Newsletter Editor', 'mailpoet'),
$this->user_capability,
'mailpoet-newsletter-editor',
array(
$this,
'newletterEditor'
)
);
}
// Forms page
if($this->access_control->validatePermission(AccessControl::PERMISSION_MANAGE_FORMS)) {
$forms_page = add_submenu_page( $forms_page = add_submenu_page(
$main_page_slug, self::MAIN_PAGE_SLUG,
$this->setPageTitle(__('Forms', 'mailpoet')), $this->setPageTitle(__('Forms', 'mailpoet')),
__('Forms', 'mailpoet'), __('Forms', 'mailpoet'),
AccessControl::validatePermission(AccessControl::PERMISSION_MANAGE_FORMS), $this->user_capability,
'mailpoet-forms', 'mailpoet-forms',
array( array(
$this, $this,
'forms' 'forms'
) )
); );
// add limit per page to screen options // add limit per page to screen options
add_action('load-' . $forms_page, function() { add_action('load-' . $forms_page, function() {
add_screen_option('per_page', array( add_screen_option('per_page', array(
@ -111,17 +138,34 @@ class Menu {
)); ));
}); });
// 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( $subscribers_page = add_submenu_page(
$main_page_slug, self::MAIN_PAGE_SLUG,
$this->setPageTitle(__('Subscribers', 'mailpoet')), $this->setPageTitle(__('Subscribers', 'mailpoet')),
__('Subscribers', 'mailpoet'), __('Subscribers', 'mailpoet'),
AccessControl::validatePermission(AccessControl::PERMISSION_MANAGE_SUBSCRIBERS), $this->user_capability,
'mailpoet-subscribers', 'mailpoet-subscribers',
array( array(
$this, $this,
'subscribers' 'subscribers'
) )
); );
// add limit per page to screen options // add limit per page to screen options
add_action('load-' . $subscribers_page, function() { add_action('load-' . $subscribers_page, function() {
add_screen_option('per_page', array( add_screen_option('per_page', array(
@ -134,11 +178,40 @@ class Menu {
)); ));
}); });
// 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( $segments_page = add_submenu_page(
$main_page_slug, self::MAIN_PAGE_SLUG,
$this->setPageTitle(__('Lists', 'mailpoet')), $this->setPageTitle(__('Lists', 'mailpoet')),
__('Lists', 'mailpoet'), __('Lists', 'mailpoet'),
AccessControl::validatePermission(AccessControl::PERMISSION_MANAGE_SEGMENTS), $this->user_capability,
'mailpoet-segments', 'mailpoet-segments',
array( array(
$this, $this,
@ -157,24 +230,29 @@ class Menu {
'option' => 'mailpoet_segments_per_page' 'option' => 'mailpoet_segments_per_page'
)); ));
}); });
}
// Settings page
if($this->access_control->validatePermission(AccessControl::PERMISSION_MANAGE_SETTINGS)) {
add_submenu_page( add_submenu_page(
$main_page_slug, self::MAIN_PAGE_SLUG,
$this->setPageTitle(__('Settings', 'mailpoet')), $this->setPageTitle(__('Settings', 'mailpoet')),
__('Settings', 'mailpoet'), __('Settings', 'mailpoet'),
AccessControl::validatePermission(AccessControl::PERMISSION_MANAGE_SETTINGS), $this->user_capability,
'mailpoet-settings', 'mailpoet-settings',
array( array(
$this, $this,
'settings' 'settings'
) )
); );
}
// Help page
add_submenu_page( add_submenu_page(
$main_page_slug, self::MAIN_PAGE_SLUG,
$this->setPageTitle(__('Help', 'mailpoet')), $this->setPageTitle(__('Help', 'mailpoet')),
__('Help', 'mailpoet'), __('Help', 'mailpoet'),
AccessControl::validatePermission(AccessControl::PERMISSION_ACCESS_PLUGIN), $this->user_capability,
'mailpoet-help', 'mailpoet-help',
array( array(
$this, $this,
@ -182,12 +260,13 @@ class Menu {
) )
); );
// Premium page
// Only show this page in menu if the Premium plugin is not activated // Only show this page in menu if the Premium plugin is not activated
add_submenu_page( add_submenu_page(
License::getLicense() ? true : $main_page_slug, License::getLicense() ? true : self::MAIN_PAGE_SLUG,
$this->setPageTitle(__('Premium', 'mailpoet')), $this->setPageTitle(__('Premium', 'mailpoet')),
__('Premium', 'mailpoet'), __('Premium', 'mailpoet'),
AccessControl::validatePermission(AccessControl::PERMISSION_ACCESS_PLUGIN), $this->user_capability,
'mailpoet-premium', 'mailpoet-premium',
array( array(
$this, $this,
@ -195,35 +274,12 @@ class Menu {
) )
); );
add_submenu_page( // Welcome page
'admin.php?page=mailpoet-subscribers',
$this->setPageTitle(__('Import', 'mailpoet')),
__('Import', 'mailpoet'),
AccessControl::validatePermission(AccessControl::PERMISSION_MANAGE_SUBSCRIBERS),
'mailpoet-import',
array(
$this,
'import'
)
);
add_submenu_page(
true,
$this->setPageTitle(__('Export', 'mailpoet')),
__('Export', 'mailpoet'),
AccessControl::validatePermission(AccessControl::PERMISSION_MANAGE_SUBSCRIBERS),
'mailpoet-export',
array(
$this,
'export'
)
);
add_submenu_page( add_submenu_page(
true, true,
$this->setPageTitle(__('Welcome', 'mailpoet')), $this->setPageTitle(__('Welcome', 'mailpoet')),
__('Welcome', 'mailpoet'), __('Welcome', 'mailpoet'),
AccessControl::validatePermission(AccessControl::PERMISSION_ACCESS_PLUGIN), $this->user_capability,
'mailpoet-welcome', 'mailpoet-welcome',
array( array(
$this, $this,
@ -231,11 +287,12 @@ class Menu {
) )
); );
// Update page
add_submenu_page( add_submenu_page(
true, true,
$this->setPageTitle(__('Update', 'mailpoet')), $this->setPageTitle(__('Update', 'mailpoet')),
__('Update', 'mailpoet'), __('Update', 'mailpoet'),
AccessControl::validatePermission(AccessControl::PERMISSION_ACCESS_PLUGIN), $this->user_capability,
'mailpoet-update', 'mailpoet-update',
array( array(
$this, $this,
@ -243,41 +300,18 @@ class Menu {
) )
); );
// Migration page
add_submenu_page( add_submenu_page(
true, true,
$this->setPageTitle(__('Migration', 'mailpoet')), $this->setPageTitle(__('Migration', 'mailpoet')),
'', '',
AccessControl::validatePermission(AccessControl::PERMISSION_MANAGE_SETTINGS), $this->user_capability,
'mailpoet-migration', 'mailpoet-migration',
array( array(
$this, $this,
'migration' 'migration'
) )
); );
add_submenu_page(
true,
$this->setPageTitle(__('Form Editor', 'mailpoet')),
__('Form Editor', 'mailpoet'),
AccessControl::validatePermission(AccessControl::PERMISSION_MANAGE_FORMS),
'mailpoet-form-editor',
array(
$this,
'formEditor'
)
);
add_submenu_page(
true,
$this->setPageTitle(__('Newsletter', 'mailpoet')),
__('Newsletter Editor', 'mailpoet'),
AccessControl::validatePermission(AccessControl::PERMISSION_MANAGE_EMAILS),
'mailpoet-newsletter-editor',
array(
$this,
'newletterEditor'
)
);
} }
function welcome() { function welcome() {
@ -295,20 +329,20 @@ class Menu {
or or
strpos($redirect_url, 'mailpoet') === false 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( $data = array(
'settings' => Setting::getAll(), 'settings' => Setting::getAll(),
'current_user' => wp_get_current_user(), 'current_user' => wp_get_current_user(),
'redirect_url' => $redirect_url, 'redirect_url' => $redirect_url,
'sub_menu' => 'mailpoet-newsletters' 'sub_menu' => self::MAIN_PAGE_SLUG
); );
$this->displayPage('welcome.html', $data); $this->displayPage('welcome.html', $data);
} }
function migration() { function migration() {
$mp2_migrator = new MP2Migrator(); $mp2_migrator = new MP2Migrator($this->access_control);
$mp2_migrator->init(); $mp2_migrator->init();
$data = array( $data = array(
'log_file_url' => $mp2_migrator->log_file_url, 'log_file_url' => $mp2_migrator->log_file_url,
@ -330,14 +364,14 @@ class Menu {
or or
strpos($redirect_url, 'mailpoet') === false 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( $data = array(
'settings' => Setting::getAll(), 'settings' => Setting::getAll(),
'current_user' => wp_get_current_user(), 'current_user' => wp_get_current_user(),
'redirect_url' => $redirect_url, 'redirect_url' => $redirect_url,
'sub_menu' => 'mailpoet-newsletters' 'sub_menu' => self::MAIN_PAGE_SLUG
); );
$readme_file = Env::$path . '/readme.txt'; $readme_file = Env::$path . '/readme.txt';
@ -354,7 +388,7 @@ class Menu {
function premium() { function premium() {
$data = array( $data = array(
'subscriber_count' => Subscriber::getTotalSubscribers(), 'subscriber_count' => Subscriber::getTotalSubscribers(),
'sub_menu' => 'mailpoet-newsletters' 'sub_menu' => self::MAIN_PAGE_SLUG
); );
$this->displayPage('premium.html', $data); $this->displayPage('premium.html', $data);
@ -507,7 +541,7 @@ class Menu {
'shortcodes' => ShortcodesHelper::getShortcodes(), 'shortcodes' => ShortcodesHelper::getShortcodes(),
'settings' => Setting::getAll(), 'settings' => Setting::getAll(),
'current_wp_user' => Subscriber::getCurrentWPUser(), 'current_wp_user' => Subscriber::getCurrentWPUser(),
'sub_menu' => 'mailpoet-newsletters' 'sub_menu' => self::MAIN_PAGE_SLUG
); );
wp_enqueue_media(); wp_enqueue_media();
wp_enqueue_script('tinymce-wplink', includes_url('js/tinymce/plugins/wplink/plugin.js')); wp_enqueue_script('tinymce-wplink', includes_url('js/tinymce/plugins/wplink/plugin.js'));
@ -599,13 +633,13 @@ class Menu {
* This error page is used when the initialization is failed * This error page is used when the initialization is failed
* to display admin notices only * to display admin notices only
*/ */
static function addErrorPage() { static function addErrorPage(AccessControl $access_control) {
if(!self::isOnMailPoetAdminPage()) { if(!self::isOnMailPoetAdminPage()) {
return false; return false;
} }
// Check if page already exists // Check if page already exists
if(get_plugin_page_hook($_REQUEST['page'], '') 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; return false;
} }
@ -613,7 +647,7 @@ class Menu {
true, true,
'MailPoet', 'MailPoet',
'MailPoet', 'MailPoet',
Env::$use_plugin_permission, $access_control->user_capabilities[0],
$_REQUEST['page'], $_REQUEST['page'],
array( array(
__CLASS__, __CLASS__,
@ -629,7 +663,7 @@ class Menu {
function checkMailPoetAPIKey(ServicesChecker $checker = null) { function checkMailPoetAPIKey(ServicesChecker $checker = null) {
if(self::isOnMailPoetAdminPage()) { if(self::isOnMailPoetAdminPage()) {
$show_notices = isset($_REQUEST['page']) $show_notices = isset($_REQUEST['page'])
&& stripos($_REQUEST['page'], 'mailpoet-newsletters') === false; && stripos($_REQUEST['page'], self::MAIN_PAGE_SLUG) === false;
$checker = $checker ?: new ServicesChecker(); $checker = $checker ?: new ServicesChecker();
$this->mp_api_key_valid = $checker->isMailPoetAPIKeyValid($show_notices); $this->mp_api_key_valid = $checker->isMailPoetAPIKeyValid($show_notices);
} }
@ -638,7 +672,7 @@ class Menu {
function checkPremiumKey(ServicesChecker $checker = null) { function checkPremiumKey(ServicesChecker $checker = null) {
if(self::isOnMailPoetAdminPage()) { if(self::isOnMailPoetAdminPage()) {
$show_notices = isset($_REQUEST['page']) $show_notices = isset($_REQUEST['page'])
&& stripos($_REQUEST['page'], 'mailpoet-newsletters') === false; && stripos($_REQUEST['page'], self::MAIN_PAGE_SLUG) === false;
$checker = $checker ?: new ServicesChecker(); $checker = $checker ?: new ServicesChecker();
$this->premium_key_valid = $checker->isPremiumKeyValid($show_notices); $this->premium_key_valid = $checker->isPremiumKeyValid($show_notices);
} }

View File

@ -1,6 +1,7 @@
<?php <?php
namespace MailPoet\Router\Endpoints; namespace MailPoet\Router\Endpoints;
use MailPoet\Config\AccessControl;
use MailPoet\Config\Env; use MailPoet\Config\Env;
use MailPoet\Models\Newsletter; use MailPoet\Models\Newsletter;
use MailPoet\Models\SendingQueue; use MailPoet\Models\SendingQueue;
@ -20,6 +21,7 @@ class ViewInBrowser {
function __construct($data) { function __construct($data) {
$this->data = $this->_processBrowserPreviewData($data); $this->data = $this->_processBrowserPreviewData($data);
$this->access_control = new AccessControl();
} }
function view() { function view() {
@ -69,8 +71,8 @@ class ViewInBrowser {
$data->queue = false; $data->queue = false;
} }
// allow users with 'manage_options' permission to preview any newsletter // allow users with permission to manage emails to preview any newsletter
if(!empty($data->preview) && current_user_can(Env::$required_permission) if(!empty($data->preview) && $this->access_control->validatePermission(AccessControl::PERMISSION_MANAGE_EMAILS)
) return $data; ) return $data;
// allow others to preview newsletters only when newsletter hash is defined // allow others to preview newsletters only when newsletter hash is defined