WP Security Audit Log - Version 1.5.0

Version Description

(2015-03-18) = * New Features * Ability to exclude custom fields from monitoring (custom fields can be excluded from the Audit Log Viewer with a simple click or you can specify them in the settings) * Ability to exclude WordPress users and roles from monitoring

  • Improvements

    • WP Security Audit Log now has its own settings table in WordPress database. This will provide us with more flexibility and have more centralization of data
    • Updated the code where is_admin() function was being used to follow better security practises
  • Bug Fixes

    • Fixed a problem where a PHP exception was being thrown during the activation of the plugin support ticket
Download this release

Release Info

Developer WPWhiteSecurity
Plugin Icon 128x128 WP Security Audit Log
Version 1.5.0
Comparing to
See all releases

Code changes from version 1.4.1 to 1.5.0

classes/AbstractSensor.php CHANGED
@@ -31,4 +31,5 @@ abstract class WSAL_AbstractSensor {
31
  protected function LogInfo($message, $args){
32
  $this->Log(0003, $message, $args);
33
  }
 
34
  }
31
  protected function LogInfo($message, $args){
32
  $this->Log(0003, $message, $args);
33
  }
34
+
35
  }
classes/AlertManager.php CHANGED
@@ -16,7 +16,7 @@ final class WSAL_AlertManager {
16
  * @var WpSecurityAuditLog
17
  */
18
  protected $plugin;
19
-
20
  /**
21
  * Create new AlertManager instance.
22
  * @param WpSecurityAuditLog $plugin
@@ -28,7 +28,7 @@ final class WSAL_AlertManager {
28
 
29
  add_action('shutdown', array($this, '_CommitPipeline'));
30
  }
31
-
32
  /**
33
  * Add new logger from file inside autoloader path.
34
  * @param string $file Path to file.
@@ -80,13 +80,36 @@ final class WSAL_AlertManager {
80
  * @param integer $type Alert type.
81
  * @param array $data Alert data.
82
  */
83
- public function Trigger($type, $data = array(), $delayed = false){
84
- if($delayed){
85
- $this->TriggerIf($type, $data, null);
86
- }else{
87
- $this->_CommitItem($type, $data, null);
 
 
 
 
 
 
 
 
 
 
88
  }
89
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
90
 
91
  /**
92
  * Trigger only if a condition is met at the end of request.
@@ -94,20 +117,26 @@ final class WSAL_AlertManager {
94
  * @param array $data Alert data.
95
  * @param callable $cond A future condition callback (receives an object of type WSAL_AlertManager as parameter).
96
  */
97
- public function TriggerIf($type, $data, $cond = null){
98
- $this->_pipeline[] = array(
99
- 'type' => $type,
100
- 'data' => $data,
101
- 'cond' => $cond,
102
- );
 
 
 
 
 
103
  }
104
 
105
  /**
106
  * @internal Commit an alert now.
107
  */
108
- protected function _CommitItem($type, $data, $cond, $_retry = true){
 
109
  if(!$cond || !!call_user_func($cond, $this)){
110
- if($this->IsEnabled($type)){
111
  if(isset($this->_alerts[$type])){
112
  // ok, convert alert to a log entry
113
  $this->_triggered_types[] = $type;
@@ -277,5 +306,45 @@ final class WSAL_AlertManager {
277
  ksort($result);
278
  return $result;
279
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280
 
281
  }
16
  * @var WpSecurityAuditLog
17
  */
18
  protected $plugin;
19
+
20
  /**
21
  * Create new AlertManager instance.
22
  * @param WpSecurityAuditLog $plugin
28
 
29
  add_action('shutdown', array($this, '_CommitPipeline'));
30
  }
31
+
32
  /**
33
  * Add new logger from file inside autoloader path.
34
  * @param string $file Path to file.
80
  * @param integer $type Alert type.
81
  * @param array $data Alert data.
82
  */
83
+ public function Trigger($type, $data = array(), $delayed = false){
84
+ $username = wp_get_current_user()->user_login;
85
+ if (empty($username) && !empty($data["Username"])) {
86
+ $username = $data['Username'];
87
+ }
88
+ $roles = $this->plugin->settings->GetCurrentUserRoles();
89
+ if (empty($roles) && !empty($data["CurrentUserRoles"])) {
90
+ $roles = $data['CurrentUserRoles'];
91
+ }
92
+ if ( $this->CheckEnableUserRoles($username, $roles) ) {
93
+ if ($delayed) {
94
+ $this->TriggerIf($type, $data, null);
95
+ } else {
96
+ $this->_CommitItem($type, $data, null);
97
+ }
98
  }
99
  }
100
+
101
+ /**
102
+ * Check enable user and roles.
103
+ * @param string user
104
+ * @param array roles
105
+ * @return boolean True if enable false otherwise.
106
+ */
107
+ public function CheckEnableUserRoles($user, $roles) {
108
+ $is_enable = true;
109
+ if ( $user != "" && $this->IsDisabledUser($user) ) { $is_enable = false; }
110
+ if ( $roles != "" && $this->IsDisabledRole($roles) ) { $is_enable = false; }
111
+ return $is_enable;
112
+ }
113
 
114
  /**
115
  * Trigger only if a condition is met at the end of request.
117
  * @param array $data Alert data.
118
  * @param callable $cond A future condition callback (receives an object of type WSAL_AlertManager as parameter).
119
  */
120
+ public function TriggerIf($type, $data, $cond = null) {
121
+ $username = wp_get_current_user()->user_login;
122
+ $roles = $this->plugin->settings->GetCurrentUserRoles();
123
+
124
+ if ($this->CheckEnableUserRoles($username, $roles)) {
125
+ $this->_pipeline[] = array(
126
+ 'type' => $type,
127
+ 'data' => $data,
128
+ 'cond' => $cond,
129
+ );
130
+ }
131
  }
132
 
133
  /**
134
  * @internal Commit an alert now.
135
  */
136
+ protected function _CommitItem($type, $data, $cond, $_retry = true)
137
+ {
138
  if(!$cond || !!call_user_func($cond, $this)){
139
+ if($this->IsEnabled($type)) {
140
  if(isset($this->_alerts[$type])){
141
  // ok, convert alert to a log entry
142
  $this->_triggered_types[] = $type;
306
  ksort($result);
307
  return $result;
308
  }
309
+
310
+ /**
311
+ * Returns whether user is enabled or not.
312
+ * @param string user.
313
+ * @return boolean True if disabled, false otherwise.
314
+ */
315
+ public function IsDisabledUser($user)
316
+ {
317
+ return (in_array($user, $this->GetDisabledUsers())) ? true : false;
318
+ }
319
+
320
+ /**
321
+ * @return Returns an array of disabled users.
322
+ */
323
+ public function GetDisabledUsers()
324
+ {
325
+ return $this->plugin->settings->GetExcludedMonitoringUsers();
326
+ }
327
+
328
+ /**
329
+ * Returns whether user is enabled or not.
330
+ * @param array roles.
331
+ * @return boolean True if disabled, false otherwise.
332
+ */
333
+ public function IsDisabledRole($roles)
334
+ {
335
+ $is_disabled = false;
336
+ foreach ($roles as $role) {
337
+ if(in_array($role, $this->GetDisabledRoles())) $is_disabled = true;
338
+ }
339
+ return $is_disabled;
340
+ }
341
+
342
+ /**
343
+ * @return Returns an array of disabled users.
344
+ */
345
+ public function GetDisabledRoles()
346
+ {
347
+ return $this->plugin->settings->GetExcludedMonitoringRoles();
348
+ }
349
 
350
  }
classes/AuditLogListView.php CHANGED
@@ -226,7 +226,13 @@ class WSAL_AuditLogListView extends WP_List_Table {
226
 
227
  case $name == '%Message%':
228
  return esc_html($value);
229
-
 
 
 
 
 
 
230
  case in_array($name, array('%MetaValue%', '%MetaValueOld%', '%MetaValueNew%')):
231
  return '<strong>' . (
232
  strlen($value) > 50 ? (esc_html(substr($value, 0, 50)) . '&hellip;') : esc_html($value)
@@ -326,7 +332,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
326
  $query->offset = ($this->get_pagenum() - 1) * $per_page;
327
  $query->length = $per_page;
328
 
329
- $this->items = $query->Execute();
330
 
331
  $this->set_pagination_args( array(
332
  'total_items' => $total_items,
226
 
227
  case $name == '%Message%':
228
  return esc_html($value);
229
+
230
+ case $name == '%MetaLink%':
231
+ if (!empty($value)) {
232
+ return "<a href=\"#\" onclick=\"WsalDisableCustom(this, '".$value."');\"> Exclude Custom Field from the Monitoring</a>";
233
+ } else {
234
+ return "";
235
+ }
236
  case in_array($name, array('%MetaValue%', '%MetaValueOld%', '%MetaValueNew%')):
237
  return '<strong>' . (
238
  strlen($value) > 50 ? (esc_html(substr($value, 0, 50)) . '&hellip;') : esc_html($value)
332
  $query->offset = ($this->get_pagenum() - 1) * $per_page;
333
  $query->length = $per_page;
334
 
335
+ $this->items = $query->Execute();
336
 
337
  $this->set_pagination_args( array(
338
  'total_items' => $total_items,
classes/DB/Occurrence.php CHANGED
@@ -149,7 +149,7 @@ class WSAL_DB_Occurrence extends WSAL_DB_ActiveRecord {
149
  * @return boolean True on success, false on failure.
150
  */
151
  public function Delete(){
152
- foreach($this->GetMeta() as $meta)$meta->Delete();
153
  return parent::Delete();
154
  }
155
 
149
  * @return boolean True on success, false on failure.
150
  */
151
  public function Delete(){
152
+ foreach($this->GetMeta() as $meta) $meta->Delete();
153
  return parent::Delete();
154
  }
155
 
classes/DB/Option.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WSAL_DB_Option extends WSAL_DB_ActiveRecord
4
+ {
5
+ protected $_table = 'wsal_options';
6
+ protected $_idkey = 'id';
7
+
8
+ public $id = 0;
9
+ public $option_name = '';
10
+ public static $option_name_maxlength = 100;
11
+ public $option_value = '';
12
+
13
+ public function SetOptionValue($name, $value)
14
+ {
15
+ $this->GetNamedOption($name);
16
+ $this->option_name = $name;
17
+ $this->option_value = $value;
18
+ $this->Save();
19
+ }
20
+
21
+ public function GetOptionValue($name, $default = array())
22
+ {
23
+ $this->GetNamedOption($name);
24
+ return $this->IsLoaded() ? $this->option_value : $default;
25
+ }
26
+
27
+ public function GetNamedOption($name)
28
+ {
29
+ return $this->Load('option_name = %s', array($name));
30
+ }
31
+
32
+ }
classes/Nicer.php CHANGED
@@ -49,7 +49,7 @@
49
  * @param mixed $value The value to inspect and render.
50
  * @param boolean $inspectMethods Whether to inspect and output methods for objects or not.
51
  */
52
- public function __construct($value, $inspectMethods = false){
53
  $this->value = $value;
54
  $this->inspect_methods = $inspectMethods;
55
 
49
  * @param mixed $value The value to inspect and render.
50
  * @param boolean $inspectMethods Whether to inspect and output methods for objects or not.
51
  */
52
+ public function __construct($value, $inspectMethods = false){
53
  $this->value = $value;
54
  $this->inspect_methods = $inspectMethods;
55
 
classes/Sensors/Content.php CHANGED
@@ -130,6 +130,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
130
 
131
  protected function CheckCategoryCreation(){
132
  if (empty($_POST)) return;
 
133
 
134
  $categoryName = '';
135
  if(!empty($_POST['screen']) && !empty($_POST['tag-name']) &&
@@ -153,6 +154,8 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
153
 
154
  protected function CheckCategoryDeletion(){
155
  if (empty($_POST)) return;
 
 
156
  $action = !empty($_POST['action']) ? $_POST['action']
157
  : (!empty($_POST['action2']) ? $_POST['action2'] : '');
158
  if (!$action) return;
130
 
131
  protected function CheckCategoryCreation(){
132
  if (empty($_POST)) return;
133
+ if (!current_user_can("manage_categories")) return;
134
 
135
  $categoryName = '';
136
  if(!empty($_POST['screen']) && !empty($_POST['tag-name']) &&
154
 
155
  protected function CheckCategoryDeletion(){
156
  if (empty($_POST)) return;
157
+ if (!current_user_can("manage_categories")) return;
158
+
159
  $action = !empty($_POST['action']) ? $_POST['action']
160
  : (!empty($_POST['action2']) ? $_POST['action2'] : '');
161
  if (!$action) return;
classes/Sensors/LogInOut.php CHANGED
@@ -98,6 +98,7 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
98
  if($this->IsPastLoginFailureLimit($ip, $site_id, $user))return;
99
 
100
  if ($newAlertCode == 1002) {
 
101
  $occ = WSAL_DB_Occurrence::LoadMultiQuery('
102
  SELECT occurrence.* FROM `' . $tt1->GetTable() . '` occurrence
103
  INNER JOIN `' . $tt2->GetTable() . '` ipMeta on ipMeta.occurrence_id = occurrence.id
@@ -137,7 +138,7 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
137
  // create a new record exists user
138
  $this->plugin->alerts->Trigger($newAlertCode, array(
139
  'Attempts' => 1,
140
- 'Username' => $_POST["log"],
141
  'CurrentUserRoles' => $userRoles
142
  ));
143
  }
98
  if($this->IsPastLoginFailureLimit($ip, $site_id, $user))return;
99
 
100
  if ($newAlertCode == 1002) {
101
+ if (!$this->plugin->alerts->CheckEnableUserRoles($username, $userRoles))return;
102
  $occ = WSAL_DB_Occurrence::LoadMultiQuery('
103
  SELECT occurrence.* FROM `' . $tt1->GetTable() . '` occurrence
104
  INNER JOIN `' . $tt2->GetTable() . '` ipMeta on ipMeta.occurrence_id = occurrence.id
138
  // create a new record exists user
139
  $this->plugin->alerts->Trigger($newAlertCode, array(
140
  'Attempts' => 1,
141
+ 'Username' => $username,
142
  'CurrentUserRoles' => $userRoles
143
  ));
144
  }
classes/Sensors/MetaData.php CHANGED
@@ -11,8 +11,22 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
11
 
12
  protected $old_meta = array();
13
 
14
- protected function CanLogPostMeta($meta_id, $object_id, $meta_key){
15
- return substr($meta_key, 0, 1) != '_';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  }
17
 
18
  public function EventPostMetaCreated($meta_id, $object_id, $meta_key, $_meta_value){
@@ -28,6 +42,7 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
28
  'MetaID' => $meta_id,
29
  'MetaKey' => $meta_key,
30
  'MetaValue' => $_meta_value,
 
31
  ));
32
  break;
33
  case 'post':
@@ -37,6 +52,7 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
37
  'MetaID' => $meta_id,
38
  'MetaKey' => $meta_key,
39
  'MetaValue' => $_meta_value,
 
40
  ));
41
  break;
42
  default:
@@ -47,6 +63,7 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
47
  'MetaID' => $meta_id,
48
  'MetaKey' => $meta_key,
49
  'MetaValue' => $_meta_value,
 
50
  ));
51
  break;
52
  }
@@ -78,6 +95,7 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
78
  'MetaKeyNew' => $meta_key,
79
  'MetaKeyOld' => $this->old_meta[$meta_id]->key,
80
  'MetaValue' => $_meta_value,
 
81
  ));
82
  break;
83
  case 'post':
@@ -88,6 +106,7 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
88
  'MetaKeyNew' => $meta_key,
89
  'MetaKeyOld' => $this->old_meta[$meta_id]->key,
90
  'MetaValue' => $_meta_value,
 
91
  ));
92
  break;
93
  default:
@@ -99,6 +118,7 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
99
  'MetaKeyNew' => $meta_key,
100
  'MetaKeyOld' => $this->old_meta[$meta_id]->key,
101
  'MetaValue' => $_meta_value,
 
102
  ));
103
  break;
104
  }
@@ -115,6 +135,7 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
115
  'MetaKey' => $meta_key,
116
  'MetaValueNew' => $_meta_value,
117
  'MetaValueOld' => $this->old_meta[$meta_id]->val,
 
118
  ));
119
  break;
120
  case 'post':
@@ -125,6 +146,7 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
125
  'MetaKey' => $meta_key,
126
  'MetaValueNew' => $_meta_value,
127
  'MetaValueOld' => $this->old_meta[$meta_id]->val,
 
128
  ));
129
  break;
130
  default:
@@ -136,6 +158,7 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
136
  'MetaKey' => $meta_key,
137
  'MetaValueNew' => $_meta_value,
138
  'MetaValueOld' => $this->old_meta[$meta_id]->val,
 
139
  ));
140
  break;
141
  }
@@ -161,6 +184,7 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
161
  'MetaID' => $meta_id,
162
  'MetaKey' => $meta_key,
163
  'MetaValue' => $_meta_value,
 
164
  ));
165
  break;
166
  case 'post':
@@ -170,6 +194,7 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
170
  'MetaID' => $meta_id,
171
  'MetaKey' => $meta_key,
172
  'MetaValue' => $_meta_value,
 
173
  ));
174
  break;
175
  default:
@@ -180,6 +205,7 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
180
  'MetaID' => $meta_id,
181
  'MetaKey' => $meta_key,
182
  'MetaValue' => $_meta_value,
 
183
  ));
