Advanced Access Manager - Version 5.9.1

Version Description

  • Fixed the bug with controlling which capability can be deleted with Access Policy
  • Fixed typo in the aam_edit_others_policies capability slug
  • Fixed the bug with API Routes not being saved property for those that have htmlspecial characters in it
  • Fixed major bug with keeping track of active user sessions that prevents multiple session per same user
  • Added "Redirect To Login" to the LIMIT option for visitors on Posts & Terms tab
  • Added the new concept of "Boundary" to Access Policy that allows to Enforce certain statements
Download this release

Release Info

Developer vasyltech
Plugin Icon 128x128 Advanced Access Manager
Version 5.9.1
Comparing to
See all releases

Code changes from version 5.9 to 5.9.1

Application/Backend/Feature/Main/Capability.php CHANGED
@@ -56,7 +56,7 @@ class AAM_Backend_Feature_Main_Capability extends AAM_Backend_Feature_Abstract {
56
  'aam_edit_roles', 'aam_delete_roles', 'aam_toggle_users', 'aam_switch_users',
57
  'aam_manage_configpress', 'aam_manage_api_routes', 'aam_manage_uri', 'aam_manage_policy',
58
  'aam_view_help_btn', 'aam_edit_policy', 'aam_read_policy', 'aam_delete_policy',
59
- 'aam_delete_policies', 'aam_edit_policies', 'aam_edit_other_policies', 'aam_publish_policies'
60
  )
61
  );
62
 
@@ -157,7 +157,7 @@ class AAM_Backend_Feature_Main_Capability extends AAM_Backend_Feature_Abstract {
157
  $capability = AAM_Core_Request::post('capability');
158
  $roles = AAM_Core_API::getRoles();
159
 
160
- if ($this->isAllowedToEdit($capability) === false) {
161
  $response = array(
162
  'status' => 'failure',
163
  'message' => __('Permission denied to delete this capability', AAM_KEY)
56
  'aam_edit_roles', 'aam_delete_roles', 'aam_toggle_users', 'aam_switch_users',
57
  'aam_manage_configpress', 'aam_manage_api_routes', 'aam_manage_uri', 'aam_manage_policy',
58
  'aam_view_help_btn', 'aam_edit_policy', 'aam_read_policy', 'aam_delete_policy',
59
+ 'aam_delete_policies', 'aam_edit_policies', 'aam_edit_others_policies', 'aam_publish_policies'
60
  )
61
  );
62
 
157
  $capability = AAM_Core_Request::post('capability');
158
  $roles = AAM_Core_API::getRoles();
159
 
160
+ if ($this->isAllowedToDelete($capability) === false) {
161
  $response = array(
162
  'status' => 'failure',
163
  'message' => __('Permission denied to delete this capability', AAM_KEY)
Application/Backend/Feature/Main/Post.php CHANGED
@@ -506,6 +506,8 @@ class AAM_Backend_Feature_Main_Post extends AAM_Backend_Feature_Abstract {
506
  $preview = __('Valid URL', AAM_KEY);
507
  } elseif ($chunks[0] === 'callback') {
508
  $preview = __('Custom Callback', AAM_KEY);
 
 
509
  }
510
  }
511
  break;
506
  $preview = __('Valid URL', AAM_KEY);
507
  } elseif ($chunks[0] === 'callback') {
508
  $preview = __('Custom Callback', AAM_KEY);
509
+ } elseif ($chunks[0] === 'login') {
510
+ $preview = __('Redirect To Login Page', AAM_KEY);
511
  }
512
  }
513
  break;
