Advanced Access Manager - Version 5.6.1

Version Description

  • Fixed the bug with caching
  • Fixed the bug with the way post type and taxonomies are registered with extensions
  • Turned on by default the ability to edit and delete capabilities
Download this release

Release Info

Developer vasyl_m
Plugin Icon 128x128 Advanced Access Manager
Version 5.6.1
Comparing to
See all releases

Code changes from version 5.6 to 5.6.1

Application/Api/Manager.php CHANGED
@@ -66,11 +66,6 @@ class AAM_Api_Manager {
66
  // Manage access to the RESTful endpoints
67
  add_filter('rest_pre_dispatch', array($this, 'authorizeRest'), 1, 3);
68
 
69
- // Check if user has ability to perform certain task based on provided
70
- // capability and meta data
71
- $shared = AAM_Shared_Manager::getInstance();
72
- add_filter('user_has_cap', array($shared, 'userHasCap'), 999, 3);
73
-
74
  // Register any additional endpoints with ConfigPress
75
  $additional = AAM_Core_Config::get('rest.manage.endpoint');
76
 
66
  // Manage access to the RESTful endpoints
67
  add_filter('rest_pre_dispatch', array($this, 'authorizeRest'), 1, 3);
68
 
 
 
 
 
 
69
  // Register any additional endpoints with ConfigPress
70
  $additional = AAM_Core_Config::get('rest.manage.endpoint');
71
 
Application/Backend/Feature/Main/Capability.php CHANGED
@@ -54,7 +54,7 @@ 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'
58
  )
59
  );
60
 