184
  break;
185
  }
11
 
12
  protected $old_meta = array();
13
 
14
+ protected function CanLogPostMeta($meta_id, $object_id, $meta_key)
15
+ {
16
+ //check if excluded meta key or starts with _
17
+ if ( substr($meta_key, 0, 1) == '_' ) {
18
+ return false;
19
+ } else if( $this->IsExcludedCustomFields($meta_key) ) {
20
+ return false;
21
+ } else {
22
+ return true;
23
+ }
24
+ }
25
+
26
+ public function IsExcludedCustomFields($custom)
27
+ {
28
+ $customFields = $this->plugin->settings->GetExcludedMonitoringCustom();
29
+ return (in_array($custom, $customFields)) ? true : false;
30
  }
31
 
32
  public function EventPostMetaCreated($meta_id, $object_id, $meta_key, $_meta_value){
42
  'MetaID' => $meta_id,
43
  'MetaKey' => $meta_key,
44
  'MetaValue' => $_meta_value,
45
+ 'MetaLink' => $meta_key,
46
  ));
47
  break;
48
  case 'post':
52
  'MetaID' => $meta_id,
53
  'MetaKey' => $meta_key,
54
  'MetaValue' => $_meta_value,
55
+ 'MetaLink' => $meta_key,
56
  ));
57
  break;
58
  default:
63
  'MetaID' => $meta_id,
64
  'MetaKey' => $meta_key,
65
  'MetaValue' => $_meta_value,
66
+ 'MetaLink' => $meta_key,
67
  ));
68
  break;
69
  }
95
  'MetaKeyNew' => $meta_key,
96
  'MetaKeyOld' => $this->old_meta[$meta_id]->key,
97
  'MetaValue' => $_meta_value,
98
+ 'MetaLink' => $meta_key,
99
  ));
100
  break;
101
  case 'post':
106
  'MetaKeyNew' => $meta_key,
107
  'MetaKeyOld' => $this->old_meta[$meta_id]->key,
108
  'MetaValue' => $_meta_value,
109
+ 'MetaLink' => $meta_key,
110
  ));
111
  break;
112
  default:
118
  'MetaKeyNew' => $meta_key,
119
  'MetaKeyOld' => $this->old_meta[$meta_id]->key,
120
  'MetaValue' => $_meta_value,
121
+ 'MetaLink' => $smeta_key,
122
  ));
123
  break;
124
  }
135
  'MetaKey' => $meta_key,
136
  'MetaValueNew' => $_meta_value,
137
  'MetaValueOld' => $this->old_meta[$meta_id]->val,
138
+ 'MetaLink' => $meta_key,
139
  ));
140
  break;
141
  case 'post':
146
  'MetaKey' => $meta_key,
147
  'MetaValueNew' => $_meta_value,
148
  'MetaValueOld' => $this->old_meta[$meta_id]->val,
149
+ 'MetaLink' => $meta_key,
150
  ));
151
  break;
152
  default:
158
  'MetaKey' => $meta_key,
159
  'MetaValueNew' => $_meta_value,
160
  'MetaValueOld' => $this->old_meta[$meta_id]->val,
161
+ 'MetaLink' => $meta_key,
162
  ));
163
  break;
164
  }
184
  'MetaID' => $meta_id,
185
  'MetaKey' => $meta_key,
186
  'MetaValue' => $_meta_value,
187
+ 'MetaLink' => $meta_key,
188
  ));
189
  break;
190
  case 'post':
194
  'MetaID' => $meta_id,
195
  'MetaKey' => $meta_key,
196
  'MetaValue' => $_meta_value,
197
+ 'MetaLink' => $meta_key,
198
  ));
199
  break;
200
  default:
205
  'MetaID' => $meta_id,
206
  'MetaKey' => $meta_key,
207
  'MetaValue' => $_meta_value,
208
+ 'MetaLink' => $meta_key,
209
  ));
210
  break;
211
  }
classes/Sensors/Multisite.php CHANGED
@@ -24,6 +24,7 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
24
  }
25
 
26
  public function EventAdminShutdown(){
 
27
  if(is_null($this->old_allowedthemes))return;
28
  $new_allowedthemes = array_keys((array)get_site_option('allowedthemes'));
29
 
24
  }
25
 
