Advanced Access Manager - Version 5.7.2

Version Description

  • Fixed bug with Posts & Terms feature for WP version under 4.8
  • Fixed bug were Access Policy can't be attached to any principal on the Policy edit screen
  • Fixed bug with Access URI options were not merged for users with multiple roles
  • Fixed bug with Access URI options were not exported
  • Fixed but with Post PUBLISH option due to the fact that Gutenberg is using RESTful API
  • Extended Access & Security Policy to support Posts & Terms options
  • Added /validate-jwt RESTful API endpoint to validate JWT
  • Added ability to extract JWT token from GET queries or POST payload
  • Added custom capability aam_view_help_btn to hide HELP icon on AAM UI
  • Significantly improved capability mapping mechanism and access control based on caps
  • Added URI Access support to Access & Security Policy
  • Added Post, Term, PostType support to Access & Security Policy
Download this release

Release Info

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

Code changes from version 5.7.1 to 5.7.2

Application/Api/Rest/Resource/Post.php CHANGED
@@ -48,7 +48,11 @@ class AAM_Api_Rest_Resource_Post {
48
  case 'POST':
49
  case 'PUT':
50
  case 'PATCH':
51
- $result = $this->authorizeUpdate($post);
 
 
 
 
52
  break;
53
 
54
  case 'DELETE':
@@ -93,6 +97,20 @@ class AAM_Api_Rest_Resource_Post {
93
  return $this->processPipeline($steps, $post, $request);
94
  }
95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  /**
97
  *
98
  * @param AAM_Core_Object_Post $post
@@ -310,6 +328,33 @@ class AAM_Api_Rest_Resource_Post {
310
  return $result;
311
  }
312
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
313
  /**
314
  * Check EDIT & EDIT_BY_OTHERS options
315
  *
48
  case 'POST':
49
  case 'PUT':
50
  case 'PATCH':
51
+ if ($request['status'] === 'publish') {
52
+ $result = $this->authorizePublish($post);
53
+ } else {
54
+ $result = $this->authorizeUpdate($post);
55
+ }
56
  break;
57
 
58
  case 'DELETE':
97
  return $this->processPipeline($steps, $post, $request);
98
  }
99
 
100
+ /**
101
+ *
102
+ * @param AAM_Core_Object_Post $post
103
+ * @return type
104
+ */
105
+ protected function authorizePUblish(AAM_Core_Object_Post $post) {
106
+ $steps = array(
107
+ // Step #1. Check if publish action is alloed
108
+ array($this, 'checkPublish'),
109
+ );
110
+
111
+ return $this->processPipeline($steps, $post);
112
+ }
113
+
114
  /**
115
  *
116
  * @param AAM_Core_Object_Post $post
328
  return $result;
329
  }
330
 
331
+ /**
332
+ * Check PUBLISH & PUBLISH_BY_OTHERS options
333
+ *
334
+ * @param AAM_Core_Object_Post $post
335
+ *
336
+ * @return void
337
+ *
338
+ * @access protected
339
+ */
340
+ protected function checkPublish(AAM_Core_Object_Post $post) {
341
+ $result = null;
342
+
343
+ // Keep this compatible with older version of Publish (without Gutenberg)
344
+ if (!$post->allowed('api.publish') || !$post->allowed('backend.publish')) {
345
+ $result = new WP_Error(
346
+ 'rest_post_cannot_publish',
347
+ "User is unauthorized to publish the post. Access denied.",
348
+ array(
349
+ 'action' => 'api.publish',
350
+ 'status' => 401
351
+ )
352
+ );
353
+ }
354
+
355
+ return $result;
356
+ }
357
+
358
  /**
359
  * Check EDIT & EDIT_BY_OTHERS options
360
  *
Application/Backend/Feature/Main/Capability.php CHANGED
@@ -54,7 +54,8 @@ class AAM_Backend_Feature_Main_Capability extends AAM_Backend_Feature_Abstract {
54
  'aam_manage_404_redirect', 'aam_manage_ip_check', 'aam_manage_admin_toolbar',
55
  'aam_manage_default', 'aam_manage_visitors', 'aam_manage_roles', 'aam_manage_users',
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
  )
59
  );
60
 
@@ -153,7 +154,7 @@ class AAM_Backend_Feature_Main_Capability extends AAM_Backend_Feature_Abstract {
153
 
154
  $toggle = ($subject->hasCapability($cap) ? 'checked' : 'unchecked');
155
 
156
- if (AAM::api()->isAllowed("Capability:{$cap}", 'AAM:toggle') === false) {
157
  $toggle = 'no-' . $toggle;
158
  }
159
 
@@ -191,7 +192,7 @@ class AAM_Backend_Feature_Main_Capability extends AAM_Backend_Feature_Abstract {
191
  }
192
 
193
  // Access & Security policy has higher priority
194
- if (AAM::api()->isAllowed("Capability:{$cap}", 'AAM:update') === false) {
195
  $allowed = false;
196
  }
197
 
@@ -212,7 +213,7 @@ class AAM_Backend_Feature_Main_Capability extends AAM_Backend_Feature_Abstract {
212
  }
213
 
214
  // Access & Security policy has higher priority
215
- if (AAM::api()->isAllowed("Capability:{$cap}", 'AAM:delete') === false) {
216
  $allowed = false;
217
  }
218
 
@@ -250,10 +251,25 @@ class AAM_Backend_Feature_Main_Capability extends AAM_Backend_Feature_Abstract {
250
  */
251
  protected function retrieveAllCaps() {
252
  $response = array();
253
- $caps = AAM_Core_API::getAllCapabilities();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254
 
255
  foreach (array_keys($caps) as $cap) {
256
- if (AAM::api()->isAllowed("Capability:{$cap}", 'AAM:list') !== false) {
257
  $response[] = array(
258
  $cap,
259
  $this->getGroup($cap),
54
  'aam_manage_404_redirect', 'aam_manage_ip_check', 'aam_manage_admin_toolbar',
55
  'aam_manage_default', 'aam_manage_visitors', 'aam_manage_roles', 'aam_manage_users',
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'
59
  )
60
  );
61
 
154
 
155
  $toggle = ($subject->hasCapability($cap) ? 'checked' : 'unchecked');
156
 
157
+ if (AAM::api()->isAllowed("Capability:{$cap}:AAM:toggle") === false) {
158
  $toggle = 'no-' . $toggle;
159
  }
160
 
192
  }
193
 
194
  // Access & Security policy has higher priority
195
+ if (AAM::api()->isAllowed("Capability:{$cap}:AAM:update") === false) {
196
  $allowed = false;
197
  }
198
 
213
  }
214
 
215
  // Access & Security policy has higher priority
216
+ if (AAM::api()->isAllowed("Capability:{$cap}:AAM:delete") === false) {
217
  $allowed = false;
218
  }
219
 
251
  */
252
  protected function retrieveAllCaps() {
253
  $response = array();
254
+
255
+ // Load also capabilities defined in policy
256
+ $stms = AAM_Core_Policy_Manager::getInstance()->find(
257
+ "/^Capability:/i", AAM_Backend_Subject::getInstance()->get()
258
+ );
259
+
260
+ $policyCaps = array();
261
+
262
+ foreach($stms as $key => $stm) {
263
+ $chunks = explode(':', $key);
264
+ if (count($chunks) === 2) {
265
+ $policyCaps[$chunks[1]] = ($stm['Effect'] === 'allow' ? 1 : 0);
266
+ }
267
+ }
268
+
269
+ $caps = array_merge($policyCaps, AAM_Core_API::getAllCapabilities());
270
 
271
  foreach (array_keys($caps) as $cap) {
272
+ if (AAM::api()->isAllowed("Capability:{$cap}:AAM:list") !== false) {
273
  $response[] = array(
274
  $cap,
275
  $this->getGroup($cap),
Application/Backend/Feature/Main/Menu.php CHANGED
@@ -53,6 +53,7 @@ class AAM_Backend_Feature_Main_Menu extends AAM_Backend_Feature_Abstract {
53
 
54
  //let's create menu list with submenus
55
  if (!empty($menu)) {
 
56
  foreach ($menu as $item) {
57
  if (preg_match('/^separator/', $item[2])) {
58
  continue; //skip separator
@@ -63,15 +64,18 @@ class AAM_Backend_Feature_Main_Menu extends AAM_Backend_Feature_Abstract {
63
  $allowed = AAM_Backend_Subject::getInstance()->hasCapability($item[1]);
64
 
65
  if ($allowed || count($submenu) > 0) {
66
- $response[] = array(
67
  //add menu- prefix to define that this is the top level menu
68
  //WordPress by default gives the same menu id to the first
69
  //submenu
70
  'id' => 'menu-' . $item[2],
71
  'name' => $this->filterMenuName($item[0]),
72
  'submenu' => $submenu,
73
- 'capability' => $item[1]
 
74
  );
 
 
75
  }
76
  }
77
  }
@@ -111,6 +115,7 @@ class AAM_Backend_Feature_Main_Menu extends AAM_Backend_Feature_Abstract {
111
  */
112
  protected function getSubmenu($menu) {
113
  $submenu = json_decode(base64_decode(AAM_Core_Request::post('submenu')), 1);
 
114
 
115
  $response = array();
116
  $subject = AAM_Backend_Subject::getInstance();
@@ -119,11 +124,15 @@ class AAM_Backend_Feature_Main_Menu extends AAM_Backend_Feature_Abstract {
119
  if (array_key_exists($menu, $submenu) && is_array($submenu[$menu])) {
120
  foreach ($submenu[$menu] as $item) {
121
  if ($subject->hasCapability($item[1]) || $isDefault) {
122
- $response[] = array(
123
- 'id' => $this->normalizeItem($item[2]),
 
124
  'name' => $this->filterMenuName($item[0]),
125
- 'capability' => $item[1]
 
126
  );
 
 
127
  }
128
  }
129
  }
@@ -151,16 +160,15 @@ class AAM_Backend_Feature_Main_Menu extends AAM_Backend_Feature_Abstract {
151
 
152
  /**
153
  *
154
- * @param type $object
155
  * @param type $subs
156
  * @return boolean
157
  */
158
- protected function hasSubmenuChecked($object, $subs) {
159
  $has = false;
160
 
161
  if (!empty($subs)) {
162
  foreach($subs as $submenu) {
163
- if ($object->has($submenu['id'])) {
164
  $has = true;
165
  break;
166
  }
53
 
54
  //let's create menu list with submenus
55
  if (!empty($menu)) {
56
+ $object = AAM_Backend_Subject::getInstance()->getObject('menu');
57
  foreach ($menu as $item) {
58
  if (preg_match('/^separator/', $item[2])) {
59
  continue; //skip separator
64
  $allowed = AAM_Backend_Subject::getInstance()->hasCapability($item[1]);
65
 
66
  if ($allowed || count($submenu) > 0) {
67
+ $menuItem = array(
68
  //add menu- prefix to define that this is the top level menu
69
  //WordPress by default gives the same menu id to the first
70
  //submenu
71
  'id' => 'menu-' . $item[2],
72
  'name' => $this->filterMenuName($item[0]),
73
  'submenu' => $submenu,
74
+ 'capability' => $item[1],
75
+ 'crc32' => crc32('menu-' . $item[2]),
76
  );
77
+ $menuItem['checked'] = $object->has($menuItem['id']) || $object->has($menuItem['crc32']);
78
+ $response[] = $menuItem;
79
  }
80
  }
81
  }
115
  */
116
  protected function getSubmenu($menu) {
117
  $submenu = json_decode(base64_decode(AAM_Core_Request::post('submenu')), 1);
118
+ $object = AAM_Backend_Subject::getInstance()->getObject('menu');
119
 
120
  $response = array();
121
  $subject = AAM_Backend_Subject::getInstance();
124
  if (array_key_exists($menu, $submenu) && is_array($submenu[$menu])) {
125
  foreach ($submenu[$menu] as $item) {
126
  if ($subject->hasCapability($item[1]) || $isDefault) {
127
+ $id = $this->normalizeItem($item[2]);
128
+ $menuItem = array(
129
+ 'id' => $id,
130
  'name' => $this->filterMenuName($item[0]),
131
+ 'capability' => $item[1],
132
+ 'crc32' => crc32($id)
133
  );
134
+ $menuItem['checked'] = $object->has($menuItem['id']) || $object->has($menuItem['crc32']);
135
+ $response[] = $menuItem;
136
  }
137
  }
138
  }
160
 
161
  /**
162
  *
 
163
  * @param type $subs
164
  * @return boolean
165
  */
166
+ protected function hasSubmenuChecked($subs) {
167
  $has = false;
168
 
169
  if (!empty($subs)) {
170
  foreach($subs as $submenu) {
171
+ if ($submenu['checked']) {
172
  $has = true;
173
  break;
174
  }
Application/Backend/Feature/Main/Policy.php CHANGED
@@ -31,18 +31,14 @@ class AAM_Backend_Feature_Main_Policy extends AAM_Backend_Feature_Abstract {
31
  * @access public
32
  */
33
  public function save() {
34
- if (defined('AAM_PLUS_PACKAGE')) {
35
- $subject = AAM_Backend_Subject::getInstance();
36
- $id = AAM_Core_Request::post('id');
37
- $effect = AAM_Core_Request::post('effect');
38
 
39
- //clear cache
40
- AAM_Core_API::clearCache();
41
 
42
- $result = $subject->save($id, $effect, 'policy');
43
- } else {
44
- $result = false;
45
- }
46
 
47
  return wp_json_encode(array(
48
  'status' => ($result ? 'success' : 'failure')
31
  * @access public
32
  */
33
  public function save() {
34
+ $subject = AAM_Backend_Subject::getInstance();
35
+ $id = AAM_Core_Request::post('id');
36
+ $effect = AAM_Core_Request::post('effect');
 
37
 
38
+ //clear cache
39
+ AAM_Core_API::clearCache();
40
 
41
+ $result = $subject->save($id, $effect, 'policy');
 
 
 
42
 
43
  return wp_json_encode(array(
44
  'status' => ($result ? 'success' : 'failure')
Application/Backend/Feature/Main/Post.php CHANGED
@@ -167,16 +167,7 @@ class AAM_Backend_Feature_Main_Post extends AAM_Backend_Feature_Abstract {
167
  'term',
168
  $record->name,
169
  'manage,edit',
170
- rtrim(get_term_parents_list(
171
- $record->term_id,
172
- $record->taxonomy,
173
- array(
174
- 'link' => false,
175
- 'format' => 'name',
176
- 'separator' => '/',
177
- 'inclusive' => false
178
- )
179
- ), '/'),
180
  apply_filters(
181
  'aam-term-override-status',
182
  false,
@@ -190,6 +181,51 @@ class AAM_Backend_Feature_Main_Post extends AAM_Backend_Feature_Abstract {
190
  return $response;
191
  }
192
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
  /**
194
  *
195
  * @return type
167
  'term',
168
  $record->name,
169
  'manage,edit',
170
+ rtrim($this->getParentTermList($record), '/'),
 
 
 
 
 
 
 
 
 
171
  apply_filters(
172
  'aam-term-override-status',
173
  false,
181
  return $response;
182
  }
183
 
184
+ /**
185
+ *
186
+ * @global type $wp_version
187
+ * @param type $term
188
+ * @return type
189
+ * @todo Remove when min WP version will be 4.8
190
+ */
191
+ protected function getParentTermList($term) {
192
+ global $wp_version;
193
+
194
+ $list = '';
195
+ $args = array(
196
+ 'link' => false,
197
+ 'format' => 'name',
198
+ 'separator' => '/',
199
+ 'inclusive' => false
200
+ );
201
+
202
+ if (version_compare($wp_version, '4.8.0') === -1) {
203
+ $term = get_term($term->term_id, $term->taxonomy);
204
+
205
+ foreach (array('link', 'inclusive') as $bool) {
206
+ $args[$bool] = wp_validate_boolean($args[$bool]);
207
+ }
208
+
209
+ $parents = get_ancestors($term->term_id, $term->taxonomy, 'taxonomy');
210
+
211
+ foreach (array_reverse($parents) as $term_id) {
212
+ $parent = get_term($term_id, $term->taxonomy);
213
+
214
+ if ($args['link']) {
215
+ $url = esc_url(get_term_link($parent->term_id, $term->taxonomy));
216
+ $list .= sprintf('<a href="%s">%s</a>', $url, $parent->name);
217
+ } else {
218
+ $list .= $parent->name;
219
+ }
220
+ $list .= $args['separator'];
221
+ }
222
+ } else {
223
+ $list = get_term_parents_list($term->term_id, $term->taxonomy, $args);
224
+ }
225
+
226
+ return $list;
227
+ }
228
+
229
  /**
230
  *
231
  * @return type
Application/Backend/Manager.php CHANGED
@@ -290,12 +290,16 @@ EOT;
290
  AAM_Core_API::clearCache(new AAM_Core_Subject_User($id));
291
 
292
  //check if role has expiration data set
293
- $role = (is_array($user->roles) ? $user->roles[0] : '');
294
- $expire = AAM_Core_API::getOption("aam-role-{$role}-expiration", '');
295
-
296
- if ($expire) {
297
- update_user_option($id, "aam-original-roles", $old->roles);
298
- update_user_option($id, "aam-role-expires", strtotime($expire));
 
 
 
 
299
  }
300
  }
301
  }
@@ -740,7 +744,7 @@ EOT;
740
  public function printJavascript() {
741
  if (AAM::isAAM()) {
742
  wp_enqueue_script('aam-vendor', AAM_MEDIA . '/js/vendor.js');
743
- wp_enqueue_script('aam-main', AAM_MEDIA . '/js/aam-5.7.js');
744
 
745
  //add plugin localization
746
  $this->printLocalization('aam-main');
@@ -883,7 +887,7 @@ EOT;
883
  check_ajax_referer('aam_ajax');
884
 
885
  // flush any output buffer
886
- ob_clean();
887
 
888
  if (AAM::getUser()->hasCapability('aam_manager')) {
889
  $response = AAM_Backend_View::getInstance()->renderContent(
290
  AAM_Core_API::clearCache(new AAM_Core_Subject_User($id));
291
 
292
  //check if role has expiration data set
293
+ // TODO: This supports only the first role and NOT the multi-roles
294
+ if (is_array($user->roles)) {
295
+ $roles = array_values($user->roles);
296
+ $role = array_shift($roles);
297
+ $expire = AAM_Core_API::getOption("aam-role-{$role}-expiration", '');
298
+
299
+ if ($expire) {
300
+ update_user_option($id, "aam-original-roles", $old->roles);
301
+ update_user_option($id, "aam-role-expires", strtotime($expire));
302
+ }
303
  }
304
  }
305
  }
744
  public function printJavascript() {
745
  if (AAM::isAAM()) {
746
  wp_enqueue_script('aam-vendor', AAM_MEDIA . '/js/vendor.js');
747
+ wp_enqueue_script('aam-main', AAM_MEDIA . '/js/aam-5.7.2.js');
748
 
749
  //add plugin localization
750
  $this->printLocalization('aam-main');
887
  check_ajax_referer('aam_ajax');
888
 
889
  // flush any output buffer
890
+ @ob_clean();
891
 
892
  if (AAM::getUser()->hasCapability('aam_manager')) {
893
  $response = AAM_Backend_View::getInstance()->renderContent(
Application/Backend/Subject.php CHANGED
@@ -70,7 +70,11 @@ class AAM_Backend_Subject {
70
  $classname = 'AAM_Core_Subject_' . ucfirst($type);
71
 
72
  if (class_exists($classname)) {
73
- $this->setSubject(new $classname(stripslashes($id)));
 
 
 
 
74
  }
75
  }
76
 
70
  $classname = 'AAM_Core_Subject_' . ucfirst($type);
71
 
72
  if (class_exists($classname)) {
73
+ $subject = new $classname(stripslashes($id));
74
+ // Load access policy
75
+ $subject->getObject('policy');
76
+
77
+ $this->setSubject($subject);
78
  }
79
  }
80
 
Application/Backend/phtml/index.phtml CHANGED
@@ -62,10 +62,12 @@
62
  <span>Extensions</span>
63
  </a>
64
  <?php } ?>
65
- <a href="https://aamplugin.com/help" title="Help" target="_blank">
66
- <i class="icon-help-circled"></i>
67
- <span>Help</span>
68
- </a>
 
 
69
  </div>
70
  </div>
71
  </div>
62
  <span>Extensions</span>
63
  </a>
64
  <?php } ?>
65
+ <?php if (current_user_can('aam_view_help_btn')) { ?>
66
+ <a href="https://aamplugin.com/help" title="Help" target="_blank">
67
+ <i class="icon-help-circled"></i>
68
+ <span>Help</span>
69
+ </a>
70
+ <?php } ?>
71
  </div>
72
  </div>
73
  </div>
Application/Backend/phtml/main/menu.phtml CHANGED
@@ -31,9 +31,9 @@
31
  <a role="button" data-toggle="collapse" data-parent="#admin-menu" href="#menu-<?php echo $i; ?>" aria-controls="menu-<?php echo $i; ?>" <?php if (!$first) { echo 'aria-expanded="true"'; } ?>>
32
  <?php echo $menu['name']; ?> <small class="aam-menu-capability"><?php echo $menu['capability']; ?></small>
33
  </a>
34
- <?php if ($object->has($menu['id'])) { ?>
35
  <i class="aam-panel-title-icon icon-eye-off text-danger"></i>
36
- <?php } elseif ($this->hasSubmenuChecked($object, $menu['submenu'])) { ?>
37
  <i class="aam-panel-title-icon icon-attention-circled text-warning"></i>
38
  <?php } ?>
39
  </h4>
@@ -44,14 +44,14 @@
44
  <?php if ($menu['id'] != 'menu-index.php') { ?>
45
  <div class="row aam-inner-tab">
46
  <div class="col-xs-12 text-center">
47
- <small class="aam-menu-capability"><?php echo __('Menu ID:', AAM_KEY); ?> <b><?php echo crc32($menu['id']); ?></b></small>
48
  </div>
49
  </div>
50
  <hr class="aam-divider" />
51
  <?php } ?>
52
  <?php if (!empty($menu['submenu'])) { ?>
53
  <div class="row aam-inner-tab">
54
- <?php echo ($object->has($menu['id']) ? '<div class="aam-lock"></div>' : ''); ?>
55
  <?php foreach ($menu['submenu'] as $j => $submenu) { ?>
56
  <?php if ($submenu['id'] == 'index.php') { ?>
57
  <div class="col-xs-12 col-md-6 aam-submenu-item">
@@ -64,9 +64,9 @@
64
  <label for="menu-item-<?php echo $i . $j; ?>">
65
  <u><?php echo $submenu['name']; ?></u>
66
  <small class="aam-menu-capability"><?php echo __('Cap:', AAM_KEY), ' <b>', $submenu['capability']; ?></b></small>
67
- <small class="aam-menu-capability"><?php echo __('ID:', AAM_KEY), ' <b>', crc32($submenu['id']); ?></b></small>
68
  </label>
69
- <input type="checkbox" class="aam-checkbox-danger" id="menu-item-<?php echo $i . $j; ?>" data-menu-id="<?php echo $submenu['id']; ?>"<?php echo ($object->has($submenu['id']) ? ' checked="checked"' : ''); ?> />
70
  <label for="menu-item-<?php echo $i . $j; ?>" data-toggle="tooltip" title="<?php echo ($object->has($submenu['id']) ? __('Uncheck to allow', AAM_KEY) : __('Check to restrict', AAM_KEY)); ?>"></label>
71
  </div>
72
  <?php } ?>
@@ -79,7 +79,7 @@
79
  <?php if ($menu['id'] != 'menu-index.php') { ?>
80
  <div class="row<?php echo (!empty($menu['submenu']) ? ' aam-margin-top-xs' : ''); ?>">
81
  <div class="col-xs-10 col-md-6 col-xs-offset-1 col-md-offset-3">
82
- <?php if ($object->has($menu['id'])) { ?>
83
  <a href="#" class="btn btn-primary btn-sm btn-block aam-restrict-menu" data-menu-id="<?php echo $menu['id']; ?>" data-target="#menu-<?php echo $i; ?>">
84
  <i class="icon-eye"></i> <?php echo __('Show Menu', AAM_KEY); ?>
85
  </a>
31
  <a role="button" data-toggle="collapse" data-parent="#admin-menu" href="#menu-<?php echo $i; ?>" aria-controls="menu-<?php echo $i; ?>" <?php if (!$first) { echo 'aria-expanded="true"'; } ?>>
32
  <?php echo $menu['name']; ?> <small class="aam-menu-capability"><?php echo $menu['capability']; ?></small>
33
  </a>
34
+ <?php if ($menu['checked']) { ?>
35
  <i class="aam-panel-title-icon icon-eye-off text-danger"></i>
36
+ <?php } elseif ($this->hasSubmenuChecked($menu['submenu'])) { ?>
37
  <i class="aam-panel-title-icon icon-attention-circled text-warning"></i>
38
  <?php } ?>
39
  </h4>
44
  <?php if ($menu['id'] != 'menu-index.php') { ?>
45
  <div class="row aam-inner-tab">
46
  <div class="col-xs-12 text-center">
47
+ <small class="aam-menu-capability"><?php echo __('Menu ID:', AAM_KEY); ?> <b><?php echo $menu['crc32']; ?></b></small>
48
  </div>
49
  </div>
50
  <hr class="aam-divider" />
51
  <?php } ?>
52
  <?php if (!empty($menu['submenu'])) { ?>
53
  <div class="row aam-inner-tab">
54
+ <?php echo ($menu['checked'] ? '<div class="aam-lock"></div>' : ''); ?>
55
  <?php foreach ($menu['submenu'] as $j => $submenu) { ?>
56
  <?php if ($submenu['id'] == 'index.php') { ?>
57
  <div class="col-xs-12 col-md-6 aam-submenu-item">
64
  <label for="menu-item-<?php echo $i . $j; ?>">
65
  <u><?php echo $submenu['name']; ?></u>
66
  <small class="aam-menu-capability"><?php echo __('Cap:', AAM_KEY), ' <b>', $submenu['capability']; ?></b></small>
67
+ <small class="aam-menu-capability"><?php echo __('ID:', AAM_KEY), ' <b>', $submenu['crc32']; ?></b></small>
68
  </label>
69
+ <input type="checkbox" class="aam-checkbox-danger" id="menu-item-<?php echo $i . $j; ?>" data-menu-id="<?php echo $submenu['id']; ?>"<?php echo ($submenu['checked'] ? ' checked="checked"' : ''); ?> />
70
  <label for="menu-item-<?php echo $i . $j; ?>" data-toggle="tooltip" title="<?php echo ($object->has($submenu['id']) ? __('Uncheck to allow', AAM_KEY) : __('Check to restrict', AAM_KEY)); ?>"></label>
71
  </div>
72
  <?php } ?>
79
  <?php if ($menu['id'] != 'menu-index.php') { ?>
80
  <div class="row<?php echo (!empty($menu['submenu']) ? ' aam-margin-top-xs' : ''); ?>">
81
  <div class="col-xs-10 col-md-6 col-xs-offset-1 col-md-offset-3">
82
+ <?php if ($menu['checked']) { ?>
83
  <a href="#" class="btn btn-primary btn-sm btn-block aam-restrict-menu" data-menu-id="<?php echo $menu['id']; ?>" data-target="#menu-<?php echo $i; ?>">
84
  <i class="icon-eye"></i> <?php echo __('Show Menu', AAM_KEY); ?>
85
  </a>
Application/Backend/phtml/main/metabox.phtml CHANGED
@@ -62,7 +62,7 @@
62
  <div class="col-xs-12 col-md-6 aam-submenu-item">
63
  <label for="metabox-<?php echo $screen; ?>-<?php echo $metabox['id']; ?>">
64
  <u><?php echo $metabox['title']; ?></u>
65
- <small class="aam-metabox-details"><?php echo __('ID:', AAM_KEY); ?> <b><?php echo crc32($screen . $metabox['id']); ?></b></small>
66
  </label>
67
  <input type="checkbox" class="aam-checkbox-danger" id="metabox-<?php echo $screen; ?>-<?php echo $metabox['id']; ?>" data-metabox="<?php echo $screen; ?>|<?php echo $metabox['id']; ?>"<?php echo ($object->has($screen, $metabox['id']) ? ' checked="checked"' : ''); ?> />
68
  <label for="metabox-<?php echo $screen; ?>-<?php echo $metabox['id']; ?>" data-toggle="tooltip" title="<?php echo ($object->has($screen, $metabox['id']) ? __('Uncheck to show', AAM_KEY) : __('Check to hide', AAM_KEY)); ?>"></label>
62
  <div class="col-xs-12 col-md-6 aam-submenu-item">
63
  <label for="metabox-<?php echo $screen; ?>-<?php echo $metabox['id']; ?>">
64
  <u><?php echo $metabox['title']; ?></u>
65
+ <small class="aam-metabox-details"><?php echo __('ID:', AAM_KEY); ?> <b><?php echo crc32($screen . '|' . $metabox['id']); ?></b></small>
66
  </label>
67
  <input type="checkbox" class="aam-checkbox-danger" id="metabox-<?php echo $screen; ?>-<?php echo $metabox['id']; ?>" data-metabox="<?php echo $screen; ?>|<?php echo $metabox['id']; ?>"<?php echo ($object->has($screen, $metabox['id']) ? ' checked="checked"' : ''); ?> />
68
  <label for="metabox-<?php echo $screen; ?>-<?php echo $metabox['id']; ?>" data-toggle="tooltip" title="<?php echo ($object->has($screen, $metabox['id']) ? __('Uncheck to show', AAM_KEY) : __('Check to hide', AAM_KEY)); ?>"></label>
Application/Core/Compatibility.php CHANGED
@@ -35,6 +35,58 @@ class AAM_Core_Compatibility {
35
  return $key;
36
  }
37
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  /**
39
  * Convert all-style AAM settings to standard ConfigPress style settings
40
  *
35
  return $key;
36
  }
37
 
38
+ /**
39
+ * Converting metabox options from 2 dimensional to 1
40
+ *
41
+ * @param array $metaboxes
42
+ *
43
+ * @return array
44
+ * @todo Remove in 2021
45
+ */
46
+ public static function convertMetaboxes($metaboxes) {
47
+ $response = array();
48
+
49
+ if (is_array($metaboxes)) {
50
+ foreach($metaboxes as $key => $value) {
51
+ if (is_array($value)) {
52
+ foreach($value as $id => $grand) {
53
+ $response["{$key}|{$id}"] = $grand;
54
+ }
55
+ } else {
56
+ $response[$key] = $value;
57
+ }
58
+ }
59
+ }
60
+
61
+ return $response;
62
+ }
63
+
64
+ /**
65
+ *
66
+ * @param type $list
67
+ * @return type
68
+ * @todo Remove in 2021
69
+ */
70
+ public static function convertRoute($list) {
71
+ $response = array();
72
+
73
+ if (is_array($list)) {
74
+ foreach($list as $type => $routes) {
75
+ if (is_array($routes)) {
76
+ foreach($routes as $route => $methods) {
77
+ foreach($methods as $method => $grand) {
78
+ $response[strtolower("{$type}|{$route}|{$method}")] = $grand;
79
+ }
80
+ }
81
+ } else {
82
+ $response[$type] = $routes;
83
+ }
84
+ }
85
+ }
86
+
87
+ return $response;
88
+ }
89
+
90
  /**
91
  * Convert all-style AAM settings to standard ConfigPress style settings
92
  *
Application/Core/Exporter.php CHANGED
@@ -120,6 +120,8 @@ class AAM_Core_Exporter {
120
  $this->pushData('options', '/^aam_menu_role/');
121
  } elseif ($feature === 'toolbar') {
122
  $this->pushData('options', '/^aam_toolbar_role/');
 
 
123
  } elseif ($feature === 'route') {
124
  $this->pushData('options', '/^aam_route_role/');
125
  } elseif ($feature === 'metabox') {
@@ -148,6 +150,8 @@ class AAM_Core_Exporter {
148
  $this->pushData('usermeta', '/^' . $wpdb->prefix . 'aam_menu/');
149
  } elseif ($feature === 'toolbar') {
150
  $this->pushData('usermeta', '/^' . $wpdb->prefix . 'aam_toolbar/');
 
 
151
  } elseif ($feature === 'route') {
152
  $this->pushData('usermeta', '/^' . $wpdb->prefix . 'aam_route/');
153
  } elseif ($feature === 'metabox') {
@@ -182,6 +186,8 @@ class AAM_Core_Exporter {
182
  $this->pushData('options', '/^aam_visitor_redirect/');
183
  } elseif ($feature === 'route') {
184
  $this->pushData('options', '/^aam_visitor_route/');
 
 
185
  }
186
  }
187
  }
@@ -200,6 +206,8 @@ class AAM_Core_Exporter {
200
  $this->pushData('options', '/^aam_route_default/');
201
  } elseif ($feature === 'toolbar') {
202
  $this->pushData('options', '/^aam_toolbar_default/');
 
 
203
  } elseif ($feature === 'post') {
204
  $this->pushData('options', '/^aam_type_[\w_\-]_default/');
205
  $this->pushData('options', '/^aam_term_[\d]+\|.+_default/');
120
  $this->pushData('options', '/^aam_menu_role/');
121
  } elseif ($feature === 'toolbar') {
122
  $this->pushData('options', '/^aam_toolbar_role/');
123
+ } elseif ($feature === 'uri') {
124
+ $this->pushData('options', '/^aam_uri_role/');
125
  } elseif ($feature === 'route') {
126
  $this->pushData('options', '/^aam_route_role/');
127
  } elseif ($feature === 'metabox') {
150
  $this->pushData('usermeta', '/^' . $wpdb->prefix . 'aam_menu/');
151
  } elseif ($feature === 'toolbar') {
152
  $this->pushData('usermeta', '/^' . $wpdb->prefix . 'aam_toolbar/');
153
+ } elseif ($feature === 'uri') {
154
+ $this->pushData('usermeta', '/^' . $wpdb->prefix . 'aam_uri/');
155
  } elseif ($feature === 'route') {
156
  $this->pushData('usermeta', '/^' . $wpdb->prefix . 'aam_route/');
157
  } elseif ($feature === 'metabox') {
186
  $this->pushData('options', '/^aam_visitor_redirect/');
187
  } elseif ($feature === 'route') {
188
  $this->pushData('options', '/^aam_visitor_route/');
189
+ } elseif ($feature === 'uri') {
190
+ $this->pushData('options', '/^aam_visitor_uri/');
191
  }
192
  }
193
  }
206
  $this->pushData('options', '/^aam_route_default/');
207
  } elseif ($feature === 'toolbar') {
208
  $this->pushData('options', '/^aam_toolbar_default/');
209
+ } elseif ($feature === 'uri') {
210
+ $this->pushData('options', '/^aam_uri_default/');
211
  } elseif ($feature === 'post') {
212
  $this->pushData('options', '/^aam_type_[\w_\-]_default/');
213
  $this->pushData('options', '/^aam_term_[\d]+\|.+_default/');
Application/Core/Gateway.php CHANGED
@@ -104,7 +104,20 @@ final class AAM_Core_Gateway {
104
  * exact match found
105
  */
106
  public function isAllowed($resource, $action = null) {
107
- return AAM::api()->getUser()->getObject('policy')->isAllowed($resource, $action);
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  }
109
 
110
  /**
104
  * exact match found
105
  */
106
  public function isAllowed($resource, $action = null) {
107
+ $policy = AAM::api()->getUser()->getObject('policy');
108
+
109
+ return $policy->isAllowed($resource, $action);
110
+ }
111
+
112
+ /**
113
+ * Get policy manager
114
+ *
115
+ * @return AAM_Core_Policy_Manager
116
+ *
117
+ * @access public
118
+ */
119
+ public function getPolicyManager() {
120
+ return AAM_Core_Policy_Manager::getInstance();
121
  }
122
 
123
  /**
Application/Core/JwtAuth.php CHANGED
@@ -48,6 +48,7 @@ class AAM_Core_JwtAuth {
48
  * @access public
49
  */
50
  public function registerAPI() {
 
51
  register_rest_route('aam/v1', '/authenticate', array(
52
  'methods' => 'POST',
53
  'callback' => array($this, 'authenticate'),
@@ -62,6 +63,18 @@ class AAM_Core_JwtAuth {
62
  )
63
  ),
64
  ));
 
 
 
 
 
 
 
 
 
 
 
 
65
  }
66
 
67
  /**
@@ -110,6 +123,38 @@ class AAM_Core_JwtAuth {
110
  return apply_filters('aam-jwt-response-filter', $response);
111
  }
112
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  /**
114
  * Generate JWT token
115
  *
@@ -123,7 +168,9 @@ class AAM_Core_JwtAuth {
123
  public function generateJWT($userId, $container = 'header') {
124
  $key = AAM_Core_Config::get('authentication.jwt.secret', SECURE_AUTH_KEY);
125
  $expire = AAM_Core_Config::get('authentication.jwt.expires', 86400);
126
- $container = AAM_Core_Config::get('authentication.jwt.container', $container);
 
 
127
  $alg = AAM_Core_Config::get('authentication.jwt.algorithm', 'HS256');
128
 
129
  if ($key) {
@@ -135,7 +182,7 @@ class AAM_Core_JwtAuth {
135
 
136
  $token = Firebase\JWT\JWT::encode($claims, $key, $alg);
137
 
138
- if ($container === 'cookie') {
139
  setcookie(
140
  'aam-jwt',
141
  $token,
@@ -188,26 +235,38 @@ class AAM_Core_JwtAuth {
188
  * @return type
189
  */
190
  protected function extractJwt() {
191
- $container = AAM_Core_Config::get('authentication.jwt.container', 'header');
 
 
192
 
193
- if ($container === 'header') {
194
- $jwt = apply_filters(
195
- 'aam-jwt-authentication-header-filter',
196
- AAM_Core_Request::server('HTTP_AUTHENTICATION')
197
- );
198
- } elseif ($container === 'cookie') {
199
- $jwt = apply_filters(
200
- 'aam-jwt-authentication-cookie-filter',
201
- AAM_Core_Request::cookie('aam-jwt')
202
- );
203
- } else {
204
- AAM_Core_Console::add(
205
- sprint_f(
206
- __('Invalid value %s for property %s', AAM_KEY),
207
- $container,
208
- 'authentication.jwt.container'
209
- )
210
- );
 
 
 
 
 
 
 
 
 
 
211
  }
212
 
213
  return (!empty($jwt) ? preg_replace('/^Bearer /', '', $jwt) : null);
48
  * @access public
49
  */
50
  public function registerAPI() {
51
+ // Authenticate user
52
  register_rest_route('aam/v1', '/authenticate', array(
53
  'methods' => 'POST',
54
  'callback' => array($this, 'authenticate'),
63
  )
64
  ),
65
  ));
66
+
67
+ // Validate JWT token
68
+ register_rest_route('aam/v1', '/validate-jwt', array(
69
+ 'methods' => 'POST',
70
+ 'callback' => array($this, 'validateJWT'),
71
+ 'args' => array(
72
+ 'jwt' => array(
73
+ 'description' => __('JWT token.', AAM_KEY),
74
+ 'type' => 'string',
75
+ )
76
+ ),
77
+ ));
78
  }
79
 
80
  /**
123
  return apply_filters('aam-jwt-response-filter', $response);
124
  }
125
 
126
+ /**
127
+ *
128
+ * @param WP_REST_Request $request
129
+ */
130
+ public function validateJWT(WP_REST_Request $request) {
131
+ $jwt = $request->get_param('jwt');
132
+ $key = AAM_Core_Config::get('authentication.jwt.secret', SECURE_AUTH_KEY);
133
+
134
+ $response = new WP_REST_Response(array(
135
+ 'status' => 'invalid'
136
+ ), 400);
137
+
138
+ if (!empty($jwt)) {
139
+ try {
140
+ $claims = Firebase\JWT\JWT::decode(
141
+ $jwt, $key, array_keys(Firebase\JWT\JWT::$supported_algs)
142
+ );
143
+
144
+ if (isset($claims->userId)) {
145
+ $response->status = 200;
146
+ $response->data = array (
147
+ 'status' => 'valid'
148
+ );
149
+ }
150
+ } catch (Exception $ex) {
151
+ // Do nothing
152
+ }
153
+ }
154
+
155
+ return $response;
156
+ }
157
+
158
  /**
159
  * Generate JWT token
160
  *
168
  public function generateJWT($userId, $container = 'header') {
169
  $key = AAM_Core_Config::get('authentication.jwt.secret', SECURE_AUTH_KEY);
170
  $expire = AAM_Core_Config::get('authentication.jwt.expires', 86400);
171
+ $container = explode(
172
+ ',', AAM_Core_Config::get('authentication.jwt.container', $container)
173
+ );
174
  $alg = AAM_Core_Config::get('authentication.jwt.algorithm', 'HS256');
175
 
176
  if ($key) {
182
 
183
  $token = Firebase\JWT\JWT::encode($claims, $key, $alg);
184
 
185
+ if (in_array('cookie', $container, true)) {
186
  setcookie(
187
  'aam-jwt',
188
  $token,
235
  * @return type
236
  */
237
  protected function extractJwt() {
238
+ $container = explode(',', AAM_Core_Config::get(
239
+ 'authentication.jwt.container', 'header'
240
+ ));
241
 
242
+ $jwt = null;
243
+
244
+ foreach($container as $method) {
245
+ switch(strtolower(trim($method))) {
246
+ case 'header':
247
+ $jwt = AAM_Core_Request::server('HTTP_AUTHENTICATION');
248
+ break;
249
+
250
+ case 'cookie':
251
+ $jwt = AAM_Core_Request::cookie('aam-jwt');
252
+ break;
253
+
254
+ case 'query':
255
+ $jwt = AAM_Core_Request::get('aam-jwt');
256
+ break;
257
+
258
+ case 'post':
259
+ $jwt = AAM_Core_Request::post('aam-jwt');
260
+ break;
261
+
262
+ default:
263
+ $jwt = apply_filters('aam-get-jwt-filter', null, $method);
264
+ break;
265
+ }
266
+
267
+ if (!is_null($jwt)) {
268
+ break;
269
+ }
270
  }
271
 
272
  return (!empty($jwt) ? preg_replace('/^Bearer /', '', $jwt) : null);
Application/Core/Object/Capability.php CHANGED
@@ -27,17 +27,32 @@ class AAM_Core_Object_Capability extends AAM_Core_Object {
27
  public function __construct(AAM_Core_Subject $subject) {
28
  parent::__construct($subject);
29
 
30
- $this->setOption($this->getSubject()->getCapabilities());
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
  //check if capabilities are overwritten but only for user subject
33
  if (is_a($this->getSubject(), 'AAM_Core_Subject_User')) {
34
- $caps = get_user_option(
35
  AAM_Core_Subject_User::AAM_CAPKEY, $this->getSubject()->getId()
36
  );
37
- if (!empty($caps)) {
 
38
  $this->setOverwritten(true);
39
  }
40
  }
 
 
41
  }
42
 
43
  /**
27
  public function __construct(AAM_Core_Subject $subject) {
28
  parent::__construct($subject);
29
 
30
+ $caps = $this->getSubject()->getCapabilities();
31
+
32
+ // Load Capabilities from the policy
33
+ $stms = AAM_Core_Policy_Manager::getInstance()->find(
34
+ "/^Capability:/i", $subject
35
+ );
36
+
37
+ foreach($stms as $key => $stm) {
38
+ $chunks = explode(':', $key);
39
+ if (count($chunks) === 2) {
40
+ $caps[$chunks[1]] = ($stm['Effect'] === 'allow' ? 1 : 0);
41
+ }
42
+ }
43
 
44
  //check if capabilities are overwritten but only for user subject
45
  if (is_a($this->getSubject(), 'AAM_Core_Subject_User')) {
46
+ $userCaps = get_user_option(
47
  AAM_Core_Subject_User::AAM_CAPKEY, $this->getSubject()->getId()
48
  );
49
+ if (!empty($userCaps)) {
50
+ $caps = array_merge($caps, $userCaps);
51
  $this->setOverwritten(true);
52
  }
53
  }
54
+
55
+ $this->setOption($caps);
56
  }
57
 
58
  /**
Application/Core/Object/Menu.php CHANGED
@@ -29,10 +29,25 @@ class AAM_Core_Object_Menu extends AAM_Core_Object {
29
 
30
  $option = $this->getSubject()->readOption('menu');
31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  if (empty($option)) {
33
  $option = $this->getSubject()->inheritFromParent('menu');
34
- } else {
35
- $this->setOverwritten(true);
36
  }
37
 
38
  $this->setOption($option);
@@ -104,6 +119,27 @@ class AAM_Core_Object_Menu extends AAM_Core_Object {
104
 
105
  return $menu;
106
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
 
108
  /**
109
  * Filter submenu
@@ -190,20 +226,14 @@ class AAM_Core_Object_Menu extends AAM_Core_Object {
190
  $options = $this->getOption();
191
  $parent = $this->getParentMenu($decoded);
192
 
193
- // Policy API
194
- $api = AAM::api();
195
- $crc = crc32($decoded);
196
- $bcrc = crc32('menu-' . $decoded);
197
- $pcrc = crc32('menu-' . $parent);
198
-
199
  // Step #1. Check if menu is directly restricted
200
- $direct = !empty($options[$decoded]) || ($api->isAllowed("BackendMenu:{$crc}") === false);
201
 
202
  // Step #2. Check if whole branch is restricted
203
- $branch = ($both && (!empty($options['menu-' . $decoded]) || ($api->isAllowed("BackendMenu:{$bcrc}") === false)));
204
 
205
  // Step #3. Check if dynamic submenu is restricted because of whole branch
206
- $indirect = ($parent && (!empty($options['menu-' . $parent]) || ($api->isAllowed("BackendMenu:{$pcrc}") === false)));
207
 
208
  return $direct || $branch || $indirect;
209
  }
29
 
30
  $option = $this->getSubject()->readOption('menu');
31
 
32
+ if (!empty($option)) {
33
+ $this->setOverwritten(true);
34
+ }
35
+
36
+ // Load settings from Access & Security Policy
37
+ if (empty($option)) {
38
+ $stms = AAM_Core_Policy_Manager::getInstance()->find(
39
+ "/^BackendMenu:/i", $subject
40
+ );
41
+
42
+ foreach($stms as $key => $stm) {
43
+ $chunks = explode(':', $key);
44
+ $option[$chunks[1]] = ($stm['Effect'] === 'deny' ? 1 : 0);
45
+ }
46
+ }
47
+
48
+ // Finally try to load from parent
49
  if (empty($option)) {
50
  $option = $this->getSubject()->inheritFromParent('menu');
 
 
51
  }
52
 
53
  $this->setOption($option);
119
 
120
  return $menu;
121
  }
122
+
123
+ /**
124
+ * Update single option item
125
+ *
126
+ * @param string $item
127
+ * @param mixed $value
128
+ *
129
+ * @return boolean Always true
130
+ *
131
+ * @access public
132
+ */
133
+ public function updateOptionItem($item, $value) {
134
+ $option = $this->getOption();
135
+
136
+ $option[$item] = $value;
137
+ $option[crc32($item)] = $value;
138
+
139
+ $this->setOption($option);
140
+
141
+ return true;
142
+ }
143
 
144
  /**
145
  * Filter submenu
226
  $options = $this->getOption();
227
  $parent = $this->getParentMenu($decoded);
228
 
 
 
 
 
 
 
229
  // Step #1. Check if menu is directly restricted
230
+ $direct = !empty($options[$decoded]) || !empty($options[crc32($decoded)]);
231
 
232
  // Step #2. Check if whole branch is restricted
233
+ $branch = ($both && (!empty($options['menu-' . $decoded]) || !empty($options[crc32('menu-' . $decoded)])));
234
 
235
  // Step #3. Check if dynamic submenu is restricted because of whole branch
236
+ $indirect = ($parent && (!empty($options['menu-' . $parent]) || !empty($options[crc32('menu-' . $parent)])));
237
 
238
  return $direct || $branch || $indirect;
239
  }
Application/Core/Object/Metabox.php CHANGED
@@ -27,12 +27,28 @@ class AAM_Core_Object_Metabox extends AAM_Core_Object {
27
  public function __construct(AAM_Core_Subject $subject) {
28
  parent::__construct($subject);
29
 
30
- $option = $this->getSubject()->readOption('metabox');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
  if (empty($option)) {
33
  $option = $this->getSubject()->inheritFromParent('metabox');
34
- } else {
35
- $this->setOverwritten(true);
36
  }
37
 
38
  $this->setOption($option);
@@ -143,10 +159,10 @@ class AAM_Core_Object_Metabox extends AAM_Core_Object {
143
  * @inheritdoc
144
  */
145
  public function save($metabox, $granted) {
146
- $param = explode('|', $metabox);
147
  $option = $this->getOption();
148
 
149
- $option[$param[0]][$param[1]] = $granted;
 
150
 
151
  return $this->getSubject()->updateOption($option, 'metabox');
152
  }
@@ -166,12 +182,9 @@ class AAM_Core_Object_Metabox extends AAM_Core_Object {
166
  */
167
  public function has($screen, $metabox) {
168
  $options = $this->getOption();
 
169
 
170
- $area = ($screen === 'widgets' ? 'Widget' : 'Metabox');
171
- $uid = crc32($screen . $metabox);
172
- $isAllowed = AAM::api()->isAllowed("{$area}:{$uid}");
173
-
174
- return !empty($options[$screen][$metabox]) || ($isAllowed === false);
175
  }
176
 
177
  /**
27
  public function __construct(AAM_Core_Subject $subject) {
28
  parent::__construct($subject);
29
 
30
+ $option = AAM_Core_Compatibility::convertMetaboxes(
31
+ $this->getSubject()->readOption('metabox')
32
+ );
33
+
34
+ if (!empty($option)) {
35
+ $this->setOverwritten(true);
36
+ }
37
+
38
+ // Load settings from Access & Security Policy
39
+ if (empty($option)) {
40
+ $stms = AAM_Core_Policy_Manager::getInstance()->find(
41
+ "/^(Metabox|Widget):/i", $subject
42
+ );
43
+
44
+ foreach($stms as $key => $stm) {
45
+ $chunks = explode(':', $key);
46
+ $option[$chunks[1]] = ($stm['Effect'] === 'deny' ? 1 : 0);
47
+ }
48
+ }
49
 
50
  if (empty($option)) {
51
  $option = $this->getSubject()->inheritFromParent('metabox');
 
 
52
  }
53
 
54
  $this->setOption($option);
159
  * @inheritdoc
160
  */
161
  public function save($metabox, $granted) {
 
162
  $option = $this->getOption();
163
 
164
+ $option[$metabox] = $granted;
165
+ $option[crc32($metabox)] = $granted;
166
 
167
  return $this->getSubject()->updateOption($option, 'metabox');
168
  }
182
  */
183
  public function has($screen, $metabox) {
184
  $options = $this->getOption();
185
+ $mid = "{$screen}|{$metabox}";
186
 
187
+ return !empty($options[$mid]) || !empty($options[crc32($mid)]);
 
 
 
 
188
  }
189
 
190
  /**
Application/Core/Object/Policy.php CHANGED
@@ -16,10 +16,16 @@
16
  class AAM_Core_Object_Policy extends AAM_Core_Object {
17
 
18
  /**
19
- *
20
- * @var type
 
 
 
 
 
 
21
  */
22
- protected $resources = array();
23
 
24
  /**
25
  * Constructor
@@ -33,12 +39,21 @@ class AAM_Core_Object_Policy extends AAM_Core_Object {
33
  public function __construct(AAM_Core_Subject $subject) {
34
  parent::__construct($subject);
35
 
36
- $parent = $this->getSubject()->inheritFromParent('policy');
 
 
 
 
 
 
 
 
 
37
  if(empty($parent)) {
38
  $parent = array();
39
  }
40
 
41
- $option = $this->getSubject()->readOption('policy');
42
  if (empty($option)) {
43
  $option = array();
44
  } else {
@@ -50,36 +65,41 @@ class AAM_Core_Object_Policy extends AAM_Core_Object {
50
  }
51
 
52
  $this->setOption($parent);
 
 
 
 
 
53
  }
54
 
55
  /**
56
  *
57
  */
58
- public function load() {
59
  $resources = array();
60
-
61
- foreach($this->loadStatements() as $statement) {
62
  if (isset($statement['Resource']) && $this->applicable($statement)) {
63
  $this->evaluateStatement($statement, $resources);
64
  }
65
  }
66
 
67
- $this->resources = $resources;
68
  }
69
 
70
  /**
71
  *
72
  * @return type
73
  */
74
- protected function loadStatements() {
75
  $cache = AAM::api()->getUser()->getObject('cache');
76
- $statements = $cache->get('policyStatements', 0, null);
77
-
78
  // Step #1. Extract all statements
79
  if (is_null($statements)) {
80
  $statements = array();
81
 
82
- foreach($this->getOption() as $id => $effect) {
83
  if ($effect) {
84
  $policy = get_post($id);
85
 
@@ -93,7 +113,7 @@ class AAM_Core_Object_Policy extends AAM_Core_Object {
93
  }
94
  }
95
  }
96
- $cache->add('policyStatements', 0, $statements);
97
  }
98
 
99
  return $statements;
@@ -597,10 +617,11 @@ class AAM_Core_Object_Policy extends AAM_Core_Object {
597
  public function isAllowed($resource, $action = null) {
598
  $allowed = null;
599
 
600
- $id = strtolower($resource . (!empty($action) ? ":{$action}" : ''));
 
601
 
602
- if (isset($this->resources[$id])) {
603
- $allowed = ($this->resources[$id]['Effect'] === 'allow');
604
  }
605
 
606
  return $allowed;
@@ -631,4 +652,31 @@ class AAM_Core_Object_Policy extends AAM_Core_Object {
631
  return AAM::api()->mergeSettings($external, $this->getOption(), 'policy');
632
  }
633
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
634
  }
16
  class AAM_Core_Object_Policy extends AAM_Core_Object {
17
 
18
  /**
19
+ * Resource tree
20
+ *
21
+ * Shared resource tree across all the policy instances
22
+ *
23
+ * @var array
24
+ *
25
+ * @access protected
26
+ * @static
27
  */
28
+ protected static $resources = array();
29
 
30
  /**
31
  * Constructor
39
  public function __construct(AAM_Core_Subject $subject) {
40
  parent::__construct($subject);
41
 
42
+ $this->initialize(); // Read options from the database table first
43
+ }
44
+
45
+ /**
46
+ *
47
+ */
48
+ public function initialize() {
49
+ $subject = $this->getSubject();
50
+ $parent = $subject->inheritFromParent('policy');
51
+
52
  if(empty($parent)) {
53
  $parent = array();
54
  }
55
 
56
+ $option = $subject->readOption('policy');
57
  if (empty($option)) {
58
  $option = array();
59
  } else {
65
  }
66
 
67
  $this->setOption($parent);
68
+
69
+ // Load statements for policies
70
+ $subjectId = $subject->getUID();
71
+ $subjectId .= ($subject->getId() ? ".{$subject->getId()}" : '');
72
+ $this->load($subjectId, $option);
73
  }
74
 
75
  /**
76
  *
77
  */
78
+ public function load($subjectId, $policies) {
79
  $resources = array();
80
+
81
+ foreach($this->loadStatements($subjectId, $policies) as $statement) {
82
  if (isset($statement['Resource']) && $this->applicable($statement)) {
83
  $this->evaluateStatement($statement, $resources);
84
  }
85
  }
86
 
87
+ self::$resources[$subjectId] = $resources;
88
  }
89
 
90
  /**
91
  *
92
  * @return type
93
  */
94
+ protected function loadStatements($subjectId, $policies) {
95
  $cache = AAM::api()->getUser()->getObject('cache');
96
+ $statements = $cache->get('policy', $subjectId, null);
97
+
98
  // Step #1. Extract all statements
99
  if (is_null($statements)) {
100
  $statements = array();
101
 
102
+ foreach($policies as $id => $effect) {
103
  if ($effect) {
104
  $policy = get_post($id);
105
 
113
  }
114
  }
115
  }
116
+ $cache->add('policy', $subjectId, $statements);
117
  }
118
 
119
  return $statements;
617
  public function isAllowed($resource, $action = null) {
618
  $allowed = null;
619
 
620
+ $id = strtolower($resource . (!empty($action) ? ":{$action}" : ''));
621
+ $res = $this->getResources();
622
 
623
+ if (isset($res[$id])) {
624
+ $allowed = ($res[$id]['Effect'] === 'allow');
625
  }
626
 
627
  return $allowed;
652
  return AAM::api()->mergeSettings($external, $this->getOption(), 'policy');
653
  }
654
 
655
+ /**
656
+ *
657
+ * @return type
658
+ */
659
+ public function getResources(AAM_Core_Subject $subject = null) {
660
+ $response = array();
661
+
662
+ if (is_null($subject)) {
663
+ if (!isset(self::$resources['__combined'])) {
664
+ foreach(self::$resources as $resources) {
665
+ $response = array_merge($resources, $response);
666
+ }
667
+ self::$resources['__combined'] = $response;
668
+ } else {
669
+ $response = self::$resources['__combined'];
670
+ }
671
+ } else {
672
+ $subjectId = $subject->getUID();
673
+ $subjectId .= ($subject->getId() ? ".{$subject->getId()}" : '');
674
+
675
+ if (isset(self::$resources[$subjectId])) {
676
+ $response = self::$resources[$subjectId];
677
+ }
678
+ }
679
+
680
+ return $response;
681
+ }
682
  }
Application/Core/Object/Post.php CHANGED
@@ -40,7 +40,7 @@ class AAM_Core_Object_Post extends AAM_Core_Object {
40
  //make sure that we are dealing with WP_Post object
41
  if (is_object($post)) {
42
  $this->setPost($post);
43
- } elseif (intval($post)) {
44
  $this->setPost(get_post($post));
45
  }
46
 
@@ -93,6 +93,23 @@ class AAM_Core_Object_Post extends AAM_Core_Object {
93
  $option = get_post_meta($post->ID, $this->getOptionName(), true);
94
  $this->setOverwritten(!empty($option));
95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  // Inherit from terms or default settings - AAM Plus Package
97
  if (empty($option)) {
98
  $option = apply_filters('aam-post-access-filter', $option, $this);
40
  //make sure that we are dealing with WP_Post object
41
  if (is_object($post)) {
42
  $this->setPost($post);
43
+ } elseif (is_numeric($post)) {
44
  $this->setPost(get_post($post));
45
  }
46
 
93
  $option = get_post_meta($post->ID, $this->getOptionName(), true);
94
  $this->setOverwritten(!empty($option));
95
 
96
+ // Read settings from access policy
97
+ if (empty($option)) {
98
+ $stms = AAM_Core_Policy_Manager::getInstance()->find(
99
+ "/^post:{$post->post_type}:({$post->post_name}|{$post->ID}):/",
100
+ $subject
101
+ );
102
+
103
+ foreach($stms as $key => $stm) {
104
+ // TODO: Prepare better conversion from policy Action to AAM
105
+ // post & term action. For example listToOthers -> list_others
106
+ $chunks = explode(':', $key);
107
+ $option["frontend.{$chunks[3]}"] = $stm['Effect'] === 'deny';
108
+ $option["backend.{$chunks[3]}"] = $stm['Effect'] === 'deny';
109
+ $option["api.{$chunks[3]}"] = $stm['Effect'] === 'deny';
110
+ }
111
+ }
112
+
113
  // Inherit from terms or default settings - AAM Plus Package
114
  if (empty($option)) {
115
  $option = apply_filters('aam-post-access-filter', $option, $this);
Application/Core/Object/Route.php CHANGED
@@ -27,12 +27,30 @@ class AAM_Core_Object_Route extends AAM_Core_Object {
27
  public function __construct(AAM_Core_Subject $subject) {
28
  parent::__construct($subject);
29
 
30
- $option = $this->getSubject()->readOption('route');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
  if (empty($option)) {
33
  $option = $this->getSubject()->inheritFromParent('route');
34
- } else {
35
- $this->setOverwritten(true);
36
  }
37
 
38
  $this->setOption($option);
@@ -51,8 +69,9 @@ class AAM_Core_Object_Route extends AAM_Core_Object {
51
  */
52
  public function has($type, $route, $method = 'POST') {
53
  $options = $this->getOption();
 
54
 
55
- return !empty($options[$type][$route][$method]);
56
  }
57
 
58
  /**
@@ -64,7 +83,10 @@ class AAM_Core_Object_Route extends AAM_Core_Object {
64
  */
65
  public function save($type, $route, $method, $value) {
66
  $option = $this->getOption();
67
- $option[$type][$route][$method] = $value;
 
 
 
68
  $this->setOption($option);
69
 
70
  return $this->getSubject()->updateOption($this->getOption(), 'route');
27
  public function __construct(AAM_Core_Subject $subject) {
28
  parent::__construct($subject);
29
 
30
+ $option = AAM_Core_Compatibility::convertRoute(
31
+ $this->getSubject()->readOption('route')
32
+ );
33
+
34
+ if (!empty($option)) {
35
+ $this->setOverwritten(true);
36
+ }
37
+
38
+ // Load settings from Access & Security Policy
39
+ if (empty($option)) {
40
+ $stms = AAM_Core_Policy_Manager::getInstance()->find(
41
+ "/^Route:/i", $subject
42
+ );
43
+
44
+ foreach($stms as $key => $stm) {
45
+ $chunks = explode(':', $key);
46
+ $id = "{$chunks[1]}|{$chunks[2]}|{$chunks[3]}";
47
+
48
+ $option[$id] = ($stm['Effect'] === 'deny' ? 1 : 0);
49
+ }
50
+ }
51
 
52
  if (empty($option)) {
53
  $option = $this->getSubject()->inheritFromParent('route');
 
 
54
  }
55
 
56
  $this->setOption($option);
69
  */
70
  public function has($type, $route, $method = 'POST') {
71
  $options = $this->getOption();
72
+ $id = strtolower("{$type}|{$route}|{$method}");
73
 
74
+ return !empty($options[$id]);
75
  }
76
 
77
  /**
83
  */
84
  public function save($type, $route, $method, $value) {
85
  $option = $this->getOption();
86
+
87
+ $id = strtolower("{$type}|{$route}|{$method}");
88
+ $option[$id] = $value;
89
+
90
  $this->setOption($option);
91
 
92
  return $this->getSubject()->updateOption($this->getOption(), 'route');
Application/Core/Object/Toolbar.php CHANGED
@@ -29,10 +29,24 @@ class AAM_Core_Object_Toolbar extends AAM_Core_Object {
29
 
30
  $option = $this->getSubject()->readOption('toolbar');
31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  if (empty($option)) {
33
  $option = $this->getSubject()->inheritFromParent('toolbar');
34
- } else {
35
- $this->setOverwritten(true);
36
  }
37
 
38
  $this->setOption($option);
@@ -52,14 +66,11 @@ class AAM_Core_Object_Toolbar extends AAM_Core_Object {
52
  public function has($item, $both = false) {
53
  $options = $this->getOption();
54
 
55
- // Policy API
56
- $api = AAM::api();
57
-
58
  // Step #1. Check if toolbar item is directly restricted
59
- $direct = !empty($options[$item]) || ($api->isAllowed("Toolbar:{$item}") === false);
60
 
61
  // Step #2. Check if whole branch is restricted
62
- $branch = ($both && (!empty($options['toolbar-' . $item]) || ($api->isAllowed("Toolbar:toolbar-{$item}") === false)));
63
 
64
  return $direct || $branch;
65
  }
29
 
30
  $option = $this->getSubject()->readOption('toolbar');
31
 
32
+ if (!empty($option)) {
33
+ $this->setOverwritten(true);
34
+ }
35
+
36
+ // Load settings from Access & Security Policy
37
+ if (empty($option)) {
38
+ $stms = AAM_Core_Policy_Manager::getInstance()->find(
39
+ "/^Toolbar:/i", $subject
40
+ );
41
+
42
+ foreach($stms as $key => $stm) {
43
+ $chunks = explode(':', $key);
44
+ $option[$chunks[1]] = ($stm['Effect'] === 'deny' ? 1 : 0);
45
+ }
46
+ }
47
+
48
  if (empty($option)) {
49
  $option = $this->getSubject()->inheritFromParent('toolbar');
 
 
50
  }
51
 
52
  $this->setOption($option);
66
  public function has($item, $both = false) {
67
  $options = $this->getOption();
68
 
 
 
 
69
  // Step #1. Check if toolbar item is directly restricted
70
+ $direct = !empty($options[$item]);
71
 
72
  // Step #2. Check if whole branch is restricted
73
+ $branch = ($both && !empty($options['toolbar-' . $item]));
74
 
75
  return $direct || $branch;
76
  }
Application/Core/Object/Uri.php CHANGED
@@ -29,10 +29,67 @@ class AAM_Core_Object_Uri extends AAM_Core_Object {
29
 
30
  $option = $this->getSubject()->readOption('uri');
31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  if (empty($option)) {
33
  $option = $this->getSubject()->inheritFromParent('uri');
34
- } else {
35
- $this->setOverwritten(true);
36
  }
37
 
38
  $this->setOption($option);
@@ -115,5 +172,14 @@ class AAM_Core_Object_Uri extends AAM_Core_Object {
115
  public function reset() {
116
  return $this->getSubject()->deleteOption('uri');
117
  }
 
 
 
 
 
 
 
 
 
118
 
119
  }
29
 
30
  $option = $this->getSubject()->readOption('uri');
31
 
32
+ if (!empty($option)) {
33
+ $this->setOverwritten(true);
34
+ }
35
+
36
+ if (empty($option)) {
37
+ $stms = AAM_Core_Policy_Manager::getInstance()->find(
38
+ "/^URI:/i", $subject
39
+ );
40
+
41
+ foreach($stms as $key => $stm) {
42
+ $chunks = explode(':', $key);
43
+ $effect = ($stm['Effect'] === 'deny' ? 1 : 0);
44
+ $type = $stm['Effect'];
45
+ $destination = null;
46
+
47
+ if ($effect === 1 && !empty($stm['Metadata']['Redirect'])) {
48
+ $type = strtolower($stm['Metadata']['Redirect']['Type']);
49
+
50
+ switch($type) {
51
+ case 'message':
52
+ $destination = $stm['Metadata']['Redirect']['Message'];
53
+ break;
54
+
55
+ case 'page':
56
+ if (isset($stm['Metadata']['Redirect']['Id'])) {
57
+ $destination = intval($stm['Metadata']['Redirect']['Id']);
58
+ } elseif (isset($stm['Metadata']['Redirect']['Slug'])) {
59
+ $page = $post = get_page_by_path(
60
+ $stm['Metadata']['Redirect']['Slug'], OBJECT
61
+ );
62
+ $destination = (is_a($page, 'WP_Post') ? $page->ID : 0);
63
+ }
64
+ break;
65
+
66
+ case 'url':
67
+ $destination = filter_var(
68
+ $stm['Metadata']['Redirect']['URL'],
69
+ FILTER_VALIDATE_URL
70
+ );
71
+ if (empty($destination)) {
72
+ $type = 'message';
73
+ $destination = "Invalid URL: [{$stm['Metadata']['Redirect']['URL']}]";
74
+ }
75
+ break;
76
+
77
+ case 'callback':
78
+ $destination = $stm['Metadata']['Redirect']['Callback'];
79
+ break;
80
+ }
81
+ }
82
+
83
+ $option[crc32($chunks[1] . $type. $destination)] = array(
84
+ 'uri' => $chunks[1],
85
+ 'type' => $type,
86
+ 'action' => $destination
87
+ );
88
+ }
89
+ }
90
+
91
  if (empty($option)) {
92
  $option = $this->getSubject()->inheritFromParent('uri');
 
 
93
  }
94
 
95
  $this->setOption($option);
172
  public function reset() {
173
  return $this->getSubject()->deleteOption('uri');
174
  }
175
+
176
+ /**
177
+ *
178
+ * @param type $external
179
+ * @return type
180
+ */
181
+ public function mergeOption($external) {
182
+ return array_merge($external, $this->getOption());
183
+ }
184
 
185
  }
Application/Core/Object/Visibility.php CHANGED
@@ -45,7 +45,8 @@ class AAM_Core_Object_Visibility extends AAM_Core_Object {
45
  if ($option === false) { //if false, then the cache is empty but exists
46
  $option = array();
47
  } elseif (empty($option)) {
48
- $query = "SELECT pm.`post_id`, pm.`meta_value`, p.`post_type` FROM {$wpdb->postmeta} AS pm ";
 
49
  $query .= "LEFT JOIN {$wpdb->posts} AS p ON (pm.`post_id` = p.ID) ";
50
  $query .= "WHERE pm.`meta_key` = %s";
51
 
@@ -56,6 +57,36 @@ class AAM_Core_Object_Visibility extends AAM_Core_Object {
56
  }
57
  }
58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  do_action('aam-visibility-initialize-action', $this);
60
 
61
  // inherit settings from parent
45
  if ($option === false) { //if false, then the cache is empty but exists
46
  $option = array();
47
  } elseif (empty($option)) {
48
+ $query = "SELECT pm.`post_id`, pm.`meta_value`, p.`post_type` ";
49
+ $query .= "FROM {$wpdb->postmeta} AS pm ";
50
  $query .= "LEFT JOIN {$wpdb->posts} AS p ON (pm.`post_id` = p.ID) ";
51
  $query .= "WHERE pm.`meta_key` = %s";
52
 
57
  }
58
  }
59
 
60
+ // Read all the settings from the Access & Security Policies
61
+ $area = AAM_Core_Api_Area::get();
62
+ $stms = AAM_Core_Policy_Manager::getInstance()->find(
63
+ "/^post:(.*):(list|listtoothers)$/",
64
+ $subject
65
+ );
66
+
67
+ foreach($stms as $key => $stm) {
68
+ $chunks = explode(':', $key);
69
+
70
+ $action = ($chunks[3] === 'listtoothers' ? 'list_others' : 'list');
71
+
72
+ if (is_numeric($chunks[2])) {
73
+ $postId = $chunks[2];
74
+ } else {
75
+ $post = get_page_by_path(
76
+ $chunks[2], OBJECT, $chunks[1]
77
+ );
78
+ $postId = (is_a($post, 'WP_Post') ? $post->ID : 0);
79
+ }
80
+
81
+ $this->pushOptions(
82
+ 'post',
83
+ "{$postId}|{$chunks[1]}",
84
+ array(
85
+ "{$area}.{$action}" => ($stm['Effect'] === 'deny' ? 1 : 0)
86
+ )
87
+ );
88
+ }
89
+
90
  do_action('aam-visibility-initialize-action', $this);
91
 
92
  // inherit settings from parent
Application/Core/Policy/Manager.php ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * ======================================================================
5
+ * LICENSE: This file is subject to the terms and conditions defined in *
6
+ * file 'license.txt', which is part of this source code package. *
7
+ * ======================================================================
8
+ */
9
+
10
+ /**
11
+ * AAM core policy manager
12
+ *
13
+ * @package AAM
14
+ * @author Vasyl Martyniuk <vasyl@vasyltech.com>
15
+ * @since AAM v5.7.2
16
+ */
17
+ final class AAM_Core_Policy_Manager {
18
+
19
+ /**
20
+ * Single instance of itself
21
+ *
22
+ * @var AAM_Core_Policy_Manager
23
+ *
24
+ * @access private
25
+ * @static
26
+ */
27
+ private static $_instance = null;
28
+
29
+ /**
30
+ * Policy core object
31
+ *
32
+ * @var AAM_Core_Object_Policy
33
+ *
34
+ * @access protected
35
+ */
36
+ protected $policyObject;
37
+
38
+ /**
39
+ * Constructor
40
+ *
41
+ * @access protected
42
+ *
43
+ * @return void
44
+ */
45
+ protected function __construct() {
46
+ $this->policyObject = AAM::getUser()->getObject('policy');
47
+ }
48
+
49
+ /**
50
+ * Find all the matching policies
51
+ *
52
+ * @param string $s RegEx
53
+ * @param AAM_Core_Subject $subject Subject to search for
54
+ *
55
+ * @return array
56
+ *
57
+ * @access public
58
+ */
59
+ public function find($s, AAM_Core_Subject $subject = null) {
60
+ $statements = array();
61
+
62
+ // Get list of policies
63
+ if (is_null($subject)) {
64
+ $policies = $this->policyObject;
65
+ } else {
66
+ $policies = $subject->getObject('policy');
67
+ }
68
+
69
+ foreach($policies->getResources($subject) as $key => $stm) {
70
+ if (preg_match($s, $key)) {
71
+ $statements[strtolower($key)] = $stm;
72
+ }
73
+ }
74
+
75
+ return $statements;
76
+ }
77
+
78
+ /**
79
+ * Get single instance of itself
80
+ *
81
+ * @return AAM_Core_Policy_Manager
82
+ *
83
+ * @access public
84
+ * @static
85
+ */
86
+ public static function getInstance() {
87
+ if (is_null(self::$_instance)) {
88
+ self::$_instance = new self();
89
+ }
90
+
91
+ return self::$_instance;
92
+ }
93
+
94
+ /**
95
+ * Load the policy manager
96
+ *
97
+ * @return void
98
+ *
99
+ * @access public
100
+ * @static
101
+ */
102
+ public static function bootstrap() {
103
+ self::getInstance();
104
+ }
105
+ }
Application/Core/Subject.php CHANGED
@@ -252,7 +252,6 @@ abstract class AAM_Core_Subject {
252
  }
253
  } else {
254
  $object = $this->_objects[$type][$id];
255
- $object->initialize();
256
  }
257
 
258
  return $object;
252
  }
253
  } else {
254
  $object = $this->_objects[$type][$id];
 
255
  }
256
 
257
  return $object;
Application/Core/Subject/Role.php CHANGED
@@ -127,6 +127,28 @@ class AAM_Core_Subject_Role extends AAM_Core_Subject {
127
  public function getCapabilities() {
128
  return $this->getSubject()->capabilities;
129
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
 
131
  /**
132
  *
127
  public function getCapabilities() {
128
  return $this->getSubject()->capabilities;
129
  }
130
+
131
+ /**
132
+ * Check if subject has capability
133
+ *
134
+ * @param string $cap
135
+ *
136
+ * @return boolean
137
+ *
138
+ * @access public
139
+ */
140
+ public function hasCapability($cap) {
141
+ $has = $this->getSubject()->has_cap($cap);
142
+
143
+ // Override by policy if is set
144
+ $stm = AAM::api()->getPolicyManager()->find("/^Capability:{$cap}$/i", $this);
145
+ if (!empty($stm)) {
146
+ $val = end($stm);
147
+ $has = ($val['Effect'] === 'allow' ? 1 : 0);
148
+ }
149
+
150
+ return $has;
151
+ }
152
 
153
  /**
154
  *
Application/Core/Subject/User.php CHANGED
@@ -170,26 +170,47 @@ class AAM_Core_Subject_User extends AAM_Core_Subject {
170
  * @access protected
171
  */
172
  protected function retrieveSubject() {
173
- $subject = new WP_User($this->getId());
174
-
175
- //retrieve aam capabilities if are not retrieved yet
176
- $caps = get_user_option(self::AAM_CAPKEY, $this->getId());
177
- if (is_array($caps)) {
178
- $caps = array_merge($subject->caps, $caps);
179
- $allcaps = array_merge($subject->allcaps, $caps);
180
-
181
- //reset the user capabilities
182
- $subject->allcaps = $allcaps;
183
- $subject->caps = $caps;
184
-
185
- if (wp_get_current_user()->ID === $subject->ID) {
186
- wp_get_current_user()->allcaps = $allcaps;
187
- wp_get_current_user()->caps = $caps;
188
- }
189
  }
190
 
191
  return $subject;
192
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
 
194
  /**
195
  * Get user capabilities
170
  * @access protected
171
  */
172
  protected function retrieveSubject() {
173
+ if ($this->getId() === get_current_user_id()) {
174
+ $subject = wp_get_current_user();
175
+ } else {
176
+ $subject = new WP_User($this->getId());