@@ -147,13 +147,30 @@ class AAM_Backend_Feature_Main_Capability extends AAM_Backend_Feature_Abstract {
147
  $subject = AAM_Backend_Subject::getInstance();
148
  $actions = array();
149
 
150
- $actions[] = ($subject->hasCapability($cap) ? 'checked' : 'unchecked');
 
 
 
 
 
 
151
 
152
  //allow to delete or update capability only for roles!
153
- if (AAM_Core_Config::get('core.settings.editCapabilities', false)
154
  && ($subject->getUID() === AAM_Core_Subject_Role::UID)) {
155
- $actions[] = 'edit';
156
- $actions[] = 'delete';
 
 
 
 
 
 
 
 
 
 
 
157
  } else {
158
  $actions[] = 'no-edit';
159
  $actions[] = 'no-delete';
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
 
147
  $subject = AAM_Backend_Subject::getInstance();
148
  $actions = array();
149
 
150
+ $toggle = ($subject->hasCapability($cap) ? 'checked' : 'unchecked');
151
+
152
+ if (AAM::api()->isAllowed("Capability:{$cap}", 'AAM:toggle') === false) {
153
+ $toggle = 'no-' . $toggle;
154
+ }
155
+
156
+ $actions[] = $toggle;
157
 
158
  //allow to delete or update capability only for roles!
159
+ if (AAM_Core_Config::get('core.settings.editCapabilities', true)
160
  && ($subject->getUID() === AAM_Core_Subject_Role::UID)) {
161
+ $edit = 'edit';
162
+ $delete = 'delete';
163
+
164
+ if (AAM::api()->isAllowed("Capability:{$cap}", 'AAM:update') === false) {
165
+ $edit = 'no-' . $edit;
166
+ }
167
+
168
+ if (AAM::api()->isAllowed("Capability:{$cap}", 'AAM:delete') === false) {
169
+ $edit = 'no-' . $delete;
170
+ }
171
+
172
+ $actions[] = $edit;
173
+ $actions[] = $delete;
174
  } else {
175
  $actions[] = 'no-edit';
176
  $actions[] = 'no-delete';
Application/Backend/Feature/Main/Policy.php ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ * WordPress API manager
12
+ *
13
+ * @package AAM
14
+ * @author Vasyl Martyniuk <vasyl@vasyltech.com>
15
+ */
16
+ class AAM_Backend_Feature_Main_Policy extends AAM_Backend_Feature_Abstract {
17
+
18
+ /**
19
+ *
20
+ * @return type
21
+ */
22
+ public function getTable() {
23
+ return wp_json_encode($this->retrievePolicies());
24
+ }
25
+
26
+ /**
27
+ *
28
+ * @return type
29
+ */
30
+ public function savePolicy() {
31
+ $id = filter_input(INPUT_POST, 'id');
32
+ $policy = filter_input(INPUT_POST, 'policy');
33
+
34
+ $policies = AAM_Core_API::getOption('aam-policy-list', array(), 'site');
35
+
36
+ if (empty($id)) {
37
+ $id = uniqid();
38
+ }
39
+
40
+ $policies[$id] = $policy;
41
+
42
+ AAM_Core_API::updateOption('aam-policy-list', $policies, 'site');
43
+
44
+ return wp_json_encode(array('status' => 'success'));
45
+ }
46
+
47
+ /**
48
+ *
49
+ * @return type
50
+ */
51
+ public function deletePolicy() {
52
+ $id = filter_input(INPUT_POST, 'id');
53
+
54
+ $policies = AAM_Core_API::getOption('aam-policy-list', array(), 'site');
55
+
56
+ if (isset($policies[$id])) {
57
+ unset($policies[$id]);
58
+ }
59
+
60
+ AAM_Core_API::updateOption('aam-policy-list', $policies, 'site');
61
+
62
+ return wp_json_encode(array('status' => 'success'));
63
+ }
64
+
65
+ /**
66
+ * Save post properties
67
+ *
68
+ * @return string
69
+ *
70
+ * @access public
71
+ */
72
+ public function save() {
73
+ $subject = AAM_Backend_Subject::getInstance();
74
+
75
+
76
+ $id = AAM_Core_Request::post('id');
77
+ $effect = AAM_Core_Request::post('effect');
78
+
79
+ //clear cache
80
+ AAM_Core_API::clearCache();
81
+
82
+ $result = $subject->save($id, $effect, 'policy');
83
+
84
+ return wp_json_encode(array(
85
+ 'status' => ($result ? 'success' : 'failure')
86
+ ));
87
+ }
88
+
89
+ /**
90
+ * @inheritdoc
91
+ */
92
+ public static function getTemplate() {
93
+ return 'main/policy.phtml';
94
+ }
95
+
96
+ /**
97
+ * Check inheritance status
98
+ *
99
+ * Check if menu settings are overwritten
100
+ *
101
+ * @return boolean
102
+ *
103
+ * @access protected
104
+ */
105
+ protected function isOverwritten() {
106
+ $object = AAM_Backend_Subject::getInstance()->getObject('policy');
107
+
108
+ return $object->isOverwritten();
109
+ }
110
+
111
+ /**
112
+ *
113
+ * @return type
114
+ */
115
+ protected function retrievePolicies() {
116
+ $list = AAM_Core_API::getOption('aam-policy-list', array(), 'site');
117
+
118
+ $response = array(
119
+ 'recordsTotal' => count($list),
120
+ 'recordsFiltered' => count($list),
121
+ 'draw' => AAM_Core_Request::request('draw'),
122
+ 'data' => array(),
123
+ );
124
+
125
+ foreach($list as $id => $json) {
126
+ $policy = json_decode($json);
127
+ $response['data'][] = array(
128
+ $id,
129
+ $this->buildTitle($policy),
130
+ $json,
131
+ $this->buildActionList($id)
132
+ );
133
+ }
134
+
135
+ return $response;
136
+ }
137
+
138
+ protected function buildTitle($policy) {
139
+ $title = (isset($policy->Title) ? esc_js($policy->Title) : __('No Title', AAM_KEY));
140
+ $title .= '<br/>';
141
+
142
+ if (isset($policy->Description)) {
143
+ $title .= '<small>' . esc_js($policy->Description) . '</small>';
144
+ }
145
+
146
+ return $title;
147
+ }
148
+
149
+ /**
150
+ *
151
+ * @param type $id
152
+ * @return type
153
+ */
154
+ protected function buildActionList($id) {
155
+ //'assign,edit,clone,delete'
156
+ $subject = AAM_Backend_Subject::getInstance();
157
+ $object = $subject->getObject('policy');
158
+ $actions = array();
159
+
160
+ $actions[] = $object->has($id) ? 'unassign' : 'assign';
161
+ $actions[] = 'edit';
162
+ $actions[] = 'delete';
163
+
164
+ return implode(',', $actions);
165
+ }
166
+
167
+ /**
168
+ * Register Menu feature
169
+ *
170
+ * @return void
171
+ *
172
+ * @access public
173
+ */
174
+ public static function register() {
175
+ AAM_Backend_Feature::registerFeature((object) array(
176
+ 'uid' => 'policy',
177
+ 'position' => 2,
178
+ 'title' => __('Access Policies', AAM_KEY) . '<span class="badge">NEW</span>',
179
+ 'capability' => 'aam_manage_policy',
180
+ 'type' => 'main',
181
+ 'subjects' => array(
182
+ AAM_Core_Subject_Role::UID,
183
+ AAM_Core_Subject_User::UID,
184
+ AAM_Core_Subject_Visitor::UID,
185
+ AAM_Core_Subject_Default::UID
186
+ ),
187
+ 'view' => __CLASS__
188
+ ));
189
+ }
190
+
191
+ }
Application/Backend/Feature/Settings/Core.php CHANGED
@@ -36,7 +36,7 @@ class AAM_Backend_Feature_Settings_Core extends AAM_Backend_Feature_Abstract {
36
  'core.settings.editCapabilities' => array(
37
  'title' => __('Edit/Delete Capabilities', AAM_KEY),
38
  'descr' => AAM_Backend_View_Helper::preparePhrase('Allow to edit or delete any existing capability on the Capabilities tab. [Warning!] For experienced users only. Changing or deleting capability may result in loosing access to some features or even the entire website.', 'b'),
39
- 'value' => AAM_Core_Config::get('core.settings.editCapabilities', false)
40
  ),
41
  'core.settings.backendAccessControl' => array(
42
  'title' => __('Backend Access Control', AAM_KEY),
36
  'core.settings.editCapabilities' => array(
37
  'title' => __('Edit/Delete Capabilities', AAM_KEY),
38
  'descr' => AAM_Backend_View_Helper::preparePhrase('Allow to edit or delete any existing capability on the Capabilities tab. [Warning!] For experienced users only. Changing or deleting capability may result in loosing access to some features or even the entire website.', 'b'),
39
+ 'value' => AAM_Core_Config::get('core.settings.editCapabilities', true)
40
  ),
41
  'core.settings.backendAccessControl' => array(
42
  'title' => __('Backend Access Control', AAM_KEY),
Application/Backend/Filter.php CHANGED
@@ -61,15 +61,6 @@ class AAM_Backend_Filter {
61
  add_filter('views_users', array($this, 'filterViews'));
62
  }
63
 
64
- // Check if user has ability to perform certain task based on provided
65
- // capability and meta data
66
- add_filter(
67
- 'user_has_cap',
68
- array(AAM_Shared_Manager::getInstance(), 'userHasCap'),
69
- 999,
70
- 3
71
- );
72
-
73
  AAM_Backend_Authorization::bootstrap(); //bootstrap backend authorization
74
 
75
  //check URI
61
  add_filter('views_users', array($this, 'filterViews'));
62
  }
63
 
 
 
 
 
 
 
 
 
 
64
  AAM_Backend_Authorization::bootstrap(); //bootstrap backend authorization
65
 
66
  //check URI
Application/Backend/View.php CHANGED
@@ -34,6 +34,7 @@ class AAM_Backend_View {
34
  protected function __construct() {
35
  //register default features
36
  AAM_Backend_Feature_Main_GetStarted::register();
 
37
  AAM_Backend_Feature_Main_Menu::register();
38
  AAM_Backend_Feature_Main_Toolbar::register();
39
  AAM_Backend_Feature_Main_Metabox::register();
@@ -269,7 +270,7 @@ class AAM_Backend_View {
269
  );
270
 
271
  // Making sure that user that we are switching too is not logged in
272
- // already. Kinding by https://github.com/KenAer
273
  $sessions = WP_Session_Tokens::get_instance($user->ID);
274
  if (count($sessions->get_all()) > 1) {
275
  $sessions->destroy_all();
34
  protected function __construct() {
35
  //register default features
36
  AAM_Backend_Feature_Main_GetStarted::register();
37
+ //AAM_Backend_Feature_Main_Policy::register();
38
  AAM_Backend_Feature_Main_Menu::register();
39
  AAM_Backend_Feature_Main_Toolbar::register();
40
  AAM_Backend_Feature_Main_Metabox::register();
270
  );
271
 
272
  // Making sure that user that we are switching too is not logged in
273
+ // already. Reported by https://github.com/KenAer
274
  $sessions = WP_Session_Tokens::get_instance($user->ID);
275
  if (count($sessions->get_all()) > 1) {
276
  $sessions->destroy_all();
Application/Backend/phtml/main/menu.phtml CHANGED
@@ -41,18 +41,31 @@
41
 
42
  <div id="menu-<?php echo $i; ?>" class="panel-collapse collapse<?php if (!$first) { echo ' in'; $first = true; } ?>" role="tabpanel" aria-labelledby="menu-<?php echo $i; ?>-heading">
43
  <div class="panel-body">
 
 
 
 
 
 
 
 
44
  <?php if (!empty($menu['submenu'])) { ?>
45
  <div class="row aam-inner-tab">
46
  <?php echo ($object->has($menu['id']) ? '<div class="aam-lock"></div>' : ''); ?>
47
  <?php foreach ($menu['submenu'] as $j => $submenu) { ?>
48
  <?php if ($submenu['id'] == 'index.php') { ?>
49
  <div class="col-xs-12 col-md-6 aam-submenu-item">
50
- <label for="menu-item-<?php echo $i . $j; ?>"><u><?php echo $submenu['name']; ?></u><small class="aam-menu-capability"><?php echo __('Cap:', AAM_KEY), ' <b>', $submenu['capability']; ?></b></small></label>
 
51
  <a href="#dashboard-lockout-modal" data-toggle="modal"><i class="icon-help-circled"></i></a>
52
  </div>
53
  <?php } else { ?>
54
  <div class="col-xs-12 col-md-6 aam-submenu-item">
55
- <label for="menu-item-<?php echo $i . $j; ?>"><u><?php echo $submenu['name']; ?></u><small class="aam-menu-capability"><?php echo __('Cap:', AAM_KEY), ' <b>', $submenu['capability']; ?></b></small></label>
 
 
 
 
56
  <input type="checkbox" class="aam-checkbox-danger" id="menu-item-<?php echo $i . $j; ?>" data-menu-id="<?php echo $submenu['id']; ?>"<?php echo ($object->has($submenu['id']) ? ' checked="checked"' : ''); ?> />
57
  <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>
58
  </div>
41
 
42
  <div id="menu-<?php echo $i; ?>" class="panel-collapse collapse<?php if (!$first) { echo ' in'; $first = true; } ?>" role="tabpanel" aria-labelledby="menu-<?php echo $i; ?>-heading">
43
  <div class="panel-body">
44
+ <?php if ($menu['id'] != 'menu-index.php') { ?>
45
+ <div class="row aam-inner-tab">
46
+ <div class="col-xs-12 text-center">
47
+ <small class="aam-menu-capability"><?php echo __('Menu ID:', AAM_KEY); ?> <b><?php echo crc32($menu['id']); ?></b></small>
48
+ </div>
49
+ </div>
50
+ <hr class="aam-divider" />
51
+ <?php } ?>
52
  <?php if (!empty($menu['submenu'])) { ?>
53
  <div class="row aam-inner-tab">
54
  <?php echo ($object->has($menu['id']) ? '<div class="aam-lock"></div>' : ''); ?>
55
  <?php foreach ($menu['submenu'] as $j => $submenu) { ?>
56
  <?php if ($submenu['id'] == 'index.php') { ?>
57
  <div class="col-xs-12 col-md-6 aam-submenu-item">
58
+ <label for="menu-item-<?php echo $i . $j; ?>">
59
+ <u><?php echo $submenu['name']; ?></u><small class="aam-menu-capability"><?php echo __('Cap:', AAM_KEY), ' <b>', $submenu['capability']; ?></b></small></label>
60
  <a href="#dashboard-lockout-modal" data-toggle="modal"><i class="icon-help-circled"></i></a>
61
  </div>
62
  <?php } else { ?>
63
  <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>', crc32($submenu['id']); ?></b></small>
68
+ </label>
69
  <input type="checkbox" class="aam-checkbox-danger" id="menu-item-<?php echo $i . $j; ?>" data-menu-id="<?php echo $submenu['id']; ?>"<?php echo ($object->has($submenu['id']) ? ' checked="checked"' : ''); ?> />
70
  <label for="menu-item-<?php echo $i . $j; ?>" data-toggle="tooltip" title="<?php echo ($object->has($submenu['id']) ? __('Uncheck to allow', AAM_KEY) : __('Check to restrict', AAM_KEY)); ?>"></label>
71
  </div>
Application/Backend/phtml/main/policy.phtml ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (defined('AAM_KEY')) { ?>
2
+ <div class="aam-feature" id="policy-content">
3
+ <?php $subject = AAM_Backend_Subject::getInstance(); ?>
4
+
5
+ <div class="row">
6
+ <div class="col-xs-12">
7
+ <p class="aam-info">
8
+ <?php echo sprintf(AAM_Backend_View_Helper::preparePhrase('Manage access and security policies for [%s]. For more information check %sthis page%s.', 'b'), AAM_Backend_Subject::getInstance()->getName(), '<a href="#" target="_blank">', '</a>'); ?>
9
+ </p>
10
+ </div>
11
+ </div>
12
+
13
+ <div class="row">
14
+ <div class="col-xs-12">
15
+ <div class="aam-overwrite" id="aam-policy-overwrite" style="display: <?php echo ($this->isOverwritten() ? 'block' : 'none'); ?>">
16
+ <span><i class="icon-check"></i> <?php echo __('Policies are customized', AAM_KEY); ?></span>
17
+ <span><a href="#" id="policy-reset" class="btn btn-xs btn-primary"><?php echo __('Reset To Default', AAM_KEY); ?></a>
18
+ </div>
19
+ </div>
20
+ </div>
21
+
22
+ <div class="row">
23
+ <div class="col-xs-12">
24
+ <table id="policy-list" class="table table-striped table-bordered">
25
+ <thead>
26
+ <tr>
27
+ <th>ID</th>
28
+ <th width="80%"><?php echo __('Policy', AAM_KEY); ?></th>
29
+ <th>JSON</th>
30
+ <th><?php echo __('Actions', AAM_KEY); ?></th>
31
+ </tr>
32
+ </thead>
33
+ <tbody></tbody>
34
+ </table>
35
+ </div>
36
+ </div>
37
+
38
+ <div class="modal fade" id="policy-model" tabindex="-1" role="dialog">
39
+ <div class="modal-dialog modal-lg" role="document">
40
+ <div class="modal-content">
41
+ <div class="modal-header">
42
+ <button type="button" class="close" data-dismiss="modal" aria-label="<?php echo __('Close', AAM_KEY); ?>"><span aria-hidden="true">&times;</span></button>
43
+ <h4 class="modal-title"><?php echo __('Manage Policy', AAM_KEY); ?></h4>
44
+ </div>
45
+ <div class="modal-body">
46
+ <div class="form-group">
47
+ <label><?php echo AAM_Backend_View_Helper::preparePhrase('Policy Document', 'small'); ?></label>
48
+ <div class="alert alert-danger hidden" id="policy-parsing-error"></div>
49
+ <div class="aam-outer-top-xxs">
50
+ <textarea id="policy-editor" class="policy-editor" rows="10"></textarea>
51
+ </div>
52
+ </div>
53
+ </div>
54
+ <div class="modal-footer">
55
+ <button type="button" class="btn btn-success" id="policy-save-btn"><?php echo __('Save', AAM_KEY); ?></button>
56
+ <button type="button" class="btn btn-default" data-dismiss="modal"><?php echo __('Close', AAM_KEY); ?></button>
57
+ </div>
58
+ </div>
59
+ </div>
60
+ </div>
61
+
62
+ <div class="modal fade" id="policy-delete-model" tabindex="-1" role="dialog">
63
+ <div class="modal-dialog modal-sm" role="document">
64
+ <div class="modal-content">
65
+ <div class="modal-header">
66
+ <button type="button" class="close" data-dismiss="modal" aria-label="<?php echo __('Close', AAM_KEY); ?>"><span aria-hidden="true">&times;</span></button>
67
+ <h4 class="modal-title"><?php echo __('Delete Policy', AAM_KEY); ?></h4>
68
+ </div>
69
+ <div class="modal-body">
70
+ <div class="form-group">
71
+ <p class="aam-notification">
72
+ You are about to delete the access policy. Please confirm!
73
+ </p>
74
+ </div>
75
+ </div>
76
+ <div class="modal-footer">
77
+ <button type="button" class="btn btn-danger" id="policy-delete-btn"><?php echo __('Delete', AAM_KEY); ?></button>
78
+ <button type="button" class="btn btn-default" data-dismiss="modal"><?php echo __('Close', AAM_KEY); ?></button>
79
+ </div>
80
+ </div>
81
+ </div>
82
+ </div>
83
+ </div>
84
+ <?php }
Application/Backend/phtml/main/route.phtml CHANGED
@@ -5,8 +5,7 @@
5
  <div class="row">
6
  <div class="col-xs-12">
7
  <p class="aam-info">
8
- <?php echo sprintf(AAM_Backend_View_Helper::preparePhrase('Manage access to the website API routes for [%s]. For full RESTful API experience, you might want to use %sJWT authentication%s that is already available in AAM.', 'b'), AAM_Backend_Subject::getInstance()->getName(), '<a href="https://aamplugin.com/help/how-to-authenticate-wordpress-user-with-jwt-token" target="_blank">', '</a>'); ?><br/><br/>
9
- <?php echo AAM_Backend_View_Helper::preparePhrase('[Please note!] It is the initial version of this feature. It can be significantly enhanced with a lot of useful functionality. Your feedback and suggestions are highly appreciated!', 'b'); ?>
10
  </p>
11
  </div>
12
  </div>
5
  <div class="row">
6
  <div class="col-xs-12">
7
  <p class="aam-info">
8
+ <?php echo sprintf(AAM_Backend_View_Helper::preparePhrase('Manage access to the website API routes for [%s]. For full RESTful API experience, you might want to use %sJWT authentication%s that is already available in AAM.', 'b'), AAM_Backend_Subject::getInstance()->getName(), '<a href="https://aamplugin.com/help/how-to-authenticate-wordpress-user-with-jwt-token" target="_blank">', '</a>'); ?>
 
9
  </p>
10
  </div>
11
  </div>
Application/Backend/phtml/main/toolbar.phtml CHANGED
@@ -39,12 +39,22 @@
39
 
40
  <div id="toolbar-<?php echo $branch->id; ?>" class="panel-collapse collapse<?php if (!$first) { echo ' in'; $first = true; } ?>" role="tabpanel" aria-labelledby="toolbar-<?php echo $branch->id; ?>-heading">
41
  <div class="panel-body">
 
 
 
 
 
 
42
  <?php if (!empty($branch->children)) { ?>
43
  <div class="row aam-inner-tab">
44
  <?php echo ($object->has('toolbar-' . $branch->id) ? '<div class="aam-lock"></div>' : ''); ?>
45
  <?php foreach($this->getAllChildren($branch) as $child) { ?>
46
  <div class="col-xs-12 aam-submenu-item">
47
- <label for="toolbar-<?php echo $child->id; ?>"><u><?php echo $this->normalizeTitle($child); ?></u><small class="aam-menu-capability"><?php echo str_replace(site_url(), '', $child->href); ?></b></small></label>
 
 
 
 
48
  <input type="checkbox" class="aam-checkbox-danger" id="toolbar-<?php echo $child->id; ?>" data-toolbar="<?php echo $child->id; ?>"<?php echo ($object->has($child->id) ? ' checked="checked"' : ''); ?> />
49
  <label for="toolbar-<?php echo $child->id; ?>" data-toggle="tooltip" title="<?php echo ($object->has($child->id) ? __('Uncheck to allow', AAM_KEY) : __('Check to restrict', AAM_KEY)); ?>"></label>
50
  </div>
39
 
40
  <div id="toolbar-<?php echo $branch->id; ?>" class="panel-collapse collapse<?php if (!$first) { echo ' in'; $first = true; } ?>" role="tabpanel" aria-labelledby="toolbar-<?php echo $branch->id; ?>-heading">
41
  <div class="panel-body">
42
+ <div class="row aam-inner-tab">
43
+ <div class="col-xs-12 text-center">
44
+ <small class="aam-menu-capability"><?php echo __('Menu ID:', AAM_KEY); ?> <b><?php echo $branch->id; ?></b></small>
45
+ </div>
46
+ </div>
47
+ <hr class="aam-divider" />
48
  <?php if (!empty($branch->children)) { ?>
49
  <div class="row aam-inner-tab">
50
  <?php echo ($object->has('toolbar-' . $branch->id) ? '<div class="aam-lock"></div>' : ''); ?>
51
  <?php foreach($this->getAllChildren($branch) as $child) { ?>
52
  <div class="col-xs-12 aam-submenu-item">
53
+ <label for="toolbar-<?php echo $child->id; ?>">
54
+ <u><?php echo $this->normalizeTitle($child); ?></u>
55
+ <small class="aam-menu-capability"><?php echo __('URI:', AAM_KEY); ?> <b><?php echo str_replace(site_url(), '', $child->href); ?></b></small>
56
+ <small class="aam-menu-capability"><?php echo __('ID:', AAM_KEY); ?> <b><?php echo esc_js($child->id); ?></b></small>
57
+ </label>
58
  <input type="checkbox" class="aam-checkbox-danger" id="toolbar-<?php echo $child->id; ?>" data-toolbar="<?php echo $child->id; ?>"<?php echo ($object->has($child->id) ? ' checked="checked"' : ''); ?> />
59
  <label for="toolbar-<?php echo $child->id; ?>" data-toggle="tooltip" title="<?php echo ($object->has($child->id) ? __('Uncheck to allow', AAM_KEY) : __('Check to restrict', AAM_KEY)); ?>"></label>
60
  </div>
Application/Core/API.php CHANGED
@@ -357,6 +357,7 @@ final class AAM_Core_API {
357
  */
358
  public static function redirect($rule, $args = null) {
359
  $path = wp_parse_url($rule);
 
360
  if ($path && !empty($path['host'])) {
361
  wp_redirect($rule, 307); exit;
362
  } elseif (preg_match('/^[\d]+$/', $rule)) {
357
  */
358
  public static function redirect($rule, $args = null) {
359
  $path = wp_parse_url($rule);
360
+
361
  if ($path && !empty($path['host'])) {
362
  wp_redirect($rule, 307); exit;
363
  } elseif (preg_match('/^[\d]+$/', $rule)) {
Application/Core/Gateway.php CHANGED
@@ -91,6 +91,22 @@ final class AAM_Core_Gateway {
91
  AAM_Core_API::reject(AAM_Core_Api_Area::get(), $params);
92
  }
93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  /**
95
  * Redirect request
96
  *
91
  AAM_Core_API::reject(AAM_Core_Api_Area::get(), $params);
92
  }
93
 
94
+ /**
95
+ * Check if current user has access to specified resource
96
+ *
97
+ * Apply all access/security policies and identify if user has access to specified
98
+ * resource.
99
+ *
100
+ * @param string $resource
101
+ * @param string $action
102
+ *
103
+ * @return mixed Boolean true|false if explicit access is defined or null if no
104
+ * exact match found
105
+ */
106
+ public function isAllowed($resource, $action = null) {
107
+ return AAM::api()->getUser()->getObject('policy')->isAllowed($resource, $action);
108
+ }
109
+
110
  /**
111
  * Redirect request
112
  *
Application/Core/Object/Cache.php CHANGED
@@ -57,13 +57,20 @@ class AAM_Core_Object_Cache extends AAM_Core_Object {
57
  if ($this->enabled) {
58
  // Register shutdown hook
59
  register_shutdown_function(array($this, 'save'));
60
-
61
- // Just get the cache from current subject level. Do not trigger
62
- // inheritance chain!
63
- $this->setOption($this->getSubject()->readOption('cache'));
64
  }
65
  }
66
 
 
 
 
 
 
 
 
 
 
67
  /**
68
  *
69
  * @param type $type
57
  if ($this->enabled) {
58
  // Register shutdown hook
59
  register_shutdown_function(array($this, 'save'));
60
+
61
+ $this->reload();
 
 
62
  }
63
  }
64
 
65
+ /**
66
+ *
67
+ */
68
+ public function reload() {
69
+ // Just get the cache from current subject level. Do not trigger
70
+ // inheritance chain!
71
+ $this->setOption($this->getSubject()->readOption('cache'));
72
+ }
73
+
74
  /**
75
  *
76
  * @param type $type
Application/Core/Object/Menu.php CHANGED
@@ -186,17 +186,24 @@ class AAM_Core_Object_Menu extends AAM_Core_Object {
186
  public function has($menu, $both = false) {
187
  //decode URL in case of any special characters like &amp;
188
  $decoded = htmlspecialchars_decode($menu);
 
189
  $options = $this->getOption();
190
  $parent = $this->getParentMenu($decoded);
191
 
 
 
 
 
 
 
192
  // Step #1. Check if menu is directly restricted
193
- $direct = !empty($options[$decoded]);
194
 
195
  // Step #2. Check if whole branch is restricted
196
- $branch = ($both && !empty($options['menu-' . $decoded]));
197
 
198
  // Step #3. Check if dynamic submenu is restricted because of whole branch
199
- $indirect = ($parent && !empty($options['menu-' . $parent]));
200
 
201
  return $direct || $branch || $indirect;
202
  }
186
  public function has($menu, $both = false) {
187
  //decode URL in case of any special characters like &amp;
188
  $decoded = htmlspecialchars_decode($menu);
189
+
190
  $options = $this->getOption();
191
  $parent = $this->getParentMenu($decoded);
192
 
193
+ // Policy API
194
+ $api = AAM::api();
195
+ $crc = crc32($decoded);
196
+ $bcrc = crc32('menu-' . $decoded);
197
+ $pcrc = crc32('menu-' . $parent);
198
+
199
  // Step #1. Check if menu is directly restricted
200
+ $direct = !empty($options[$decoded]) || ($api->isAllowed("BackendMenu:{$crc}") === false);
201
 
202
  // Step #2. Check if whole branch is restricted
203
+ $branch = ($both && (!empty($options['menu-' . $decoded]) || ($api->isAllowed("BackendMenu:{$bcrc}") === false)));
204
 
205
  // Step #3. Check if dynamic submenu is restricted because of whole branch
206
+ $indirect = ($parent && (!empty($options['menu-' . $parent]) || ($api->isAllowed("BackendMenu:{$pcrc}") === false)));
207
 
208
  return $direct || $branch || $indirect;
209
  }
Application/Core/Object/Metabox.php CHANGED
@@ -166,8 +166,11 @@ class AAM_Core_Object_Metabox extends AAM_Core_Object {
166
  */
167
  public function has($screen, $metabox) {
168
  $options = $this->getOption();
 
 
 
169
 
170
- return !empty($options[$screen][$metabox]);
171
  }
172
 
173
  /**
166
  */
167
  public function has($screen, $metabox) {
168
  $options = $this->getOption();
169
+
170
+ $area = ($screen === 'widgets' ? 'Widget' : 'Metabox');
171
+ $isAllowed = AAM::api()->isAllowed("{$area}:{$metabox}");
172
 
173
+ return !empty($options[$screen][$metabox]) || ($isAllowed === false);
174
  }
175
 
176
  /**
Application/Core/Object/Policy.php ADDED
@@ -0,0 +1,227 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ * Policy object
12
+ *
13
+ * @package AAM
14
+ * @author Vasyl Martyniuk <vasyl@vasyltech.com>
15
+ */
16
+ class AAM_Core_Object_Policy extends AAM_Core_Object {
17
+
18
+ /**
19
+ *
20
+ * @var type
21
+ */
22
+ protected $resources = array();
23
+
24
+ /**
25
+ * Constructor
26
+ *
27
+ * @param AAM_Core_Subject $subject
28
+ *
29
+ * @return void
30
+ *
31
+ * @access public
32
+ */
33
+ public function __construct(AAM_Core_Subject $subject) {
34
+ parent::__construct($subject);
35
+
36
+ $parent = $this->getSubject()->inheritFromParent('policy');
37
+ if(empty($parent)) {
38
+ $parent = array();
39
+ }
40
+
41
+ $option = $this->getSubject()->readOption('policy');
42
+ if (empty($option)) {
43
+ $option = array();
44
+ } else {
45
+ $this->setOverwritten(true);
46
+ }
47
+
48
+ $this->setOption(array_merge($parent, $option));
49
+ }
50
+
51
+ /**
52
+ *
53
+ */
54
+ public function load() {
55
+ $resources = AAM::api()->getUser()->getObject('cache')->get('policy', 0, null);
56
+
57
+ if (is_null($resources)) {
58
+ $policies = AAM_Core_API::getOption('aam-policy-list', array(), 'site');
59
+ $statements = array();
60
+
61
+ // Step #1. Extract all statements
62
+ foreach($this->getOption() as $id => $effect) {
63
+ if (isset($policies[$id]) && $effect) {
64
+ $policy = json_decode($policies[$id], true);
65
+ $statements = array_merge(
66
+ $statements, $this->extractStatements($policy)
67
+ );
68
+ }
69
+ }
70
+
71
+ // Step #2. Merge all statements
72
+ $resources = array();
73
+
74
+ foreach($statements as $statement) {
75
+ if (isset($statement['Resource'])) {
76
+ $actions = (array)(isset($statement['Action']) ? $statement['Action'] : '');
77
+
78
+ foreach((array) $statement['Resource'] as $resource) {
79
+ foreach($actions as $action) {
80
+ $id = strtolower(
81
+ $resource . (!empty($action) ? ":{$action}" : '')
82
+ );
83
+
84
+ if (!isset($resources[$id])) {
85
+ $resources[$id] = $statement;
86
+ } elseif (empty($resources[$id]['Enforce'])) {
87
+ $resources[$id] = $this->mergeStatements(
88
+ $resources[$id], $statement
89
+ );
90
+ }
91
+
92
+ // cleanup
93
+ if (isset($resources[$id]['Resource'])) { unset($resources[$id]['Resource']); }
94
+ if (isset($resources[$id]['Action'])) { unset($resources[$id]['Action']); }
95
+ }
96
+ }
97
+ }
98
+ }
99
+
100
+ AAM::api()->getUser()->getObject('cache')->add('policy', 0, $resources);
101
+ }
102
+
103
+ $this->resources = $resources;
104
+ }
105
+
106
+ /**
107
+ *
108
+ * @param type $policy
109
+ * @return type
110
+ */
111
+ protected function extractStatements($policy) {
112
+ $statements = array();
113
+
114
+ if (isset($policy['Statement'])) {
115
+ if (is_array($policy['Statement'])) {
116
+ $statements = $policy['Statement'];
117
+ } else {
118
+ $statements = array($policy['Statement']);
119
+ }
120
+ }
121
+
122
+ // normalize each statement
123
+ foreach(array('Action', 'Condition') as $prop) {
124
+ foreach($statements as $i => $statement) {
125
+ if (isset($statement[$prop])) {
126
+ $statements[$i][$prop] = (array) $statement[$prop];
127
+ }
128
+ }
129
+ }
130
+
131
+ return $statements;
132
+ }
133
+
134
+ /**
135
+ *
136
+ * @param type $left
137
+ * @param type $right
138
+ * @return type
139
+ */
140
+ protected function mergeStatements($left, $right) {
141
+ if (isset($right['Resource'])) {
142
+ unset($right['Resource']);
143
+ }
144
+
145
+ $merged = array_merge_recursive($left, $right);
146
+
147
+ if (!isset($merged['Effect'])) {
148
+ $merged['Effect'] = 'deny';
149
+ }
150
+
151
+ return $merged;
152
+ }
153
+
154
+ /**
155
+ * Save menu option
156
+ *
157
+ * @return bool
158
+ *
159
+ * @access public
160
+ */
161
+ public function save($title, $policy) {
162
+ $option = $this->getOption();
163
+ $option[$title] = $policy;
164
+
165
+ $this->setOption($option);
166
+
167
+ return $this->getSubject()->updateOption($this->getOption(), 'policy');
168
+ }
169
+
170
+ /**
171
+ *
172
+ * @param type $id
173
+ */
174
+ public function has($id) {
175
+ $option = $this->getOption();
176
+
177
+ return !empty($option[$id]);
178
+ }
179
+
180
+ /**
181
+ *
182
+ * @param type $resource
183
+ * @return type
184
+ */
185
+ public function isAllowed($resource, $action = null) {
186
+ $allowed = null;
187
+
188
+ $id = strtolower($resource . (!empty($action) ? ":{$action}" : ''));
189
+
190
+ if (isset($this->resources[$id])) {
191
+ $allowed = ($this->resources[$id]['Effect'] === 'allow');
192
+ }
193
+
194
+ return $allowed;
195
+ }
196
+
197
+ /**
198
+ *
199
+ * @param type $id
200
+ *
201
+ * @return type
202
+ */
203
+ public function delete($id) {
204
+ $option = $this->getOption();
205
+ if (isset($option[$id])) {
206
+ unset($option[$id]);
207
+ }
208
+ $this->setOption($option);
209
+
210
+ return $this->getSubject()->updateOption($this->getOption(), 'policy');
211
+ }
212
+
213
+ /**
214
+ * Reset default settings
215
+ *
216
+ * @return bool
217
+ *
218
+ * @access public
219
+ */
220
+ public function reset() {
221
+ //clear cache
222
+ AAM_Core_API::clearCache();
223
+
224
+ return $this->getSubject()->deleteOption('policy');
225
+ }
226
+
227
+ }
Application/Core/Object/Toolbar.php CHANGED
@@ -52,11 +52,14 @@ class AAM_Core_Object_Toolbar extends AAM_Core_Object {
52
  public function has($item, $both = false) {
53
  $options = $this->getOption();
54
 
 
 
 
55
  // Step #1. Check if toolbar item is directly restricted
56
- $direct = !empty($options[$item]);
57
 
58
  // Step #2. Check if whole branch is restricted
59
- $branch = ($both && !empty($options['toolbar-' . $item]));
60
 
61
  return $direct || $branch;
62
  }
52
  public function has($item, $both = false) {
53
  $options = $this->getOption();
54
 
55
+ // Policy API
56
+ $api = AAM::api();
57
+
58
  // Step #1. Check if toolbar item is directly restricted
59
+ $direct = !empty($options[$item]) || ($api->isAllowed("Toolbar:{$item}") === false);
60
 
61
  // Step #2. Check if whole branch is restricted
62
+ $branch = ($both && (!empty($options['toolbar-' . $item]) || ($api->isAllowed("Toolbar:toolbar-{$item}") === false)));
63
 
64
  return $direct || $branch;
65
  }
Application/Core/Subject.php CHANGED
@@ -74,7 +74,7 @@ abstract class AAM_Core_Subject {
74
  //retrieve and set subject itself
75
  $this->setSubject($this->retrieveSubject());
76
  }
77
-
78
  /**
79
  * Trigger Subject native methods
80
  *
@@ -238,7 +238,7 @@ abstract class AAM_Core_Subject {
238
  $id = (is_scalar($id) ? $id : 'none'); //prevent from any surprises
239
 
240
  //check if there is an object with specified ID
241
- if (!isset($this->_objects[$type][$id]) || ($type === 'cache')) {
242
  $classname = 'AAM_Core_Object_' . ucfirst($type);
243
 
244
  if (class_exists($classname)) {
74
  //retrieve and set subject itself
75
  $this->setSubject($this->retrieveSubject());
76
  }
77
+
78
  /**
79
  * Trigger Subject native methods
80
  *
238
  $id = (is_scalar($id) ? $id : 'none'); //prevent from any surprises
239
 
240
  //check if there is an object with specified ID
241
+ if (!isset($this->_objects[$type][$id])) {
242
  $classname = 'AAM_Core_Object_' . ucfirst($type);
243
 
244
  if (class_exists($classname)) {
Application/Extension/List.php CHANGED
@@ -22,7 +22,8 @@ class AAM_Extension_List {
22
  'description' => 'Get the complete list of all premium AAM extensions in one package and all future premium extensions already included for now additional cost.',
23
  'url' => 'https://aamplugin.com/complete-package',
24
  'version' => (defined('AAM_COMPLETE_PACKAGE') ? constant('AAM_COMPLETE_PACKAGE') : null),
25
- 'latest' => '3.8.9'
 
26
  ),
27
  'AAM_PLUS_PACKAGE' => array(
28
  'title' => 'Plus Package',
@@ -31,7 +32,8 @@ class AAM_Extension_List {
31
  'description' => 'Manage access to your WordPress website posts, pages, media, custom post types, categories and hierarchical taxonomies for any role, individual user, visitors or even define default access for everybody; and do this separately for frontend, backend or API levels. As the bonus, define more granular access to how comments can be managed on the backend by other users.',
32
  'url' => 'https://aamplugin.com/extension/plus-package',
33
  'version' => (defined('AAM_PLUS_PACKAGE') ? constant('AAM_PLUS_PACKAGE') : null),
34
- 'latest' => '3.8.3'
 
35
  ),
36
  'AAM_IP_CHECK' => array(
37
  'title' => 'IP Check',
@@ -40,7 +42,8 @@ class AAM_Extension_List {
40
  'description' => 'Manage access to your WordPress website by visitor\'s IP address and referred hosts or completely lockdown the entire website and allow only certain IP ranges.',
41
  'url' => 'https://aamplugin.com/extension/ip-check',
42
  'version' => (defined('AAM_IP_CHECK') ? constant('AAM_IP_CHECK') : null),
43
- 'latest' => '2.0'
 
44
  ),
45
  'AAM_ROLE_HIERARCHY' => array(
46
  'title' => 'Role Hierarchy',
@@ -49,7 +52,8 @@ class AAM_Extension_List {
49
  'description' => 'Define and manage complex WordPress role hierarchy where child role inherits all access settings from its parent with ability to override setting for any specific role.',
50
  'url' => 'https://aamplugin.com/extension/role-hierarchy',
51
  'version' => (defined('AAM_ROLE_HIERARCHY') ? constant('AAM_ROLE_HIERARCHY') : null),
52
- 'latest' => '1.4'
 
53
  ),
54
  'AAM_ECOMMERCE' => array(
55
  'title' => 'E-Commerce',
@@ -59,7 +63,8 @@ class AAM_Extension_List {
59
  'description' => 'Start monetizing access to your premium content. Restrict access to read any WordPress post, page or custom post type until user purchase access to it.',
60
  'url' => 'https://aamplugin.com/extension/ecommerce',
61
  'version' => (defined('AAM_ECOMMERCE') ? constant('AAM_ECOMMERCE') : null),
62
- 'latest' => '1.2.1'
 
63
  ),
64
  'AAM_MULTISITE' => array(
65
  'title' => 'Multisite',
@@ -68,7 +73,8 @@ class AAM_Extension_List {
68
  'license' => 'AAMMULTISITE',
69
  'description' => 'Convenient way to navigate between different sites in the Network Admin Panel. This is the open source solution and you can find it on the <a href="https://github.com/aamplugin/multisite-extension" target="_blank">Github here</a>.',
70
  'version' => (defined('AAM_MULTISITE') ? constant('AAM_MULTISITE') : null),
71
- 'latest' => '2.5.4'
 
72
  ),
73
  'AAM_USER_ACTIVITY' => array(
74
  'title' => 'User Activities',
@@ -77,7 +83,8 @@ class AAM_Extension_List {
77
  'license' => 'AAMUSERACTIVITY',
78
  'description' => 'Track any kind of user or visitor activity on your website. <a href="https://aamplugin.com/help/how-to-track-any-wordpress-user-activity" target="_blank">Read more.</a> This is the open source solution and you can find it on the <a href="https://github.com/aamplugin/user-activity-extension" target="_blank">Github here</a>.',
79
  'version' => (defined('AAM_USER_ACTIVITY') ? constant('AAM_USER_ACTIVITY') : null),
80
- 'latest' => '1.4.1'
 
81
  ),
82
  'AAM_SOCIAL_LOGIN' => array(
83
  'title' => 'Social Login',
@@ -87,7 +94,8 @@ class AAM_Extension_List {
87
  'license' => 'AAMSOCIALLOGIN',
88
  'description' => 'Login to your website with social networks like Facebook, Twitter, Instagram etc. <a href="https://aamplugin.com/help/how-does-aam-social-login-works" target="_blank">Read more.</a> This is the open source solution and you can find it on the <a href="https://github.com/aamplugin/social-login-extension" target="_blank">Github here</a>.',
89
  'version' => (defined('AAM_SOCIAL_LOGIN') ? constant('AAM_SOCIAL_LOGIN') : null),
90
- 'latest' => '0.2.1'
 
91
  ),
92
  );
93
  }
22
  'description' => 'Get the complete list of all premium AAM extensions in one package and all future premium extensions already included for now additional cost.',
23
  'url' => 'https://aamplugin.com/complete-package',
24
  'version' => (defined('AAM_COMPLETE_PACKAGE') ? constant('AAM_COMPLETE_PACKAGE') : null),
25
+ 'latest' => '3.8.10',
26
+ 'requires' => '5.6.1'
27
  ),
28
  'AAM_PLUS_PACKAGE' => array(
29
  'title' => 'Plus Package',
32
  'description' => 'Manage access to your WordPress website posts, pages, media, custom post types, categories and hierarchical taxonomies for any role, individual user, visitors or even define default access for everybody; and do this separately for frontend, backend or API levels. As the bonus, define more granular access to how comments can be managed on the backend by other users.',
33
  'url' => 'https://aamplugin.com/extension/plus-package',
34
  'version' => (defined('AAM_PLUS_PACKAGE') ? constant('AAM_PLUS_PACKAGE') : null),
35
+ 'latest' => '3.8.4',
36
+ 'requires' => '5.6.1'
37
  ),
38
  'AAM_IP_CHECK' => array(
39
  'title' => 'IP Check',
42
  'description' => 'Manage access to your WordPress website by visitor\'s IP address and referred hosts or completely lockdown the entire website and allow only certain IP ranges.',
43
  'url' => 'https://aamplugin.com/extension/ip-check',
44
  'version' => (defined('AAM_IP_CHECK') ? constant('AAM_IP_CHECK') : null),
45
+ 'latest' => '2.0',
46
+ 'requires' => '4.5'
47
  ),
48
  'AAM_ROLE_HIERARCHY' => array(
49
  'title' => 'Role Hierarchy',
52
  'description' => 'Define and manage complex WordPress role hierarchy where child role inherits all access settings from its parent with ability to override setting for any specific role.',
53
  'url' => 'https://aamplugin.com/extension/role-hierarchy',
54
  'version' => (defined('AAM_ROLE_HIERARCHY') ? constant('AAM_ROLE_HIERARCHY') : null),
55
+ 'latest' => '1.4',
56
+ 'requires' => '4.0'
57
  ),
58
  'AAM_ECOMMERCE' => array(
59
  'title' => 'E-Commerce',
63
  'description' => 'Start monetizing access to your premium content. Restrict access to read any WordPress post, page or custom post type until user purchase access to it.',
64
  'url' => 'https://aamplugin.com/extension/ecommerce',
65
  'version' => (defined('AAM_ECOMMERCE') ? constant('AAM_ECOMMERCE') : null),
66
+ 'latest' => '1.2.2',
67
+ 'requires' => '5.6.1'
68
  ),
69
  'AAM_MULTISITE' => array(
70
  'title' => 'Multisite',
73
  'license' => 'AAMMULTISITE',
74
  'description' => 'Convenient way to navigate between different sites in the Network Admin Panel. This is the open source solution and you can find it on the <a href="https://github.com/aamplugin/multisite-extension" target="_blank">Github here</a>.',
75
  'version' => (defined('AAM_MULTISITE') ? constant('AAM_MULTISITE') : null),
76
+ 'latest' => '2.5.4',
77
+ 'requires' => '4.0'
78
  ),
79
  'AAM_USER_ACTIVITY' => array(
80
  'title' => 'User Activities',
83
  'license' => 'AAMUSERACTIVITY',
84
  'description' => 'Track any kind of user or visitor activity on your website. <a href="https://aamplugin.com/help/how-to-track-any-wordpress-user-activity" target="_blank">Read more.</a> This is the open source solution and you can find it on the <a href="https://github.com/aamplugin/user-activity-extension" target="_blank">Github here</a>.',
85
  'version' => (defined('AAM_USER_ACTIVITY') ? constant('AAM_USER_ACTIVITY') : null),
86
+ 'latest' => '1.4.1',
87
+ 'requires' => '4.5'
88
  ),
89
  'AAM_SOCIAL_LOGIN' => array(
90
  'title' => 'Social Login',
94
  'license' => 'AAMSOCIALLOGIN',
95
  'description' => 'Login to your website with social networks like Facebook, Twitter, Instagram etc. <a href="https://aamplugin.com/help/how-does-aam-social-login-works" target="_blank">Read more.</a> This is the open source solution and you can find it on the <a href="https://github.com/aamplugin/social-login-extension" target="_blank">Github here</a>.',
96
  'version' => (defined('AAM_SOCIAL_LOGIN') ? constant('AAM_SOCIAL_LOGIN') : null),
97
+ 'latest' => '0.2.1',
98
+ 'requires' => '4.5'
99
  ),
100
  );
101
  }
Application/Extension/Repository.php CHANGED
@@ -116,13 +116,32 @@ class AAM_Extension_Repository {
116
  $cache = AAM_Core_Compatibility::getLicenseList();
117
  }
118
 
119
- $load = true;
120
  $config = "{$path}/config.php";
121
  $bootstrap = "{$path}/bootstrap.php";
122
 
123
  if (file_exists($config)) {
124
  $conf = require $config;
125
- $load = empty($cache[$conf['id']]['status']) || ($cache[$conf['id']]['status'] !== self::STATUS_INACTIVE);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  } else { // TODO - Remove May 2019
127
  AAM_Core_Console::add(AAM_Backend_View_Helper::preparePhrase(
128
  sprintf(
116
  $cache = AAM_Core_Compatibility::getLicenseList();
117
  }
118
 
119
+ $load = false;
120
  $config = "{$path}/config.php";
121
  $bootstrap = "{$path}/bootstrap.php";
122
 
123
  if (file_exists($config)) {
124
  $conf = require $config;
125
+
126
+ // determin if extension needs to be loaded based on the status
127
+ $status = empty($cache[$conf['id']]['status']) || ($cache[$conf['id']]['status'] !== self::STATUS_INACTIVE);
128
+
129
+ // determin if extension meets minimum required AAM version
130
+ $list = AAM_Extension_List::get();
131
+ $version = (version_compare(AAM_Core_API::version(), $list[$conf['id']]['requires']) >= 0);
132
+ $load = $status && $version;
133
+
134
+ if (!$version) {
135
+ AAM_Core_Console::add(AAM_Backend_View_Helper::preparePhrase(
136
+ sprintf(
137
+ __('[%s] was not loaded. It requires AAM version [%s] or higher.', AAM_KEY),
138
+ $list[$conf['id']]['title'],
139
+ $list[$conf['id']]['requires']
140
+ ),
141
+ 'b',
142
+ 'b'
143
+ ));
144
+ }
145
  } else { // TODO - Remove May 2019
146
  AAM_Core_Console::add(AAM_Backend_View_Helper::preparePhrase(
147
  sprintf(
Application/Shared/Manager.php CHANGED
@@ -87,6 +87,10 @@ class AAM_Shared_Manager {
87
  }
88
  }
89
 
 
 
 
 
90
  // Security. Make sure that we escaping all translation strings
91
  add_filter(
92
  'gettext', array(self::$_instance, 'escapeTranslation'), 999, 3
@@ -375,6 +379,11 @@ class AAM_Shared_Manager {
375
  $capability = (isset($args[0]) && is_string($args[0]) ? $args[0] : '');
376
  $uid = (isset($args[2]) && is_numeric($args[2]) ? $args[2] : 0);
377
 
 
 
 
 
 
378
  switch($capability) {
379
  case 'edit_user':
380
  case 'delete_user':
87
  }
88
  }
89
 
90
+ // Check if user has ability to perform certain task based on provided
91
+ // capability and meta data
92
+ add_filter('user_has_cap', array(self::$_instance, 'userHasCap'), 999, 3);
93
+
94
  // Security. Make sure that we escaping all translation strings
95
  add_filter(
96
  'gettext', array(self::$_instance, 'escapeTranslation'), 999, 3
379
  $capability = (isset($args[0]) && is_string($args[0]) ? $args[0] : '');
380
  $uid = (isset($args[2]) && is_numeric($args[2]) ? $args[2] : 0);
381
 
382
+ // Apply policy first
383
+ if (AAM::api()->isAllowed("Capability:{$capability}") === true) {
384
+ $caps[$capability] = true;
385
+ }
386
+
387
  switch($capability) {
388
  case 'edit_user':
389
  case 'delete_user':
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.6
7
  Author: Vasyl Martyniuk <vasyl@vasyltech.com>
8
  Author URI: https://vasyltech.com
9
 
@@ -115,6 +115,17 @@ class AAM {
115
  //load AAM core config
116
  AAM_Core_Config::bootstrap();
117
 
 
 
 
 
 
 
 
 
 
 
 
118
  //load WP Core hooks
119
  AAM_Shared_Manager::bootstrap();
120
 
@@ -138,14 +149,6 @@ class AAM {
138
  * @static
139
  */
140
  public static function onInit() {
141
- // Load AAM
142
- AAM::getInstance();
143
-
144
- //load all installed extension
145
- if (AAM_Core_Config::get('core.settings.extensionSupport', true)) {
146
- AAM_Extension_Repository::getInstance()->load();
147
- }
148
-
149
  //load media control
150
  AAM_Core_Media::bootstrap();
151
 
3
  /**
4
  Plugin Name: Advanced Access Manager
5
  Description: All you need to manage access to your WordPress website
6
+ Version: 5.6.1
7
  Author: Vasyl Martyniuk <vasyl@vasyltech.com>
8
  Author URI: https://vasyltech.com
9
 
115
  //load AAM core config
116
  AAM_Core_Config::bootstrap();
117
 
118
+ // Load AAM
119
+ AAM::getInstance();
120
+
121
+ //load all installed extension
122
+ if (AAM_Core_Config::get('core.settings.extensionSupport', true)) {
123
+ AAM_Extension_Repository::getInstance()->load();
124
+ }
125
+
126
+ // Load Access/Security Policies
127
+ self::getUser()->getObject('policy')->load();
128
+
129
  //load WP Core hooks
130
  AAM_Shared_Manager::bootstrap();
131
 
149
  * @static
150
  */
151
  public static function onInit() {
 
 
 
 
 
 
 
 
152
  //load media control
153
  AAM_Core_Media::bootstrap();
154
 
media/css/aam.css CHANGED
@@ -945,6 +945,10 @@ input[type=radio]:checked + label:before {
945
  margin-bottom: 20px !important;
946
  }
947
 
 
 
 
 
948
  .aam-info-modal, .aam-info-modal p, .aam-info-modal ul {
949
  font-size: 1.1em;
950
  -moz-hyphens: auto;
@@ -1057,6 +1061,15 @@ input[type=radio]:checked + label:before {
1057
  color: rgba(220, 220, 220, 0.8);
1058
  }
1059
 
 
 
 
 
 
 
 
 
 
1060
  .aam-current-subject {
1061
  background-color: #337ab7;
1062
  padding: 5px 15px 4px 10px;
@@ -1164,14 +1177,12 @@ input[type=radio]:checked + label:before {
1164
  /* GUTTER */
1165
 
1166
  .CodeMirror-gutters {
1167
- border-right: 1px solid #ddd;
1168
- background-color: #f7f7f7;
1169
  white-space: nowrap;
1170
  }
1171
  .CodeMirror-linenumbers {}
1172
  .CodeMirror-linenumber {
1173
- padding: 0 3px 0 5px;
1174
- min-width: 20px;
1175
  text-align: right;
1176
  color: #999;
1177
  white-space: nowrap;
@@ -1395,6 +1406,9 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
1395
  -webkit-font-variant-ligatures: contextual;
1396
  font-variant-ligatures: contextual;
1397
  }
 
 
 
1398
  .CodeMirror-wrap pre {
1399
  word-wrap: break-word;
1400
  white-space: pre-wrap;
945
  margin-bottom: 20px !important;
946
  }
947
 
948
+ .aam-outer-top-xxs {
949
+ margin-top: 10px;
950
+ }
951
+
952
  .aam-info-modal, .aam-info-modal p, .aam-info-modal ul {
953
  font-size: 1.1em;
954
  -moz-hyphens: auto;
1061
  color: rgba(220, 220, 220, 0.8);
1062
  }
1063
 
1064
+ .json-editor-blackbord {
1065
+ background: #333333 !important;
1066
+ border-radius: 0;
1067
+ padding: 10px 25px;
1068
+ border: 0;
1069
+ max-height: 60vh;
1070
+ overflow-y: scroll;
1071
+ }
1072
+
1073
  .aam-current-subject {
1074
  background-color: #337ab7;
1075
  padding: 5px 15px 4px 10px;
1177
  /* GUTTER */
1178
 
1179
  .CodeMirror-gutters {
 
 
1180
  white-space: nowrap;
1181
  }
1182
  .CodeMirror-linenumbers {}
1183
  .CodeMirror-linenumber {
1184
+ padding: 0 3px 0 0px;
1185
+ min-width: 15px;
1186
  text-align: right;
1187
  color: #999;
1188
  white-space: nowrap;
1406
  -webkit-font-variant-ligatures: contextual;
1407
  font-variant-ligatures: contextual;
1408
  }
1409
+ #policy-model .CodeMirror pre {
1410
+ padding-left: 20px;
1411
+ }
1412
  .CodeMirror-wrap pre {
1413
  word-wrap: break-word;
1414
  white-space: pre-wrap;
media/js/aam.js CHANGED
@@ -1111,6 +1111,295 @@
1111
  });
1112
 
1113
  })(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1114
 
1115
 
1116
  /**
@@ -1565,6 +1854,7 @@
1565
  }
1566
  });
1567
  }
 
1568
  /**
1569
  *
1570
  * @returns {undefined}
@@ -1620,6 +1910,18 @@
1620
  save(data[0], this);
1621
  }));
1622
  break;
 
 
 
 
 
 
 
 
 
 
 
 
1623
 
1624
  case 'edit':
1625
  $(container).append($('<i/>', {
1111
  });
1112
 
1113
  })(jQuery);
1114
+
1115
+ /**
1116
+ * Policy Interface
1117
+ *
1118
+ * @param {jQuery} $
1119
+ *
1120
+ * @returns {void}
1121
+ */
1122
+ (function ($) {
1123
+ var editor = null;
1124
+
1125
+ /**
1126
+ *
1127
+ * @param {type} id
1128
+ * @param {type} effect
1129
+ * @returns {undefined}
1130
+ */
1131
+ function assign(id, btn) {
1132
+ var effect = $(btn).hasClass('icon-check-empty') ? 1 : 0;
1133
+
1134
+ //show indicator
1135
+ $(btn).attr('class', 'aam-row-action icon-spin4 animate-spin');
1136
+
1137
+ getAAM().queueRequest(function() {
1138
+ $.ajax(getLocal().ajaxurl, {
1139
+ type: 'POST',
1140
+ dataType: 'json',
1141
+ data: {
1142
+ action: 'aam',
1143
+ sub_action: 'Main_Policy.save',
1144
+ subject: getAAM().getSubject().type,
1145
+ subjectId: getAAM().getSubject().id,
1146
+ _ajax_nonce: getLocal().nonce,
1147
+ id: id,
1148
+ effect: effect
1149
+ },
1150
+ success: function(response) {
1151
+ if (response.status === 'success') {
1152
+ if (effect) {
1153
+ $(btn).attr('class', 'aam-row-action text-success icon-check');
1154
+ } else {
1155
+ $(btn).attr('class', 'aam-row-action text-muted icon-check-empty');
1156
+ }
1157
+ } else {
1158
+ if (effect) {
1159
+ getAAM().notification(
1160
+ 'danger',
1161
+ getAAM().__('Failed to apply policy changes')
1162
+ );
1163
+ $(btn).attr('class', 'aam-row-action text-muted icon-check-empty');
1164
+ } else {
1165
+ $(btn).attr('class', 'aam-row-action text-success icon-check');
1166
+ }
1167
+ }
1168
+ },
1169
+ error: function () {
1170
+ getAAM().notification(
1171
+ 'danger', getAAM().__('Application Error')
1172
+ );
1173
+ }
1174
+ });
1175
+ });
1176
+ }
1177
+
1178
+ function initialize() {
1179
+ var container = '#policy-content';
1180
+
1181
+ if ($(container).length) {
1182
+ //reset button
1183
+ $('#policy-reset').bind('click', function () {
1184
+ getAAM().reset('policy', $(this));
1185
+ });
1186
+
1187
+ editor = CodeMirror.fromTextArea(
1188
+ document.getElementById("policy-editor"),
1189
+ {
1190
+ mode: "application/json",
1191
+ lineNumbers: true
1192
+ }
1193
+ );
1194
+
1195
+ $('#policy-save-btn').bind('click', function() {
1196
+ var json = editor.getValue();
1197
+
1198
+ $('#policy-parsing-error').addClass('hidden');
1199
+ try {
1200
+ JSON.parse(json);
1201
+
1202
+ getAAM().queueRequest(function() {
1203
+ $.ajax(getLocal().ajaxurl, {
1204
+ type: 'POST',
1205
+ dataType: 'json',
1206
+ data: {
1207
+ action: 'aam',
1208
+ sub_action: 'Main_Policy.savePolicy',
1209
+ subject: getAAM().getSubject().type,
1210
+ subjectId: getAAM().getSubject().id,
1211
+ _ajax_nonce: getLocal().nonce,
1212
+ policy: json,
1213
+ id: $('#policy-save-btn').attr('data-id')
1214
+ },
1215
+ beforeSend: function () {
1216
+ $('#policy-save-btn').text(getAAM().__('Saving...')).attr('disabled', true);
1217
+ },
1218
+ success: function(response) {
1219
+ if (response.status === 'success') {
1220
+ $('#policy-list').DataTable().ajax.reload();
1221
+ $('#policy-model').modal('hide');
1222
+ } else {
1223
+ aam.notification(
1224
+ 'danger', aam.__('Failed to save policy')
1225
+ );
1226
+ }
1227
+ },
1228
+ error: function () {
1229
+ getAAM().notification(
1230
+ 'danger', getAAM().__('Application Error')
1231
+ );
1232
+ },
1233
+ complete: function () {
1234
+ $('#policy-save-btn').text(getAAM().__('Save')).attr('disabled', false);
1235
+ }
1236
+ });
1237
+ });
1238
+ } catch (e) {
1239
+ $('#policy-parsing-error').removeClass('hidden').html(
1240
+ '<b>' + getAAM().__('Syntax Error') + '</b>: ' + e.message.replace('JSON.parse:', '')
1241
+ );
1242
+ }
1243
+ });
1244
+
1245
+ $('#policy-delete-btn').bind('click', function (event) {
1246
+ event.preventDefault();
1247
+
1248
+ $.ajax(aamLocal.ajaxurl, {
1249
+ type: 'POST',
1250
+ dataType: 'json',
1251
+ data: {
1252
+ action: 'aam',
1253
+ sub_action: 'Main_Policy.deletePolicy',
1254
+ _ajax_nonce: aamLocal.nonce,
1255
+ subject: getAAM().getSubject().type,
1256
+ subjectId: getAAM().getSubject().id,
1257
+ id: $('#policy-delete-btn').data('id')
1258
+ },
1259
+ beforeSend: function () {
1260
+ $('#policy-delete-btn').text(aam.__('Deleting...')).attr('disabled', true);
1261
+ },
1262
+ success: function (response) {
1263
+ if (response.status === 'success') {
1264
+ $('#policy-list').DataTable().ajax.reload();
1265
+ } else {
1266
+ getAAM().notification(
1267
+ 'danger',
1268
+ getAAM().__('Failed to delete policy')
1269
+ );
1270
+ }
1271
+ },
1272
+ error: function () {
1273
+ getAAM().notification(
1274
+ 'danger',
1275
+ getAAM().__('Application error')
1276
+ );
1277
+ },
1278
+ complete: function () {
1279
+ $('#policy-delete-model').modal('hide');
1280
+ $('#policy-delete-btn').text(getAAM().__('Delete')).attr('disabled', false);
1281
+ }
1282
+ });
1283
+ });
1284
+
1285
+ $('#policy-list').DataTable({
1286
+ autoWidth: false,
1287
+ ordering: false,
1288
+ dom: 'ftrip',
1289
+ pagingType: 'simple',
1290
+ processing: true,
1291
+ stateSave: true,
1292
+ serverSide: false,
1293
+ ajax: {
1294
+ url: aamLocal.ajaxurl,
1295
+ type: 'POST',
1296
+ dataType: 'json',
1297
+ data: {
1298
+ action: 'aam',
1299
+ sub_action: 'Main_Policy.getTable',
1300
+ _ajax_nonce: aamLocal.nonce,
1301
+ subject: getAAM().getSubject().type,
1302
+ subjectId: getAAM().getSubject().id
1303
+ }
1304
+ },
1305
+ language: {
1306
+ search: '_INPUT_',
1307
+ searchPlaceholder: getAAM().__('Search Policy'),
1308
+ info: getAAM().__('_TOTAL_ Policies'),
1309
+ infoFiltered: ''
1310
+ },
1311
+ columnDefs: [
1312
+ {visible: false, targets: [0,2]}
1313
+ ],
1314
+ initComplete: function () {
1315
+ var create = $('<a/>', {
1316
+ 'href': '#',
1317
+ 'class': 'btn btn-success'
1318
+ }).html('<i class="icon-plus"></i> ' + getAAM().__('Create'))
1319
+ .bind('click', function () {
1320
+ $('#policy-parsing-error').addClass('hidden');
1321
+ $('#policy-save-btn').removeAttr('data-id');
1322
+
1323
+ $('#policy-model').modal('show');
1324
+ setTimeout(function() {
1325
+ editor.setValue('');
1326
+ editor.focus();
1327
+ }, 500);
1328
+ });
1329
+
1330
+ $('.dataTables_filter', '#policy-list_wrapper').append(create);
1331
+ },
1332
+ createdRow: function (row, data) {
1333
+ var actions = data[3].split(',');
1334
+
1335
+ var container = $('<div/>', {'class': 'aam-row-actions'});
1336
+ $.each(actions, function (i, action) {
1337
+ switch (action) {
1338
+ case 'assign':
1339
+ $(container).append($('<i/>', {
1340
+ 'class': 'aam-row-action text-muted icon-check-empty'
1341
+ }).bind('click', function () {
1342
+ assign(data[0], this);
1343
+ }).attr({
1344
+ 'data-toggle': "tooltip",
1345
+ 'title': getAAM().__('Apply Policy')
1346
+ }));
1347
+ break;
1348
+
1349
+ case 'unassign':
1350
+ $(container).append($('<i/>', {
1351
+ 'class': 'aam-row-action text-success icon-check'
1352
+ }).bind('click', function () {
1353
+ assign(data[0], this);
1354
+ }).attr({
1355
+ 'data-toggle': "tooltip",
1356
+ 'title': getAAM().__('Revoke Policy')
1357
+ }));
1358
+ break;
1359
+
1360
+ case 'edit':
1361
+ $(container).append($('<i/>', {
1362
+ 'class': 'aam-row-action icon-pencil text-warning'
1363
+ }).bind('click', function () {
1364
+ $('#policy-save-btn').attr('data-id', data[0]);
1365
+ $('#policy-model').modal('show');
1366
+ setTimeout(function() {
1367
+ editor.setValue(data[2]);
1368
+ editor.focus();
1369
+ }, 500);
1370
+ }).attr({
1371
+ 'data-toggle': "tooltip",
1372
+ 'title': getAAM().__('Edit Policy')
1373
+ }));
1374
+ break;
1375
+
1376
+ case 'delete':
1377
+ $(container).append($('<i/>', {
1378
+ 'class': 'aam-row-action icon-trash-empty text-danger'
1379
+ }).bind('click', function () {
1380
+ $('#policy-delete-btn').attr('data-id', data[0]);
1381
+ $('#policy-delete-model').modal('show');
1382
+ }).attr({
1383
+ 'data-toggle': "tooltip",
1384
+ 'title': getAAM().__('Delete Policy')
1385
+ }));
1386
+ break;
1387
+
1388
+ default:
1389
+ break;
1390
+ }
1391
+ });
1392
+ $('td:eq(1)', row).html(container);
1393
+
1394
+ $('td:eq(0)', row).html(data[1]);
1395
+ }
1396
+ });
1397
+ }
1398
+ }
1399
+
1400
+ getAAM().addHook('init', initialize);
1401
+
1402
+ })(jQuery);
1403
 
1404
 
1405
  /**
1854
  }
1855
  });
1856
  }
1857
+
1858
  /**
1859
  *
1860
  * @returns {undefined}
1910
  save(data[0], this);
1911
  }));
1912
  break;
1913
+
1914
+ case 'no-unchecked':
1915
+ $(container).append($('<i/>', {
1916
+ 'class': 'aam-row-action text-muted icon-check-empty'
1917
+ }));
1918
+ break;
1919
+
1920
+ case 'no-checked':
1921
+ $(container).append($('<i/>', {
1922
+ 'class': 'aam-row-action text-muted icon-check'
1923
+ }));
1924
+ break;
1925
 
1926
  case 'edit':
1927
  $(container).append($('<i/>', {
media/js/vendor.js CHANGED
@@ -560,6 +560,42 @@ za;a.rmClass=Ua;a.keyNames=Ga})(F);F.version="5.34.0";return F});
560
  (function(X){"object"==typeof exports&&"object"==typeof module?X(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],X):X(CodeMirror)})(function(X){X.defineMode("properties",function(){return{token:function(I,D){var u=I.sol()||D.afterSection,U=I.eol();D.afterSection=!1;u&&(D.nextMultiline?(D.inMultiline=!0,D.nextMultiline=!1):D.position="def");U&&!D.nextMultiline&&(D.inMultiline=!1,D.position="def");if(u)for(;I.eatSpace(););U=I.next();if(!u||"#"!==
561
  U&&"!"!==U&&";"!==U){if(u&&"["===U)return D.afterSection=!0,I.skipTo("]"),I.eat("]"),"header";if("="===U||":"===U)return D.position="quote",null;"\\"===U&&"quote"===D.position&&I.eol()&&(D.nextMultiline=!0)}else return D.position="comment",I.skipToEnd(),"comment";return D.position},startState:function(){return{position:"def",nextMultiline:!1,inMultiline:!1,afterSection:!1}}}});X.defineMIME("text/x-properties","properties");X.defineMIME("text/x-ini","properties")});
562