Adds access management to router and updates endpoints accordingly

This commit is contained in:
Vlad
2017-08-17 18:25:26 -04:00
parent 5553817f9a
commit 1b756ef0b2
5 changed files with 46 additions and 9 deletions

View File

@@ -1,6 +1,8 @@
<?php <?php
namespace MailPoet\Router\Endpoints; namespace MailPoet\Router\Endpoints;
use MailPoet\Config\AccessControl;
use MailPoet\Cron\CronHelper; use MailPoet\Cron\CronHelper;
use MailPoet\Cron\Daemon; use MailPoet\Cron\Daemon;
@@ -17,6 +19,9 @@ class CronDaemon {
self::ACTION_PING_RESPONSE self::ACTION_PING_RESPONSE
); );
public $data; public $data;
public $permissions = array(
'global' => AccessControl::NO_ACCESS_RESTRICTION
);
function __construct($data) { function __construct($data) {
$this->data = $data; $this->data = $data;

View File

@@ -1,6 +1,8 @@
<?php <?php
namespace MailPoet\Router\Endpoints; namespace MailPoet\Router\Endpoints;
use MailPoet\Config\AccessControl;
use MailPoet\Subscription as UserSubscription; use MailPoet\Subscription as UserSubscription;
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;
@@ -16,6 +18,9 @@ class Subscription {
self::ACTION_UNSUBSCRIBE self::ACTION_UNSUBSCRIBE
); );
public $data; public $data;
public $permissions = array(
'global' => AccessControl::NO_ACCESS_RESTRICTION
);
function __construct($data) { function __construct($data) {
$this->data = $data; $this->data = $data;

View File

@@ -1,6 +1,8 @@
<?php <?php
namespace MailPoet\Router\Endpoints; namespace MailPoet\Router\Endpoints;
use MailPoet\Config\AccessControl;
use MailPoet\Models\Newsletter; use MailPoet\Models\Newsletter;
use MailPoet\Models\NewsletterLink; use MailPoet\Models\NewsletterLink;
use MailPoet\Models\SendingQueue; use MailPoet\Models\SendingQueue;
@@ -20,6 +22,9 @@ class Track {
self::ACTION_OPEN self::ACTION_OPEN
); );
public $data; public $data;
public $permissions = array(
'global' => AccessControl::NO_ACCESS_RESTRICTION
);
function __construct($data) { function __construct($data) {
$this->data = $this->_processTrackData($data); $this->data = $this->_processTrackData($data);
@@ -38,8 +43,8 @@ class Track {
function _processTrackData($data) { function _processTrackData($data) {
$data = (object)Links::transformUrlDataObject($data); $data = (object)Links::transformUrlDataObject($data);
if(empty($data->queue_id) || if(empty($data->queue_id) ||
empty($data->subscriber_id) || empty($data->subscriber_id) ||
empty($data->subscriber_token) empty($data->subscriber_token)
) { ) {
return false; return false;
} }

View File

@@ -1,8 +1,8 @@
<?php <?php
namespace MailPoet\Router\Endpoints; namespace MailPoet\Router\Endpoints;
use MailPoet\Config\AccessControl; use MailPoet\Config\AccessControl;
use MailPoet\Config\Env;
use MailPoet\Models\Newsletter; use MailPoet\Models\Newsletter;
use MailPoet\Models\SendingQueue; use MailPoet\Models\SendingQueue;
use MailPoet\Models\Subscriber; use MailPoet\Models\Subscriber;
@@ -18,10 +18,13 @@ class ViewInBrowser {
const ACTION_VIEW = 'view'; const ACTION_VIEW = 'view';
public $allowed_actions = array(self::ACTION_VIEW); public $allowed_actions = array(self::ACTION_VIEW);
public $data; 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); $this->data = $this->_processBrowserPreviewData($data);
$this->access_control = new AccessControl();
} }
function view() { function view() {

View File

@@ -1,6 +1,8 @@
<?php <?php
namespace MailPoet\Router; namespace MailPoet\Router;
use MailPoet\Config\AccessControl;
use MailPoet\Util\Helpers; use MailPoet\Util\Helpers;
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;
@@ -19,12 +21,13 @@ class Router {
$this->endpoint = isset($api_data['endpoint']) ? $this->endpoint = isset($api_data['endpoint']) ?
Helpers::underscoreToCamelCase($api_data['endpoint']) : Helpers::underscoreToCamelCase($api_data['endpoint']) :
false; false;
$this->action = isset($api_data['action']) ? $this->endpoint_action = isset($api_data['action']) ?
Helpers::underscoreToCamelCase($api_data['action']) : Helpers::underscoreToCamelCase($api_data['action']) :
false; false;
$this->data = isset($api_data['data']) ? $this->data = isset($api_data['data']) ?
self::decodeRequestData($api_data['data']) : self::decodeRequestData($api_data['data']) :
false; false;
$this->access_control = new AccessControl();
} }
function init() { function init() {
@@ -33,15 +36,18 @@ class Router {
if(!$this->endpoint || !class_exists($endpoint_class)) { if(!$this->endpoint || !class_exists($endpoint_class)) {
return $this->terminateRequest(self::RESPONSE_ERROR, __('Invalid router endpoint', 'mailpoet')); return $this->terminateRequest(self::RESPONSE_ERROR, __('Invalid router endpoint', 'mailpoet'));
} }
$endpoint = new $endpoint_class($this->data); $endpoint = new $endpoint_class($this->data, $this->access_control);
if(!method_exists($endpoint, $this->action) || !in_array($this->action, $endpoint->allowed_actions)) { 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')); return $this->terminateRequest(self::RESPONSE_ERROR, __('Invalid router endpoint action', 'mailpoet'));
} }
if(!$this->validatePermissions($this->endpoint_action, $endpoint->permissions)) {
return $this->terminateRequest(self::RESPONSE_ERROR, __('You do not have the required permissions.', 'mailpoet'));
}
do_action('mailpoet_conflict_resolver_router_url_query_parameters'); do_action('mailpoet_conflict_resolver_router_url_query_parameters');
return call_user_func( return call_user_func(
array( array(
$endpoint, $endpoint,
$this->action $this->endpoint_action
) )
); );
} }
@@ -74,4 +80,17 @@ class Router {
status_header($code, $message); status_header($code, $message);
exit; exit;
} }
function validatePermissions($endpoint_action, $permissions) {
// if method permission is defined, validate it
if(!empty($permissions['methods'][$endpoint_action])) {
return ($permissions['methods'][$endpoint_action] === AccessControl::NO_ACCESS_RESTRICTION) ?
true :
$this->access_control->validatePermission($permissions['methods'][$endpoint_action]);
}
// use global permission
return ($permissions['global'] === AccessControl::NO_ACCESS_RESTRICTION) ?
true :
$this->access_control->validatePermission($permissions['global']);
}
} }