26
  public function EventAdminShutdown(){
27
+ if (!current_user_can("switch_themes")) return;
28
  if(is_null($this->old_allowedthemes))return;
29
  $new_allowedthemes = array_keys((array)get_site_option('allowedthemes'));
30
 
classes/Sensors/PluginsThemes.php CHANGED
@@ -24,7 +24,7 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
24
  $is_plugins = $actype == 'plugins';
25
 
26
  // install plugin
27
- if(in_array($action, array('install-plugin', 'upload-plugin'))){
28
  $plugin = array_values(array_diff(array_keys(get_plugins()), array_keys($this->old_plugins)));
29
  if(count($plugin) != 1)
30
  return $this->LogError(
@@ -48,7 +48,7 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
48
  }
49
 
50
  // activate plugin
51
- if($is_plugins && in_array($action, array('activate', 'activate-selected'))){
52
  if(isset($_REQUEST['plugin'])){
53
  if(!isset($_REQUEST['checked']))
54
  $_REQUEST['checked'] = array();
@@ -71,7 +71,7 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
71
  }
72
 
73
  // deactivate plugin
74
- if($is_plugins && in_array($action, array('deactivate', 'deactivate-selected'))){
75
  if(isset($_REQUEST['plugin'])){
76
  if(!isset($_REQUEST['checked']))
77
  $_REQUEST['checked'] = array();
@@ -94,7 +94,7 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
94
  }
95
 
96
  // uninstall plugin
97
- if($is_plugins && in_array($action, array('delete-selected'))){
98
  if(!isset($_REQUEST['verify-delete'])){
99
  // first step, before user approves deletion
100
  // TODO store plugin data in session here
@@ -117,7 +117,7 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
117
  }
118
 
119
  // upgrade plugin
120
- if(in_array($action, array('upgrade-plugin', 'update-selected'))){
121
  if(isset($_REQUEST['plugin'])){
122
  if(!isset($_REQUEST['checked']))
123
  $_REQUEST['checked'] = array();
@@ -145,7 +145,7 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
145
  }
146
 
147
  // install theme
148
- if(in_array($action, array('install-theme', 'upload-theme'))){
149
  $themes = array_diff(wp_get_themes(), $this->old_themes);
150
  foreach($themes as $theme){
151
  $this->plugin->alerts->Trigger(5005, array(
@@ -162,7 +162,7 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
162
  }
163
 
164
  // uninstall theme
165
- if($is_themes && in_array($action, array('delete-selected', 'delete'))){
166
  foreach($this->GetRemovedThemes() as $theme){
167
  $this->plugin->alerts->Trigger(5007, array(
168
  'Theme' => (object)array(
24
  $is_plugins = $actype == 'plugins';
25
 
26
  // install plugin
27
+ if(in_array($action, array('install-plugin', 'upload-plugin')) && current_user_can("install_plugins")){
28
  $plugin = array_values(array_diff(array_keys(get_plugins()), array_keys($this->old_plugins)));
29
  if(count($plugin) != 1)
30
  return $this->LogError(
48
  }
49
 
50
  // activate plugin
51
+ if($is_plugins && in_array($action, array('activate', 'activate-selected')) && current_user_can("activate_plugins")){
52
  if(isset($_REQUEST['plugin'])){
53
  if(!isset($_REQUEST['checked']))
54
  $_REQUEST['checked'] = array();
71
  }
72
 
73
  // deactivate plugin
74
+ if($is_plugins && in_array($action, array('deactivate', 'deactivate-selected')) && current_user_can("activate_plugins")){
75
  if(isset($_REQUEST['plugin'])){
76
  if(!isset($_REQUEST['checked']))
77
  $_REQUEST['checked'] = array();
94
  }
95
 
96
  // uninstall plugin
97
+ if($is_plugins && in_array($action, array('delete-selected')) && current_user_can("delete_plugins")){
98
  if(!isset($_REQUEST['verify-delete'])){
99
  // first step, before user approves deletion
100
  // TODO store plugin data in session here
117
  }
118
 
119
  // upgrade plugin
120
+ if(in_array($action, array('upgrade-plugin', 'update-selected')) && current_user_can("update_plugins")){
121
  if(isset($_REQUEST['plugin'])){
122
  if(!isset($_REQUEST['checked']))
123
  $_REQUEST['checked'] = array();
145
  }
146
 
147
  // install theme
148
+ if(in_array($action, array('install-theme', 'upload-theme')) && current_user_can("install_themes")){
149
  $themes = array_diff(wp_get_themes(), $this->old_themes);
150
  foreach($themes as $theme){
151
  $this->plugin->alerts->Trigger(5005, array(
162
  }
163
 
164
  // uninstall theme
165
+ if($is_themes && in_array($action, array('delete-selected', 'delete')) && current_user_can("install_themes")){
166
  foreach($this->GetRemovedThemes() as $theme){
167
  $this->plugin->alerts->Trigger(5007, array(
168
  'Theme' => (object)array(
classes/Sensors/Widgets.php CHANGED
@@ -4,7 +4,7 @@ class WSAL_Sensors_Widgets extends WSAL_AbstractSensor {
4
 
5
  public function HookEvents() {
6
  add_action('widgets_init', array($this, 'EventWidgetMove'));
7
- if(is_admin())add_action('init', array($this, 'EventWidgetPostMove'));
8
  add_action('sidebar_admin_setup', array($this, 'EventWidgetActivity'));
9
  }
10
 
@@ -232,4 +232,4 @@ class WSAL_Sensors_Widgets extends WSAL_AbstractSensor {
232
 
233
  }
234
  }
235
- }
4
 
5
  public function HookEvents() {
6
  add_action('widgets_init', array($this, 'EventWidgetMove'));
7
+ if(current_user_can("edit_dashboard"))add_action('init', array($this, 'EventWidgetPostMove'));
8
  add_action('sidebar_admin_setup', array($this, 'EventWidgetActivity'));
9
  }
10
 
232
 
233
  }
234
  }
235
+ }
classes/Settings.php CHANGED
@@ -274,8 +274,8 @@ class WSAL_Settings {
274
  $this->_plugin->SetGlobalOption('items-per-page', $this->_perpage);
275
  }
276
  public function GetViewPerPage(){
277
- if(is_null($this->_perpage)){
278
- $this->_perpage = (int)$this->_plugin->GetGlobalOption('items-per-page', 10);
279
  }
280
  return $this->_perpage;
281
  }
@@ -499,6 +499,54 @@ class WSAL_Settings {
499
  return $filteredIP;
500
  }
501
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
502
 
503
  // </editor-fold>
504
  }
274
  $this->_plugin->SetGlobalOption('items-per-page', $this->_perpage);
275
  }
276
  public function GetViewPerPage(){
277
+ if(is_null($this->_perpage)){
278
+ $this->_perpage = (int)$this->_plugin->GetGlobalOption('items-per-page', 10);
279
  }
280
  return $this->_perpage;
281
  }
499
  return $filteredIP;
500
  }
501
  }
502
+
503
+ /**
504
+ * Users excluded from monitoring
505
+ */
506
+ protected $_excluded_users = array();
507
+ public function SetExcludedMonitoringUsers($users)
508
+ {
509
+ $this->_excluded_users = $users;
510
+ $this->_plugin->SetGlobalOption('excluded-users', implode(',', $this->_excluded_users));
511
+ }
512
+ public function GetExcludedMonitoringUsers()
513
+ {
514
+ if(empty($this->_excluded_users)){
515
+ $this->_excluded_users = array_unique(array_filter(explode(',', $this->_plugin->GetGlobalOption('excluded-users'))));
516
+ }
517
+ return $this->_excluded_users;
518
+ }
519
+
520
+ /**
521
+ * Roles excluded from monitoring
522
+ */
523
+ protected $_excluded_roles = array();
524
+ public function SetExcludedMonitoringRoles($roles){
525
+ $this->_excluded_roles = $roles;
526
+ $this->_plugin->SetGlobalOption('excluded-roles', implode(',', $this->_excluded_roles));
527
+ }
528
+ public function GetExcludedMonitoringRoles(){
529
+ if(empty($this->_excluded_roles)){
530
+ $this->_excluded_roles = array_unique(array_filter(explode(',', $this->_plugin->GetGlobalOption('excluded-roles'))));
531
+ }
532
+ return $this->_excluded_roles;
533
+ }
534
+
535
+ /**
536
+ * Custom fields excluded from monitoring
537
+ */
538
+ protected $_excluded_custom = array();
539
+ public function SetExcludedMonitoringCustom($custom){
540
+ $this->_excluded_custom = $custom;
541
+ $this->_plugin->SetGlobalOption('excluded-custom', implode(',', $this->_excluded_custom));
542
+ }
543
+ public function GetExcludedMonitoringCustom(){
544
+ if(empty($this->_excluded_custom)){
545
+ $this->_excluded_custom = array_unique(array_filter(explode(',', $this->_plugin->GetGlobalOption('excluded-custom'))));
546
+ asort($this->_excluded_custom);
547
+ }
548
+ return $this->_excluded_custom;
549
+ }
550
 
551
  // </editor-fold>
552
  }
classes/Views/Settings.php CHANGED
@@ -6,6 +6,8 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
6
  if (is_admin()) {
7
  add_action('wp_ajax_AjaxCheckSecurityToken', array($this, 'AjaxCheckSecurityToken'));
8
  add_action('wp_ajax_AjaxRunCleanup', array($this, 'AjaxRunCleanup'));
 
 
9
  }
10
  }
11
 
@@ -49,6 +51,11 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
49
  $this->_plugin->settings->SetWidgetsEnabled($_REQUEST['EnableDashboardWidgets']);
50
  $this->_plugin->settings->SetAllowedPluginViewers(isset($_REQUEST['Viewers']) ? $_REQUEST['Viewers'] : array());
51
  $this->_plugin->settings->SetAllowedPluginEditors(isset($_REQUEST['Editors']) ? $_REQUEST['Editors'] : array());
 
 
 
 
 
52
  $this->_plugin->settings->SetRestrictAdmins(isset($_REQUEST['RestrictAdmins']));
53
  $this->_plugin->settings->SetRefreshAlertsEnabled($_REQUEST['EnableAuditViewRefresh']);
54
  $this->_plugin->settings->SetMainIPFromProxy(isset($_REQUEST['EnableProxyIpCapture']));
@@ -89,7 +96,10 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
89
  ?><div class="error"><p><?php _e('Error: ', 'wp-security-audit-log'); ?><?php echo $ex->getMessage(); ?></p></div><?php
90
  }
91
  }
92
- ?><form id="audit-log-settings" method="post">
 
 
 
93
  <input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>" />
94
  <input type="hidden" id="ajaxurl" value="<?php echo esc_attr(admin_url('admin-ajax.php')); ?>" />
95
  <?php wp_nonce_field('wsal-settings'); ?>
@@ -105,160 +115,240 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
105
  <img src="<?php echo $this->_plugin->GetBaseUrl(); ?>/img/reporting_250x150.gif" width="250" height="150" alt=""/>
106
  </a>
107
  </div>
108
-
109
- <table class="form-table">
110
- <tbody>
111
- <tr>
112
- <th><label for="delete1"><?php _e('Security Alerts Pruning', 'wp-security-audit-log'); ?></label></th>
113
- <td>
114
- <fieldset>
115
- <?php $text = __('(eg: 1 month)', 'wp-security-audit-log'); ?>
116
- <?php $nbld = !($this->_plugin->settings->IsPruningDateEnabled() || $this->_plugin->settings->IsPruningLimitEnabled()); ?>
117
- <label for="delete0">
118
- <input type="radio" id="delete0" name="PruneBy" value="" <?php if($nbld)echo 'checked="checked"'; ?>/>
119
- <?php echo __('None', 'wp-security-audit-log'); ?>
120
- </label>
121
- </fieldset>
122
- <fieldset>
123
- <?php $text = __('(eg: 1 month)', 'wp-security-audit-log'); ?>
124
- <?php $nbld = $this->_plugin->settings->IsPruningDateEnabled(); ?>
125
- <label for="delete1">
126
- <input type="radio" id="delete1" name="PruneBy" value="date" <?php if($nbld)echo 'checked="checked"'; ?>/>
127
- <?php echo __('Delete alerts older than', 'wp-security-audit-log'); ?>
128
- </label>
129
- <input type="text" id="PruningDate" name="PruningDate" placeholder="<?php echo $text; ?>"
130
- value="<?php echo esc_attr($this->_plugin->settings->GetPruningDate()); ?>"
131
- onfocus="jQuery('#delete1').attr('checked', true);"/>
132
- <span> <?php echo $text; ?></span>
133
- </fieldset>
134
- <fieldset>
135
- <?php $text = __('(eg: 80)', 'wp-security-audit-log'); ?>
136
- <?php $nbld = $this->_plugin->settings->IsPruningLimitEnabled(); ?>
137
- <label for="delete2">
138
- <input type="radio" id="delete2" name="PruneBy" value="limit" <?php if($nbld)echo 'checked="checked"'; ?>/>
139
- <?php echo __('Keep up to', 'wp-security-audit-log'); ?>
140
- </label>
141
- <input type="text" id="PruningLimit" name="PruningLimit" placeholder="<?php echo $text;?>"
142
- value="<?php echo esc_attr($this->_plugin->settings->GetPruningLimit()); ?>"
143
- onfocus="jQuery('#delete2').attr('checked', true);"/>
144
- <?php echo __('alerts', 'wp-security-audit-log'); ?>
145
- <span><?php echo $text; ?></span>
146
- </fieldset>
147
- <p class="description"><?php
148
- echo __('Next Scheduled Cleanup is in ', 'wp-security-audit-log');
149
- echo human_time_diff(current_time('timestamp'), $next = wp_next_scheduled('wsal_cleanup'));
150
- echo '<!-- ' . date('dMy H:i:s', $next) . ' --> ';
151
- echo sprintf(
152
- __('(or %s)', 'wp-security-audit-log'),
153
- '<a href="' . admin_url('admin-ajax.php?action=AjaxRunCleanup') . '">' . __('Run Manually', 'wp-security-audit-log') . '</a>'
154
- );
155
- ?></p>
156
- </td>
157
- </tr>
158
- <tr>
159
- <th><label for="dwoption_on"><?php _e('Alerts Dashboard Widget', 'wp-security-audit-log'); ?></label></th>
160
- <td>
161
- <fieldset>
162
- <?php $dwe = $this->_plugin->settings->IsWidgetsEnabled(); ?>
163
- <label for="dwoption_on">
164
- <input type="radio" name="EnableDashboardWidgets" id="dwoption_on" style="margin-top: 2px;" <?php if($dwe)echo 'checked="checked"'; ?> value="1">
165
- <span><?php _e('On', 'wp-security-audit-log'); ?></span>
166
- </label>
167
- <br/>
168
- <label for="dwoption_off">
169
- <input type="radio" name="EnableDashboardWidgets" id="dwoption_off" style="margin-top: 2px;" <?php if(!$dwe)echo 'checked="checked"'; ?> value="0">
170
- <span><?php _e('Off', 'wp-security-audit-log'); ?></span>
171
- </label>
172
- <br/>
173
  <p class="description"><?php
 
 
 
174
  echo sprintf(
175
- __('Display a dashboard widget with the latest %d security alerts.', 'wp-security-audit-log'),
176
- $this->_plugin->settings->GetDashboardWidgetMaxAlerts()
177
  );
178
  ?></p>
179
- </fieldset>
180
- </td>
181
- </tr>
182
- <tr>
183
- <th><label for="pioption_on"><?php _e('Reverse Proxy / Firewall Options', 'wp-security-audit-log'); ?></label></th>
184
- <td>
185
- <fieldset>
186
- <label for="EnableProxyIpCapture">
187
- <input type="checkbox" name="EnableProxyIpCapture" value="1" id="EnableProxyIpCapture"<?php
188
- if($this->_plugin->settings->IsMainIPFromProxy())echo ' checked="checked"';
189
- ?>/> <?php _e('WordPress running behind firewall or proxy', 'wp-security-audit-log'); ?><br/>
190
- <span class="description"><?php _e('Enable this option if your WordPress is running behind a firewall or reverse proxy. When this option is enabled the plugin will retrieve the user\'s IP address from the proxy header.', 'wp-security-audit-log'); ?></span>
191
- </label>
192
- <br/>
193
- <label for="EnableIpFiltering">
194
- <input type="checkbox" name="EnableIpFiltering" value="1" id="EnableIpFiltering"<?php
195
- if($this->_plugin->settings->IsInternalIPsFiltered())echo ' checked="checked"';
196
- ?>/> <?php _e('Filter Internal IP Addresses', 'wp-security-audit-log'); ?><br/>
197
- <span class="description"><?php _e('Enable this option to filter internal IP addresses from the proxy headers.', 'wp-security-audit-log'); ?></span>
198
- </label>
199
- </fieldset>
200
- </td>
201
- </tr>
202
- <tr>
203
- <th><label for="ViewerQueryBox"><?php _e('Can View Alerts', 'wp-security-audit-log'); ?></label></th>
204
- <td>
205
- <fieldset>
206
- <input type="text" id="ViewerQueryBox" style="float: left; display: block; width: 250px;">
207
- <input type="button" id="ViewerQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
208
- <br style="clear: both;"/>
209
- <p class="description"><?php
210
- _e('Users and Roles in this list can view the security alerts', 'wp-security-audit-log');
211
- ?></p>
212
- <div id="ViewerList"><?php
213
- foreach($this->_plugin->settings->GetAllowedPluginViewers() as $item){
214
- ?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
215
- <input type="hidden" name="Viewers[]" value="<?php echo esc_attr($item); ?>"/>
216
- <?php echo esc_html($item); ?>
217
- <a href="javascript:;" title="Remove">&times;</a>
218
- </span><?php
219
- }
220
- ?></div>
221
- </fieldset>
222
- </td>
223
- </tr>
224
- <tr>
225
- <th><label for="EditorQueryBox"><?php _e('Can Manage Plugin', 'wp-security-audit-log'); ?></label></th>
226
- <td>
227
- <fieldset>
228
- <input type="text" id="EditorQueryBox" style="float: left; display: block; width: 250px;">
229
- <input type="button" id="EditorQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
230
- <br style="clear: both;"/>
231
- <p class="description"><?php
232
- _e('Users and Roles in this list can manage the plugin settings', 'wp-security-audit-log');
233
- ?></p>
234
- <div id="EditorList"><?php
235
- foreach($this->_plugin->settings->GetAllowedPluginEditors() as $item){
236
- ?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
237
- <input type="hidden" name="Editors[]" value="<?php echo esc_attr($item); ?>"/>
238
- <?php echo esc_html($item); ?>
239
- <a href="javascript:;" title="Remove">&times;</a>
240
- </span><?php
241
- }
242
- ?></div>
243
- </fieldset>
244
- </td>
245
- </tr>
246
- <tr>
247
- <th><label for="RestrictAdmins"><?php _e('Restrict Plugin Access', 'wp-security-audit-log'); ?></label></th>
248
- <td>
249
- <fieldset>
250
- <input type="hidden" id="RestrictAdminsDefaultUser" value="<?php echo esc_attr(wp_get_current_user()->user_login); ?>"/>
251
- <label for="RestrictAdmins">
252
- <?php $ira = $this->_plugin->settings->IsRestrictAdmins(); ?>
253
- <input type="checkbox" name="RestrictAdmins" id="RestrictAdmins"<?php if($ira)echo ' checked="checked"'; ?>/>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254
  <span class="description">
255
- <?php _e('By default all the administrators on this WordPress have access to manage this plugin.<br/>By enabling this option only the users specified in the two options above and your username will have access to view alerts and manage this plugin.', 'wp-security-audit-log'); ?>
256
  </span>
257
- </label>
258
- </fieldset>
259
- </td>
260
- </tr>
261
- <tr>
262
  <th><label for="aroption_on"><?php _e('Refresh Audit Log Viewer', 'wp-security-audit-log'); ?></label></th>
263
  <td>
264
  <fieldset>
@@ -349,9 +439,82 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
349
  </fieldset>
350
  </td>
351
  </tr>
352
- </tbody>
353
- </table>
354
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
355
  <p class="submit"><input type="submit" name="submit" id="submit" class="button button-primary" value="Save Changes"></p>
356
  </form>
357
  <script type="text/javascript">
@@ -375,6 +538,17 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
375
  array(),
376
  filemtime($this->_plugin->GetBaseDir() . '/css/settings.css')
377
  );
 
 
 
 
 
 
 
 
 
 
 
378
  }
379
 
380
  public function Footer() {
@@ -384,6 +558,44 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
384
  array(),
385
  filemtime($this->_plugin->GetBaseDir() . '/js/settings.js')
386
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
387
  }
388
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
389
  }
6
  if (is_admin()) {
7
  add_action('wp_ajax_AjaxCheckSecurityToken', array($this, 'AjaxCheckSecurityToken'));
8
  add_action('wp_ajax_AjaxRunCleanup', array($this, 'AjaxRunCleanup'));
9
+ add_action('wp_ajax_AjaxGetAllUsers', array($this, 'AjaxGetAllUsers'));
10
+ add_action('wp_ajax_AjaxGetAllRoles', array($this, 'AjaxGetAllRoles'));
11
  }
12
  }
13
 
51
  $this->_plugin->settings->SetWidgetsEnabled($_REQUEST['EnableDashboardWidgets']);
52
  $this->_plugin->settings->SetAllowedPluginViewers(isset($_REQUEST['Viewers']) ? $_REQUEST['Viewers'] : array());
53
  $this->_plugin->settings->SetAllowedPluginEditors(isset($_REQUEST['Editors']) ? $_REQUEST['Editors'] : array());
54
+
55
+ $this->_plugin->settings->SetExcludedMonitoringUsers(isset($_REQUEST['ExUsers']) ? $_REQUEST['ExUsers'] : array());
56
+ $this->_plugin->settings->SetExcludedMonitoringRoles(isset($_REQUEST['ExRoles']) ? $_REQUEST['ExRoles'] : array());
57
+ $this->_plugin->settings->SetExcludedMonitoringCustom(isset($_REQUEST['Customs']) ? $_REQUEST['Customs'] : array());
58
+
59
  $this->_plugin->settings->SetRestrictAdmins(isset($_REQUEST['RestrictAdmins']));
60
  $this->_plugin->settings->SetRefreshAlertsEnabled($_REQUEST['EnableAuditViewRefresh']);
61
  $this->_plugin->settings->SetMainIPFromProxy(isset($_REQUEST['EnableProxyIpCapture']));
96
  ?><div class="error"><p><?php _e('Error: ', 'wp-security-audit-log'); ?><?php echo $ex->getMessage(); ?></p></div><?php
97
  }
98
  }
99
+ ?>
100
+ <h2 id="wsal-tabs" class="nav-tab-wrapper"><a href="#tab-general" class="nav-tab">General</a><a href="#tab-exclude" class="nav-tab">Exclude Objects</a></h2>
101
+ <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"/></script>
102
+ <form id="audit-log-settings" method="post">
103
  <input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>" />
104
  <input type="hidden" id="ajaxurl" value="<?php echo esc_attr(admin_url('admin-ajax.php')); ?>" />
105
  <?php wp_nonce_field('wsal-settings'); ?>
115
  <img src="<?php echo $this->_plugin->GetBaseUrl(); ?>/img/reporting_250x150.gif" width="250" height="150" alt=""/>
116
  </a>
117
  </div>
118
+
119
+ <div class="nav-tabs">
120
+ <table class="form-table wsal-tab widefat" id="tab-general">
121
+ <tbody>
122
+ <tr>
123
+ <th><label for="delete1"><?php _e('Security Alerts Pruning', 'wp-security-audit-log'); ?></label></th>
124
+ <td>
125
+ <fieldset>
126
+ <?php $text = __('(eg: 1 month)', 'wp-security-audit-log'); ?>
127
+ <?php $nbld = !($this->_plugin->settings->IsPruningDateEnabled() || $this->_plugin->settings->IsPruningLimitEnabled()); ?>
128
+ <label for="delete0">
129
+ <input type="radio" id="delete0" name="PruneBy" value="" <?php if($nbld)echo 'checked="checked"'; ?>/>
130
+ <?php echo __('None', 'wp-security-audit-log'); ?>
131
+ </label>
132
+ </fieldset>
133
+ <fieldset>
134
+ <?php $text = __('(eg: 1 month)', 'wp-security-audit-log'); ?>
135
+ <?php $nbld = $this->_plugin->settings->IsPruningDateEnabled(); ?>
136
+ <label for="delete1">
137
+ <input type="radio" id="delete1" name="PruneBy" value="date" <?php if($nbld)echo 'checked="checked"'; ?>/>
138
+ <?php echo __('Delete alerts older than', 'wp-security-audit-log'); ?>
139
+ </label>
140
+ <input type="text" id="PruningDate" name="PruningDate" placeholder="<?php echo $text; ?>"
141
+ value="<?php echo esc_attr($this->_plugin->settings->GetPruningDate()); ?>"
142
+ onfocus="jQuery('#delete1').attr('checked', true);"/>
143
+ <span> <?php echo $text; ?></span>
144
+ </fieldset>
145
+ <fieldset>
146
+ <?php $text = __('(eg: 80)', 'wp-security-audit-log'); ?>
147
+ <?php $nbld = $this->_plugin->settings->IsPruningLimitEnabled(); ?>
148
+ <label for="delete2">
149
+ <input type="radio" id="delete2" name="PruneBy" value="limit" <?php if($nbld)echo 'checked="checked"'; ?>/>
150
+ <?php echo __('Keep up to', 'wp-security-audit-log'); ?>
151
+ </label>
152
+ <input type="text" id="PruningLimit" name="PruningLimit" placeholder="<?php echo $text;?>"
153
+ value="<?php echo esc_attr($this->_plugin->settings->GetPruningLimit()); ?>"
154
+ onfocus="jQuery('#delete2').attr('checked', true);"/>
155
+ <?php echo __('alerts', 'wp-security-audit-log'); ?>
156
+ <span><?php echo $text; ?></span>
157
+ </fieldset>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
  <p class="description"><?php
159
+ echo __('Next Scheduled Cleanup is in ', 'wp-security-audit-log');
160
+ echo human_time_diff(current_time('timestamp'), $next = wp_next_scheduled('wsal_cleanup'));
161
+ echo '<!-- ' . date('dMy H:i:s', $next) . ' --> ';
162
  echo sprintf(
163
+ __('(or %s)', 'wp-security-audit-log'),
164
+ '<a href="' . admin_url('admin-ajax.php?action=AjaxRunCleanup') . '">' . __('Run Manually', 'wp-security-audit-log') . '</a>'
165
  );
166
  ?></p>
167
+ </td>
168
+ </tr>
169
+ <tr>
170
+ <th><label for="dwoption_on"><?php _e('Alerts Dashboard Widget', 'wp-security-audit-log'); ?></label></th>
171
+ <td>
172
+ <fieldset>
173
+ <?php $dwe = $this->_plugin->settings->IsWidgetsEnabled(); ?>
174
+ <label for="dwoption_on">
175
+ <input type="radio" name="EnableDashboardWidgets" id="dwoption_on" style="margin-top: 2px;" <?php if($dwe)echo 'checked="checked"'; ?> value="1">
176
+ <span><?php _e('On', 'wp-security-audit-log'); ?></span>
177
+ </label>
178
+ <br/>
179
+ <label for="dwoption_off">
180
+ <input type="radio" name="EnableDashboardWidgets" id="dwoption_off" style="margin-top: 2px;" <?php if(!$dwe)echo 'checked="checked"'; ?> value="0">
181
+ <span><?php _e('Off', 'wp-security-audit-log'); ?></span>
182
+ </label>
183
+ <br/>
184
+ <p class="description"><?php
185
+ echo sprintf(
186
+ __('Display a dashboard widget with the latest %d security alerts.', 'wp-security-audit-log'),
187
+ $this->_plugin->settings->GetDashboardWidgetMaxAlerts()
188
+ );
189
+ ?></p>
190
+ </fieldset>
191
+ </td>
192
+ </tr>
193
+ <tr>
194
+ <th><label for="pioption_on"><?php _e('Reverse Proxy / Firewall Options', 'wp-security-audit-log'); ?></label></th>
195
+ <td>
196
+ <fieldset>
197
+ <label for="EnableProxyIpCapture">
198
+ <input type="checkbox" name="EnableProxyIpCapture" value="1" id="EnableProxyIpCapture"<?php
199
+ if($this->_plugin->settings->IsMainIPFromProxy())echo ' checked="checked"';
200
+ ?>/> <?php _e('WordPress running behind firewall or proxy', 'wp-security-audit-log'); ?><br/>
201
+ <span class="description"><?php _e('Enable this option if your WordPress is running behind a firewall or reverse proxy. When this option is enabled the plugin will retrieve the user\'s IP address from the proxy header.', 'wp-security-audit-log'); ?></span>
202
+ </label>
203
+ <br/>
204
+ <label for="EnableIpFiltering">
205
+ <input type="checkbox" name="EnableIpFiltering" value="1" id="EnableIpFiltering"<?php
206
+ if($this->_plugin->settings->IsInternalIPsFiltered())echo ' checked="checked"';
207
+ ?>/> <?php _e('Filter Internal IP Addresses', 'wp-security-audit-log'); ?><br/>
208
+ <span class="description"><?php _e('Enable this option to filter internal IP addresses from the proxy headers.', 'wp-security-audit-log'); ?></span>
209
+ </label>
210
+ </fieldset>
211
+ </td>
212
+ </tr>
213
+ <tr>
214
+ <th><label for="ViewerQueryBox"><?php _e('Can View Alerts', 'wp-security-audit-log'); ?></label></th>
215
+ <td>
216
+ <fieldset>
217
+ <input type="text" id="ViewerQueryBox" style="float: left; display: block; width: 250px;">
218
+ <input type="button" id="ViewerQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
219
+ <br style="clear: both;"/>
220
+ <p class="description"><?php
221
+ _e('Users and Roles in this list can view the security alerts', 'wp-security-audit-log');
222
+ ?></p>
223
+ <div id="ViewerList"><?php
224
+ foreach($this->_plugin->settings->GetAllowedPluginViewers() as $item){
225
+ ?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
226
+ <input type="hidden" name="Viewers[]" value="<?php echo esc_attr($item); ?>"/>
227
+ <?php echo esc_html($item); ?>
228
+ <a href="javascript:;" title="Remove">&times;</a>
229
+ </span><?php
230
+ }
231
+ ?></div>
232
+ </fieldset>
233
+ </td>
234
+ </tr>
235
+ <tr>
236
+ <th><label for="EditorQueryBox"><?php _e('Can Manage Plugin', 'wp-security-audit-log'); ?></label></th>
237
+ <td>
238
+ <fieldset>
239
+ <input type="text" id="EditorQueryBox" style="float: left; display: block; width: 250px;">
240
+ <input type="button" id="EditorQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
241
+ <br style="clear: both;"/>
242
+ <p class="description"><?php
243
+ _e('Users and Roles in this list can manage the plugin settings', 'wp-security-audit-log');
244
+ ?></p>
245
+ <div id="EditorList"><?php
246
+ foreach($this->_plugin->settings->GetAllowedPluginEditors() as $item){
247
+ ?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
248
+ <input type="hidden" name="Editors[]" value="<?php echo esc_attr($item); ?>"/>
249
+ <?php echo esc_html($item); ?>
250
+ <a href="javascript:;" title="Remove">&times;</a>
251
+ </span><?php
252
+ }
253
+ ?></div>
254
+ </fieldset>
255
+ </td>
256
+ </tr>
257
+ <tr>
258
+ <th><label for="RestrictAdmins"><?php _e('Restrict Plugin Access', 'wp-security-audit-log'); ?></label></th>
259
+ <td>
260
+ <fieldset>
261
+ <input type="hidden" id="RestrictAdminsDefaultUser" value="<?php echo esc_attr(wp_get_current_user()->user_login); ?>"/>
262
+ <label for="RestrictAdmins">
263
+ <?php $ira = $this->_plugin->settings->IsRestrictAdmins(); ?>
264
+ <input type="checkbox" name="RestrictAdmins" id="RestrictAdmins"<?php if($ira)echo ' checked="checked"'; ?>/>
265
+ <span class="description">
266
+ <?php _e('By default all the administrators on this WordPress have access to manage this plugin.<br/>By enabling this option only the users specified in the two options above and your username will have access to view alerts and manage this plugin.', 'wp-security-audit-log'); ?>
267
+ </span>
268
+ </label>
269
+ </fieldset>
270
+ </td>
271
+ </tr>
272
+ <tr>
273
+ <th><label for="aroption_on"><?php _e('Refresh Audit View', 'wp-security-audit-log'); ?></label></th>
274
+ <td>
275
+ <fieldset>
276
+ <?php $are = $this->_plugin->settings->IsRefreshAlertsEnabled(); ?>
277
+ <label for="aroption_on">
278
+ <input type="radio" name="EnableAuditViewRefresh" id="aroption_on" style="margin-top: 2px;" <?php if($are)echo 'checked="checked"'; ?> value="1">
279
+ <span><?php _e('Automatic', 'wp-security-audit-log'); ?></span>
280
+ </label>
281
+ <span class="description"> &mdash; <?php _e('Refresh Audit View as soon as there are new events.', 'wp-security-audit-log'); ?></span>
282
+ <br/>
283
+ <label for="aroption_off">
284
+ <input type="radio" name="EnableAuditViewRefresh" id="aroption_off" style="margin-top: 2px;" <?php if(!$are)echo 'checked="checked"'; ?> value="0">
285
+ <span><?php _e('Manual', 'wp-security-audit-log'); ?></span>
286
+ </label>
287
+ <span class="description"> &mdash; <?php _e('Refresh Audit View only when page is reloaded.', 'wp-security-audit-log'); ?></span>
288
+ <br/>
289
+ </fieldset>
290
+ </td>
291
+ </tr>
292
+ <tr>
293
+ <th><label><?php _e('Developer Options', 'wp-security-audit-log'); ?></label></th>
294
+ <td>
295
+ <fieldset>
296
+ <?php $any = $this->_plugin->settings->IsAnyDevOptionEnabled(); ?>
297
+ <a href="javascript:;" style="<?php if($any)echo 'display: none;'; ?>"
298
+ onclick="jQuery(this).hide().next().show();">Show Developer Options</a>
299
+ <div style="<?php if(!$any)echo 'display: none;'; ?>">
300
+ <p style="border-left: 3px solid #FFD000; padding: 2px 8px; margin-left: 6px; margin-bottom: 16px;"><?php
301
+ _e('Only enable these options on testing, staging and development websites. Enabling any of the settings below on LIVE websites may cause unintended side-effects including degraded performance.', 'wp-security-audit-log');
302
+ ?></p><?php
303
+ foreach(array(
304
+ WSAL_Settings::OPT_DEV_DATA_INSPECTOR => array(
305
+ __('Data Inspector', 'wp-security-audit-log'),
306
+ __('View data logged for each triggered alert.', 'wp-security-audit-log')
307
+ ),
308
+ WSAL_Settings::OPT_DEV_PHP_ERRORS => array(
309
+ __('PHP Errors', 'wp-security-audit-log'),
310
+ __('Enables sensor for alerts generated from PHP.', 'wp-security-audit-log')
311
+ ),
312
+ WSAL_Settings::OPT_DEV_REQUEST_LOG => array(
313
+ __('Request Log', 'wp-security-audit-log'),
314
+ __('Enables logging request to file.', 'wp-security-audit-log')
315
+ ),
316
+ WSAL_Settings::OPT_DEV_BACKTRACE_LOG => array(
317
+ __('Backtrace', 'wp-security-audit-log'),
318
+ __('Log full backtrace for PHP-generated alerts.', 'wp-security-audit-log')
319
+ ),
320
+ ) as $opt => $info){
321
+ ?><label for="devoption_<?php echo $opt; ?>">
322
+ <input type="checkbox" name="DevOptions[]" id="devoption_<?php echo $opt; ?>" <?php
323
+ if($this->_plugin->settings->IsDevOptionEnabled($opt))echo 'checked="checked"'; ?> value="<?php echo $opt; ?>">
324
+ <span><?php echo $info[0]; ?></span>
325
+ <?php if(isset($info[1]) && $info[1]){ ?>
326
+ <span class="description"> &mdash; <?php echo $info[1]; ?></span>
327
+ <?php }
328
+ ?></label><br/><?php
329
+ }
330
+ ?></div>
331
+ </fieldset>
332
+ </td>
333
+ </tr>
334
+
335
+ <tr>
336
+ <th><label for="Incognito"><?php _e('Hide Plugin in Plugins Page', 'wp-security-audit-log'); ?></label></th>
337
+ <td>
338
+ <fieldset>
339
+ <label for="Incognito">
340
+ <input type="checkbox" name="Incognito" value="1" id="Incognito"<?php
341
+ if($this->_plugin->settings->IsIncognito())echo ' checked="checked"';
342
+ ?>/> <?php _e('Hide', 'wp-security-audit-log'); ?>
343
+ </label>
344
+ <br/>
345
  <span class="description">
346
+ <?php _e('To manually revert this setting set the value of option wsal-hide-plugin to 0 in the wp_options table.', 'wp-security-audit-log'); ?>
347
  </span>
348
+ </fieldset>
349
+ </td>
350
+ </tr>
351
+ <tr>
 
352
  <th><label for="aroption_on"><?php _e('Refresh Audit Log Viewer', 'wp-security-audit-log'); ?></label></th>
353
  <td>
354
  <fieldset>
439
  </fieldset>
440
  </td>
441
  </tr>
442
+ </tbody>
443
+ </table>
444
+ <table class="form-table wsal-tab widefat" id="tab-exclude">
445
+ <tbody>
446
+ <tr>
447
+ <th><h2>Users &amp; Roles</h2></th>
448
+ </tr>
449
+ <tr>
450
+ <td colspan="2">Any of the users and roles listed in the below options will be excluded from monitoring. This means that any change they do will not be logged.</td>
451
+ </tr>
452
+ <tr>
453
+ <th><label for="ExUserQueryBox"><?php _e('Excluded Users', 'wp-security-audit-log'); ?></label></th>
454
+ <td>
455
+ <fieldset>
456
+ <input type="text" id="ExUserQueryBox" style="float: left; display: block; width: 250px;">
457
+ <input type="button" id="ExUserQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
458
+ <br style="clear: both;"/>
459
+ <div id="ExUserList"><?php
460
+ foreach($this->_plugin->settings->GetExcludedMonitoringUsers() as $item){
461
+ ?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
462
+ <input type="hidden" name="ExUsers[]" value="<?php echo esc_attr($item); ?>"/>
463
+ <?php echo esc_html($item); ?>
464
+ <a href="javascript:;" title="Remove">&times;</a>
465
+ </span><?php
466
+ }
467
+ ?></div>
468
+ </fieldset>
469
+ </td>
470
+ </tr>
471
+ <tr>
472
+ <th><label for="ExRoleQueryBox"><?php _e('Excluded Roles', 'wp-security-audit-log'); ?></label></th>
473
+ <td>
474
+ <fieldset>
475
+ <input type="text" id="ExRoleQueryBox" style="float: left; display: block; width: 250px;">
476
+ <input type="button" id="ExRoleQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
477
+ <br style="clear: both;"/>
478
+ <div id="ExRoleList"><?php
479
+ foreach($this->_plugin->settings->GetExcludedMonitoringRoles() as $item){
480
+ ?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
481
+ <input type="hidden" name="ExRoles[]" value="<?php echo esc_attr($item); ?>"/>
482
+ <?php echo esc_html($item); ?>
483
+ <a href="javascript:;" title="Remove">&times;</a>
484
+ </span><?php
485
+ }
486
+ ?></div>
487
+ </fieldset>
488
+ </td>
489
+ </tr>
490
+ <tr>
491
+ <th><h2>Custom Fields</h2></th>
492
+ </tr>
493
+ <tr>
494
+ <td colspan="2">Any of the custom fields listed below will be excluded from monitoring. This means that if they are changed or updated the plugin will not log such activity.</td>
495
+ </tr>
496
+ <tr>
497
+ <th><label for="CustomQueryBox"><?php _e('Excluded Custom Fields', 'wp-security-audit-log'); ?></label></th>
498
+ <td>
499
+ <fieldset>
500
+ <input type="text" id="CustomQueryBox" style="float: left; display: block; width: 250px;">
501
+ <input type="button" id="CustomQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
502
+ <br style="clear: both;"/>
503
+ <div id="CustomList"><?php
504
+ foreach($this->_plugin->settings->GetExcludedMonitoringCustom() as $item){
505
+ ?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
506
+ <input type="hidden" name="Customs[]" value="<?php echo esc_attr($item); ?>"/>
507
+ <?php echo esc_html($item); ?>
508
+ <a href="javascript:;" title="Remove">&times;</a>
509
+ </span><?php
510
+ }
511
+ ?></div>
512
+ </fieldset>
513
+ </td>
514
+ </tr>
515
+ </tbody>
516
+ </table>
517
+ </div>
518
  <p class="submit"><input type="submit" name="submit" id="submit" class="button button-primary" value="Save Changes"></p>
519
  </form>
520
  <script type="text/javascript">
538
  array(),
539
  filemtime($this->_plugin->GetBaseDir() . '/css/settings.css')
540
  );
541
+ ?><style type="text/css">
542
+ .wsal-tab {
543
+ display: none;
544
+ }
545
+ .wsal-tab tr.alert-incomplete td {
546
+ color: #9BE;
547
+ }
548
+ .wsal-tab tr.alert-unavailable td {
549
+ color: #CCC;
550
+ }
551
+ </style><?php
552
  }
553
 
554
  public function Footer() {
558
  array(),
559
  filemtime($this->_plugin->GetBaseDir() . '/js/settings.js')
560
  );
561
+ ?><script type="text/javascript">
562
+ jQuery(document).ready(function(){
563
+ // tab handling code
564
+ jQuery('#wsal-tabs>a').click(function(){
565
+ jQuery('#wsal-tabs>a').removeClass('nav-tab-active');
566
+ jQuery('table.wsal-tab').hide();
567
+ jQuery(jQuery(this).addClass('nav-tab-active').attr('href')).show();
568
+ });
569
+ // show relevant tab
570
+ var hashlink = jQuery('#wsal-tabs>a[href="' + location.hash + '"]');
571
+ if(hashlink.length){
572
+ hashlink.click();
573
+ }else{
574
+ jQuery('#wsal-tabs>a:first').click();
575
+ }
576
+ });
577
+ </script><?php
578
  }
579
 
580
+ public function AjaxGetAllUsers() {
581
+ $users = array();
582
+ foreach ( get_users() as $user ) {
583
+ if (strpos($user->user_login, $_GET['term']) !== false) {
584
+ array_push($users, $user->user_login);
585
+ }
586
+ }
587
+ echo json_encode($users);
588
+ exit;
589
+ }
590
+
591
+ public function AjaxGetAllRoles() {
592
+ $roles = array();
593
+ foreach ( get_editable_roles() as $role_name => $role_info ) {
594
+ if (strpos($role_name, $_GET['term']) !== false) {
595
+ array_push($roles, $role_name);
596
+ }
597
+ }
598
+ echo json_encode($roles);
599
+ exit;
600
+ }
601
  }
css/auditlog.css CHANGED
@@ -177,4 +177,4 @@ td.column-user {
177
  }
178
  .wsal-ssas-dd .allsites {
179
  border-bottom: 1px solid windowframe;
180
- }
177
  }
178
  .wsal-ssas-dd .allsites {
179
  border-bottom: 1px solid windowframe;
180
+ }
css/settings.css CHANGED
@@ -27,6 +27,10 @@
27
  border-radius: 3px;
28
  cursor: default;
29
  }
 
 
 
 
30
 
31
  .sectoken-user a,
32
  .sectoken-role a,
@@ -55,3 +59,13 @@
55
  .sectoken-role { background: #EFE; border-color: #5B5; }
56
  .sectoken-other { background: #FFE; border-color: #ED5; }
57
  .sectoken-del { background: #FEE; border-color: #EBB; }
 
 
 
 
 
 
 
 
 
 
27
  border-radius: 3px;
28
  cursor: default;
29
  }
30
+ .sectoken-other {
31
+ display: table;
32
+ border-collapse: separate;
33
+ }
34
 
35
  .sectoken-user a,
36
  .sectoken-role a,
59
  .sectoken-role { background: #EFE; border-color: #5B5; }
60
  .sectoken-other { background: #FFE; border-color: #ED5; }
61
  .sectoken-del { background: #FEE; border-color: #EBB; }
62
+
63
+ .wsal-tab {
64
+ margin-top: 0px;
65
+ }
66
+ .wsal-tab th {
67
+ padding-left: 20px;
68
+ }
69
+ .wsal-tab td {
70
+ padding-left: 20px;
71
+ }
defaults.php CHANGED
@@ -32,14 +32,13 @@ function wsaldefaults_wsal_init(WpSecurityAuditLog $wsal){
32
  array('name' => 'E_CRITICAL', 'description' => __('Critical, high-impact messages.', 'wp-security-audit-log')),
33
  array('name' => 'E_DEBUG', 'description' => __('Debug informational messages.', 'wp-security-audit-log')),
34
  ));
35
-
36
- // create list of default alerts
37
  $wsal->alerts->RegisterGroup(array(
38
  __('Other User Activity', 'wp-security-audit-log') => array(
39
  array(1000, E_NOTICE, __('User logs in', 'wp-security-audit-log'), __('Successfully logged in', 'wp-security-audit-log')),
40
  array(1001, E_NOTICE, __('User logs out', 'wp-security-audit-log'), __('Successfully logged out', 'wp-security-audit-log')),
41
  array(1002, E_WARNING, __('Login failed', 'wp-security-audit-log'), __('%Attempts% failed login(s) detected', 'wp-security-audit-log')),
42
- array(1003, E_WARNING, __('Login failed', 'wp-security-audit-log'), __('%Attempts% failed login(s) detected using non existing user.', 'wp-security-audit-log')),
43
  array(2010, E_NOTICE, __('User uploaded file from Uploads directory', 'wp-security-audit-log'), __('Uploaded the file %FileName% in %FilePath%', 'wp-security-audit-log')),
44
  array(2011, E_WARNING, __('User deleted file from Uploads directory', 'wp-security-audit-log'), __('Deleted the file %FileName% from %FilePath%', 'wp-security-audit-log')),
45
  array(2046, E_CRITICAL, __('User changed a file using the theme editor', 'wp-security-audit-log'), __('Modified %File% with the Theme Editor', 'wp-security-audit-log')),
@@ -63,10 +62,10 @@ function wsaldefaults_wsal_init(WpSecurityAuditLog $wsal){
63
  array(2027, E_NOTICE, __('User changed the date of a blog post', 'wp-security-audit-log'), __('Changed the date of %PostTitle% blog post from %OldDate% to %NewDate%', 'wp-security-audit-log')),
64
  array(2049, E_NOTICE, __('User sets a post as sticky', 'wp-security-audit-log'), __('Set the post %PostTitle% as Sticky', 'wp-security-audit-log')),
65
  array(2050, E_NOTICE, __('User removes post from sticky', 'wp-security-audit-log'), __('Removed the post %PostTitle% from Sticky', 'wp-security-audit-log')),
66
- array(2053, E_NOTICE, __('User creates a custom field for a post', 'wp-security-audit-log'), __('Created custom field %MetaKey% with value %MetaValue% in post %PostTitle%', 'wp-security-audit-log')),
67
- array(2054, E_NOTICE, __('User updates a custom field value for a post', 'wp-security-audit-log'), __('Modified the value of custom field %MetaKey% from %MetaValueOld% to %MetaValueNew% in post %PostTitle%', 'wp-security-audit-log')),
68
- array(2055, E_NOTICE, __('User deletes a custom field from a post', 'wp-security-audit-log'), __('Deleted custom field %MetaKey% with value %MetaValue% from post %PostTitle%', 'wp-security-audit-log')),
69
- array(2062, E_NOTICE, __('User updates a custom field name for a post', 'wp-security-audit-log'), __('Changed the custom field name from %MetaKeyOld% to %MetaKeyNew% in post %PostTitle%', 'wp-security-audit-log')),
70
  array(2065, E_WARNING, __('User modifies content for a published post', 'wp-security-audit-log'), __('Modified the content of published post %PostTitle%', 'wp-security-audit-log')),
71
  array(2068, E_NOTICE, __('User modifies content for a draft post', 'wp-security-audit-log'), __('Modified the content of draft post %PostTitle%', 'wp-security-audit-log')),
72
  ),
@@ -85,10 +84,10 @@ function wsaldefaults_wsal_init(WpSecurityAuditLog $wsal){
85
  array(2028, E_NOTICE, __('User changed the date of a page post', 'wp-security-audit-log'), __('Changed the date of %PostTitle% page from %OldDate% to %NewDate%', 'wp-security-audit-log')),
86
  array(2047, E_NOTICE, __('User changed the parent of a page', 'wp-security-audit-log'), __('Changed the parent of %PostTitle% page from %OldParentName% to %NewParentName%', 'wp-security-audit-log')),
87
  array(2048, E_CRITICAL, __('User changes the template of a page', 'wp-security-audit-log'), __('Changed the template of %PostTitle% page from %OldTemplate% to %NewTemplate%', 'wp-security-audit-log')),
88
- array(2059, E_NOTICE, __('User creates a custom field for a page', 'wp-security-audit-log'), __('Created custom field %MetaKey% with value %MetaValue% in page %PostTitle%', 'wp-security-audit-log')),
89
- array(2060, E_NOTICE, __('User updates a custom field value for a page', 'wp-security-audit-log'), __('Modified the value of custom field %MetaKey% from %MetaValueOld% to %MetaValueNew% in page %PostTitle%', 'wp-security-audit-log')),
90
- array(2061, E_NOTICE, __('User deletes a custom field from a page', 'wp-security-audit-log'), __('Deleted custom field %MetaKey% with value %MetaValue% from page %PostTitle%', 'wp-security-audit-log')),
91
- array(2064, E_NOTICE, __('User updates a custom field name for a page', 'wp-security-audit-log'), __('Changed the custom field name from %MetaKeyOld% to %MetaKeyNew% in page %PostTitle%', 'wp-security-audit-log')),
92
  array(2066, E_WARNING, __('User modifies content for a published page', 'wp-security-audit-log'), __('Modified the content of published page %PostTitle%', 'wp-security-audit-log')),
93
  array(2069, E_NOTICE, __('User modifies content for a draft page', 'wp-security-audit-log'), __('Modified the content of draft page %PostTitle%', 'wp-security-audit-log')),
94
  ),
@@ -106,10 +105,10 @@ function wsaldefaults_wsal_init(WpSecurityAuditLog $wsal){
106
  array(2039, E_NOTICE, __('User changed the status of post with custom post type', 'wp-security-audit-log'), __('Changed the status of custom post %PostTitle% of type %PostType% from %OldStatus% to %NewStatus%', 'wp-security-audit-log')),
107
  array(2040, E_WARNING, __('User changed the visibility of a post with custom post type', 'wp-security-audit-log'), __('Changed the visibility of custom post %PostTitle% of type %PostType% from %OldVisibility% to %NewVisibility%', 'wp-security-audit-log')),
108
  array(2041, E_NOTICE, __('User changed the date of post with custom post type', 'wp-security-audit-log'), __('Changed the date of custom post %PostTitle% of type %PostType% from %OldDate% to %NewDate%', 'wp-security-audit-log')),
109
- array(2056, E_NOTICE, __('User creates a custom field for a custom post', 'wp-security-audit-log'), __('Created custom field %MetaKey% with value %MetaValue% in custom post %PostTitle% of type %PostType%', 'wp-security-audit-log')),
110
- array(2057, E_NOTICE, __('User updates a custom field for a custom post', 'wp-security-audit-log'), __('Modified the value of custom field %MetaKey% from %MetaValueOld% to %MetaValueNew% in custom post %PostTitle% of type %PostType%', 'wp-security-audit-log')),
111
- array(2058, E_NOTICE, __('User deletes a custom field from a custom post', 'wp-security-audit-log'), __('Deleted custom field %MetaKey% with value %MetaValue% from custom post %PostTitle% of type %PostType%', 'wp-security-audit-log')),
112
- array(2063, E_NOTICE, __('User updates a custom field name for a custom post', 'wp-security-audit-log'), __('Changed the custom field name from %MetaKeyOld% to %MetaKeyNew% in custom post %PostTitle% of type %PostType%', 'wp-security-audit-log')),
113
  array(2067, E_WARNING, __('User modifies content for a published custom post', 'wp-security-audit-log'), __('Modified the content of published custom post type %PostTitle%', 'wp-security-audit-log')),
114
  array(2070, E_NOTICE, __('User modifies content for a draft custom post', 'wp-security-audit-log'), __('Modified the content of draft custom post type %PostTitle%', 'wp-security-audit-log')),
115
  ),
32
  array('name' => 'E_CRITICAL', 'description' => __('Critical, high-impact messages.', 'wp-security-audit-log')),
33
  array('name' => 'E_DEBUG', 'description' => __('Debug informational messages.', 'wp-security-audit-log')),
34
  ));
35
+ // create list of default alerts
 
36
  $wsal->alerts->RegisterGroup(array(
37
  __('Other User Activity', 'wp-security-audit-log') => array(
38
  array(1000, E_NOTICE, __('User logs in', 'wp-security-audit-log'), __('Successfully logged in', 'wp-security-audit-log')),
39
  array(1001, E_NOTICE, __('User logs out', 'wp-security-audit-log'), __('Successfully logged out', 'wp-security-audit-log')),
40
  array(1002, E_WARNING, __('Login failed', 'wp-security-audit-log'), __('%Attempts% failed login(s) detected', 'wp-security-audit-log')),
41
+ array(1003, E_WARNING, __('Login failed / non existing user', 'wp-security-audit-log'), __('%Attempts% failed login(s) detected using non existing user.', 'wp-security-audit-log')),
42
  array(2010, E_NOTICE, __('User uploaded file from Uploads directory', 'wp-security-audit-log'), __('Uploaded the file %FileName% in %FilePath%', 'wp-security-audit-log')),
43
  array(2011, E_WARNING, __('User deleted file from Uploads directory', 'wp-security-audit-log'), __('Deleted the file %FileName% from %FilePath%', 'wp-security-audit-log')),
44
  array(2046, E_CRITICAL, __('User changed a file using the theme editor', 'wp-security-audit-log'), __('Modified %File% with the Theme Editor', 'wp-security-audit-log')),
62
  array(2027, E_NOTICE, __('User changed the date of a blog post', 'wp-security-audit-log'), __('Changed the date of %PostTitle% blog post from %OldDate% to %NewDate%', 'wp-security-audit-log')),
63
  array(2049, E_NOTICE, __('User sets a post as sticky', 'wp-security-audit-log'), __('Set the post %PostTitle% as Sticky', 'wp-security-audit-log')),
64
  array(2050, E_NOTICE, __('User removes post from sticky', 'wp-security-audit-log'), __('Removed the post %PostTitle% from Sticky', 'wp-security-audit-log')),
65
+ array(2053, E_NOTICE, __('User creates a custom field for a post', 'wp-security-audit-log'), __('Created custom field %MetaKey% with value %MetaValue% in post %PostTitle%'.'%MetaLink%', 'wp-security-audit-log')),
66
+ array(2054, E_NOTICE, __('User updates a custom field value for a post', 'wp-security-audit-log'), __('Modified the value of custom field %MetaKey% from %MetaValueOld% to %MetaValueNew% in post %PostTitle%'.'%MetaLink%', 'wp-security-audit-log')),
67
+ array(2055, E_NOTICE, __('User deletes a custom field from a post', 'wp-security-audit-log'), __('Deleted custom field %MetaKey% with value %MetaValue% from post %PostTitle%'.'%MetaLink%', 'wp-security-audit-log')),
68
+ array(2062, E_NOTICE, __('User updates a custom field name for a post', 'wp-security-audit-log'), __('Changed the custom field name from %MetaKeyOld% to %MetaKeyNew% in post %PostTitle%'.'%MetaLink%', 'wp-security-audit-log')),
69
  array(2065, E_WARNING, __('User modifies content for a published post', 'wp-security-audit-log'), __('Modified the content of published post %PostTitle%', 'wp-security-audit-log')),
70
  array(2068, E_NOTICE, __('User modifies content for a draft post', 'wp-security-audit-log'), __('Modified the content of draft post %PostTitle%', 'wp-security-audit-log')),
71
  ),
84
  array(2028, E_NOTICE, __('User changed the date of a page post', 'wp-security-audit-log'), __('Changed the date of %PostTitle% page from %OldDate% to %NewDate%', 'wp-security-audit-log')),
85
  array(2047, E_NOTICE, __('User changed the parent of a page', 'wp-security-audit-log'), __('Changed the parent of %PostTitle% page from %OldParentName% to %NewParentName%', 'wp-security-audit-log')),
86
  array(2048, E_CRITICAL, __('User changes the template of a page', 'wp-security-audit-log'), __('Changed the template of %PostTitle% page from %OldTemplate% to %NewTemplate%', 'wp-security-audit-log')),
87
+ array(2059, E_NOTICE, __('User creates a custom field for a page', 'wp-security-audit-log'), __('Created custom field %MetaKey% with value %MetaValue% in page %PostTitle%'.'%MetaLink%', 'wp-security-audit-log')),
88
+ array(2060, E_NOTICE, __('User updates a custom field value for a page', 'wp-security-audit-log'), __('Modified the value of custom field %MetaKey% from %MetaValueOld% to %MetaValueNew% in page %PostTitle%'.'%MetaLink%', 'wp-security-audit-log')),
89
+ array(2061, E_NOTICE, __('User deletes a custom field from a page', 'wp-security-audit-log'), __('Deleted custom field %MetaKey% with value %MetaValue% from page %PostTitle%'.'%MetaLink%', 'wp-security-audit-log')),
90
+ array(2064, E_NOTICE, __('User updates a custom field name for a page', 'wp-security-audit-log'), __('Changed the custom field name from %MetaKeyOld% to %MetaKeyNew% in page %PostTitle%'.'%MetaLink%', 'wp-security-audit-log')),
91
  array(2066, E_WARNING, __('User modifies content for a published page', 'wp-security-audit-log'), __('Modified the content of published page %PostTitle%', 'wp-security-audit-log')),
92
  array(2069, E_NOTICE, __('User modifies content for a draft page', 'wp-security-audit-log'), __('Modified the content of draft page %PostTitle%', 'wp-security-audit-log')),
93
  ),
105
  array(2039, E_NOTICE, __('User changed the status of post with custom post type', 'wp-security-audit-log'), __('Changed the status of custom post %PostTitle% of type %PostType% from %OldStatus% to %NewStatus%', 'wp-security-audit-log')),
106
  array(2040, E_WARNING, __('User changed the visibility of a post with custom post type', 'wp-security-audit-log'), __('Changed the visibility of custom post %PostTitle% of type %PostType% from %OldVisibility% to %NewVisibility%', 'wp-security-audit-log')),
107
  array(2041, E_NOTICE, __('User changed the date of post with custom post type', 'wp-security-audit-log'), __('Changed the date of custom post %PostTitle% of type %PostType% from %OldDate% to %NewDate%', 'wp-security-audit-log')),
108
+ array(2056, E_NOTICE, __('User creates a custom field for a custom post', 'wp-security-audit-log'), __('Created custom field %MetaKey% with value %MetaValue% in custom post %PostTitle% of type %PostType%'.'%MetaLink%', 'wp-security-audit-log')),
109
+ array(2057, E_NOTICE, __('User updates a custom field for a custom post', 'wp-security-audit-log'), __('Modified the value of custom field %MetaKey% from %MetaValueOld% to %MetaValueNew% in custom post %PostTitle% of type %PostType%'.'%MetaLink%', 'wp-security-audit-log')),
110
+ array(2058, E_NOTICE, __('User deletes a custom field from a custom post', 'wp-security-audit-log'), __('Deleted custom field %MetaKey% with value %MetaValue% from custom post %PostTitle% of type %PostType%'.'%MetaLink%', 'wp-security-audit-log')),
111
+ array(2063, E_NOTICE, __('User updates a custom field name for a custom post', 'wp-security-audit-log'), __('Changed the custom field name from %MetaKeyOld% to %MetaKeyNew% in custom post %PostTitle% of type %PostType%'.'%MetaLink%', 'wp-security-audit-log')),
112
  array(2067, E_WARNING, __('User modifies content for a published custom post', 'wp-security-audit-log'), __('Modified the content of published custom post type %PostTitle%', 'wp-security-audit-log')),
113
  array(2070, E_NOTICE, __('User modifies content for a draft custom post', 'wp-security-audit-log'), __('Modified the content of draft custom post type %PostTitle%', 'wp-security-audit-log')),
114
  ),
js/auditlog.js CHANGED
@@ -133,3 +133,18 @@ function WsalSsasChange(value){
133
  jQuery('#wsal-cbid').val(value);
134
  jQuery('#audit-log-viewer').submit();
135
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  jQuery('#wsal-cbid').val(value);
134
  jQuery('#audit-log-viewer').submit();
135
  }
136
+
137
+ function WsalDisableCustom(link, meta_key){
138
+ var nfe = jQuery(this).parents('div:first');
139
+ jQuery(link).hide();
140
+ jQuery.ajax({
141
+ type: 'POST',
142
+ url: ajaxurl,
143
+ async: false,
144
+ data: { action: 'AjaxDisableCustomField', notice: meta_key },
145
+ success: function(data) {
146
+ var notice = jQuery('<div class="updated" data-notice-name="notifications-extension"></div>').html(data);
147
+ jQuery("h2:first").after(notice);
148
+ }
149
+ });
150
+ }
js/settings.js CHANGED
@@ -6,7 +6,7 @@ jQuery(document).ready(function(){
6
  });
7
  };
8
 
9
- jQuery('#ViewerQueryBox, #EditorQueryBox').keydown(function(event){
10
  if(event.keyCode === 13) {
11
  var type = jQuery(this).attr('id').substr(0, 6);
12
  jQuery('#'+type+'QueryAdd').click();
@@ -14,7 +14,7 @@ jQuery(document).ready(function(){
14
  }
15
  });
16
 
17
- jQuery('#ViewerQueryAdd, #EditorQueryAdd').click(function(){
18
  var type = jQuery(this).attr('id').substr(0, 6);
19
  var value = jQuery.trim(jQuery('#'+type+'QueryBox').val());
20
  var existing = jQuery('#'+type+'List input').filter(function() { return this.value === value; });
@@ -24,7 +24,13 @@ jQuery(document).ready(function(){
24
  jQuery('#'+type+'QueryBox, #'+type+'QueryAdd').attr('disabled', true);
25
  jQuery.post(jQuery('#ajaxurl').val(), {action: 'AjaxCheckSecurityToken', token: value}, function(data){
26
  jQuery('#'+type+'QueryBox, #'+type+'QueryAdd').attr('disabled', false);
27
- if(data==='other' && !confirm('The specified token is not a user nor a role, do you still want to add it?'))return;
 
 
 
 
 
 
28
  jQuery('#'+type+'QueryBox').val('');
29
  jQuery('#'+type+'List').append(jQuery('<span class="sectoken-'+data+'"/>').text(value).append(
30
  jQuery('<input type="hidden" name="'+type+'s[]"/>').val(value),
@@ -33,7 +39,7 @@ jQuery(document).ready(function(){
33
  });
34
  });
35
 
36
- jQuery('#ViewerList>span>a, #EditorList>span>a').click(RemoveSecToken);
37
 
38
  jQuery('#RestrictAdmins').change(function(){
39
  var user = jQuery('#RestrictAdminsDefaultUser').val();
@@ -46,4 +52,20 @@ jQuery(document).ready(function(){
46
  );
47
  }
48
  });
49
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  });
7
  };
8
 
9
+ jQuery('#ViewerQueryBox, #EditorQueryBox, #ExRoleQueryBox, #ExUserQueryBox, #CustomQueryBox').keydown(function(event){
10
  if(event.keyCode === 13) {
11
  var type = jQuery(this).attr('id').substr(0, 6);
12
  jQuery('#'+type+'QueryAdd').click();
14
  }
15
  });
16
 
17
+ jQuery('#ViewerQueryAdd, #EditorQueryAdd, #ExRoleQueryAdd, #ExUserQueryAdd, #CustomQueryAdd').click(function(){
18
  var type = jQuery(this).attr('id').substr(0, 6);
19
  var value = jQuery.trim(jQuery('#'+type+'QueryBox').val());
20
  var existing = jQuery('#'+type+'List input').filter(function() { return this.value === value; });
24
  jQuery('#'+type+'QueryBox, #'+type+'QueryAdd').attr('disabled', true);
25
  jQuery.post(jQuery('#ajaxurl').val(), {action: 'AjaxCheckSecurityToken', token: value}, function(data){
26
  jQuery('#'+type+'QueryBox, #'+type+'QueryAdd').attr('disabled', false);
27
+ if (type != 'Custom') {
28
+ if(data==='other') {
29
+ alert('The specified token is not a user nor a role!');
30
+ jQuery('#'+type+'QueryBox').val('');
31
+ return;
32
+ }
33
+ }
34
  jQuery('#'+type+'QueryBox').val('');
35
  jQuery('#'+type+'List').append(jQuery('<span class="sectoken-'+data+'"/>').text(value).append(
36
  jQuery('<input type="hidden" name="'+type+'s[]"/>').val(value),
39
  });
40
  });
41
 
42
+ jQuery('#ViewerList>span>a, #EditorList>span>a, #ExRoleList>span>a, #ExUserList>span>a, #CustomList>span>a').click(RemoveSecToken);
43
 
44
  jQuery('#RestrictAdmins').change(function(){
45
  var user = jQuery('#RestrictAdminsDefaultUser').val();
52
  );
53
  }
54
  });
55
+
56
+
57
+ var usersUrl = ajaxurl + "?action=AjaxGetAllUsers";
58
+ jQuery("#ExUserQueryBox").autocomplete({
59
+ source: usersUrl,
60
+ minLength:1
61
+ });
62
+
63
+ var rolesUrl = ajaxurl + "?action=AjaxGetAllRoles";
64
+ jQuery("#ExRoleQueryBox").autocomplete({
65
+ source: rolesUrl,
66
+ minLength:1
67
+ });
68
+
69
+ });
70
+
71
+
readme.txt CHANGED
@@ -7,7 +7,7 @@ License URI: http://www.gnu.org/licenses/gpl.html
7
  Tags: wordpress security plugin, wordpress security audit log, audit log, wordpress log, event log wordpress, wordpress user tracking, wordpress activity log, wordpress audit, security event log, audit trail, security audit trail, wordpress security alerts, wordpress monitor, wordpress security monitor, wordpress admin, wordpress admin monitoring, analytics, activity, admin, multisite, wordpress multisite, actions, dashboard, log, notification, wordpress monitoring, email notification, wordpress email alerts, tracking, user tracking, user activity report
8
  Requires at least: 3.6
9
  Tested up to: 4.1.1
10
- Stable tag: 1.4.1
11
 
12
  Keep an WordPress audit log of all users' changes and other under the hood activity - Identify WordPress issues before they become security problems.
13
 
@@ -171,6 +171,18 @@ Yes it is possible to do so with the premium [WSAL Reporting Extension](http://w
171
 
172
  == Changelog ==
173
 
 
 
 
 
 
 
 
 
 
 
 
 
174
  = 1.4.1 (2015-03-12) =
175
  * **Bug Fix**
176
  * Fixed an issue where the IP address was not being reported for anyone using PHP version 5.3.3 or earlier [support ticket](https://wordpress.org/support/topic/invalid-ip-address-error?replies=4)
7
  Tags: wordpress security plugin, wordpress security audit log, audit log, wordpress log, event log wordpress, wordpress user tracking, wordpress activity log, wordpress audit, security event log, audit trail, security audit trail, wordpress security alerts, wordpress monitor, wordpress security monitor, wordpress admin, wordpress admin monitoring, analytics, activity, admin, multisite, wordpress multisite, actions, dashboard, log, notification, wordpress monitoring, email notification, wordpress email alerts, tracking, user tracking, user activity report
8
  Requires at least: 3.6
9
  Tested up to: 4.1.1
10
+ Stable tag: 1.5.0
11
 
12
  Keep an WordPress audit log of all users' changes and other under the hood activity - Identify WordPress issues before they become security problems.
13
 
171
 
172
  == Changelog ==
173
 
174
+ = 1.5.0 (2015-03-18) =
175
+ * **New Features**
176
+ * Ability to exclude custom fields from monitoring (custom fields can be excluded from the Audit Log Viewer with a simple click or you can specify them in the settings)
177
+ * Ability to exclude WordPress users and roles from monitoring
178
+
179
+ * **Improvements**
180
+ * WP Security Audit Log now has its own settings table in WordPress database. This will provide us with more flexibility and have more centralization of data
181
+ * Updated the code where is_admin() function was being used to follow better security practises
182
+
183
+ * **Bug Fixes**
184
+ * Fixed a problem where a PHP exception was being thrown during the activation of the plugin [support ticket](https://wordpress.org/support/topic/php-error-alert-with-code-5001-has-not-be-registered?replies=11)
185
+
186
  = 1.4.1 (2015-03-12) =
187
  * **Bug Fix**
188
  * Fixed an issue where the IP address was not being reported for anyone using PHP version 5.3.3 or earlier [support ticket](https://wordpress.org/support/topic/invalid-ip-address-error?replies=4)
wp-security-audit-log.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: WP Security Audit Log
4
  Plugin URI: http://www.wpwhitesecurity.com/wordpress-security-plugins/wp-security-audit-log/
5
  Description: Identify WordPress security issues before they become a problem. Keep track of everything happening on your WordPress including WordPress users activity. Similar to Windows Event Log and Linux Syslog, WP Security Audit Log generates a security alert for everything that happens on your WordPress blogs and websites. Use the Audit Log Viewer included in the plugin to see all the security alerts.
6
  Author: WP White Security
7
- Version: 1.4.1
8
  Text Domain: wp-security-audit-log
9
  Author URI: http://www.wpwhitesecurity.com/
10
  License: GPL2
@@ -83,6 +83,12 @@ class WpSecurityAuditLog {
83
  * @var WSAL_SimpleProfiler
84
  */
85
  public $profiler;
 
 
 
 
 
 
86
 
87
  /**
88
  * Contains a list of cleanup callbacks.
@@ -110,9 +116,13 @@ class WpSecurityAuditLog {
110
  * Initialize plugin.
111
  */
112
  public function __construct(){
 
113
  // profiler has to be loaded manually
114
  require_once('classes/SimpleProfiler.php');
115
  $this->profiler = new WSAL_SimpleProfiler();
 
 
 
116
 
117
  // load autoloader and register base paths
118
  require_once('classes/Autoloader.php');
@@ -130,6 +140,9 @@ class WpSecurityAuditLog {
130
 
131
  // listen for installation event
132
  register_activation_hook(__FILE__, array($this, 'Install'));
 
 
 
133
 
134
  // listen for cleanup event
135
  add_action('wsal_cleanup', array($this, 'CleanUp'));
@@ -139,8 +152,19 @@ class WpSecurityAuditLog {
139
 
140
  // render wsal footer
141
  add_action('admin_footer', array($this, 'RenderFooter'));
 
 
 
 
 
 
 
 
 
142
 
 
143
  }
 
144
 
145
  /**
146
  * @internal Render plugin stuff in page header.
@@ -148,6 +172,22 @@ class WpSecurityAuditLog {
148
  public function RenderHeader(){
149
  // common.css?
150
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
 
152
  /**
153
  * @internal Render plugin stuff in page footer.
@@ -198,15 +238,22 @@ class WpSecurityAuditLog {
198
  die(1);
199
  }
200
 
 
 
 
201
  $PreInstalled = $this->IsInstalled();
202
 
203
  // if system already installed, do updates now (if any)
204
  $OldVersion = $this->GetOldVersion();
205
  $NewVersion = $this->GetNewVersion();
206
  if ($PreInstalled && $OldVersion != $NewVersion) $this->Update($OldVersion, $NewVersion);
207
-
208
- // ensure that the system is installed and schema is correct
209
- WSAL_DB_ActiveRecord::InstallAll();
 
 
 
 
210
 
211
  // if system wasn't installed, try migration now
212
  if (!$PreInstalled && $this->CanMigrate()) $this->Migrate();
@@ -236,7 +283,7 @@ class WpSecurityAuditLog {
236
  $this->GetGlobalOption('version', $new_version);
237
 
238
  // disable all developer options
239
- $this->settings->ClearDevOptions();
240
 
241
  // do version-to-version specific changes
242
  if(version_compare($old_version, '1.2.3') == -1){
@@ -250,16 +297,14 @@ class WpSecurityAuditLog {
250
  public function Uninstall(){
251
  if ($this->GetGlobalOption("delete-data") == 1) {
252
  WSAL_DB_ActiveRecord::UninstallAll();
253
- $flag = true;
254
- while ( $flag ) {
255
- $flag = $this->delete_options_prefixed( 'wsal-' );
256
- }
257
  }
258
  wp_clear_scheduled_hook('wsal_cleanup');
259
  }
260
 
261
  public function delete_options_prefixed( $prefix ) {
262
  global $wpdb;
 
263
  if ( $this->IsMultisite() ) {
264
  $table_name = $wpdb->prefix .'sitemeta';
265
  $result = $wpdb->query( "DELETE FROM {$table_name} WHERE meta_key LIKE '{$prefix}%'" );
@@ -268,18 +313,36 @@ class WpSecurityAuditLog {
268
  }
269
  return ($result) ? true : false;
270
  }
 
 
 
 
 
 
 
271
 
272
  public function read_options_prefixed( $prefix ) {
273
  global $wpdb;
274
  if ( $this->IsMultisite() ) {
275
  $table_name = $wpdb->prefix .'sitemeta';
276
- $result = $wpdb->get_results( "SELECT site_id,meta_key,meta_value FROM {$table_name} WHERE meta_key LIKE '{$prefix}%'", ARRAY_A );
277
  } else {
278
- $result = $wpdb->get_results( "SELECT option_name,option_value FROM {$wpdb->options} WHERE option_name LIKE '{$prefix}%'", ARRAY_A );
279
  }
280
- return $result;
281
  }
282
-
 
 
 
 
 
 
 
 
 
 
 
283
  /**
284
  * Migrate data from old plugin.
285
  */
@@ -395,8 +458,11 @@ class WpSecurityAuditLog {
395
  * @return mixed Option's value or $default if option not set.
396
  */
397
  public function GetGlobalOption($option, $default = false, $prefix = self::OPT_PRFX){
398
- $fn = $this->IsMultisite() ? 'get_site_option' : 'get_option';
399
- return $fn($prefix . $option, $default);
 
 
 
400
  }
401
 
402
  /**
@@ -406,8 +472,10 @@ class WpSecurityAuditLog {
406
  * @param string $prefix (Optional) A prefix used before option name.
407
  */
408
  public function SetGlobalOption($option, $value, $prefix = self::OPT_PRFX){
409
- $fn = $this->IsMultisite() ? 'update_site_option' : 'update_option';
410
- $fn($prefix . $option, $value);
 
 
411
  }
412
 
413
  /**
@@ -521,7 +589,7 @@ add_action('plugins_loaded', array(WpSecurityAuditLog::GetInstance(), 'Load'));
521
  WpSecurityAuditLog::GetInstance()->LoadDefaults();
522
 
523
  // Start listening to events
524
- WpSecurityAuditLog::GetInstance()->sensors->HookEvents();
525
 
526
  // End profile snapshot
527
  $s->Stop();
4
  Plugin URI: http://www.wpwhitesecurity.com/wordpress-security-plugins/wp-security-audit-log/
5
  Description: Identify WordPress security issues before they become a problem. Keep track of everything happening on your WordPress including WordPress users activity. Similar to Windows Event Log and Linux Syslog, WP Security Audit Log generates a security alert for everything that happens on your WordPress blogs and websites. Use the Audit Log Viewer included in the plugin to see all the security alerts.
6
  Author: WP White Security
7
+ Version: 1.5.0
8
  Text Domain: wp-security-audit-log
9
  Author URI: http://www.wpwhitesecurity.com/
10
  License: GPL2
83
  * @var WSAL_SimpleProfiler
84
  */
85
  public $profiler;
86
+
87
+ /**
88
+ * Options.
89
+ * @var WSAL_DB_Option
90
+ */
91
+ public $options;
92
 
93
  /**
94
  * Contains a list of cleanup callbacks.
116
  * Initialize plugin.
117
  */
118
  public function __construct(){
119
+
120
  // profiler has to be loaded manually
121
  require_once('classes/SimpleProfiler.php');
122
  $this->profiler = new WSAL_SimpleProfiler();
123
+
124
+ require_once('classes/DB/ActiveRecord.php');
125
+ require_once('classes/DB/Option.php');
126
 
127
  // load autoloader and register base paths
128
  require_once('classes/Autoloader.php');
140
 
141
  // listen for installation event
142
  register_activation_hook(__FILE__, array($this, 'Install'));
143
+
144
+ // listen for init event
145
+ add_action('init', array($this, 'Init'));
146
 
147
  // listen for cleanup event
148
  add_action('wsal_cleanup', array($this, 'CleanUp'));
152
 
153
  // render wsal footer
154
  add_action('admin_footer', array($this, 'RenderFooter'));
155
+
156
+ // handle admin Disable Custom Field
157
+ add_action('wp_ajax_AjaxDisableCustomField', array($this, 'AjaxDisableCustomField'));
158
+ }
159
+
160
+ /**
161
+ * @internal Start to trigger the events after installation.
162
+ */
163
+ public function Init(){
164
 
165
+ WpSecurityAuditLog::GetInstance()->sensors->HookEvents();
166
  }
167
+
168
 
169
  /**
170
  * @internal Render plugin stuff in page header.
172
  public function RenderHeader(){
173
  // common.css?
174
  }
175
+
176
+ /**
177
+ * Disable Custom Field through ajax.
178
+ * @internal
179
+ */
180
+ public function AjaxDisableCustomField(){
181
+ $fields = $this->GetGlobalOption('excluded-custom');
182
+ if ( isset($fields) && $fields != "") {
183
+ $fields .= ",".$_POST['notice'];
184
+ } else {
185
+ $fields = $_POST['notice'];
186
+ }
187
+ $this->SetGlobalOption('excluded-custom', $fields);
188
+ echo 'Custom Field '.$_POST['notice'].' is no longer being monitored.<br />Enable the monitoring of this custom field again from the <a href="admin.php?page=wsal-settings#tab-exclude"> Excluded Objects </a> tab in the plugin settings';
189
+ die;
190
+ }
191
 
192
  /**
193
  * @internal Render plugin stuff in page footer.
238
  die(1);
239
  }
240
 
241
+ // ensure that the system is installed and schema is correct
242
+ WSAL_DB_ActiveRecord::InstallAll();
243
+
244
  $PreInstalled = $this->IsInstalled();
245
 
246
  // if system already installed, do updates now (if any)
247
  $OldVersion = $this->GetOldVersion();
248
  $NewVersion = $this->GetNewVersion();
249
  if ($PreInstalled && $OldVersion != $NewVersion) $this->Update($OldVersion, $NewVersion);
250
+
251
+ // Load options from wp_options table or wp_sitemeta in multisite enviroment
252
+ $data = $this->read_options_prefixed("wsal-");
253
+ if (!empty($data)) {
254
+ $this->SetOptions($data);
255
+ }
256
+ $this->deleteAllOptions();
257
 
258
  // if system wasn't installed, try migration now
259
  if (!$PreInstalled && $this->CanMigrate()) $this->Migrate();
283
  $this->GetGlobalOption('version', $new_version);
284
 
285
  // disable all developer options
286
+ //$this->settings->ClearDevOptions();
287
 
288
  // do version-to-version specific changes
289
  if(version_compare($old_version, '1.2.3') == -1){
297
  public function Uninstall(){
298
  if ($this->GetGlobalOption("delete-data") == 1) {
299
  WSAL_DB_ActiveRecord::UninstallAll();
300
+ $this->deleteAllOptions();
 
 
 
301
  }
302
  wp_clear_scheduled_hook('wsal_cleanup');
303
  }
304
 
305
  public function delete_options_prefixed( $prefix ) {
306
  global $wpdb;
307
+
308
  if ( $this->IsMultisite() ) {
309
  $table_name = $wpdb->prefix .'sitemeta';
310
  $result = $wpdb->query( "DELETE FROM {$table_name} WHERE meta_key LIKE '{$prefix}%'" );
313
  }
314
  return ($result) ? true : false;
315
  }
316
+
317
+ private function deleteAllOptions() {
318
+ $flag = true;
319
+ while ( $flag ) {
320
+ $flag = $this->delete_options_prefixed( 'wsal-' );
321
+ }
322
+ }
323
 
324
  public function read_options_prefixed( $prefix ) {
325
  global $wpdb;
326
  if ( $this->IsMultisite() ) {
327
  $table_name = $wpdb->prefix .'sitemeta';
328
+ $results = $wpdb->get_results( "SELECT site_id,meta_key,meta_value FROM {$table_name} WHERE meta_key LIKE '{$prefix}%'", ARRAY_A );
329
  } else {
330
+ $results = $wpdb->get_results( "SELECT option_name,option_value FROM {$wpdb->options} WHERE option_name LIKE '{$prefix}%'", ARRAY_A );
331
  }
332
+ return $results;
333
  }
334
+
335
+ public function SetOptions($data){
336
+ foreach($data as $key => $option) {
337
+ $this->options = new WSAL_DB_Option();
338
+ if ( $this->IsMultisite() ) {
339
+ $this->options->SetOptionValue($option['meta_key'], $option['meta_value']);
340
+ } else {
341
+ $this->options->SetOptionValue($option['option_name'], $option['option_value']);
342
+ }
343
+ }
344
+ }
345
+
346
  /**
347
  * Migrate data from old plugin.
348
  */
458
  * @return mixed Option's value or $default if option not set.
459
  */
460
  public function GetGlobalOption($option, $default = false, $prefix = self::OPT_PRFX){
461
+ //$fn = $this->IsMultisite() ? 'get_site_option' : 'get_option';
462
+ //var_dump($fn($prefix . $option, $default));
463
+ //return $fn($prefix . $option, $default);
464
+ $this->options = new WSAL_DB_Option();
465
+ return $this->options->GetOptionValue($prefix . $option, $default);
466
  }
467
 
468
  /**
472
  * @param string $prefix (Optional) A prefix used before option name.
473
  */
474
  public function SetGlobalOption($option, $value, $prefix = self::OPT_PRFX){
475
+ //$fn = $this->IsMultisite() ? 'update_site_option' : 'update_option';
476
+ //$fn($prefix . $option, $value);
477
+ $this->options = new WSAL_DB_Option();
478
+ $this->options->SetOptionValue($prefix . $option, $value);
479
  }
480
 
481
  /**
589
  WpSecurityAuditLog::GetInstance()->LoadDefaults();
590
 
591
  // Start listening to events
592
+ //WpSecurityAuditLog::GetInstance()->sensors->HookEvents();
593
 
594
  // End profile snapshot
595
  $s->Stop();