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 | 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 +46 -1
- Application/Backend/Feature/Main/Capability.php +22 -6
- Application/Backend/Feature/Main/Menu.php +16 -8
- Application/Backend/Feature/Main/Policy.php +6 -10
- Application/Backend/Feature/Main/Post.php +46 -10
- Application/Backend/Manager.php +12 -8
- Application/Backend/Subject.php +5 -1
- Application/Backend/phtml/index.phtml +6 -4
- Application/Backend/phtml/main/menu.phtml +7 -7
- Application/Backend/phtml/main/metabox.phtml +1 -1
- Application/Core/Compatibility.php +52 -0
- Application/Core/Exporter.php +8 -0
- Application/Core/Gateway.php +14 -1
- Application/Core/JwtAuth.php +80 -21
- Application/Core/Object/Capability.php +18 -3
- Application/Core/Object/Menu.php +41 -11
- Application/Core/Object/Metabox.php +23 -10
- Application/Core/Object/Policy.php +65 -17
- Application/Core/Object/Post.php +18 -1
- Application/Core/Object/Route.php +27 -5
- Application/Core/Object/Toolbar.php +18 -7
- Application/Core/Object/Uri.php +68 -2
- Application/Core/Object/Visibility.php +32 -1
- Application/Core/Policy/Manager.php +105 -0
- Application/Core/Subject.php +0 -1
- Application/Core/Subject/Role.php +22 -0
- Application/Core/Subject/User.php +37 -16
- Application/Extension/Repository.php +4 -4
- Application/Shared/Manager.php +69 -69
- aam.php +5 -2
- media/js/{aam-5.7.js → aam-5.7.2.js} +2 -2
- readme.txt +20 -4
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 |
-
$
|
|
|
|
|
|
|
|
|
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}
|
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}
|
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}
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
254 |
|
255 |
foreach (array_keys($caps) as $cap) {
|
256 |
-
if (AAM::api()->isAllowed("Capability:{$cap}
|
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 |
-
$
|
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 |
-
$
|
123 |
-
|
|
|
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($
|
159 |
$has = false;
|
160 |
|
161 |
if (!empty($subs)) {
|
162 |
foreach($subs as $submenu) {
|
163 |
-
if ($
|
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 |
-
|
35 |
-
|
36 |
-
|
37 |
-
$effect = AAM_Core_Request::post('effect');
|
38 |
|
39 |
-
|
40 |
-
|
41 |
|
42 |
-
|
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(
|
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 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
|
|
|
|
|
|
|
|
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 |
-
$
|
|
|
|
|
|
|
|
|
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 |
-
|
66 |
-
<
|
67 |
-
|
68 |
-
|
|
|
|
|
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 ($
|
35 |
<i class="aam-panel-title-icon icon-eye-off text-danger"></i>
|
36 |
-
<?php } elseif ($this->hasSubmenuChecked($
|
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
|
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 ($
|
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>',
|
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 ($
|
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 ($
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 =
|
|
|
|
|
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
|
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 =
|
|
|
|
|
192 |
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
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 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
|
32 |
//check if capabilities are overwritten but only for user subject
|
33 |
if (is_a($this->getSubject(), 'AAM_Core_Subject_User')) {
|
34 |
-
$
|
35 |
AAM_Core_Subject_User::AAM_CAPKEY, $this->getSubject()->getId()
|
36 |
);
|
37 |
-
if (!empty($
|
|
|
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]) || ($
|
201 |
|
202 |
// Step #2. Check if whole branch is restricted
|
203 |
-
$branch = ($both && (!empty($options['menu-' . $decoded]) || ($
|
204 |
|
205 |
// Step #3. Check if dynamic submenu is restricted because of whole branch
|
206 |
-
$indirect = ($parent && (!empty($options['menu-' . $parent]) || ($
|
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 =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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[$
|
|
|
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 |
-
|
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 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
if(empty($parent)) {
|
38 |
$parent = array();
|
39 |
}
|
40 |
|
41 |
-
$option = $
|
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 |
-
$
|
68 |
}
|
69 |
|
70 |
/**
|
71 |
*
|
72 |
* @return type
|
73 |
*/
|
74 |
-
protected function loadStatements() {
|
75 |
$cache = AAM::api()->getUser()->getObject('cache');
|
76 |
-
$statements = $cache->get('
|
77 |
-
|
78 |
// Step #1. Extract all statements
|
79 |
if (is_null($statements)) {
|
80 |
$statements = array();
|
81 |
|
82 |
-
foreach($
|
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('
|
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
|
|
|
601 |
|
602 |
-
if (isset($
|
603 |
-
$allowed = ($
|
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 (
|
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 =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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[$
|
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 |
-
|
|
|
|
|
|
|
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])
|
60 |
|
61 |
// Step #2. Check if whole branch is restricted
|
62 |
-
$branch = ($both &&
|
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`
|
|
|
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 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
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());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
177 |
}
|
178 |
|
179 |
return $subject;
|
180 |
}
|
181 |
+
|
182 |
+
/**
|
183 |
+
*
|
184 |
+
*/
|
185 |
+
public function loadCapabilities() {
|
186 |
+
$subject = $this->getSubject();
|
187 |
+
|
188 |
+
// Retrieve all capabilities set in Access Policy
|
189 |
+
// Load Capabilities from the policy
|
190 |
+
$stms = AAM_Core_Policy_Manager::getInstance()->find("/^Capability:/i");
|
191 |
+
|
192 |
+
$policyCaps = array();
|
193 |
+
|
194 |
+
foreach($stms as $key => $stm) {
|
195 |
+
$chunks = explode(':', $key);
|
196 |
+
if (count($chunks) === 2) {
|
197 |
+
$policyCaps[$chunks[1]] = ($stm['Effect'] === 'allow' ? 1 : 0);
|
198 |
+
}
|
199 |
+
}
|
200 |
+
|
201 |
+
//reset the user capabilities
|
202 |
+
$subject->allcaps = array_merge($subject->allcaps, $policyCaps);
|
203 |
+
$subject->caps = array_merge($subject->caps, $policyCaps);
|
204 |
+
|
205 |
+
// Retrieve user capabilities set with AAM
|
206 |
+
$userCaps = get_user_option(self::AAM_CAPKEY, $this->getId());
|
207 |
+
|
208 |
+
if (is_array($userCaps)) {
|
209 |
+
//reset the user capabilities
|
210 |
+
$subject->allcaps = array_merge($subject->allcaps, $userCaps);
|
211 |
+
$subject->caps = array_merge($subject->caps, $userCaps);
|
212 |
+
}
|
213 |
+
}
|
214 |
|
215 |
/**
|
216 |
* Get user capabilities
|
Application/Extension/Repository.php
CHANGED
@@ -139,14 +139,14 @@ class AAM_Extension_Repository {
|
|
139 |
|
140 |
// determin if extension meets minimum required AAM version
|
141 |
$list = AAM_Extension_List::get();
|
142 |
-
$
|
143 |
-
$load = $status &&
|
144 |
|
145 |
-
if (
|
146 |
if (!empty($list[$conf['id']]['title'])) { // Any custom extensions
|
147 |
AAM_Core_Console::add(AAM_Backend_View_Helper::preparePhrase(
|
148 |
sprintf(
|
149 |
-
__('[%s] was not loaded. Update
|
150 |
$list[$conf['id']]['title']
|
151 |
),
|
152 |
'b'
|
139 |
|
140 |
// determin if extension meets minimum required AAM version
|
141 |
$list = AAM_Extension_List::get();
|
142 |
+
$issue = !empty($conf['requires']['aam']) && (version_compare(AAM_Core_API::version(), $conf['requires']['aam']) === -1);
|
143 |
+
$load = $status && !$issue;
|
144 |
|
145 |
+
if ($issue) {
|
146 |
if (!empty($list[$conf['id']]['title'])) { // Any custom extensions
|
147 |
AAM_Core_Console::add(AAM_Backend_View_Helper::preparePhrase(
|
148 |
sprintf(
|
149 |
+
__('[%s] was not loaded. Update AAM plugin to the latest version.', AAM_KEY),
|
150 |
$list[$conf['id']]['title']
|
151 |
),
|
152 |
'b'
|
Application/Shared/Manager.php
CHANGED
@@ -92,7 +92,7 @@ class AAM_Shared_Manager {
|
|
92 |
|
93 |
// Check if user has ability to perform certain task based on provided
|
94 |
// capability and meta data
|
95 |
-
add_filter('
|
96 |
|
97 |
// Security. Make sure that we escaping all translation strings
|
98 |
add_filter(
|
@@ -273,7 +273,7 @@ class AAM_Shared_Manager {
|
|
273 |
} else {
|
274 |
$query = '';
|
275 |
}
|
276 |
-
|
277 |
$clauses['where'] .= apply_filters(
|
278 |
'aam-post-where-clause-filter', $query, $wpQuery, $option
|
279 |
);
|
@@ -434,61 +434,67 @@ class AAM_Shared_Manager {
|
|
434 |
*
|
435 |
* @access public
|
436 |
*/
|
437 |
-
public function
|
438 |
-
|
439 |
-
$uid = (isset($args[2]) && is_numeric($args[2]) ? $args[2] : 0);
|
440 |
-
|
441 |
-
// Apply policy first
|
442 |
-
$effect = AAM::api()->isAllowed("Capability:{$capability}");
|
443 |
-
|
444 |
-
if ($effect !== null) {
|
445 |
-
$caps = $this->updateCapabilities($caps, $meta, $effect);
|
446 |
-
}
|
447 |
|
448 |
-
switch($
|
449 |
case 'edit_user':
|
450 |
case 'delete_user':
|
451 |
-
$caps = $this->authorizeUserUpdate($
|
452 |
break;
|
453 |
|
454 |
case 'edit_post':
|
455 |
-
|
|
|
456 |
break;
|
457 |
|
458 |
case 'delete_post':
|
459 |
-
|
|
|
460 |
break;
|
461 |
|
462 |
-
case '
|
463 |
-
case '
|
464 |
-
$caps = $this->
|
|
|
|
|
|
|
|
|
465 |
break;
|
466 |
|
467 |
case 'install_plugins':
|
468 |
-
$caps = $this->checkPluginsAction('install', $caps, $
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
469 |
break;
|
470 |
|
471 |
case 'delete_plugins':
|
472 |
-
$caps = $this->checkPluginsAction('delete', $caps, $
|
473 |
break;
|
474 |
|
475 |
case 'edit_plugins':
|
476 |
-
$caps = $this->checkPluginsAction('edit', $caps, $
|
477 |
break;
|
478 |
|
479 |
case 'update_plugins':
|
480 |
-
$caps = $this->checkPluginsAction('update', $caps, $
|
481 |
break;
|
482 |
|
483 |
case 'activate_plugin':
|
484 |
$caps = $this->checkPluginAction(
|
485 |
-
(isset($args[
|
486 |
);
|
487 |
break;
|
488 |
|
489 |
case 'deactivate_plugin':
|
490 |
$caps = $this->checkPluginAction(
|
491 |
-
(isset($args[
|
492 |
);
|
493 |
break;
|
494 |
|
@@ -503,14 +509,14 @@ class AAM_Shared_Manager {
|
|
503 |
*
|
504 |
* @param type $action
|
505 |
* @param type $caps
|
506 |
-
* @param type $
|
507 |
* @return type
|
508 |
*/
|
509 |
-
protected function checkPluginsAction($action, $caps, $
|
510 |
$allow = AAM::api()->isAllowed("Plugin", "WP:{$action}");
|
511 |
|
512 |
if ($allow !== null) {
|
513 |
-
$caps = $
|
514 |
}
|
515 |
|
516 |
return $caps;
|
@@ -521,18 +527,16 @@ class AAM_Shared_Manager {
|
|
521 |
* @param type $plugin
|
522 |
* @param type $action
|
523 |
* @param type $caps
|
524 |
-
* @param type $
|
525 |
* @return type
|
526 |
*/
|
527 |
-
protected function checkPluginAction($plugin, $action, $caps, $
|
528 |
$parts = explode('/', $plugin);
|
529 |
$slug = (!empty($parts[0]) ? $parts[0] : null);
|
530 |
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
$caps = $this->updateCapabilities($caps, $meta, $allow);
|
535 |
-
}
|
536 |
}
|
537 |
|
538 |
return $caps;
|
@@ -612,8 +616,8 @@ class AAM_Shared_Manager {
|
|
612 |
*
|
613 |
* @access protected
|
614 |
*/
|
615 |
-
protected function authorizeUserUpdate($
|
616 |
-
$user = new WP_User($
|
617 |
|
618 |
//current user max level
|
619 |
$maxLevel = AAM_Core_API::maxLevel(AAM::getUser()->allcaps);
|
@@ -621,10 +625,10 @@ class AAM_Shared_Manager {
|
|
621 |
$userLevel = AAM_Core_API::maxLevel($user->allcaps);
|
622 |
|
623 |
if ($maxLevel < $userLevel) {
|
624 |
-
$
|
625 |
}
|
626 |
|
627 |
-
return $
|
628 |
}
|
629 |
|
630 |
/**
|
@@ -638,16 +642,16 @@ class AAM_Shared_Manager {
|
|
638 |
*
|
639 |
* @access protected
|
640 |
*/
|
641 |
-
protected function authorizePostEdit($
|
642 |
$object = AAM::getUser()->getObject('post', $id);
|
643 |
$draft = $object->post_status === 'auto-draft';
|
644 |
$area = AAM_Core_Api_Area::get();
|
645 |
|
646 |
-
if (!$draft && !$object->allowed($area . '.edit')) {
|
647 |
-
$
|
648 |
}
|
649 |
|
650 |
-
return $
|
651 |
}
|
652 |
|
653 |
/**
|
@@ -661,15 +665,15 @@ class AAM_Shared_Manager {
|
|
661 |
*
|
662 |
* @access protected
|
663 |
*/
|
664 |
-
protected function authorizePostDelete($
|
665 |
$object = AAM::getUser()->getObject('post', $id);
|
666 |
$area = AAM_Core_Api_Area::get();
|
667 |
|
668 |
if (!$object->allowed($area . '.delete')) {
|
669 |
-
$
|
670 |
}
|
671 |
|
672 |
-
return $
|
673 |
}
|
674 |
|
675 |
/**
|
@@ -683,42 +687,37 @@ class AAM_Shared_Manager {
|
|
683 |
* @access protected
|
684 |
* @global WP_Post $post
|
685 |
*/
|
686 |
-
protected function authorizePublishPost($
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
$
|
692 |
-
|
693 |
-
if (!$object->allowed($area . '.publish')) {
|
694 |
-
$allcaps = $this->updateCapabilities($allcaps, $metacaps);
|
695 |
-
}
|
696 |
}
|
697 |
|
698 |
-
return $
|
699 |
}
|
700 |
|
701 |
/**
|
702 |
-
*
|
703 |
-
*
|
704 |
-
* Iterate through the list of meta capabilities and disable them in the
|
705 |
-
* list of all user capabilities. Keep in mind that this disable caps only
|
706 |
-
* for one time call.
|
707 |
*
|
708 |
-
* @param array $
|
709 |
-
* @param array $
|
710 |
-
* @param bool $allow
|
711 |
*
|
712 |
* @return array
|
713 |
*
|
714 |
* @access protected
|
|
|
715 |
*/
|
716 |
-
protected function
|
717 |
-
|
718 |
-
|
|
|
|
|
|
|
719 |
}
|
720 |
|
721 |
-
return $
|
722 |
}
|
723 |
|
724 |
/**
|
@@ -736,4 +735,5 @@ class AAM_Shared_Manager {
|
|
736 |
|
737 |
return self::$_instance;
|
738 |
}
|
|
|
739 |
}
|
92 |
|
93 |
// Check if user has ability to perform certain task based on provided
|
94 |
// capability and meta data
|
95 |
+
add_filter('map_meta_cap', array(self::$_instance, 'mapMetaCaps'), 999, 4);
|
96 |
|
97 |
// Security. Make sure that we escaping all translation strings
|
98 |
add_filter(
|
273 |
} else {
|
274 |
$query = '';
|
275 |
}
|
276 |
+
|
277 |
$clauses['where'] .= apply_filters(
|
278 |
'aam-post-where-clause-filter', $query, $wpQuery, $option
|
279 |
);
|
434 |
*
|
435 |
* @access public
|
436 |
*/
|
437 |
+
public function mapMetaCaps($caps, $cap, $user_id, $args) {
|
438 |
+
global $post;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
439 |
|
440 |
+
switch($cap) {
|
441 |
case 'edit_user':
|
442 |
case 'delete_user':
|
443 |
+
$caps = $this->authorizeUserUpdate($caps, $args[0]);
|
444 |
break;
|
445 |
|
446 |
case 'edit_post':
|
447 |
+
case 'edit_page':
|
448 |
+
$caps = $this->authorizePostEdit($caps, $args[0]);
|
449 |
break;
|
450 |
|
451 |
case 'delete_post':
|
452 |
+
case 'delete_page':
|
453 |
+
$caps = $this->authorizePostDelete($caps, $args[0]);
|
454 |
break;
|
455 |
|
456 |
+
case 'read_post':
|
457 |
+
case 'read_page':
|
458 |
+
$caps = $this->authorizePostRead($caps, $args[0]);
|
459 |
+
break;
|
460 |
+
|
461 |
+
case 'publish_post':
|
462 |
+
$caps = $this->authorizePublishPost($caps, $args[0]);
|
463 |
break;
|
464 |
|
465 |
case 'install_plugins':
|
466 |
+
$caps = $this->checkPluginsAction('install', $caps, $cap);
|
467 |
+
break;
|
468 |
+
|
469 |
+
case 'publish_posts':
|
470 |
+
// There is a bug in WP core that instead of checking if user has
|
471 |
+
// ability to publish_post, it checks for edit_post
|
472 |
+
if (is_a($post, 'WP_Post')) {
|
473 |
+
$caps = $this->authorizePublishPost($caps, $post->ID);
|
474 |
+
}
|
475 |
break;
|
476 |
|
477 |
case 'delete_plugins':
|
478 |
+
$caps = $this->checkPluginsAction('delete', $caps, $cap);
|
479 |
break;
|
480 |
|
481 |
case 'edit_plugins':
|
482 |
+
$caps = $this->checkPluginsAction('edit', $caps, $cap);
|
483 |
break;
|
484 |
|
485 |
case 'update_plugins':
|
486 |
+
$caps = $this->checkPluginsAction('update', $caps, $cap);
|
487 |
break;
|
488 |
|
489 |
case 'activate_plugin':
|
490 |
$caps = $this->checkPluginAction(
|
491 |
+
(isset($args[0]) ? $args[0] : ''), 'activate', $caps, $cap
|
492 |
);
|
493 |
break;
|
494 |
|
495 |
case 'deactivate_plugin':
|
496 |
$caps = $this->checkPluginAction(
|
497 |
+
(isset($args[0]) ? $args[0] : ''), 'deactivate', $caps, $cap
|
498 |
);
|
499 |
break;
|
500 |
|
509 |
*
|
510 |
* @param type $action
|
511 |
* @param type $caps
|
512 |
+
* @param type $cap
|
513 |
* @return type
|
514 |
*/
|
515 |
+
protected function checkPluginsAction($action, $caps, $cap) {
|
516 |
$allow = AAM::api()->isAllowed("Plugin", "WP:{$action}");
|
517 |
|
518 |
if ($allow !== null) {
|
519 |
+
$caps[] = $allow ? $cap : 'do_not_allow';
|
520 |
}
|
521 |
|
522 |
return $caps;
|
527 |
* @param type $plugin
|
528 |
* @param type $action
|
529 |
* @param type $caps
|
530 |
+
* @param type $cap
|
531 |
* @return type
|
532 |
*/
|
533 |
+
protected function checkPluginAction($plugin, $action, $caps, $cap) {
|
534 |
$parts = explode('/', $plugin);
|
535 |
$slug = (!empty($parts[0]) ? $parts[0] : null);
|
536 |
|
537 |
+
$allow = AAM::api()->isAllowed("Plugin:{$slug}", "WP:{$action}");
|
538 |
+
if ($allow !== null) {
|
539 |
+
$caps[] = $allow ? $cap : 'do_not_allow';
|
|
|
|
|
540 |
}
|
541 |
|
542 |
return $caps;
|
616 |
*
|
617 |
* @access protected
|
618 |
*/
|
619 |
+
protected function authorizeUserUpdate($caps, $userId) {
|
620 |
+
$user = new WP_User($userId);
|
621 |
|
622 |
//current user max level
|
623 |
$maxLevel = AAM_Core_API::maxLevel(AAM::getUser()->allcaps);
|
625 |
$userLevel = AAM_Core_API::maxLevel($user->allcaps);
|
626 |
|
627 |
if ($maxLevel < $userLevel) {
|
628 |
+
$caps[] = 'do_not_allow';
|
629 |
}
|
630 |
|
631 |
+
return $caps;
|
632 |
}
|
633 |
|
634 |
/**
|
642 |
*
|
643 |
* @access protected
|
644 |
*/
|
645 |
+
protected function authorizePostEdit($caps, $id) {
|
646 |
$object = AAM::getUser()->getObject('post', $id);
|
647 |
$draft = $object->post_status === 'auto-draft';
|
648 |
$area = AAM_Core_Api_Area::get();
|
649 |
|
650 |
+
if (!$draft && (!$object->allowed($area . '.edit') )) {
|
651 |
+
$caps[] = 'do_not_allow';
|
652 |
}
|
653 |
|
654 |
+
return $caps;
|
655 |
}
|
656 |
|
657 |
/**
|
665 |
*
|
666 |
* @access protected
|
667 |
*/
|
668 |
+
protected function authorizePostDelete($caps, $id) {
|
669 |
$object = AAM::getUser()->getObject('post', $id);
|
670 |
$area = AAM_Core_Api_Area::get();
|
671 |
|
672 |
if (!$object->allowed($area . '.delete')) {
|
673 |
+
$caps[] = 'do_not_allow';
|
674 |
}
|
675 |
|
676 |
+
return $caps;
|
677 |
}
|
678 |
|
679 |
/**
|
687 |
* @access protected
|
688 |
* @global WP_Post $post
|
689 |
*/
|
690 |
+
protected function authorizePublishPost($caps, $id) {
|
691 |
+
$object = AAM::getUser()->getObject('post', $id);
|
692 |
+
$area = AAM_Core_Api_Area::get();
|
693 |
+
|
694 |
+
if (!$object->allowed($area . '.publish')) {
|
695 |
+
$caps[] = 'do_not_allow';
|
|
|
|
|
|
|
|
|
696 |
}
|
697 |
|
698 |
+
return $caps;
|
699 |
}
|
700 |
|
701 |
/**
|
702 |
+
* Check if user is allowed to publish post
|
|
|
|
|
|
|
|
|
703 |
*
|
704 |
+
* @param array $allcaps
|
705 |
+
* @param array $metacaps
|
|
|
706 |
*
|
707 |
* @return array
|
708 |
*
|
709 |
* @access protected
|
710 |
+
* @global WP_Post $post
|
711 |
*/
|
712 |
+
protected function authorizePostRead($caps, $id) {
|
713 |
+
$object = AAM::getUser()->getObject('post', $id);
|
714 |
+
$area = AAM_Core_Api_Area::get();
|
715 |
+
|
716 |
+
if (!$object->allowed($area . '.read')) {
|
717 |
+
$caps[] = 'do_not_allow';
|
718 |
}
|
719 |
|
720 |
+
return $caps;
|
721 |
}
|
722 |
|
723 |
/**
|
735 |
|
736 |
return self::$_instance;
|
737 |
}
|
738 |
+
|
739 |
}
|
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.7.
|
7 |
Author: Vasyl Martyniuk <vasyl@vasyltech.com>
|
8 |
Author URI: https://vasyltech.com
|
9 |
|
@@ -124,7 +124,7 @@ class AAM {
|
|
124 |
}
|
125 |
|
126 |
// Load Access/Security Policies
|
127 |
-
|
128 |
|
129 |
//load WP Core hooks
|
130 |
AAM_Shared_Manager::bootstrap();
|
@@ -172,6 +172,9 @@ class AAM {
|
|
172 |
if (is_null(self::$_instance)) {
|
173 |
self::$_instance = new self;
|
174 |
|
|
|
|
|
|
|
175 |
// Logout user if he/she is blocked
|
176 |
self::$_instance->getUser()->validateUserStatus();
|
177 |
|
3 |
/**
|
4 |
Plugin Name: Advanced Access Manager
|
5 |
Description: All you need to manage access to your WordPress website
|
6 |
+
Version: 5.7.2
|
7 |
Author: Vasyl Martyniuk <vasyl@vasyltech.com>
|
8 |
Author URI: https://vasyltech.com
|
9 |
|
124 |
}
|
125 |
|
126 |
// Load Access/Security Policies
|
127 |
+
AAM_Core_Policy_Manager::bootstrap();
|
128 |
|
129 |
//load WP Core hooks
|
130 |
AAM_Shared_Manager::bootstrap();
|
172 |
if (is_null(self::$_instance)) {
|
173 |
self::$_instance = new self;
|
174 |
|
175 |
+
// Load user capabilities
|
176 |
+
self::$_instance->getUser()->loadCapabilities();
|
177 |
+
|
178 |
// Logout user if he/she is blocked
|
179 |
self::$_instance->getUser()->validateUserStatus();
|
180 |
|
media/js/{aam-5.7.js → aam-5.7.2.js}
RENAMED
@@ -406,7 +406,7 @@
|
|
406 |
id: data[0]
|
407 |
},
|
408 |
$('#object-id').val(),
|
409 |
-
1,
|
410 |
this
|
411 |
);
|
412 |
}));
|
@@ -424,7 +424,7 @@
|
|
424 |
id: data[0]
|
425 |
},
|
426 |
$('#object-id').val(),
|
427 |
-
0,
|
428 |
this
|
429 |
);
|
430 |
}));
|
406 |
id: data[0]
|
407 |
},
|
408 |
$('#object-id').val(),
|
409 |
+
($(this).hasClass('icon-check-empty') ? 1 : 0),
|
410 |
this
|
411 |
);
|
412 |
}));
|
424 |
id: data[0]
|
425 |
},
|
426 |
$('#object-id').val(),
|
427 |
+
($(this).hasClass('icon-check') ? 0 : 1),
|
428 |
this
|
429 |
);
|
430 |
}));
|
readme.txt
CHANGED
@@ -1,9 +1,9 @@
|
|
1 |
=== Advanced Access Manager ===
|
2 |
Contributors: vasyltech
|
3 |
-
Tags: access control, membership, backend menu, user role, restricted content
|
4 |
Requires at least: 4.0
|
5 |
-
Tested up to:
|
6 |
-
Stable tag: 5.7.
|
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 |
|
@@ -15,8 +15,8 @@ https://www.youtube.com/watch?v=mj5Xa_Wc16Y
|
|
15 |
|
16 |
= Few Quick Facts =
|
17 |
|
|
|
18 |
* Bullet-proven plugin that is used on over 90,000 websites where all features are well-tested and [documented](https://aamplugin.com/help). Very low amount of support tickets speaks for quality;
|
19 |
-
* AAM contains the most powerful and flexible set of features to manage access to your WordPress website and were majority of them are absolutely free;
|
20 |
* It is the only plugin that gives you the ability to manage access to your website content for any role, individual user and visitors or even define the default access to all posts, pages, custom post types, categories and custom hierarchical taxonomies;
|
21 |
* AAM is [developer oriented plugin](https://aamplugin.com/developers). It has dozens of hooks and configurations. It is integrated with WordPress RESTful and XML-RPC APIs and has numerous abstract layers to simplify coding;
|
22 |
* No ads or other promotional crap. The UI is clean and well crafted so you can focus only on what matters;
|
@@ -25,6 +25,7 @@ https://www.youtube.com/watch?v=mj5Xa_Wc16Y
|
|
25 |
|
26 |
= Main Areas Of Focus =
|
27 |
|
|
|
28 |
* Content access control on frontend, backend and API sides to posts, pages, custom post types, categories, custom hierarchical taxonomies and CPTs for any role, user and visitors;
|
29 |
* Roles & capabilities management with ability to create new roles and capabilities, edit, clone or delete existing;
|
30 |
* Access control to backend area including backend menu, toolbar, metaboxes & widgets;
|
@@ -42,6 +43,7 @@ https://www.youtube.com/watch?v=mj5Xa_Wc16Y
|
|
42 |
* [free] Backend Lockdown. Restrict access to your website backend side for any user or role. Find out more from [How to lockdown WordPress backend](https://aamplugin.com/help/how-to-lockdown-wordpress-backend) article;
|
43 |
* [free] Secure Login Widget & Shortcode. Drop AJAX login widget or shortcode anywhere on your website. Find out more from [How does AAM Secure Login works](https://aamplugin.com/help/how-does-aam-secure-login-works) article;
|
44 |
* [free] Ability to enable/disable RESTful and XML-RPC APIs.
|
|
|
45 |
* [free] Manage access to RESTful or XML-RPC individual endpoints for any role, user or visitors.
|
46 |
* [free] JWT authentication. Authenticate user with WordPress RESTful API and use received JWT token for further requests. Fid out more from [Hot to authenticate WordPress user with JWT token](https://aamplugin.com/help/how-to-authenticate-wordpress-user-with-jwt-token)
|
47 |
* [free] Content Filter. Filter or replace parts of your content with AAM shortcodes. Find out more from [How to filter WordPress post content](https://aamplugin.com/help/how-to-filter-wordpress-post-content) article;
|
@@ -76,6 +78,20 @@ https://www.youtube.com/watch?v=mj5Xa_Wc16Y
|
|
76 |
|
77 |
== Changelog ==
|
78 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
= 5.7.1 =
|
80 |
* Fixed the bug with AAM notifications related to extension updates
|
81 |
* Fixed the bug with AAM not taking in consideration capabilities that defined in policy
|
1 |
=== Advanced Access Manager ===
|
2 |
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.0.2
|
6 |
+
Stable tag: 5.7.2
|
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 |
|
15 |
|
16 |
= Few Quick Facts =
|
17 |
|
18 |
+
* The only plugin that gives you absolute freedom to define the most granular access to any aspect of your website and most of the feature are free;
|
19 |
* Bullet-proven plugin that is used on over 90,000 websites where all features are well-tested and [documented](https://aamplugin.com/help). Very low amount of support tickets speaks for quality;
|
|
|
20 |
* It is the only plugin that gives you the ability to manage access to your website content for any role, individual user and visitors or even define the default access to all posts, pages, custom post types, categories and custom hierarchical taxonomies;
|
21 |
* AAM is [developer oriented plugin](https://aamplugin.com/developers). It has dozens of hooks and configurations. It is integrated with WordPress RESTful and XML-RPC APIs and has numerous abstract layers to simplify coding;
|
22 |
* No ads or other promotional crap. The UI is clean and well crafted so you can focus only on what matters;
|
25 |
|
26 |
= Main Areas Of Focus =
|
27 |
|
28 |
+
* [Access & Security Policy](https://aamplugin.com/access-and-security-policy) allows you to define who, when, how and under what conditions your website resources can be accessed;
|
29 |
* Content access control on frontend, backend and API sides to posts, pages, custom post types, categories, custom hierarchical taxonomies and CPTs for any role, user and visitors;
|
30 |
* Roles & capabilities management with ability to create new roles and capabilities, edit, clone or delete existing;
|
31 |
* Access control to backend area including backend menu, toolbar, metaboxes & widgets;
|
43 |
* [free] Backend Lockdown. Restrict access to your website backend side for any user or role. Find out more from [How to lockdown WordPress backend](https://aamplugin.com/help/how-to-lockdown-wordpress-backend) article;
|
44 |
* [free] Secure Login Widget & Shortcode. Drop AJAX login widget or shortcode anywhere on your website. Find out more from [How does AAM Secure Login works](https://aamplugin.com/help/how-does-aam-secure-login-works) article;
|
45 |
* [free] Ability to enable/disable RESTful and XML-RPC APIs.
|
46 |
+
* [limited] URI Access. Allow or deny access to any page of you website by the page URL as well as how to redirect user when access is denied;
|
47 |
* [free] Manage access to RESTful or XML-RPC individual endpoints for any role, user or visitors.
|
48 |
* [free] JWT authentication. Authenticate user with WordPress RESTful API and use received JWT token for further requests. Fid out more from [Hot to authenticate WordPress user with JWT token](https://aamplugin.com/help/how-to-authenticate-wordpress-user-with-jwt-token)
|
49 |
* [free] Content Filter. Filter or replace parts of your content with AAM shortcodes. Find out more from [How to filter WordPress post content](https://aamplugin.com/help/how-to-filter-wordpress-post-content) article;
|
78 |
|
79 |
== Changelog ==
|
80 |
|
81 |
+
= 5.7.2 =
|
82 |
+
* Fixed bug with Posts & Terms feature for WP version under 4.8
|
83 |
+
* Fixed bug were Access Policy can't be attached to any principal on the Policy edit screen
|
84 |
+
* Fixed bug with Access URI options were not merged for users with multiple roles
|
85 |
+
* Fixed bug with Access URI options were not exported
|
86 |
+
* Fixed but with Post PUBLISH option due to the fact that Gutenberg is using RESTful API
|
87 |
+
* Extended Access & Security Policy to support Posts & Terms options
|
88 |
+
* Added /validate-jwt RESTful API endpoint to validate JWT
|
89 |
+
* Added ability to extract JWT token from GET queries or POST payload
|
90 |
+
* Added custom capability aam_view_help_btn to hide HELP icon on AAM UI
|
91 |
+
* Significantly improved capability mapping mechanism and access control based on caps
|
92 |
+
* Added URI Access support to Access & Security Policy
|
93 |
+
* Added Post, Term, PostType support to Access & Security Policy
|
94 |
+
|
95 |
= 5.7.1 =
|
96 |
* Fixed the bug with AAM notifications related to extension updates
|
97 |
* Fixed the bug with AAM not taking in consideration capabilities that defined in policy
|