Version Description
- Fixed the bug with LIST and LIST TO OTHERS options for multiple roles support
- Fixed the bug with managing access to custom post types that contain "-" in name
- Added ability to refresh JWT token with new RESTful endpoint /refresh-jwt
- Added ability to filter out metabox by its name with Access Policy
- Improved Posts & Terms access control with Access Policy
Download this release
Release Info
Developer | vasyltech |
Plugin | Advanced Access Manager |
Version | 5.9.3 |
Comparing to | |
See all releases |
Code changes from version 5.9.2.1 to 5.9.3
- Application/Backend/Manager.php +1 -1
- Application/Backend/phtml/main/metabox.phtml +1 -0
- Application/Core/Compatibility.php +6 -4
- Application/Core/Gateway.php +11 -0
- Application/Core/Jwt/Auth.php +2 -7
- Application/Core/Jwt/Issuer.php +7 -3
- Application/Core/Jwt/Manager.php +98 -14
- Application/Core/Object/Metabox.php +16 -7
- Application/Core/Object/Post.php +20 -10
- Application/Core/Object/Visibility.php +9 -0
- Application/Core/Policy/Manager.php +23 -4
- Application/Core/Policy/Token.php +1 -1
- Application/Core/Subject.php +1 -1
- Application/Shared/Manager.php +6 -6
- aam.php +1 -1
- readme.txt +8 -1
Application/Backend/Manager.php
CHANGED
@@ -556,7 +556,7 @@ class AAM_Backend_Manager {
|
|
556 |
if ($needAC && $allowed && $notASP) {
|
557 |
add_meta_box(
|
558 |
'aam-access-manager',
|
559 |
-
__('Access Manager', AAM_KEY)
|
560 |
array($this, 'renderPostMetabox'),
|
561 |
null,
|
562 |
'advanced',
|
556 |
if ($needAC && $allowed && $notASP) {
|
557 |
add_meta_box(
|
558 |
'aam-access-manager',
|
559 |
+
__('Access Manager', AAM_KEY),
|
560 |
array($this, 'renderPostMetabox'),
|
561 |
null,
|
562 |
'advanced',
|
Application/Backend/phtml/main/metabox.phtml
CHANGED
@@ -62,6 +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 |
<?php echo $metabox['title']; ?>
|
|
|
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"' : ''); ?> />
|
62 |
<div class="col-xs-12 col-md-6 aam-submenu-item">
|
63 |
<label for="metabox-<?php echo $screen; ?>-<?php echo $metabox['id']; ?>">
|
64 |
<?php echo $metabox['title']; ?>
|
65 |
+
<small class="aam-metabox-details"><?php echo __('Screen ID:', AAM_KEY); ?> <b><?php echo $screen; ?></b></small>
|
66 |
<small class="aam-metabox-details"><?php echo __('ID:', AAM_KEY); ?> <b><?php echo crc32($screen . '|' . $metabox['id']); ?></b></small>
|
67 |
</label>
|
68 |
<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"' : ''); ?> />
|
Application/Core/Compatibility.php
CHANGED
@@ -29,11 +29,13 @@ class AAM_Core_Compatibility {
|
|
29 |
* @param [type] $effect
|
30 |
* @return void
|
31 |
*/
|
32 |
-
public static function convertPolicyAction($action, $effect) {
|
|
|
|
|
33 |
return array(
|
34 |
-
"frontend.{$action}" => $effect,
|
35 |
-
"backend.{$action}" => $effect,
|
36 |
-
"api.{$action}" => $effect
|
37 |
);
|
38 |
}
|
39 |
|
29 |
* @param [type] $effect
|
30 |
* @return void
|
31 |
*/
|
32 |
+
public static function convertPolicyAction($action, $effect, $prefix = '') {
|
33 |
+
$action = apply_filters('aam-policy-post-resource-action-filter', $action);
|
34 |
+
|
35 |
return array(
|
36 |
+
"{$prefix}frontend.{$action}" => $effect,
|
37 |
+
"{$prefix}backend.{$action}" => $effect,
|
38 |
+
"{$prefix}api.{$action}" => $effect
|
39 |
);
|
40 |
}
|
41 |
|
Application/Core/Gateway.php
CHANGED
@@ -255,6 +255,17 @@ final class AAM_Core_Gateway {
|
|
255 |
|
256 |
return $merged;
|
257 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
258 |
|
259 |
/**
|
260 |
* Get instance of the API gateway
|
255 |
|
256 |
return $merged;
|
257 |
}
|
258 |
+
|
259 |
+
/**
|
260 |
+
* Get current AAM version
|
261 |
+
*
|
262 |
+
* @return string
|
263 |
+
*
|
264 |
+
* @access public
|
265 |
+
*/
|
266 |
+
public function getAAMVersion() {
|
267 |
+
return AAM_Core_API::version();
|
268 |
+
}
|
269 |
|
270 |
/**
|
271 |
* Get instance of the API gateway
|
Application/Core/Jwt/Auth.php
CHANGED
@@ -47,14 +47,9 @@ class AAM_Core_Jwt_Auth {
|
|
47 |
|
48 |
if ($result['status'] === 'success') { // generate token
|
49 |
try {
|
50 |
-
$issuer = new AAM_Core_Jwt_Issuer();
|
51 |
-
$token = $issuer->issueToken(
|
52 |
-
array('userId' => $result['user']->ID, 'revocable' => true)
|
53 |
-
);
|
54 |
-
|
55 |
$response = array(
|
56 |
-
'
|
57 |
-
'user'
|
58 |
);
|
59 |
} catch (Exception $ex) {
|
60 |
$response['reason'] = $ex->getMessage();
|
47 |
|
48 |
if ($result['status'] === 'success') { // generate token
|
49 |
try {
|
|
|
|
|
|
|
|
|
|
|
50 |
$response = array(
|
51 |
+
'status' => 'success',
|
52 |
+
'user' => $result['user']
|
53 |
);
|
54 |
} catch (Exception $ex) {
|
55 |
$response['reason'] = $ex->getMessage();
|
Application/Core/Jwt/Issuer.php
CHANGED
@@ -71,8 +71,8 @@ class AAM_Core_Jwt_Issuer {
|
|
71 |
/**
|
72 |
* Issue JWT token
|
73 |
*
|
74 |
-
* @param array
|
75 |
-
* @param string $expires
|
76 |
*
|
77 |
* @return stdClass
|
78 |
*
|
@@ -81,7 +81,11 @@ class AAM_Core_Jwt_Issuer {
|
|
81 |
*/
|
82 |
public function issueToken($args = array(), $expires = null) {
|
83 |
if (!empty($expires)) {
|
84 |
-
|
|
|
|
|
|
|
|
|
85 |
} else {
|
86 |
$time = new DateTime(
|
87 |
AAM_Core_Config::get('authentication.jwt.expires', '+24 hours')
|
71 |
/**
|
72 |
* Issue JWT token
|
73 |
*
|
74 |
+
* @param array $args
|
75 |
+
* @param string|DateTime $expires
|
76 |
*
|
77 |
* @return stdClass
|
78 |
*
|
81 |
*/
|
82 |
public function issueToken($args = array(), $expires = null) {
|
83 |
if (!empty($expires)) {
|
84 |
+
if (is_a($expires, 'DateTime')) {
|
85 |
+
$time = $expires;
|
86 |
+
} else {
|
87 |
+
$time = DateTime::createFromFormat('m/d/Y, H:i O', $expires);
|
88 |
+
}
|
89 |
} else {
|
90 |
$time = new DateTime(
|
91 |
AAM_Core_Config::get('authentication.jwt.expires', '+24 hours')
|
Application/Core/Jwt/Manager.php
CHANGED
@@ -52,7 +52,7 @@ class AAM_Core_Jwt_Manager {
|
|
52 |
// Authenticate user
|
53 |
register_rest_route('aam/v1', '/authenticate', array(
|
54 |
'methods' => 'POST',
|
55 |
-
'callback' => array($this, '
|
56 |
'args' => array(
|
57 |
'username' => array(
|
58 |
'description' => __('Valid username.', AAM_KEY),
|
@@ -76,6 +76,18 @@ class AAM_Core_Jwt_Manager {
|
|
76 |
)
|
77 |
),
|
78 |
));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
}
|
80 |
|
81 |
/**
|
@@ -87,7 +99,7 @@ class AAM_Core_Jwt_Manager {
|
|
87 |
*
|
88 |
* @access public
|
89 |
*/
|
90 |
-
public function
|
91 |
$username = $request->get_param('username');
|
92 |
$password = $request->get_param('password');
|
93 |
$response = new WP_REST_Response();
|
@@ -102,15 +114,14 @@ class AAM_Core_Jwt_Manager {
|
|
102 |
strip_tags($result->reason)
|
103 |
);
|
104 |
} else {
|
|
|
|
|
105 |
$response->status = 200;
|
106 |
$response->data = array(
|
107 |
-
'token' => $
|
108 |
-
'token_expires' => $
|
109 |
'user' => $result->user
|
110 |
);
|
111 |
-
|
112 |
-
// Finally register token so it can be revoked
|
113 |
-
$this->registerToken($result->user->ID, $result->jwt->token);
|
114 |
}
|
115 |
|
116 |
return apply_filters('aam-jwt-response-filter', $response);
|
@@ -145,6 +156,49 @@ class AAM_Core_Jwt_Manager {
|
|
145 |
|
146 |
return $response;
|
147 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
148 |
|
149 |
/**
|
150 |
* Determine current user by JWT
|
@@ -178,23 +232,30 @@ class AAM_Core_Jwt_Manager {
|
|
178 |
*
|
179 |
* @param int $userId
|
180 |
* @param string $token
|
181 |
-
* @param
|
182 |
*
|
183 |
* @return bool
|
184 |
*
|
185 |
* @access public
|
186 |
*/
|
187 |
-
public function registerToken($userId, $token) {
|
188 |
$registry = $this->getTokenRegistry($userId);
|
189 |
$limit = AAM_Core_Config::get('authentication.jwt.registryLimit', 10);
|
190 |
|
191 |
-
|
192 |
-
|
193 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
194 |
}
|
195 |
|
196 |
-
|
197 |
-
return
|
198 |
}
|
199 |
|
200 |
/**
|
@@ -233,6 +294,29 @@ class AAM_Core_Jwt_Manager {
|
|
233 |
return (!empty($registry) ? $registry : array());
|
234 |
}
|
235 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
236 |
/**
|
237 |
* Extract JWT token from the request
|
238 |
*
|
52 |
// Authenticate user
|
53 |
register_rest_route('aam/v1', '/authenticate', array(
|
54 |
'methods' => 'POST',
|
55 |
+
'callback' => array($this, 'authenticate'),
|
56 |
'args' => array(
|
57 |
'username' => array(
|
58 |
'description' => __('Valid username.', AAM_KEY),
|
76 |
)
|
77 |
),
|
78 |
));
|
79 |
+
|
80 |
+
// Refresh JWT token
|
81 |
+
register_rest_route('aam/v1', '/refresh-jwt', array(
|
82 |
+
'methods' => 'POST',
|
83 |
+
'callback' => array($this, 'refreshToken'),
|
84 |
+
'args' => array(
|
85 |
+
'jwt' => array(
|
86 |
+
'description' => __('JWT token.', AAM_KEY),
|
87 |
+
'type' => 'string',
|
88 |
+
)
|
89 |
+
),
|
90 |
+
));
|
91 |
}
|
92 |
|
93 |
/**
|
99 |
*
|
100 |
* @access public
|
101 |
*/
|
102 |
+
public function authenticate(WP_REST_Request $request) {
|
103 |
$username = $request->get_param('username');
|
104 |
$password = $request->get_param('password');
|
105 |
$response = new WP_REST_Response();
|
114 |
strip_tags($result->reason)
|
115 |
);
|
116 |
} else {
|
117 |
+
$jwt = $this->issueToken($result->user->ID);
|
118 |
+
|
119 |
$response->status = 200;
|
120 |
$response->data = array(
|
121 |
+
'token' => $jwt->token,
|
122 |
+
'token_expires' => $jwt->claims['exp'],
|
123 |
'user' => $result->user
|
124 |
);
|
|
|
|
|
|
|
125 |
}
|
126 |
|
127 |
return apply_filters('aam-jwt-response-filter', $response);
|
156 |
|
157 |
return $response;
|
158 |
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Refresh/renew JWT token
|
162 |
+
*
|
163 |
+
* @param WP_REST_Request $request
|
164 |
+
*
|
165 |
+
* @return WP_REST_Response
|
166 |
+
*
|
167 |
+
* @access public
|
168 |
+
*/
|
169 |
+
public function refreshToken(WP_REST_Request $request) {
|
170 |
+
$jwt = $request->get_param('jwt');
|
171 |
+
$issuer = new AAM_Core_Jwt_Issuer();
|
172 |
+
$response = new WP_REST_Response();
|
173 |
+
|
174 |
+
$result = $issuer->validateToken($jwt);
|
175 |
+
|
176 |
+
if ($result->status === 'valid') {
|
177 |
+
// calculate the new expiration
|
178 |
+
$issuedAt = new DateTime();
|
179 |
+
$issuedAt->setTimestamp($result->iat);
|
180 |
+
$expires = DateTime::createFromFormat('m/d/Y, H:i O', $result->exp);
|
181 |
+
|
182 |
+
$exp = new DateTime();
|
183 |
+
$exp->add($issuedAt->diff($expires));
|
184 |
+
|
185 |
+
$new = $this->issueToken($result->userId, $jwt, $exp);
|
186 |
+
|
187 |
+
$response->status = 200;
|
188 |
+
$response->data = array(
|
189 |
+
'token' => $new->token,
|
190 |
+
'token_expires' => $new->claims['exp'],
|
191 |
+
);
|
192 |
+
} else {
|
193 |
+
$response->status = 400;
|
194 |
+
$response->data = new WP_Error(
|
195 |
+
'rest_jwt_validation_failure',
|
196 |
+
$result->reason
|
197 |
+
);
|
198 |
+
}
|
199 |
+
|
200 |
+
return $response;
|
201 |
+
}
|
202 |
|
203 |
/**
|
204 |
* Determine current user by JWT
|
232 |
*
|
233 |
* @param int $userId
|
234 |
* @param string $token
|
235 |
+
* @param string $replaceExisting
|
236 |
*
|
237 |
* @return bool
|
238 |
*
|
239 |
* @access public
|
240 |
*/
|
241 |
+
public function registerToken($userId, $token, $replaceExisting = false) {
|
242 |
$registry = $this->getTokenRegistry($userId);
|
243 |
$limit = AAM_Core_Config::get('authentication.jwt.registryLimit', 10);
|
244 |
|
245 |
+
if ($replaceExisting) {
|
246 |
+
$result = update_user_meta($userId, 'aam-jwt', $token, $replaceExisting);
|
247 |
+
} else {
|
248 |
+
// Make sure that we do not overload the user meta
|
249 |
+
if (count($registry) >= $limit) {
|
250 |
+
$this->revokeToken($userId, array_shift($registry));
|
251 |
+
}
|
252 |
+
|
253 |
+
// Save token
|
254 |
+
$result = add_user_meta($userId, 'aam-jwt', $token);
|
255 |
}
|
256 |
|
257 |
+
|
258 |
+
return $result;
|
259 |
}
|
260 |
|
261 |
/**
|
294 |
return (!empty($registry) ? $registry : array());
|
295 |
}
|
296 |
|
297 |
+
/**
|
298 |
+
* Issue JWT token
|
299 |
+
*
|
300 |
+
* @param int $userId
|
301 |
+
* @param string $replace
|
302 |
+
* @param string $expires
|
303 |
+
*
|
304 |
+
* @return object
|
305 |
+
*
|
306 |
+
* @access protected
|
307 |
+
*/
|
308 |
+
protected function issueToken($userId, $replace = null, $expires = null) {
|
309 |
+
$issuer = new AAM_Core_Jwt_Issuer();
|
310 |
+
$result = $issuer->issueToken(
|
311 |
+
array('userId' => $userId, 'revocable' => true), $expires
|
312 |
+
);
|
313 |
+
|
314 |
+
// Finally register token so it can be revoked
|
315 |
+
$this->registerToken($userId, $result->token, $replace);
|
316 |
+
|
317 |
+
return $result;
|
318 |
+
}
|
319 |
+
|
320 |
/**
|
321 |
* Extract JWT token from the request
|
322 |
*
|
Application/Core/Object/Metabox.php
CHANGED
@@ -146,9 +146,9 @@ class AAM_Core_Object_Metabox extends AAM_Core_Object {
|
|
146 |
* @param type $screen_id
|
147 |
*/
|
148 |
protected function filterMetaboxes($zone, $metaboxes, $screen_id) {
|
149 |
-
foreach (
|
150 |
-
if ($this->has($screen_id, $metabox)) {
|
151 |
-
remove_meta_box($
|
152 |
}
|
153 |
}
|
154 |
}
|
@@ -178,11 +178,20 @@ class AAM_Core_Object_Metabox extends AAM_Core_Object {
|
|
178 |
* @param type $metabox
|
179 |
* @return type
|
180 |
*/
|
181 |
-
public function has($screen, $
|
182 |
$options = $this->getOption();
|
183 |
-
$mid = "{$screen}|{$
|
184 |
-
|
185 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
186 |
}
|
187 |
|
188 |
/**
|
146 |
* @param type $screen_id
|
147 |
*/
|
148 |
protected function filterMetaboxes($zone, $metaboxes, $screen_id) {
|
149 |
+
foreach ($metaboxes as $id => $metabox) {
|
150 |
+
if ($this->has($screen_id, $id, $metabox['title'])) {
|
151 |
+
remove_meta_box($id, $screen_id, $zone);
|
152 |
}
|
153 |
}
|
154 |
}
|
178 |
* @param type $metabox
|
179 |
* @return type
|
180 |
*/
|
181 |
+
public function has($screen, $metaboxId, $metaboxTitle = null) {
|
182 |
$options = $this->getOption();
|
183 |
+
$mid = "{$screen}|{$metaboxId}";
|
184 |
+
|
185 |
+
if(function_exists('mb_strtolower')) {
|
186 |
+
$mtl = mb_strtolower("{$screen}|{$metaboxTitle}");
|
187 |
+
} else {
|
188 |
+
$mtl = strtolower("{$screen}|{$metaboxTitle}");
|
189 |
+
}
|
190 |
+
|
191 |
+
// Also remove any HTML tags
|
192 |
+
$mtl = wp_strip_all_tags($mtl);
|
193 |
+
|
194 |
+
return !empty($options[$mid]) || !empty($options[crc32($mid)]) || !empty($options[$mtl]);
|
195 |
}
|
196 |
|
197 |
/**
|
Application/Core/Object/Post.php
CHANGED
@@ -34,17 +34,27 @@ class AAM_Core_Object_Post extends AAM_Core_Object {
|
|
34 |
*
|
35 |
* @access public
|
36 |
*/
|
37 |
-
public function __construct(AAM_Core_Subject $subject, $post) {
|
38 |
parent::__construct($subject);
|
39 |
|
40 |
-
//
|
41 |
-
|
42 |
-
|
|
|
43 |
} elseif (is_numeric($post)) {
|
44 |
$this->setPost(get_post($post));
|
45 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
|
47 |
-
$this->initialize();
|
48 |
}
|
49 |
|
50 |
/**
|
@@ -65,9 +75,9 @@ class AAM_Core_Object_Post extends AAM_Core_Object {
|
|
65 |
/**
|
66 |
*
|
67 |
*/
|
68 |
-
public function initialize() {
|
69 |
if ($this->getPost()) {
|
70 |
-
$this->read();
|
71 |
}
|
72 |
}
|
73 |
|
@@ -80,7 +90,7 @@ class AAM_Core_Object_Post extends AAM_Core_Object {
|
|
80 |
*
|
81 |
* @access public
|
82 |
*/
|
83 |
-
public function read() {
|
84 |
$subject = $this->getSubject();
|
85 |
$post = $this->getPost();
|
86 |
|
@@ -115,7 +125,7 @@ class AAM_Core_Object_Post extends AAM_Core_Object {
|
|
115 |
);
|
116 |
}
|
117 |
}
|
118 |
-
|
119 |
// Inherit from terms or default settings - AAM Plus Package
|
120 |
if (empty($option)) {
|
121 |
$option = apply_filters('aam-post-access-filter', $option, $this);
|
@@ -124,7 +134,7 @@ class AAM_Core_Object_Post extends AAM_Core_Object {
|
|
124 |
// Cache result but only if it is not empty
|
125 |
if (!empty($option)) {
|
126 |
$subject->getObject('cache')->add('post', $post->ID, $option);
|
127 |
-
}
|
128 |
$option = $subject->inheritFromParent('post', $post->ID, $post);
|
129 |
}
|
130 |
|
34 |
*
|
35 |
* @access public
|
36 |
*/
|
37 |
+
public function __construct(AAM_Core_Subject $subject, $post, $param = null) {
|
38 |
parent::__construct($subject);
|
39 |
|
40 |
+
// Make sure that we are dealing with WP_Post object
|
41 |
+
// This is done to remove redundant calls to the database on the backend view
|
42 |
+
if (is_object($param) && is_a($param, 'WP_Post')) {
|
43 |
+
$this->setPost($param);
|
44 |
} elseif (is_numeric($post)) {
|
45 |
$this->setPost(get_post($post));
|
46 |
}
|
47 |
+
|
48 |
+
//var_dump($settings);
|
49 |
+
// Determine if we need to skip inheritance change from the parent subject
|
50 |
+
// This is done to eliminate constrains related to Inherit From Parent Post
|
51 |
+
if (is_array($param)) {
|
52 |
+
$void = !empty($param['voidInheritance']);
|
53 |
+
} else {
|
54 |
+
$void = false;
|
55 |
+
}
|
56 |
|
57 |
+
$this->initialize($void);
|
58 |
}
|
59 |
|
60 |
/**
|
75 |
/**
|
76 |
*
|
77 |
*/
|
78 |
+
public function initialize($voidInheritance = false) {
|
79 |
if ($this->getPost()) {
|
80 |
+
$this->read($voidInheritance);
|
81 |
}
|
82 |
}
|
83 |
|
90 |
*
|
91 |
* @access public
|
92 |
*/
|
93 |
+
public function read($voidInheritance = false) {
|
94 |
$subject = $this->getSubject();
|
95 |
$post = $this->getPost();
|
96 |
|
125 |
);
|
126 |
}
|
127 |
}
|
128 |
+
|
129 |
// Inherit from terms or default settings - AAM Plus Package
|
130 |
if (empty($option)) {
|
131 |
$option = apply_filters('aam-post-access-filter', $option, $this);
|
134 |
// Cache result but only if it is not empty
|
135 |
if (!empty($option)) {
|
136 |
$subject->getObject('cache')->add('post', $post->ID, $option);
|
137 |
+
} elseif ($voidInheritance === false) { // No settings for a post. Try to inherit from the parent
|
138 |
$option = $subject->inheritFromParent('post', $post->ID, $post);
|
139 |
}
|
140 |
|
Application/Core/Object/Visibility.php
CHANGED
@@ -171,4 +171,13 @@ class AAM_Core_Object_Visibility extends AAM_Core_Object {
|
|
171 |
return $meta_key;
|
172 |
}
|
173 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
174 |
}
|
171 |
return $meta_key;
|
172 |
}
|
173 |
|
174 |
+
/**
|
175 |
+
*
|
176 |
+
* @param type $external
|
177 |
+
* @return type
|
178 |
+
*/
|
179 |
+
public function mergeOption($external) {
|
180 |
+
return AAM::api()->mergeSettings($external, $this->getOption(), 'post');
|
181 |
+
}
|
182 |
+
|
183 |
}
|
Application/Core/Policy/Manager.php
CHANGED
@@ -92,7 +92,7 @@ final class AAM_Core_Policy_Manager {
|
|
92 |
|
93 |
foreach($tree['Statement'] as $key => $stm) {
|
94 |
if (preg_match($s, $key) && $this->isApplicable($stm, $args)) {
|
95 |
-
$statements[
|
96 |
}
|
97 |
}
|
98 |
|
@@ -114,7 +114,7 @@ final class AAM_Core_Policy_Manager {
|
|
114 |
public function isAllowed($resource, $args = array()) {
|
115 |
$allowed = null;
|
116 |
$tree = $this->preparePolicyTree();
|
117 |
-
$id =
|
118 |
|
119 |
if (isset($tree['Statement'][$id])) {
|
120 |
$stm = $tree['Statement'][$id];
|
@@ -128,6 +128,25 @@ final class AAM_Core_Policy_Manager {
|
|
128 |
return $allowed;
|
129 |
}
|
130 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
/**
|
132 |
* Determine if resource is the boundary
|
133 |
*
|
@@ -145,7 +164,7 @@ final class AAM_Core_Policy_Manager {
|
|
145 |
public function isBoundary($resource, $args = array()) {
|
146 |
$denied = false;
|
147 |
$tree = $this->preparePolicyTree();
|
148 |
-
$id =
|
149 |
|
150 |
if (isset($tree['Statement'][$id])) {
|
151 |
$stm = $tree['Statement'][$id];
|
@@ -314,7 +333,7 @@ final class AAM_Core_Policy_Manager {
|
|
314 |
|
315 |
foreach($list as $res) {
|
316 |
foreach($acts as $act) {
|
317 |
-
$id =
|
318 |
|
319 |
if (!isset($tree['Statement'][$id]) || empty($tree['Statement'][$id]['Enforce'])) {
|
320 |
$tree['Statement'][$id] = $this->removeKeys($stm, array('Resource', 'Action'));
|
92 |
|
93 |
foreach($tree['Statement'] as $key => $stm) {
|
94 |
if (preg_match($s, $key) && $this->isApplicable($stm, $args)) {
|
95 |
+
$statements[$this->strToLower($key)] = $stm;
|
96 |
}
|
97 |
}
|
98 |
|
114 |
public function isAllowed($resource, $args = array()) {
|
115 |
$allowed = null;
|
116 |
$tree = $this->preparePolicyTree();
|
117 |
+
$id = $this->strToLower($resource);
|
118 |
|
119 |
if (isset($tree['Statement'][$id])) {
|
120 |
$stm = $tree['Statement'][$id];
|
128 |
return $allowed;
|
129 |
}
|
130 |
|
131 |
+
/**
|
132 |
+
* Convert string to lowercase
|
133 |
+
*
|
134 |
+
* @param string $str
|
135 |
+
*
|
136 |
+
* @return string
|
137 |
+
*
|
138 |
+
* @access protected
|
139 |
+
*/
|
140 |
+
protected function strToLower($str) {
|
141 |
+
if (function_exists('mb_strtolower')) {
|
142 |
+
$result = mb_strtolower($str);
|
143 |
+
} else {
|
144 |
+
$result = strtolower($str);
|
145 |
+
}
|
146 |
+
|
147 |
+
return $result;
|
148 |
+
}
|
149 |
+
|
150 |
/**
|
151 |
* Determine if resource is the boundary
|
152 |
*
|
164 |
public function isBoundary($resource, $args = array()) {
|
165 |
$denied = false;
|
166 |
$tree = $this->preparePolicyTree();
|
167 |
+
$id = $this->strToLower($resource);
|
168 |
|
169 |
if (isset($tree['Statement'][$id])) {
|
170 |
$stm = $tree['Statement'][$id];
|
333 |
|
334 |
foreach($list as $res) {
|
335 |
foreach($acts as $act) {
|
336 |
+
$id = $this->strToLower($res . (!empty($act) ? ":{$act}" : ''));
|
337 |
|
338 |
if (!isset($tree['Statement'][$id]) || empty($tree['Statement'][$id]['Enforce'])) {
|
339 |
$tree['Statement'][$id] = $this->removeKeys($stm, array('Resource', 'Action'));
|
Application/Core/Policy/Token.php
CHANGED
@@ -112,7 +112,7 @@ final class AAM_Core_Policy_Token {
|
|
112 |
case 'capabilities':
|
113 |
case 'caps':
|
114 |
$value = array();
|
115 |
-
foreach($user->allcaps as $cap => $effect) {
|
116 |
if (!empty($effect)) {
|
117 |
$value[] = $cap;
|
118 |
}
|
112 |
case 'capabilities':
|
113 |
case 'caps':
|
114 |
$value = array();
|
115 |
+
foreach((array) $user->allcaps as $cap => $effect) {
|
116 |
if (!empty($effect)) {
|
117 |
$value[] = $cap;
|
118 |
}
|
Application/Core/Subject.php
CHANGED
@@ -247,7 +247,7 @@ abstract class AAM_Core_Subject {
|
|
247 |
$classname = 'AAM_Core_Object_' . ucfirst($type);
|
248 |
|
249 |
if (class_exists($classname)) {
|
250 |
-
$object = new $classname($this,
|
251 |
}
|
252 |
|
253 |
$object = apply_filters('aam-object-filter', $object, $type, $id, $this);
|
247 |
$classname = 'AAM_Core_Object_' . ucfirst($type);
|
248 |
|
249 |
if (class_exists($classname)) {
|
250 |
+
$object = new $classname($this, $id, $param);
|
251 |
}
|
252 |
|
253 |
$object = apply_filters('aam-object-filter', $object, $type, $id, $this);
|
Application/Shared/Manager.php
CHANGED
@@ -144,7 +144,7 @@ class AAM_Shared_Manager {
|
|
144 |
if (is_a($object, 'WP_Post_Type')) { // Work only with WP 4.6.0 or higher
|
145 |
foreach($object->cap as $type => $capability) {
|
146 |
if (in_array($type, $this->primitiveCaps, true)) {
|
147 |
-
$object->cap->{$type} = "aam
|
148 |
}
|
149 |
}
|
150 |
}
|
@@ -299,7 +299,7 @@ class AAM_Shared_Manager {
|
|
299 |
public function filterPostQuery($clauses, $wpQuery) {
|
300 |
if (!$wpQuery->is_singular && $this->isPostFilterEnabled()) {
|
301 |
$option = AAM::getUser()->getObject('visibility', 0)->getOption();
|
302 |
-
|
303 |
if (!empty($option['post'])) {
|
304 |
$query = $this->preparePostQuery($option['post'], $wpQuery);
|
305 |
} else {
|
@@ -474,8 +474,8 @@ class AAM_Shared_Manager {
|
|
474 |
|
475 |
// First of all delete all artificial capability from the $caps
|
476 |
foreach($caps as $i => $capability) {
|
477 |
-
if (strpos($capability, 'aam
|
478 |
-
$parts = explode('
|
479 |
$capability = $parts[2];
|
480 |
$primitive = $parts[1];
|
481 |
} else {
|
@@ -550,7 +550,7 @@ class AAM_Shared_Manager {
|
|
550 |
break;
|
551 |
|
552 |
default:
|
553 |
-
if (strpos($cap, 'aam
|
554 |
if (!$this->skipMetaCheck) {
|
555 |
$this->skipMetaCheck = true;
|
556 |
$caps = $this->checkPostTypePermission($caps, $cap, $objectId);
|
@@ -583,7 +583,7 @@ class AAM_Shared_Manager {
|
|
583 |
// [0] === aam
|
584 |
// [1] === WP_Post_Type->cap key
|
585 |
// [2] === The capability
|
586 |
-
$parts = explode('
|
587 |
|
588 |
// Build the argument array for the current_user_can
|
589 |
$args = array($parts[2]);
|
144 |
if (is_a($object, 'WP_Post_Type')) { // Work only with WP 4.6.0 or higher
|
145 |
foreach($object->cap as $type => $capability) {
|
146 |
if (in_array($type, $this->primitiveCaps, true)) {
|
147 |
+
$object->cap->{$type} = "aam|{$type}|{$capability}";
|
148 |
}
|
149 |
}
|
150 |
}
|
299 |
public function filterPostQuery($clauses, $wpQuery) {
|
300 |
if (!$wpQuery->is_singular && $this->isPostFilterEnabled()) {
|
301 |
$option = AAM::getUser()->getObject('visibility', 0)->getOption();
|
302 |
+
|
303 |
if (!empty($option['post'])) {
|
304 |
$query = $this->preparePostQuery($option['post'], $wpQuery);
|
305 |
} else {
|
474 |
|
475 |
// First of all delete all artificial capability from the $caps
|
476 |
foreach($caps as $i => $capability) {
|
477 |
+
if (strpos($capability, 'aam|') === 0) {
|
478 |
+
$parts = explode('|', $capability);
|
479 |
$capability = $parts[2];
|
480 |
$primitive = $parts[1];
|
481 |
} else {
|
550 |
break;
|
551 |
|
552 |
default:
|
553 |
+
if (strpos($cap, 'aam|') === 0) {
|
554 |
if (!$this->skipMetaCheck) {
|
555 |
$this->skipMetaCheck = true;
|
556 |
$caps = $this->checkPostTypePermission($caps, $cap, $objectId);
|
583 |
// [0] === aam
|
584 |
// [1] === WP_Post_Type->cap key
|
585 |
// [2] === The capability
|
586 |
+
$parts = explode('|', $cap);
|
587 |
|
588 |
// Build the argument array for the current_user_can
|
589 |
$args = array($parts[2]);
|
aam.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
/**
|
4 |
* Plugin Name: Advanced Access Manager
|
5 |
* Description: All you need to manage access to your WordPress website
|
6 |
-
* Version: 5.9.
|
7 |
* Author: Vasyl Martyniuk <vasyl@vasyltech.com>
|
8 |
* Author URI: https://vasyltech.com
|
9 |
*
|
3 |
/**
|
4 |
* Plugin Name: Advanced Access Manager
|
5 |
* Description: All you need to manage access to your WordPress website
|
6 |
+
* Version: 5.9.3
|
7 |
* Author: Vasyl Martyniuk <vasyl@vasyltech.com>
|
8 |
* Author URI: https://vasyltech.com
|
9 |
*
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: vasyltech
|
|
3 |
Tags: access control, membership, backend menu, user role, restricted content, security, jwt
|
4 |
Requires at least: 4.0
|
5 |
Tested up to: 5.1
|
6 |
-
Stable tag: 5.9.
|
7 |
|
8 |
All you need to manage access to you WordPress websites on frontend, backend and API levels for any role, user or visitors.
|
9 |
|
@@ -80,6 +80,13 @@ https://www.youtube.com/watch?v=mj5Xa_Wc16Y
|
|
80 |
|
81 |
== Changelog ==
|
82 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
= 5.9.2.1 =
|
84 |
* Fixed several bugs that are related to post, page or custom post type editing
|
85 |
|
3 |
Tags: access control, membership, backend menu, user role, restricted content, security, jwt
|
4 |
Requires at least: 4.0
|
5 |
Tested up to: 5.1
|
6 |
+
Stable tag: 5.9.3
|
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 |
|
80 |
|
81 |
== Changelog ==
|
82 |
|
83 |
+
= 5.9.3 =
|
84 |
+
* Fixed the bug with LIST and LIST TO OTHERS options for multiple roles support
|
85 |
+
* Fixed the bug with managing access to custom post types that contain "-" in name
|
86 |
+
* Added ability to refresh JWT token with new RESTful endpoint /refresh-jwt
|
87 |
+
* Added ability to filter out metabox by its name with Access Policy
|
88 |
+
* Improved Posts & Terms access control with Access Policy
|
89 |
+
|
90 |
= 5.9.2.1 =
|
91 |
* Fixed several bugs that are related to post, page or custom post type editing
|
92 |
|