Application/Backend/Feature/Main/Route.php CHANGED
@@ -86,6 +86,7 @@ class AAM_Backend_Feature_Main_Route extends AAM_Backend_Feature_Abstract {
86
 
87
  foreach(array_unique($methods) as $method) {
88
  $response[] = array(
 
89
  'restful',
90
  $method,
91
  htmlspecialchars($route),
@@ -99,6 +100,7 @@ class AAM_Backend_Feature_Main_Route extends AAM_Backend_Feature_Abstract {
99
  if (AAM::api()->getConfig('core.settings.xmlrpc', true)) {
100
  foreach(array_keys(AAM_Core_API::getXMLRPCServer()->methods) as $route) {
101
  $response[] = array(
 
102
  'xmlrpc',
103
  'POST',
104
  htmlspecialchars($route),
86
 
87
  foreach(array_unique($methods) as $method) {
88
  $response[] = array(
89
+ $route,
90
  'restful',
91
  $method,
92
  htmlspecialchars($route),
100
  if (AAM::api()->getConfig('core.settings.xmlrpc', true)) {
101
  foreach(array_keys(AAM_Core_API::getXMLRPCServer()->methods) as $route) {
102
  $response[] = array(
103
+ $route,
104
  'xmlrpc',
105
  'POST',
106
  htmlspecialchars($route),
Application/Backend/Feature/Subject/User.php CHANGED
@@ -109,7 +109,7 @@ class AAM_Backend_Feature_Subject_User {
109
  // Making sure that user that we are switching too is not logged in
110
  // already. Reported by https://github.com/KenAer
111
  $sessions = WP_Session_Tokens::get_instance($user->ID);
112
- if (count($sessions->get_all()) > 1) {
113
  $sessions->destroy_all();
114
  }
115
 
109
  // Making sure that user that we are switching too is not logged in
110
  // already. Reported by https://github.com/KenAer
111
  $sessions = WP_Session_Tokens::get_instance($user->ID);
112
+ if (count($sessions->get_all()) >= 1) {
113
  $sessions->destroy_all();
114
  }
115
 
Application/Backend/Manager.php CHANGED
@@ -833,7 +833,7 @@ class AAM_Backend_Manager {
833
  public function printJavascript() {
834
  if (AAM::isAAM()) {
835
  wp_enqueue_script('aam-vendor', AAM_MEDIA . '/js/vendor.js');
836
- wp_enqueue_script('aam-main', AAM_MEDIA . '/js/aam-5.9.js');
837
 
838
  //add plugin localization
839
  $this->printLocalization('aam-main');
833
  public function printJavascript() {
834
  if (AAM::isAAM()) {
835
  wp_enqueue_script('aam-vendor', AAM_MEDIA . '/js/vendor.js');
836
+ wp_enqueue_script('aam-main', AAM_MEDIA . '/js/aam-5.9.1.js');
837
 
838
  //add plugin localization
839
  $this->printLocalization('aam-main');
Application/Backend/phtml/main/route.phtml CHANGED
@@ -22,6 +22,7 @@
22
  <table id="route-list" class="table table-striped table-bordered">
23
  <thead>
24
  <tr>
 
25
  <th>Type</th>
26
  <th width="10%">Method</th>
27
  <th width="80%"><?php echo __('Route', AAM_KEY); ?></th>
22
  <table id="route-list" class="table table-striped table-bordered">
23
  <thead>
24
  <tr>
25
+ <th>Route Raw</th>
26
  <th>Type</th>
27
  <th width="10%">Method</th>
28
  <th width="80%"><?php echo __('Route', AAM_KEY); ?></th>
Application/Backend/phtml/partial/post-advanced-settings.phtml CHANGED
@@ -80,6 +80,10 @@
80
  <input type="radio" id="post-redirect-url" name="post-redirect-type" class="post-redirect-type" data-action="#post-redirect-url-action" value="url" />
81
  <label for="post-redirect-url"><?php echo AAM_Backend_View_Helper::preparePhrase('Redirected to the URL [(enter full URL starting from http or https)]', 'small'); ?></label>
82
  </div>
 
 
 
 
83
  <div class="radio">
84
  <input type="radio" id="post-redirect-callback" name="post-redirect-type" class="post-redirect-type" data-action="#post-redirect-callback-action" value="callback" />
85
  <label for="post-redirect-callback"><?php echo sprintf(AAM_Backend_View_Helper::preparePhrase('Trigger PHP callback function [(valid %sPHP callback%s is required)]', 'small'), '<a href="http://php.net/manual/en/language.types.callable.php" target="_blank">', '</a>'); ?></label>
80
  <input type="radio" id="post-redirect-url" name="post-redirect-type" class="post-redirect-type" data-action="#post-redirect-url-action" value="url" />
81
  <label for="post-redirect-url"><?php echo AAM_Backend_View_Helper::preparePhrase('Redirected to the URL [(enter full URL starting from http or https)]', 'small'); ?></label>
82
  </div>
83
+ <div class="radio hidden" id="post-login-redirect-visitor">
84
+ <input type="radio" id="post-redirect-login" name="post-redirect-type" class="post-redirect-type" value="login" data-action="none" />
85
+ <label for="post-redirect-login"><?php echo AAM_Backend_View_Helper::preparePhrase('Redirect to the login page [(after login, user will be redirected back to the restricted page)]', 'small'); ?></label>
86
+ </div>
87
  <div class="radio">
88
  <input type="radio" id="post-redirect-callback" name="post-redirect-type" class="post-redirect-type" data-action="#post-redirect-callback-action" value="callback" />
89
  <label for="post-redirect-callback"><?php echo sprintf(AAM_Backend_View_Helper::preparePhrase('Trigger PHP callback function [(valid %sPHP callback%s is required)]', 'small'), '<a href="http://php.net/manual/en/language.types.callable.php" target="_blank">', '</a>'); ?></label>
Application/Core/Login.php CHANGED
@@ -150,7 +150,7 @@ class AAM_Core_Login {
150
  } elseif (AAM_Core_Config::get('core.settings.singleSession', false)) {
151
  $sessions = WP_Session_Tokens::get_instance($user->ID);
152
 
153
- if (count($sessions->get_all()) > 1) {
154
  $sessions->destroy_all();
155
  }
156
  }
@@ -238,10 +238,10 @@ class AAM_Core_Login {
238
  * @access protected
239
  */
240
  protected function updateLoginCounter($increment) {
241
- $attempts = get_transient('aam_login_attemtps');
242
 
243
  if ($attempts !== false) {
244
- $timeout = get_option('_transient_timeout_aam_login_attemtps') - time();
245
  $attempts = intval($attempts) + $increment;
246
  } else {
247
  $attempts = 1;
@@ -255,7 +255,7 @@ class AAM_Core_Login {
255
  wp_safe_redirect(site_url('index.php'));
256
  exit;
257
  } else {
258
- set_transient('aam_login_attemtps', $attempts, $timeout);
259
  }
260
  }
261
 
150
  } elseif (AAM_Core_Config::get('core.settings.singleSession', false)) {
151
  $sessions = WP_Session_Tokens::get_instance($user->ID);
152
 
153
+ if (count($sessions->get_all()) >= 1) {
154
  $sessions->destroy_all();
155
  }
156
  }
238
  * @access protected
239
  */
240
  protected function updateLoginCounter($increment) {
241
+ $attempts = get_transient('aam_login_attempts');
242
 
243
  if ($attempts !== false) {
244
+ $timeout = get_option('_transient_timeout_aam_login_attempts') - time();
245
  $attempts = intval($attempts) + $increment;
246
  } else {
247
  $attempts = 1;
255
  wp_safe_redirect(site_url('index.php'));
256
  exit;
257
  } else {
258
+ set_transient('aam_login_attempts', $attempts, $timeout);
259
  }
260
  }
261
 
Application/Core/Object/Menu.php CHANGED
@@ -89,7 +89,7 @@ class AAM_Core_Object_Menu extends AAM_Core_Object {
89
  }
90
  }
91
  }
92
-
93
  // remove duplicated separators
94
  $count = 0;
95
  foreach ($menu as $id => $item) {
89
  }
90
  }
91
  }
92
+
93
  // remove duplicated separators
94
  $count = 0;
95
  foreach ($menu as $id => $item) {
Application/Core/Policy/Manager.php CHANGED
@@ -127,6 +127,37 @@ final class AAM_Core_Policy_Manager {
127
 
128
  return $allowed;
129
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
 
131
  /**
132
  * Get Policy Param
127
 
128
  return $allowed;
129
  }
130
+
131
+ /**
132
+ * Determine if resource is the boundary
133
+ *
134
+ * The Boundary is type of resource that is denied and is enforced so no other
135
+ * statements can override it. For example edit_posts capability can be boundary
136
+ * for any statement that user Role resource
137
+ *
138
+ * @param string $resource
139
+ * @param array $args
140
+ *
141
+ * @return boolean
142
+ *
143
+ * @access public
144
+ */
145
+ public function isBoundary($resource, $args = array()) {
146
+ $denied = false;
147
+ $tree = $this->preparePolicyTree();
148
+ $id = strtolower($resource);
149
+
150
+ if (isset($tree['Statement'][$id])) {
151
+ $stm = $tree['Statement'][$id];
152
+
153
+ if ($this->isApplicable($stm, $args)) {
154
+ $effect = strtolower($stm['Effect']);
155
+ $denied = ($effect === 'deny' && !empty($stm['Enforce']));
156
+ }
157
+ }
158
+
159
+ return $denied;
160
+ }
161
 
162
  /**
163
  * Get Policy Param
Application/Core/Subject/User.php CHANGED
@@ -70,7 +70,7 @@ class AAM_Core_Subject_User extends AAM_Core_Subject {
70
 
71
  // Retrieve user capabilities set with AAM
72
  $aamCaps = get_user_option(self::AAM_CAPKEY, $id);
73
-
74
  if (is_array($aamCaps)) {
75
  $this->aamCaps = $aamCaps;
76
  }
@@ -103,7 +103,7 @@ class AAM_Core_Subject_User extends AAM_Core_Subject {
103
  if ($stm['Effect'] === 'allow') {
104
  if (!in_array($chunks[1], $roles, true)) {
105
  if ($allRoles->is_role($chunks[1])) {
106
- $roleCaps = array_merge($roleCaps, $allRoles->get_role($chunks[1])->capabilities);
107
  $roleCaps[] = $chunks[1];
108
  }
109
  $roles[] = $chunks[1];
@@ -123,6 +123,32 @@ class AAM_Core_Subject_User extends AAM_Core_Subject {
123
  //reset the user capabilities
124
  $subject->allcaps = array_merge($subject->allcaps, $roleCaps, $policyCaps, $this->aamCaps);
125
  $subject->caps = array_merge($subject->caps, $roleCaps, $policyCaps, $this->aamCaps);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  }
127
 
128
  /**
70
 
71
  // Retrieve user capabilities set with AAM
72
  $aamCaps = get_user_option(self::AAM_CAPKEY, $id);
73
+
74
  if (is_array($aamCaps)) {
75
  $this->aamCaps = $aamCaps;
76
  }
103
  if ($stm['Effect'] === 'allow') {
104
  if (!in_array($chunks[1], $roles, true)) {
105
  if ($allRoles->is_role($chunks[1])) {
106
+ $roleCaps = array_merge($roleCaps, $allRoles->get_role($chunks[1])->capabilities);
107
  $roleCaps[] = $chunks[1];
108
  }
109
  $roles[] = $chunks[1];
123
  //reset the user capabilities
124
  $subject->allcaps = array_merge($subject->allcaps, $roleCaps, $policyCaps, $this->aamCaps);
125
  $subject->caps = array_merge($subject->caps, $roleCaps, $policyCaps, $this->aamCaps);
126
+
127
+ //make sure that no capabilities are going outside of define boundary
128
+ $subject->allcaps = $this->applyCapabilityBoundaries($manager, $subject->allcaps);
129
+ $subject->caps = $this->applyCapabilityBoundaries($manager, $subject->caps);
130
+ }
131
+
132
+ /**
133
+ * Check if any of the capabilities going out of the defined boundary
134
+ *
135
+ * @param AAM_Core_Policy_Manager $manager
136
+ * @param array $caps
137
+ *
138
+ * @return array
139
+ *
140
+ * @access protected
141
+ */
142
+ protected function applyCapabilityBoundaries($manager, $caps) {
143
+ $final = array();
144
+
145
+ foreach($caps as $key => $effect) {
146
+ if ($manager->isBoundary("Capability:{$key}") === false) {
147
+ $final[$key] = $effect;
148
+ }
149
+ }
150
+
151
+ return $final;
152
  }
153
 
154
  /**
Application/Extension/List.php CHANGED
@@ -22,7 +22,7 @@ class AAM_Extension_List {
22
  'description' => 'Get the complete list of all premium AAM extensions in one package and all future premium extensions already included for now additional cost.',
23
  'url' => 'https://aamplugin.com/complete-package',
24
  'version' => (defined('AAM_COMPLETE_PACKAGE') ? constant('AAM_COMPLETE_PACKAGE') : null),
25
- 'latest' => '3.8.14'
26
  ),
27
  'AAM_PLUS_PACKAGE' => array(
28
  'title' => 'Plus Package',
22
  'description' => 'Get the complete list of all premium AAM extensions in one package and all future premium extensions already included for now additional cost.',
23
  'url' => 'https://aamplugin.com/complete-package',
24
  'version' => (defined('AAM_COMPLETE_PACKAGE') ? constant('AAM_COMPLETE_PACKAGE') : null),
25
+ 'latest' => '3.8.16'
26
  ),
27
  'AAM_PLUS_PACKAGE' => array(
28
  'title' => 'Plus Package',
Application/Frontend/Authorization.php CHANGED
@@ -143,7 +143,11 @@ class AAM_Frontend_Authorization {
143
  $code = apply_filters('aam-post-redirect-http-code-filter', 307);
144
 
145
  if (count($rule) === 1) { // TODO: legacy. Remove in Jul 2020
146
- AAM_Core_API::redirect($rule[0]);
 
 
 
 
147
  } elseif ($rule[0] === 'page') {
148
  wp_safe_redirect(get_page_link($rule[1]), $code); exit;
149
  } elseif ($rule[0] === 'url') {
143
  $code = apply_filters('aam-post-redirect-http-code-filter', 307);
144
 
145
  if (count($rule) === 1) { // TODO: legacy. Remove in Jul 2020
146
+ if ($rule[0] === 'login') {
147
+ AAM::api()->redirect('login');
148
+ } else {
149
+ AAM_Core_API::redirect($rule[0]);
150
+ }
151
  } elseif ($rule[0] === 'page') {
152
  wp_safe_redirect(get_page_link($rule[1]), $code); exit;
153
  } elseif ($rule[0] === 'url') {
Application/Frontend/Filter.php CHANGED
@@ -48,9 +48,6 @@ class AAM_Frontend_Filter {
48
 
49
  //widget filters
50
  add_filter('sidebars_widgets', array($this, 'filterWidgets'), 999);
51
-
52
- //get control over commenting stuff
53
- add_filter('comments_open', array($this, 'commentOpen'), 10, 2);
54
  }
55
 
56
  /**
@@ -76,8 +73,7 @@ class AAM_Frontend_Filter {
76
  AAM_Core_Config::get("frontend.404redirect.{$type}")
77
  );
78
  }
79
- } elseif ($wp_query->is_single || $wp_query->is_page
80
- || $wp_query->is_posts_page || $wp_query->is_home) {
81
  $post = AAM_Core_API::getCurrentPost();
82
 
83
  if ($post) {
@@ -179,22 +175,6 @@ class AAM_Frontend_Filter {
179
  return AAM::getUser()->getObject('metabox')->filterFrontend($widgets);
180
  }
181
 
182
- /**
183
- * Control frontend commenting feature
184
- *
185
- * @param boolean $open
186
- * @param int $post_id
187
- *
188
- * @return boolean
189
- *
190
- * @access public
191
- */
192
- public function commentOpen($open, $post_id) {
193
- $object = AAM::getUser()->getObject('post', $post_id);
194
-
195
- return ($object->has('frontend.comment') ? false : $open);
196
- }
197
-
198
  /**
199
  * Register backend filters and actions
200
  *
48
 
49
  //widget filters
50
  add_filter('sidebars_widgets', array($this, 'filterWidgets'), 999);
 
 
 
51
  }
52
 
53
  /**
73
  AAM_Core_Config::get("frontend.404redirect.{$type}")
74
  );
75
  }
76
+ } elseif ($wp_query->is_single || $wp_query->is_page) {
 
77
  $post = AAM_Core_API::getCurrentPost();
78
 
79
  if ($post) {
175
  return AAM::getUser()->getObject('metabox')->filterFrontend($widgets);
176
  }
177
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
  /**
179
  * Register backend filters and actions
180
  *
Application/Shared/Manager.php CHANGED
@@ -23,7 +23,7 @@ class AAM_Shared_Manager {
23
  * @access private
24
  */
25
  private static $_instance = null;
26
-
27
  /**
28
  * Constructor
29
  *
@@ -98,6 +98,9 @@ class AAM_Shared_Manager {
98
  add_filter(
99
  'gettext', array(self::$_instance, 'escapeTranslation'), 999, 3
100
  );
 
 
 
101
 
102
  // Role Manager. Tracking user role changes and if there is expiration
103
  // set, then trigger hooks
@@ -144,7 +147,7 @@ class AAM_Shared_Manager {
144
  'delete_post' => 'aam_delete_policy',
145
  'delete_posts' => 'aam_delete_policies',
146
  'edit_posts' => 'aam_edit_policies',
147
- 'edit_others_posts' => 'aam_edit_other_policies',
148
  'publish_posts' => 'aam_publish_policies',
149
  )
150
  ));
@@ -421,7 +424,7 @@ class AAM_Shared_Manager {
421
 
422
  return $response;
423
  }
424
-
425
  /**
426
  * Check user capability
427
  *
@@ -430,60 +433,28 @@ class AAM_Shared_Manager {
430
  * "0" element, it performs additional check on user's capability to manage
431
  * post, users etc.
432
  *
433
- * @param array $caps
434
- * @param array $meta
435
- * @param array $args
 
436
  *
437
  * @return array
438
  *
439
  * @access public
440
  */
441
  public function mapMetaCaps($caps, $cap, $user_id, $args) {
442
- global $post;
443
-
444
  switch($cap) {
445
  case 'edit_user':
446
  case 'delete_user':
447
  $caps = $this->authorizeUserUpdate($caps, $args[0]);
448
  break;
449
 
450
- case 'edit_post':
451
- case 'edit_page':
452
- case 'aam_edit_policy':
453
- $caps = $this->authorizePostEdit($caps, $args[0]);
454
- break;
455
-
456
- case 'delete_post':
457
- case 'delete_page':
458
- case 'aam_delete_policy':
459
- $caps = $this->authorizePostDelete($caps, $args[0]);
460
- break;
461
-
462
- case 'read_post':
463
- case 'read_page':
464
- case 'aam_read_policy':
465
- $caps = $this->authorizePostRead($caps, $args[0]);
466
- break;
467
-
468
- case 'publish_post':
469
- case 'aam_publish_policy':
470
- $caps = $this->authorizePublishPost($caps, $args[0]);
471
- break;
472
-
473
  case 'install_plugins':
474
  $caps = $this->checkPluginsAction('install', $caps, $cap);
475
  break;
476
 
477
- case 'publish_posts':
478
- case 'publish_pages':
479
- case 'aam_publish_policies':
480
- // There is a bug in WP core that instead of checking if user has
481
- // ability to publish_post, it checks for edit_post
482
- if (is_a($post, 'WP_Post')) {
483
- $caps = $this->authorizePublishPost($caps, $post->ID);
484
- }
485
- break;
486
-
487
  case 'delete_plugins':
488
  $caps = $this->checkPluginsAction('delete', $caps, $cap);
489
  break;
@@ -509,12 +480,68 @@ class AAM_Shared_Manager {
509
  break;
510
 
511
  default:
 
 
 
 
512
  break;
513
  }
514
 
515
  return $caps;
516
  }
517
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
518
  /**
519
  *
520
  * @param type $action
@@ -639,6 +666,23 @@ class AAM_Shared_Manager {
639
 
640
  return $caps;
641
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
642
 
643
  /**
644
  * Check if current user is allowed to edit post
@@ -697,11 +741,11 @@ class AAM_Shared_Manager {
697
  protected function authorizePublishPost($caps, $id) {
698
  $object = AAM::getUser()->getObject('post', $id);
699
  $area = AAM_Core_Api_Area::get();
700
-
701
  if (!$object->allowed($area . '.publish')) {
702
  $caps[] = 'do_not_allow';
703
  }
704
-
705
  return $caps;
706
  }
707
 
23
  * @access private
24
  */
25
  private static $_instance = null;
26
+
27
  /**
28
  * Constructor
29
  *
98
  add_filter(
99
  'gettext', array(self::$_instance, 'escapeTranslation'), 999, 3
100
  );
101
+
102
+ //get control over commenting stuff
103
+ add_filter('comments_open', array(self::$_instance, 'commentOpen'), 10, 2);
104
 
105
  // Role Manager. Tracking user role changes and if there is expiration
106
  // set, then trigger hooks
147
  'delete_post' => 'aam_delete_policy',
148
  'delete_posts' => 'aam_delete_policies',
149
  'edit_posts' => 'aam_edit_policies',
150
+ 'edit_others_posts' => 'aam_edit_others_policies',
151
  'publish_posts' => 'aam_publish_policies',
152
  )
153
  ));
424
 
425
  return $response;
426
  }
427
+
428
  /**
429
  * Check user capability
430
  *
433
  * "0" element, it performs additional check on user's capability to manage
434
  * post, users etc.
435
  *
436
+ * @param array $caps
437
+ * @param string $cap
438
+ * @param int $user_id
439
+ * @param array $args
440
  *
441
  * @return array
442
  *
443
  * @access public
444
  */
445
  public function mapMetaCaps($caps, $cap, $user_id, $args) {
446
+ global $post;
447
+
448
  switch($cap) {
449
  case 'edit_user':
450
  case 'delete_user':
451
  $caps = $this->authorizeUserUpdate($caps, $args[0]);
452
  break;
453
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
454
  case 'install_plugins':
455
  $caps = $this->checkPluginsAction('install', $caps, $cap);
456
  break;
457
 
 
 
 
 
 
 
 
 
 
 
458
  case 'delete_plugins':
459
  $caps = $this->checkPluginsAction('delete', $caps, $cap);
460
  break;
480
  break;
481
 
482
  default:
483
+ //potentially post type cap
484
+ $caps = $this->checkPostPermission(
485
+ $caps, $cap, (isset($args[0]) ? $args[0] : null)
486
+ );
487
  break;
488
  }
489
 
490
  return $caps;
491
  }
492
+
493
+ /**
494
+ * Check Post Permissions
495
+ *
496
+ * @param [type] $caps
497
+ * @param [type] $cap
498
+ * @param [type] $id
499
+ *
500
+ * @return array
501
+ *
502
+ * @access protected
503
+ */
504
+ protected function checkPostPermission($caps, $cap, $id = null) {
505
+ global $post;
506
+
507
+ $postId = (empty($id) && is_a($post, 'WP_Post') ? $post->ID : $id);
508
+ switch($cap) {
509
+ case 'edit_post':
510
+ case 'aam_edit_policy':
511
+ $caps = $this->authorizePostEdit($caps, $postId);
512
+ break;
513
+
514
+ case 'delete_post':
515
+ case 'aam_delete_policy':
516
+ $caps = $this->authorizePostDelete($caps, $postId);
517
+ break;
518
+
519
+ case 'read_post':
520
+ case 'read':
521
+ case 'aam_read_policy':
522
+ $caps = $this->authorizePostRead($caps, $postId);
523
+ break;
524
+
525
+
526
+ case 'publish_post':
527
+ case 'publish_posts':
528
+ case 'publish_pages':
529
+ case 'aam_publish_policies':
530
+ // There is a bug in WP core that instead of checking if user has
531
+ // ability to publish_post, it checks for edit_post. That is why
532
+ // user has to be on the edit
533
+ if (is_a($post, 'WP_Post')) {
534
+ $caps = $this->authorizePublishPost($caps, $postId);
535
+ }
536
+ break;
537
+
538
+ default:
539
+ break;
540
+ }
541
+
542
+ return $caps;
543
+ }
544
+
545
  /**
546
  *
547
  * @param type $action
666
 
667
  return $caps;
668
  }
669
+
670
+ /**
671
+ * Control frontend commenting feature
672
+ *
673
+ * @param boolean $open
674
+ * @param int $post_id
675
+ *
676
+ * @return boolean
677
+ *
678
+ * @access public
679
+ */
680
+ public function commentOpen($open, $post_id) {
681
+ $object = AAM::getUser()->getObject('post', $post_id);
682
+ $area = AAM_Core_Api_Area::get();
683
+
684
+ return ($object->has($area . '.comment') ? false : $open);
685
+ }
686
 
687
  /**
688
  * Check if current user is allowed to edit post
741
  protected function authorizePublishPost($caps, $id) {
742
  $object = AAM::getUser()->getObject('post', $id);
743
  $area = AAM_Core_Api_Area::get();
744
+
745
  if (!$object->allowed($area . '.publish')) {
746
  $caps[] = 'do_not_allow';
747
  }
748
+
749
  return $caps;
750
  }
751
 
aam.php CHANGED
@@ -3,7 +3,7 @@
3
  /**
4
  Plugin Name: Advanced Access Manager
5
  Description: All you need to manage access to your WordPress website
6
- Version: 5.9
7
  Author: Vasyl Martyniuk <vasyl@vasyltech.com>
8
  Author URI: https://vasyltech.com
9
 
@@ -275,7 +275,7 @@ if (defined('ABSPATH')) {
275
  wp_schedule_event(time(), 'daily', 'aam-cron');
276
  }
277
  add_action('aam-cron', 'AAM::cron');
278
-
279
  //activation & deactivation hooks
280
  register_activation_hook(__FILE__, array('AAM', 'activate'));
281
  register_uninstall_hook(__FILE__, array('AAM', 'uninstall'));
3
  /**
4
  Plugin Name: Advanced Access Manager
5
  Description: All you need to manage access to your WordPress website
6
+ Version: 5.9.1
7
  Author: Vasyl Martyniuk <vasyl@vasyltech.com>
8
  Author URI: https://vasyltech.com
9
 
275
  wp_schedule_event(time(), 'daily', 'aam-cron');
276
  }
277
  add_action('aam-cron', 'AAM::cron');
278
+
279
  //activation & deactivation hooks
280
  register_activation_hook(__FILE__, array('AAM', 'activate'));
281
  register_uninstall_hook(__FILE__, array('AAM', 'uninstall'));
media/js/{aam-5.9.js → aam-5.9.1.js} RENAMED
@@ -2954,6 +2954,12 @@
2954
  $('.post-redirect-action').hide();
2955
  $('.post-redirect-value').val('');
2956
  $('.post-redirect-type').prop('checked', false);
 
 
 
 
 
 
2957
 
2958
  if ($('#post-redirect-rule').val()) {
2959
  var rule = $('#post-redirect-rule').val().split('|');
@@ -3477,7 +3483,7 @@
3477
  }
3478
  },
3479
  columnDefs: [
3480
- // {visible: false, targets: [0]},
3481
  {className: 'text-center', targets: [0, 1]}
3482
  ],
3483
  language: {
@@ -3485,23 +3491,23 @@
3485
  searchPlaceholder: getAAM().__('Search Route'),
3486
  info: getAAM().__('_TOTAL_ route(s)'),
3487
  infoFiltered: '',
3488
- emptyTable: getAAM().__('No API enpoints found. You might have APIs disabled.'),
3489
  infoEmpty: getAAM().__('Nothing to show'),
3490
  lengthMenu: '_MENU_'
3491
  },
3492
  createdRow: function (row, data) {
3493
  // decorate the method
3494
  var method = $('<span/>', {
3495
- 'class': 'aam-api-method ' + data[1].toLowerCase()
3496
- }).text(data[1]);
3497
 
3498
  $('td:eq(0)', row).html(
3499
- $('<small/>').text(data[0] === 'restful' ? 'JSON' : 'XML')
3500
  );
3501
 
3502
  $('td:eq(1)', row).html(method);
3503
 
3504
- var actions = data[3].split(',');
3505
 
3506
  var container = $('<div/>', {'class': 'aam-row-actions'});
3507
  $.each(actions, function (i, action) {
@@ -3510,7 +3516,7 @@
3510
  $(container).append($('<i/>', {
3511
  'class': 'aam-row-action text-muted icon-check-empty'
3512
  }).bind('click', function () {
3513
- save(data[0], data[2], data[1], this);
3514
  }));
3515
  break;
3516
 
@@ -3518,7 +3524,7 @@
3518
  $(container).append($('<i/>', {
3519
  'class': 'aam-row-action text-danger icon-check'
3520
  }).bind('click', function () {
3521
- save(data[0], data[2], data[1], this);
3522
  }));
3523
  break;
3524
 
2954
  $('.post-redirect-action').hide();
2955
  $('.post-redirect-value').val('');
2956
  $('.post-redirect-type').prop('checked', false);
2957
+
2958
+ if (getAAM().getSubject().type === 'visitor') {
2959
+ $('#post-login-redirect-visitor').removeClass('hidden');
2960
+ } else {
2961
+ $('#post-login-redirect-visitor').addClass('hidden');
2962
+ }
2963
 
2964
  if ($('#post-redirect-rule').val()) {
2965
  var rule = $('#post-redirect-rule').val().split('|');
3483
  }
3484
  },
3485
  columnDefs: [
3486
+ {visible: false, targets: [0]},
3487
  {className: 'text-center', targets: [0, 1]}
3488
  ],
3489
  language: {
3491
  searchPlaceholder: getAAM().__('Search Route'),
3492
  info: getAAM().__('_TOTAL_ route(s)'),
3493
  infoFiltered: '',
3494
+ emptyTable: getAAM().__('No API endpoints found. You might have APIs disabled.'),
3495
  infoEmpty: getAAM().__('Nothing to show'),
3496
  lengthMenu: '_MENU_'
3497
  },
3498
  createdRow: function (row, data) {
3499
  // decorate the method
3500
  var method = $('<span/>', {
3501
+ 'class': 'aam-api-method ' + data[2].toLowerCase()
3502
+ }).text(data[2]);
3503
 
3504
  $('td:eq(0)', row).html(
3505
+ $('<small/>').text(data[1] === 'restful' ? 'JSON' : 'XML')
3506
  );
3507
 
3508
  $('td:eq(1)', row).html(method);
3509
 
3510
+ var actions = data[4].split(',');
3511
 
3512
  var container = $('<div/>', {'class': 'aam-row-actions'});
3513
  $.each(actions, function (i, action) {
3516
  $(container).append($('<i/>', {
3517
  'class': 'aam-row-action text-muted icon-check-empty'
3518
  }).bind('click', function () {
3519
+ save(data[1], data[0], data[2], this);
3520
  }));
3521
  break;
3522
 
3524
  $(container).append($('<i/>', {
3525
  'class': 'aam-row-action text-danger icon-check'
3526
  }).bind('click', function () {
3527
+ save(data[1], data[0], data[2], this);
3528
  }));
3529
  break;
3530
 
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: vasyltech
3
  Tags: access control, membership, backend menu, user role, restricted content, security, jwt
4
  Requires at least: 4.0
5
  Tested up to: 5.1
6
- Stable tag: 5.9
7
 
8
  All you need to manage access to you WordPress websites on frontend, backend and API levels for any role, user or visitors.
9
 
@@ -79,6 +79,14 @@ https://www.youtube.com/watch?v=mj5Xa_Wc16Y
79
 
80
  == Changelog ==
81
 
 
 
 
 
 
 
 
 
82
  = 5.9 =
83
  * Fixed the bug with publish pages not being managed correctly
84
  * Fixed the bug with getting correct post from the list of posts
@@ -90,7 +98,7 @@ https://www.youtube.com/watch?v=mj5Xa_Wc16Y
90
  * Fixed the bug with multi-lingual support
91
  * Fixed the bug with LIMIT option that escaped quotes in the message
92
  * Fixed the bug with managing access to Access Policies
93
- * Added support for aam_edit_policy, aam_read_policy, aam_delete_policy, aam_delete_policies, aam_edit_policies, aam_edit_other_policies, aam_publish_policies capabilities
94
  * Refactored Default Category functionality (moved it to Plus Package extension)
95
  * Added support for the nav_menu_meta_box_object hook to filter posts on Menu Builder page
96
  * Extend Access Policy with more features
3
  Tags: access control, membership, backend menu, user role, restricted content, security, jwt
4
  Requires at least: 4.0
5
  Tested up to: 5.1
6
+ Stable tag: 5.9.1
7
 
8
  All you need to manage access to you WordPress websites on frontend, backend and API levels for any role, user or visitors.
9
 
79
 
80
  == Changelog ==
81
 
82
+ = 5.9.1 =
83
+ * Fixed the bug with controlling which capability can be deleted with Access Policy
84
+ * Fixed typo in the aam_edit_others_policies capability slug
85
+ * Fixed the bug with API Routes not being saved property for those that have htmlspecial characters in it
86
+ * Fixed major bug with keeping track of active user sessions that prevents multiple session per same user
87
+ * Added "Redirect To Login" to the LIMIT option for visitors on Posts & Terms tab
88
+ * Added the new concept of "Boundary" to Access Policy that allows to Enforce certain statements
89
+
90
  = 5.9 =
91
  * Fixed the bug with publish pages not being managed correctly
92
  * Fixed the bug with getting correct post from the list of posts
98
  * Fixed the bug with multi-lingual support
99
  * Fixed the bug with LIMIT option that escaped quotes in the message
100
  * Fixed the bug with managing access to Access Policies
101
+ * Added support for aam_edit_policy, aam_read_policy, aam_delete_policy, aam_delete_policies, aam_edit_policies, aam_edit_others_policies, aam_publish_policies capabilities
102
  * Refactored Default Category functionality (moved it to Plus Package extension)
103
  * Added support for the nav_menu_meta_box_object hook to filter posts on Menu Builder page
104
  * Extend Access Policy with more features