WP Security Audit Log - Version 0.5

Version Description

  • New WordPress Security Alerts for monitoring of Widgets

    • Alert 2042: New widget was added
    • Alert 2043: A widget was modified
    • Alert 2044: A widget was deleted
    • Alert 2045: A widget was moved
  • New Plugin Features

    • New setting to allow specific user(s) and role(s) to view the Audit Log Viewer (read only)
    • New setting to allow specific user(s) and role(s) to manage the WP Security Audit Log plugin (can change plugin settings, enable disable WordPress security alerts etc)
  • Plugin Improvements

    • Renamed "login/logout" tab in "Enable/Disable Alerts" section to plugins to "Other User Activity"
    • Added the files alerts (uploaded / delete files) to the "Enable/Disable Alerts" (previously unavailable)
  • Bug Fixes

    • Fixed issue where all users were able to see the Dashboard widgets with security alerts - now restricted only to users who have access to the plugin
    • Fixed user reported issue (http://wordpress.org/support/topic/errors-on-enabledisable-alerts-page)
Download this release

Release Info

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

Code changes from version 0.4 to 0.5

inc/WPPH.php CHANGED
@@ -5,15 +5,111 @@
5
  class WPPH
6
  {
7
  /**
8
- * @return bool
9
- * Convenient method to check whether or not the user has access rights
 
10
  */
11
- public static function canRun() {
12
- if(! WPPHUtil::isAdministrator()){ return false; }
13
- // todo: when we add option to select individual admins...
14
- //todo...
15
- return true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  }
 
 
17
  /**
18
  * @return bool
19
  * Convenient method to check whether or not the plugin's resources can be loaded
@@ -33,18 +129,42 @@ class WPPH
33
 
34
  public static function createPluginWpSidebar()
35
  {
36
- if (!current_user_can('administrator')){return false;}
37
- if (function_exists('add_menu_page'))
 
 
 
38
  {
39
- $baseMenuSlug = 'wpph_';
40
- $reqCap = 'activate_plugins';
41
-
42
- add_menu_page('WP Security Audit Log', 'WP Security Audit Log', $reqCap, $baseMenuSlug, 'WPPH::pageMain', WPPH_PLUGIN_URL.'res/img/logo-main-menu.png');
43
- add_submenu_page($baseMenuSlug, 'Audit Log Viewer', 'Audit Log Viewer', $reqCap, $baseMenuSlug, 'WPPH::pageMain');
44
- add_submenu_page($baseMenuSlug, __('Settings',WPPH_PLUGIN_TEXT_DOMAIN), __('Settings',WPPH_PLUGIN_TEXT_DOMAIN), $reqCap, $baseMenuSlug.'settings', 'WPPH::pageSettings');
45
- add_submenu_page($baseMenuSlug, __('Enable/Disable Alerts',WPPH_PLUGIN_TEXT_DOMAIN), __('Enable/Disable Alerts',WPPH_PLUGIN_TEXT_DOMAIN), $reqCap, $baseMenuSlug.'alerts', 'WPPH::pageAlerts');
46
- add_submenu_page($baseMenuSlug, __('About',WPPH_PLUGIN_TEXT_DOMAIN), __('About',WPPH_PLUGIN_TEXT_DOMAIN), $reqCap, $baseMenuSlug.'about', 'WPPH::pageAbout');
47
- add_submenu_page($baseMenuSlug, __('Support',WPPH_PLUGIN_TEXT_DOMAIN), __('Support',WPPH_PLUGIN_TEXT_DOMAIN), $reqCap, $baseMenuSlug.'support', 'WPPH::pageSupport');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  }
49
  }
50
 
@@ -59,26 +179,62 @@ class WPPH
59
  public static function pageAbout() { include(WPPH_PLUGIN_DIR.'pages/about.php'); }
60
  public static function pageSupport() { include(WPPH_PLUGIN_DIR.'pages/support.php'); }
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  public static function createPluginDefaultSettings()
63
  {
64
- global $wpphEvents;
65
  $settings = new stdClass();
66
  $settings->daysToKeep = 0;
67
  $settings->eventsToKeep = WPPH_KEEP_MAX_EVENTS; // default delete option
68
  $settings->showEventsViewList = 50; // how many items to show in the event viewer by default
69
  $settings->lastCleanup = time();
70
  $settings->cleanupRan = 0;
71
- $settings->logEvents = $wpphEvents; // holds the list of events that will be triggered
72
  $settings->showDW = 1; // whether or not to show the dashboard widget. @since v0.4
73
  update_option(WPPH_PLUGIN_SETTING_NAME, $settings);
 
74
  wpphLog('Settings added.');
 
75
  }
76
  public static function getPluginSettings()
77
  {
78
  $settings = get_option(WPPH_PLUGIN_SETTING_NAME);
79
  if(false === $settings){
80
- self::createPluginDefaultSettings();
81
- $settings = get_option(WPPH_PLUGIN_SETTING_NAME);
82
  }
83
  return $settings;
84
  }
@@ -228,7 +384,6 @@ class WPPH
228
  {
229
  wp_clear_scheduled_hook(WPPH_PLUGIN_DEL_EVENTS_CRON_TASK_NAME);
230
  delete_option(WPPH_PLUGIN_ERROR_OPTION_NAME);
231
- delete_option(WPPH_PLUGIN_SETTING_NAME);
232
  wpphLog('__FUNCTION__.() triggered.');
233
  }
234
 
@@ -250,12 +405,12 @@ class WPPH
250
  update_option(WPPH_PLUGIN_DB_UPDATED,1);
251
  delete_option(WPPH_PLUGIN_ERROR_OPTION_NAME);
252
  update_option(WPPH_PLUGIN_VERSION_OPTION_NAME, WPPH_PLUGIN_VERSION);
 
253
  if($triggerInstallEvent)
254
  {
255
- define('WPPH_PLUGIN_INSTALLED_OK',true);
256
- $current_user = wp_get_current_user();
257
  // log plugin installation
258
- WPPHEvent::_addLogEvent(5000,$current_user->ID, WPPHUtil::getIP(), array(WPPH_PLUGIN_NAME));
259
  wpphLog('Plugin installed.', array('plugin'=>WPPH_PLUGIN_NAME));
260
  }
261
  // log plugin activation
5
  class WPPH
6
  {
7
  /**
8
+ * The required user capability to display the menu
9
+ * @since v0.5
10
+ * @var string
11
  */
12
+ static $requiredCapMenu = 'read';
13
+ /**
14
+ * @since v0.5
15
+ * @var string
16
+ */
17
+ static $baseMenuSlug = WPPH_PLUGIN_PREFIX;
18
+
19
+ /**
20
+ * @since v0.5
21
+ * Retrieve the list of all events to display in the enable/disable alerts page
22
+ * @return array
23
+ */
24
+ static function getDefaultEvents()
25
+ {
26
+ return array(
27
+ 'Other_User_Activity' => array(
28
+ 1000 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User logs in',WPPH_PLUGIN_TEXT_DOMAIN)),
29
+ 1001 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User Logs out',WPPH_PLUGIN_TEXT_DOMAIN)),
30
+ 1002 => array('type' => WPPH_E_WARNING_TEXT, 'text' => __('Failed login detected',WPPH_PLUGIN_TEXT_DOMAIN)),
31
+ 2010 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User uploaded a file to the uploads directory',WPPH_PLUGIN_TEXT_DOMAIN)),
32
+ 2011 => array('type' => WPPH_E_WARNING_TEXT, 'text' => __('User deleted a file from the uploads directory',WPPH_PLUGIN_TEXT_DOMAIN)),
33
+ ),
34
+ 'Pages' => array(
35
+ 2004 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User created a new WordPress page and saved it as draft',WPPH_PLUGIN_TEXT_DOMAIN)),
36
+ 2005 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User published a WorPress page',WPPH_PLUGIN_TEXT_DOMAIN)),
37
+ 2006 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User modified a published WordPress page',WPPH_PLUGIN_TEXT_DOMAIN)),
38
+ 2007 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User modified a draft WordPress page',WPPH_PLUGIN_TEXT_DOMAIN)),
39
+ 2009 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User permanently deleted a page from the trash',WPPH_PLUGIN_TEXT_DOMAIN)),
40
+ 2013 => array('type' => WPPH_E_WARNING_TEXT, 'text' => __('User moved WordPress page to the trash',WPPH_PLUGIN_TEXT_DOMAIN)),
41
+ 2015 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('User restored a WordPress page from trash',WPPH_PLUGIN_TEXT_DOMAIN)),
42
+ 2018 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed page URL',WPPH_PLUGIN_TEXT_DOMAIN)),
43
+ 2020 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed page author',WPPH_PLUGIN_TEXT_DOMAIN)),
44
+ 2022 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed page status',WPPH_PLUGIN_TEXT_DOMAIN)),
45
+ 2026 => array('type' => WPPH_E_WARNING_TEXT, 'text' => __('User changed the visibility of a page',WPPH_PLUGIN_TEXT_DOMAIN)),
46
+ 2028 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed the date of a page post',WPPH_PLUGIN_TEXT_DOMAIN)),
47
+ ),
48
+ 'Blog_Posts' => array(
49
+ 2000 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User created a new blog post and saved it as draft',WPPH_PLUGIN_TEXT_DOMAIN)),
50
+ 2001 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User published a blog post',WPPH_PLUGIN_TEXT_DOMAIN)),
51
+ 2002 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User modified a published blog post',WPPH_PLUGIN_TEXT_DOMAIN)),
52
+ 2003 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User modified a draft blog post',WPPH_PLUGIN_TEXT_DOMAIN)),
53
+ 2008 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User permanently deleted a blog post from the trash',WPPH_PLUGIN_TEXT_DOMAIN)),
54
+ 2012 => array('type' => WPPH_E_WARNING_TEXT, 'text' => __('User moved a blog post to the trash',WPPH_PLUGIN_TEXT_DOMAIN)),
55
+ 2014 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('User restored a blog post from trash',WPPH_PLUGIN_TEXT_DOMAIN)),
56
+ 2016 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed blog post category',WPPH_PLUGIN_TEXT_DOMAIN)),
57
+ 2017 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed blog post URL',WPPH_PLUGIN_TEXT_DOMAIN)),
58
+ 2019 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed blog post author',WPPH_PLUGIN_TEXT_DOMAIN)),
59
+ 2021 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed blog post status',WPPH_PLUGIN_TEXT_DOMAIN)),
60
+ 2023 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User created new category',WPPH_PLUGIN_TEXT_DOMAIN)),
61
+ 2024 => array('type' => WPPH_E_WARNING_TEXT, 'text' => __('User deleted a category',WPPH_PLUGIN_TEXT_DOMAIN)),
62
+ 2025 => array('type' => WPPH_E_WARNING_TEXT, 'text' => __('User changed the visibility of a blog post',WPPH_PLUGIN_TEXT_DOMAIN)),
63
+ 2027 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed the date of a blog post',WPPH_PLUGIN_TEXT_DOMAIN)),
64
+ ),
65
+ 'Custom_Posts' => array(
66
+ 2029 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User created a new custom blog post and saved it as draft',WPPH_PLUGIN_TEXT_DOMAIN)),
67
+ 2030 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User published a custom blog post',WPPH_PLUGIN_TEXT_DOMAIN)),
68
+ 2031 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User modified a published custom blog post',WPPH_PLUGIN_TEXT_DOMAIN)),
69
+ 2032 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User modified a draft custom blog post',WPPH_PLUGIN_TEXT_DOMAIN)),
70
+ 2033 => array('type' => WPPH_E_WARNING_TEXT, 'text' => __('User permanently deleted a custom blog post from the trash',WPPH_PLUGIN_TEXT_DOMAIN)),
71
+ 2034 => array('type' => WPPH_E_WARNING_TEXT, 'text' => __('User moved a custom blog post to the trash',WPPH_PLUGIN_TEXT_DOMAIN)),
72
+ 2035 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('User restored a custom blog post from trash',WPPH_PLUGIN_TEXT_DOMAIN)),
73
+ 2036 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed custom blog post category',WPPH_PLUGIN_TEXT_DOMAIN)),
74
+ 2037 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed custom blog post URL',WPPH_PLUGIN_TEXT_DOMAIN)),
75
+ 2038 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed custom blog post author',WPPH_PLUGIN_TEXT_DOMAIN)),
76
+ 2039 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed custom blog post status',WPPH_PLUGIN_TEXT_DOMAIN)),
77
+ 2040 => array('type' => WPPH_E_WARNING_TEXT, 'text' => __('User changed the visibility of a custom blog post',WPPH_PLUGIN_TEXT_DOMAIN)),
78
+ 2041 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed the date of a custom blog post',WPPH_PLUGIN_TEXT_DOMAIN)),
79
+ ),
80
+ 'Users_Profiles' => array(
81
+ 4000 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('A new user was created on WordPress',WPPH_PLUGIN_TEXT_DOMAIN)),
82
+ 4001 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('A user created another WordPress user',WPPH_PLUGIN_TEXT_DOMAIN)),
83
+ 4002 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('The role of a user was changed by another WordPress user',WPPH_PLUGIN_TEXT_DOMAIN)),
84
+ 4003 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('User has changed his or her password',WPPH_PLUGIN_TEXT_DOMAIN)),
85
+ 4004 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('A user changed another user\'s password',WPPH_PLUGIN_TEXT_DOMAIN)),
86
+ 4005 => array('type' => WPPH_E_NOTICE_TEXT,'text' => __('User changed his or her email address',WPPH_PLUGIN_TEXT_DOMAIN)),
87
+ 4006 => array('type' => WPPH_E_NOTICE_TEXT,'text' => __('A user changed another user\'s email address',WPPH_PLUGIN_TEXT_DOMAIN)),
88
+ 4007 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('A user was deleted by another user',WPPH_PLUGIN_TEXT_DOMAIN)),
89
+ ),
90
+ 'Widgets' => array(
91
+ 2042 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('User added a new widget',WPPH_PLUGIN_TEXT_DOMAIN)),
92
+ 2043 => array('type' => WPPH_E_WARNING_TEXT, 'text' => __('User modified a widget',WPPH_PLUGIN_TEXT_DOMAIN)),
93
+ 2044 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('User deleted a widget',WPPH_PLUGIN_TEXT_DOMAIN)),
94
+ 2045 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User moved a widget',WPPH_PLUGIN_TEXT_DOMAIN)),
95
+ ),
96
+ 'Plugins' => array(
97
+ 5000 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('User installed a plugin',WPPH_PLUGIN_TEXT_DOMAIN)),
98
+ 5001 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('User activated a WordPress plugin',WPPH_PLUGIN_TEXT_DOMAIN)),
99
+ 5002 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('User deactivated a WordPress plugin',WPPH_PLUGIN_TEXT_DOMAIN)),
100
+ 5003 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('User uninstalled a plugin',WPPH_PLUGIN_TEXT_DOMAIN)),
101
+ 5004 => array('type' => WPPH_E_WARNING_TEXT, 'text' => __('User upgraded a plugin',WPPH_PLUGIN_TEXT_DOMAIN)),
102
+ ),
103
+ 'Settings_And_System_Activity' => array(
104
+ 6000 => array('type' => WPPH_E_NOTICE_TEXT,'text' => __('Security alerts automatically pruned by system',WPPH_PLUGIN_TEXT_DOMAIN)),
105
+ 6001 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('Option Anyone Can Register in WordPress settings changed',WPPH_PLUGIN_TEXT_DOMAIN)),
106
+ 6002 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('New User Default Role changed',WPPH_PLUGIN_TEXT_DOMAIN)),
107
+ 6003 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('WordPress Administrator Notification email changed',WPPH_PLUGIN_TEXT_DOMAIN))
108
+ ),
109
+ );
110
  }
111
+
112
+
113
  /**
114
  * @return bool
115
  * Convenient method to check whether or not the plugin's resources can be loaded
129
 
130
  public static function createPluginWpSidebar()
131
  {
132
+ $reqCap = self::$requiredCapMenu;
133
+ $user = wp_get_current_user();
134
+ $userId = $user->ID;
135
+
136
+ if (!function_exists('add_menu_page'))
137
  {
138
+ wpphLog('The required function "add_menu_page" to create the menu is not available on this installation.');
139
+ return;
140
+ }
141
+
142
+ if(WPPHUtil::isAdministrator($userId)){
143
+ self::_createMenu($reqCap, true, true, true);
144
+ }
145
+ elseif (WPPHUtil::isAllowedChange()){
146
+ self::_createMenu($reqCap, true, true);
147
+ }
148
+ elseif(WPPHUtil::isAllowedAccess()){
149
+ self::_createMenu($reqCap, true);
150
+ }
151
+ }
152
+
153
+ private static function _createMenu($reqCap, $allowedAccess = false, $allowedChange = false, $isAdministrator = false)
154
+ {
155
+ if($isAdministrator || $allowedChange){
156
+ add_menu_page('WP Security Audit Log', 'WP Security Audit Log', $reqCap, self::$baseMenuSlug, 'WPPH::pageMain', WPPH_PLUGIN_URL.'res/img/logo-main-menu.png');
157
+ add_submenu_page(self::$baseMenuSlug, 'Audit Log Viewer', 'Audit Log Viewer', $reqCap, self::$baseMenuSlug, 'WPPH::pageMain');
158
+ add_submenu_page(self::$baseMenuSlug, __('Settings',WPPH_PLUGIN_TEXT_DOMAIN), __('Settings',WPPH_PLUGIN_TEXT_DOMAIN), $reqCap, self::$baseMenuSlug.'settings', 'WPPH::pageSettings');
159
+ add_submenu_page(self::$baseMenuSlug, __('Enable/Disable Alerts',WPPH_PLUGIN_TEXT_DOMAIN), __('Enable/Disable Alerts',WPPH_PLUGIN_TEXT_DOMAIN), $reqCap, self::$baseMenuSlug.'alerts', 'WPPH::pageAlerts');
160
+ add_submenu_page(self::$baseMenuSlug, __('About',WPPH_PLUGIN_TEXT_DOMAIN), __('About',WPPH_PLUGIN_TEXT_DOMAIN), $reqCap, self::$baseMenuSlug.'about', 'WPPH::pageAbout');
161
+ add_submenu_page(self::$baseMenuSlug, __('Support',WPPH_PLUGIN_TEXT_DOMAIN), __('Support',WPPH_PLUGIN_TEXT_DOMAIN), $reqCap, self::$baseMenuSlug.'support', 'WPPH::pageSupport');
162
+ }
163
+ elseif($allowedAccess){
164
+ add_menu_page('WP Security Audit Log', 'WP Security Audit Log', $reqCap, self::$baseMenuSlug, 'WPPH::pageMain', WPPH_PLUGIN_URL.'res/img/logo-main-menu.png');
165
+ add_submenu_page(self::$baseMenuSlug, 'Audit Log Viewer', 'Audit Log Viewer', $reqCap, self::$baseMenuSlug, 'WPPH::pageMain');
166
+ add_submenu_page(self::$baseMenuSlug, __('About',WPPH_PLUGIN_TEXT_DOMAIN), __('About',WPPH_PLUGIN_TEXT_DOMAIN), $reqCap, self::$baseMenuSlug.'about', 'WPPH::pageAbout');
167
+ add_submenu_page(self::$baseMenuSlug, __('Support',WPPH_PLUGIN_TEXT_DOMAIN), __('Support',WPPH_PLUGIN_TEXT_DOMAIN), $reqCap, self::$baseMenuSlug.'support', 'WPPH::pageSupport');
168
  }
169
  }
170
 
179
  public static function pageAbout() { include(WPPH_PLUGIN_DIR.'pages/about.php'); }
180
  public static function pageSupport() { include(WPPH_PLUGIN_DIR.'pages/support.php'); }
181
 
182
+ /**
183
+ * @since v0.5
184
+ * Create, save and retrieve the default list of events
185
+ * @return array
186
+ */
187
+ public static function createDefaultEventsList()
188
+ {
189
+ $alerts = array();
190
+ $events = self::getDefaultEvents();
191
+ if(!empty($events)){
192
+ foreach($events as $section => $values){
193
+ $alerts[$section] = array();
194
+ $_events = array_keys($values);
195
+ if(! empty($_events)){
196
+ foreach($_events as $k){
197
+ $alerts[$section][$k] = 1;
198
+ }
199
+ }
200
+ }
201
+ }
202
+ update_option(WPPH_PLUGIN_EVENTS_LIST_OPTION_NAME, $alerts);
203
+ return $alerts;
204
+ }
205
+
206
+ /**
207
+ * @since v0.5
208
+ * Retrieve the list of all events from database
209
+ * @return array
210
+ */
211
+ static function getEvents(){
212
+ $events = get_option(WPPH_PLUGIN_EVENTS_LIST_OPTION_NAME);
213
+ if(false === $events){
214
+ $events = self::createDefaultEventsList();
215
+ }
216
+ return $events;
217
+ }
218
+
219
  public static function createPluginDefaultSettings()
220
  {
 
221
  $settings = new stdClass();
222
  $settings->daysToKeep = 0;
223
  $settings->eventsToKeep = WPPH_KEEP_MAX_EVENTS; // default delete option
224
  $settings->showEventsViewList = 50; // how many items to show in the event viewer by default
225
  $settings->lastCleanup = time();
226
  $settings->cleanupRan = 0;
 
227
  $settings->showDW = 1; // whether or not to show the dashboard widget. @since v0.4
228
  update_option(WPPH_PLUGIN_SETTING_NAME, $settings);
229
+ self::createDefaultEventsList();
230
  wpphLog('Settings added.');
231
+ return $settings;
232
  }
233
  public static function getPluginSettings()
234
  {
235
  $settings = get_option(WPPH_PLUGIN_SETTING_NAME);
236
  if(false === $settings){
237
+ $settings = self::createPluginDefaultSettings();
 
238
  }
239
  return $settings;
240
  }
384
  {
385
  wp_clear_scheduled_hook(WPPH_PLUGIN_DEL_EVENTS_CRON_TASK_NAME);
386
  delete_option(WPPH_PLUGIN_ERROR_OPTION_NAME);
 
387
  wpphLog('__FUNCTION__.() triggered.');
388
  }
389
 
405
  update_option(WPPH_PLUGIN_DB_UPDATED,1);
406
  delete_option(WPPH_PLUGIN_ERROR_OPTION_NAME);
407
  update_option(WPPH_PLUGIN_VERSION_OPTION_NAME, WPPH_PLUGIN_VERSION);
408
+ WPPHUtil::saveInitialAccessChangeList();
409
  if($triggerInstallEvent)
410
  {
411
+ define('WPPH_PLUGIN_INSTALLED_OK',true); //@see: WPPHEventWatcher::watchPluginInstall()
 
412
  // log plugin installation
413
+ WPPHEvent::_addLogEvent(5000,wp_get_current_user()->ID, WPPHUtil::getIP(), array(WPPH_PLUGIN_NAME));
414
  wpphLog('Plugin installed.', array('plugin'=>WPPH_PLUGIN_NAME));
415
  }
416
  // log plugin activation
inc/WPPHEvent.php CHANGED
@@ -106,6 +106,16 @@ class WPPHEvent
106
  // 2041 - Changed the date of %post_name% custom post from %old_date% to %new_date%
107
  array( 'id' => 2041, 'category' => WPPH_E_NOTICE_TEXT, 'text' => __('Changed the date of custom post <strong>%s</strong> of type <strong>%s</strong> from <strong>%s</strong> to <strong>%s</strong>.',WPPH_PLUGIN_TEXT_DOMAIN)),
108
 
 
 
 
 
 
 
 
 
 
 
109
  // 3xxx - Themes management
110
  // Activated the theme %themeName%
111
  array( 'id' => 3000, 'category' => WPPH_E_NOTICE_TEXT, 'text' => __('Activated the theme <strong>%s</strong>.',WPPH_PLUGIN_TEXT_DOMAIN)),
@@ -1412,6 +1422,186 @@ class WPPHEventWatcher extends WPPHEvent
1412
  }
1413
  }
1414
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1415
  // 3000 - Theme activated
1416
  static function watchThemeChange($themeName)
1417
  {
106
  // 2041 - Changed the date of %post_name% custom post from %old_date% to %new_date%
107
  array( 'id' => 2041, 'category' => WPPH_E_NOTICE_TEXT, 'text' => __('Changed the date of custom post <strong>%s</strong> of type <strong>%s</strong> from <strong>%s</strong> to <strong>%s</strong>.',WPPH_PLUGIN_TEXT_DOMAIN)),
108
 
109
+ // WIDGETS
110
+ // 2042 - Added a new %type% widget in %section%
111
+ array( 'id' => 2042, 'category' => WPPH_E_HIGH_TEXT, 'text' => __('Added a new <strong>%s</strong> widget in <strong>%s</strong>.',WPPH_PLUGIN_TEXT_DOMAIN)),
112
+ // 2043 - Modified the %type% widget in %section%
113
+ array( 'id' => 2043, 'category' => WPPH_E_WARNING_TEXT, 'text' => __('Modified the <strong>%s</strong> widget in <strong>%s</strong>.',WPPH_PLUGIN_TEXT_DOMAIN)),
114
+ // 2044 - Deleted the %type% widget from %section%
115
+ array( 'id' => 2044, 'category' => WPPH_E_HIGH_TEXT, 'text' => __('Deleted the <strong>%s</strong> widget from <strong>%s</strong>.',WPPH_PLUGIN_TEXT_DOMAIN)),
116
+ // 2045 - Moved the %type% widget from %old_location% to %new_location%
117
+ array( 'id' => 2045, 'category' => WPPH_E_NOTICE_TEXT, 'text' => __('Moved the <strong>%s</strong> widget from <strong>%s</strong> to <strong>%s</strong>.',WPPH_PLUGIN_TEXT_DOMAIN)),
118
+
119
  // 3xxx - Themes management
120
  // Activated the theme %themeName%
121
  array( 'id' => 3000, 'category' => WPPH_E_NOTICE_TEXT, 'text' => __('Activated the theme <strong>%s</strong>.',WPPH_PLUGIN_TEXT_DOMAIN)),
1422
  }
1423
  }
1424
 
1425
+ static function watchWidgetActivity()
1426
+ {
1427
+ if ('POST' != strtoupper($_SERVER['REQUEST_METHOD']))
1428
+ {
1429
+ return;
1430
+ }
1431
+ if(!isset($_POST['widget-id']) || empty($_POST['widget-id'])){
1432
+ return;
1433
+ }
1434
+
1435
+ $postData = $_POST;
1436
+
1437
+ wpphLog(__METHOD__.'() triggered by hook.');
1438
+ //wpphLog('POST DATA', $postData);
1439
+
1440
+ global $wp_registered_sidebars;
1441
+ $canCheckSidebar = (empty($wp_registered_sidebars) ? false : true);
1442
+ $userID = wp_get_current_user()->ID;
1443
+
1444
+ // if widget added
1445
+ if(isset($postData['add_new']) && $postData['add_new'] == 'multi')
1446
+ {
1447
+ $widgetType = $postData['id_base'];
1448
+ $sidebar = $postData['sidebar'];
1449
+ if($canCheckSidebar && preg_match("/^sidebar-/",$sidebar)){
1450
+ $sidebar = $wp_registered_sidebars[$sidebar]['name'];
1451
+ }
1452
+ self::_addLogEvent(2042, $userID, WPPHUtil::getIP(), array($widgetType, $sidebar));
1453
+ wpphLog('User added a widget.', array('type'=>$widgetType, 'sidebar'=>$sidebar));
1454
+ }
1455
+ // if widget deleted
1456
+ elseif(isset($postData['delete_widget']) && intval($postData['delete_widget']) == 1)
1457
+ {
1458
+ $widgetType = $postData['id_base'];
1459
+ $sidebar = $postData['sidebar'];
1460
+ if($canCheckSidebar && preg_match("/^sidebar-/",$sidebar)){
1461
+ $sidebar = $wp_registered_sidebars[$sidebar]['name'];
1462
+ }
1463
+ self::_addLogEvent(2044, $userID, WPPHUtil::getIP(), array($widgetType, $sidebar));
1464
+ wpphLog('User deleted a widget.', array('type'=>$widgetType, 'sidebar'=>$sidebar));
1465
+ }
1466
+ // if widget modified
1467
+ elseif(isset($postData['id_base']) && !empty($postData['id_base']))
1468
+ {
1469
+ wpphLog('CHECKING IF WIDGET MODIFIED....');
1470
+ // get info from $_POST
1471
+ $wId = 0;
1472
+ if(! empty($postData['multi_number'])){
1473
+ $wId = intval($postData['multi_number']);
1474
+ }
1475
+ else {
1476
+ if(! empty($postData['widget_number'])){
1477
+ $wId = intval($postData['widget_number']);
1478
+ }
1479
+ }
1480
+ if(empty($wId)){
1481
+ wpphLog('EMPTY $wId');
1482
+ return;
1483
+ }
1484
+ $wName = $postData['id_base'];
1485
+ $sidebar = $postData['sidebar'];
1486
+ $wData = isset($postData["widget-".$wName][$wId]) ? $postData["widget-".$wName][$wId] : null;
1487
+
1488
+ if(empty($wData)){
1489
+ wpphLog('EMPTY $wData');
1490
+ return;
1491
+ }
1492
+ // get info from db
1493
+ $wdbData = get_option("widget_".$wName);
1494
+ if(empty($wdbData[$wId])){
1495
+ wpphLog('EMPTY $wbData[$wId]');
1496
+ return;
1497
+ }
1498
+ // transform 'on' -> 1
1499
+ foreach($wData as $k=>&$v){
1500
+ if($v == 'on'){ $v = 1; }
1501
+ }
1502
+ // compare - checks for any changes inside widgets
1503
+ $diff = array_diff_assoc($wData, $wdbData[$wId]);
1504
+ $count = count($diff);
1505
+ if($count > 0){
1506
+ if($canCheckSidebar && preg_match("/^sidebar-/",$sidebar)){
1507
+ $sidebar = $wp_registered_sidebars[$sidebar]['name'];
1508
+ }
1509
+ //wpphLog('DIFF EXISTS.', array('wdata'=>$wData, 'wdbdata'=>$wdbData[$wId], 'diff'=>$diff));
1510
+ self::_addLogEvent(2043, $userID, WPPHUtil::getIP(), array($wName, $sidebar));
1511
+ wpphLog('User modified a widget.', array('type'=>$wName, 'sidebar'=>$sidebar));
1512
+ }
1513
+ else {wpphLog('No change.');}
1514
+ }
1515
+ }
1516
+ //@ 2045
1517
+ static function watchWidgetMove()
1518
+ {
1519
+ if(isset($_POST) && !empty($_POST['sidebars']))
1520
+ {
1521
+ wpphLog('Checking for moved widgets');
1522
+ $crtSidebars = $_POST['sidebars'];
1523
+ $sidebars = array();
1524
+ //-- WP
1525
+ foreach ( $crtSidebars as $key => $val ) {
1526
+ $sb = array();
1527
+ if ( !empty($val) ) {
1528
+ $val = explode(',', $val);
1529
+ foreach ( $val as $k => $v ) {
1530
+ if ( strpos($v, 'widget-') === false ){ continue; }
1531
+ $sb[$k] = substr($v, strpos($v, '_') + 1);
1532
+ }
1533
+ }
1534
+ $sidebars[$key] = $sb;
1535
+ }
1536
+ //-- WP
1537
+ $crtSidebars = $sidebars;
1538
+ $dbSidebars = get_option('sidebars_widgets');
1539
+ $wName = $fromSidebar = $toSidebar = '';
1540
+ foreach($crtSidebars as $sidebarName => $values)
1541
+ {
1542
+ if(is_array($values) && ! empty($values))
1543
+ {
1544
+ if(isset($dbSidebars[$sidebarName]))
1545
+ {
1546
+ foreach($values as $i => $widgetName)
1547
+ {
1548
+ if(! in_array($widgetName, $dbSidebars[$sidebarName])){
1549
+ $toSidebar = $sidebarName;
1550
+ $wName = $widgetName;
1551
+ foreach($dbSidebars as $name => $v){
1552
+ if(is_array($v) && !empty($v)){
1553
+ if(in_array($widgetName, $v)){
1554
+ $fromSidebar = $name;
1555
+ break;
1556
+ }
1557
+ }
1558
+ }
1559
+ }
1560
+ }
1561
+ }
1562
+ }
1563
+ }
1564
+ if(empty($wName) || empty($fromSidebar) || empty($toSidebar)){
1565
+ wpphLog('No change.');
1566
+ return;
1567
+ }
1568
+
1569
+ $userID = wp_get_current_user()->ID;
1570
+ $ip = WPPHUtil::getIP();
1571
+
1572
+ if(preg_match("/^sidebar-/", $fromSidebar) || preg_match("/^sidebar-/",$toSidebar)){
1573
+ // This option will hold the data needed to trigger the event 2045
1574
+ // as at this moment the $wp_registered_sidebars variable is not yet populated
1575
+ // so we cannot retrieve the name for sidebar-1 || sidebar-2
1576
+ // we will then check for this variable in the triggerWidgetMoveEvent() function
1577
+ $GLOBALS['WPPH_WIDGET_MOVE'] = array('widget'=>$wName, 'from'=>$fromSidebar, 'to'=>$toSidebar, 'user'=>$userID, 'ip', 'ip'=>$ip);
1578
+ wpphLog('Widget moved. Data saved to variable: WPPH_WIDGET_MOVE');
1579
+ return;
1580
+ }
1581
+ self::_addLogEvent(2045, $userID, $ip, array($wName, $fromSidebar, $toSidebar));
1582
+ }
1583
+ }
1584
+
1585
+ static function triggerWidgetMoveEvent()
1586
+ {
1587
+ wpphLog(__METHOD__.'() triggered.');
1588
+ $data = (isset($GLOBALS['WPPH_WIDGET_MOVE']) ? $GLOBALS['WPPH_WIDGET_MOVE'] : null);
1589
+ if(empty($data)){
1590
+ wpphLog('variable not found: WPPH_WIDGET_MOVE');
1591
+ return;
1592
+ }
1593
+ $from = $data['from'];
1594
+ $to = $data['to'];
1595
+
1596
+ global $wp_registered_sidebars;
1597
+
1598
+ if(preg_match("/^sidebar-/", $from)){ $from = (isset($wp_registered_sidebars[$from]) ? $wp_registered_sidebars[$from]['name'] : $from); }
1599
+ if(preg_match("/^sidebar-/", $to)){ $to = (isset($wp_registered_sidebars[$to]) ? $wp_registered_sidebars[$to]['name'] : $to); }
1600
+
1601
+ self::_addLogEvent(2045, $data['user'], $data['ip'], array($data['widget'], $from, $to));
1602
+ }
1603
+
1604
+
1605
  // 3000 - Theme activated
1606
  static function watchThemeChange($themeName)
1607
  {
inc/WPPHUtil.php CHANGED
@@ -1,19 +1,16 @@
1
  <?php
2
  class WPPHUtil
3
  {
4
- static function loadPluggable(){
5
- if(! function_exists('user_can')){
6
- @include_once(ABSPATH.'wp-includes/pluggable.php');
7
- }
8
- }
9
 
10
  static function getIP() { return(!empty($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0'); }
11
 
12
  /**
13
  * Check to see whether or not the current user is an administrator
 
14
  * @return bool
15
  */
16
- static function isAdministrator(){ return user_can(wp_get_current_user(),'update_core'); }
17
 
18
  /**
19
  * Will respond to the ajax requests getting the events
@@ -50,7 +47,7 @@ class WPPHUtil
50
  $eventsNum = count($events);
51
 
52
  if($eventsNum == 0){
53
- exit( __formatJsonOutput(array(),__('There are no events to display.',WPPH_PLUGIN_TEXT_DOMAIN)) );
54
  }
55
 
56
  $out = array();
@@ -109,19 +106,22 @@ class WPPHUtil
109
 
110
  static function addDashboardWidget()
111
  {
112
- $settings = WPPH::getPluginSettings();
113
- if(! empty($settings->showDW)){
114
- wp_add_dashboard_widget('wpphPluginDashboardWidget', __('Latest WordPress Security Alerts').' | WP Security Audit Log', array(get_class(),'createDashboardWidget'));
 
 
 
115
  }
116
  }
117
  static function createDashboardWidget()
118
  {
119
  // get and display data
120
- $results = $events = WPPHEvent::getEvents('EventNumber', 'DESC', array(0,5));
121
  echo '<div>';
122
  if(empty($results))
123
  {
124
- echo '<p>'.__('',WPPH_PLUGIN_TEXT_DOMAIN).'</p>';
125
  }
126
  else {
127
  echo '<table class="wp-list-table widefat" cellspacing="0" cellpadding="0">';
@@ -166,4 +166,114 @@ class WPPHUtil
166
  echo '</div>';
167
  }
168
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  }
1
  <?php
2
  class WPPHUtil
3
  {
4
+ static function loadPluggable(){ @include_once(ABSPATH.'wp-includes/pluggable.php'); }
 
 
 
 
5
 
6
  static function getIP() { return(!empty($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0'); }
7
 
8
  /**
9
  * Check to see whether or not the current user is an administrator
10
+ * @param int $userId
11
  * @return bool
12
  */
13
+ static function isAdministrator($userId=0){ if(empty($userId)){$userId = wp_get_current_user();} return user_can($userId,'administrator'); }
14
 
15
  /**
16
  * Will respond to the ajax requests getting the events
47
  $eventsNum = count($events);
48
 
49
  if($eventsNum == 0){
50
+ exit( __formatJsonOutput(array(),__('There are no security alerts to display.',WPPH_PLUGIN_TEXT_DOMAIN)) );
51
  }
52
 
53
  $out = array();
106
 
107
  static function addDashboardWidget()
108
  {
109
+ if(! empty(WPPH::getPluginSettings()->showDW))
110
+ {
111
+ $currentUser = wp_get_current_user();
112
+ if(WPPHUtil::isAdministrator($currentUser->ID)|| WPPHUtil::isAllowedAccess($currentUser->ID) || WPPHUtil::isAllowedChange($currentUser->ID)){
113
+ wp_add_dashboard_widget('wpphPluginDashboardWidget', __('Latest WordPress Security Alerts').' | WP Security Audit Log', array(get_class(),'createDashboardWidget'));
114
+ }
115
  }
116
  }
117
  static function createDashboardWidget()
118
  {
119
  // get and display data
120
+ $results = WPPHEvent::getEvents('EventNumber', 'DESC', array(0,5));
121
  echo '<div>';
122
  if(empty($results))
123
  {
124
+ echo '<p>'.__('No alerts found.',WPPH_PLUGIN_TEXT_DOMAIN).'</p>';
125
  }
126
  else {
127
  echo '<table class="wp-list-table widefat" cellspacing="0" cellpadding="0">';
166
  echo '</div>';
167
  }
168
 
169
+
170
+ /**
171
+ * Check to see whether or not a user has access to view any of the plugin's pages
172
+ * @since v0.5
173
+ * @return bool
174
+ */
175
+ static function canViewPage()
176
+ {
177
+ $currentUser = wp_get_current_user();
178
+ if(WPPHUtil::isAdministrator($currentUser->ID)|| WPPHUtil::isAllowedAccess($currentUser->ID) || WPPHUtil::isAllowedChange($currentUser->ID)){
179
+ return true;
180
+ }
181
+ return false;
182
+ }
183
+
184
+ /**
185
+ * Check to see whether or not the current user is allowed to VIEW the plugin
186
+ * @since v0.5
187
+ * @return bool
188
+ */
189
+ static function isAllowedAccess()
190
+ {
191
+ $data = get_option(WPPH_PLUGIN_ALLOW_ACCESS_OPTION_NAME, array());
192
+ if(empty($data)){return false;}
193
+ $userID = wp_get_current_user()->ID;
194
+ $userInfo = WPPHDB::getUserInfo($userID);
195
+ return (in_array($userInfo['userName'], $data) || in_array($userInfo['userRole'], $data));
196
+ }
197
+ /**
198
+ * Check to see whether or not the current user allowed to CHANGE the plugin's settings
199
+ * @since v0.5
200
+ * @return bool
201
+ */
202
+ static function isAllowedChange()
203
+ {
204
+ $data = get_option(WPPH_PLUGIN_ALLOW_CHANGE_OPTION_NAME, array());
205
+ if(empty($data)){return false;}
206
+ $userID = wp_get_current_user()->ID;
207
+ $userInfo = WPPHDB::getUserInfo($userID);
208
+ return (in_array($userInfo['userName'], $data) || in_array($userInfo['userRole'], $data));
209
+ }
210
+ /**
211
+ * @param array $data
212
+ * @since v0.5
213
+ * @return bool False if value was not updated and true if value was updated.
214
+ */
215
+ static function saveAllowAccessUserList(array $data) {return update_option(WPPH_PLUGIN_ALLOW_ACCESS_OPTION_NAME, $data);}
216
+ /**
217
+ * @param array $data
218
+ * @since v0.5
219
+ * @return bool False if value was not updated and true if value was updated.
220
+ */
221
+ static function saveAllowedChangeUserList(array $data){return update_option(WPPH_PLUGIN_ALLOW_CHANGE_OPTION_NAME, $data);}
222
+
223
+
224
+
225
+ /**
226
+ * Saves the default list of users with access to plugin
227
+ * @since v0.5
228
+ * @return bool
229
+ */
230
+ static function saveInitialAccessChangeList(){
231
+ self::saveAllowAccessUserList(array());
232
+ self::saveAllowedChangeUserList(array());
233
+ }
234
+
235
+ // ajax
236
+ static function check_user_role()
237
+ {
238
+ // VALIDATE REQUEST
239
+ $rm = strtoupper($_SERVER['REQUEST_METHOD']);
240
+ if($rm != 'POST'){ exit(__('Error: Invalid request',WPPH_PLUGIN_TEXT_DOMAIN)); }
241
+
242
+ $value = $_POST['check_input'];
243
+
244
+ if(empty($value)){
245
+ exit(__('Error: Invalid request',WPPH_PLUGIN_TEXT_DOMAIN));
246
+ }
247
+
248
+ $value = strtolower($value);
249
+ $value = stripslashes($value);
250
+ $value = strip_tags($value);
251
+ $value = esc_sql($value);
252
+
253
+ // check user
254
+ $result = self::_userExists($value);
255
+ if ($result){
256
+ exit('1');
257
+ }
258
+ // check role
259
+ $result = self::_roleExists($value);
260
+ if ($result){
261
+ exit('1');
262
+ }
263
+ exit('0');
264
+ }
265
+
266
+ static function _userExists($username){
267
+ global $wpdb;
268
+ $result = $wpdb->get_var($wpdb->prepare("SELECT `ID` FROM {$wpdb->users} WHERE user_login = '%s' OR display_name = '%s'", $username, $username));
269
+ if ($result !== false && $result > 0){
270
+ return true;
271
+ }
272
+ return false;
273
+ }
274
+
275
+ static function _roleExists($role){
276
+ global $wp_roles;
277
+ return (isset($wp_roles->roles[$role]) ? true : false);
278
+ }
279
  }
inc/wpphFunctions.php CHANGED
@@ -33,8 +33,11 @@ function wpph_isEventEnabled($event, array $events = array())
33
  {
34
  if(empty($event)){ return false; }
35
  if(empty($events)){
36
- $temp = WPPH::getPluginSettings();
37
- $events = $temp->logEvents;
 
 
 
38
  }
39
  foreach($events as $k=>$entries){
40
  foreach($entries as $_event => $enabled){
@@ -52,88 +55,3 @@ function wpphCustomLinks($links) { return array_merge(array('<a href="admin.php?
52
  function wpphLoadTextDomain() { load_plugin_textdomain(WPPH_PLUGIN_TEXT_DOMAIN, false, 'wp-security-audit-log/languages/'); }
53
 
54
 
55
- //@see: http://codex.wordpress.org/Function_Reference/register_activation_hook#A_Note_on_Variable_Scope
56
- global $wpphEvents;
57
- /**
58
- * @array
59
- * @since v0.4
60
- * Holds the list of all events
61
- */
62
- $wpphEvents = array(
63
- 'Login_Logout' => array(
64
- 1000 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User logs in',WPPH_PLUGIN_TEXT_DOMAIN)),
65
- 1001 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User Logs out',WPPH_PLUGIN_TEXT_DOMAIN)),
66
- 1002 => array('type' => WPPH_E_WARNING_TEXT, 'text' => __('Failed login detected',WPPH_PLUGIN_TEXT_DOMAIN)),
67
- ),
68
- 'Pages' => array(
69
- 2004 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User created a new WordPress page and saved it as draft',WPPH_PLUGIN_TEXT_DOMAIN)),
70
- 2005 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User published a WorPress page',WPPH_PLUGIN_TEXT_DOMAIN)),
71
- 2006 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User modified a published WordPress page',WPPH_PLUGIN_TEXT_DOMAIN)),
72
- 2007 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User modified a draft WordPress page',WPPH_PLUGIN_TEXT_DOMAIN)),
73
- 2009 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User permanently deleted a page from the trash',WPPH_PLUGIN_TEXT_DOMAIN)),
74
- 2013 => array('type' => WPPH_E_WARNING_TEXT, 'text' => __('User moved WordPress page to the trash',WPPH_PLUGIN_TEXT_DOMAIN)),
75
- 2015 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('User restored a WordPress page from trash',WPPH_PLUGIN_TEXT_DOMAIN)),
76
- 2018 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed page URL',WPPH_PLUGIN_TEXT_DOMAIN)),
77
- 2020 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed page author',WPPH_PLUGIN_TEXT_DOMAIN)),
78
- 2022 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed page status',WPPH_PLUGIN_TEXT_DOMAIN)),
79
- 2026 => array('type' => WPPH_E_WARNING_TEXT, 'text' => __('User changed the visibility of a page',WPPH_PLUGIN_TEXT_DOMAIN)),
80
- 2028 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed the date of a page post',WPPH_PLUGIN_TEXT_DOMAIN)),
81
- ),
82
- 'Blog_Posts' => array(
83
- 2000 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User created a new blog post and saved it as draft',WPPH_PLUGIN_TEXT_DOMAIN)),
84
- 2001 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User published a blog post',WPPH_PLUGIN_TEXT_DOMAIN)),
85
- 2002 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User modified a published blog post',WPPH_PLUGIN_TEXT_DOMAIN)),
86
- 2003 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User modified a draft blog post',WPPH_PLUGIN_TEXT_DOMAIN)),
87
- 2008 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User permanently deleted a blog post from the trash',WPPH_PLUGIN_TEXT_DOMAIN)),
88
- 2010 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User uploaded a file to the uploads directory',WPPH_PLUGIN_TEXT_DOMAIN)),
89
- 2011 => array('type' => WPPH_E_WARNING_TEXT, 'text' => __('User deleted a file from the uploads directory',WPPH_PLUGIN_TEXT_DOMAIN)),
90
- 2012 => array('type' => WPPH_E_WARNING_TEXT, 'text' => __('User moved a blog post to the trash',WPPH_PLUGIN_TEXT_DOMAIN)),
91
- 2014 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('User restored a blog post from trash',WPPH_PLUGIN_TEXT_DOMAIN)),
92
- 2016 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed blog post category',WPPH_PLUGIN_TEXT_DOMAIN)),
93
- 2017 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed blog post URL',WPPH_PLUGIN_TEXT_DOMAIN)),
94
- 2019 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed blog post author',WPPH_PLUGIN_TEXT_DOMAIN)),
95
- 2021 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed blog post status',WPPH_PLUGIN_TEXT_DOMAIN)),
96
- 2023 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User created new category',WPPH_PLUGIN_TEXT_DOMAIN)),
97
- 2024 => array('type' => WPPH_E_WARNING_TEXT, 'text' => __('User deleted a category',WPPH_PLUGIN_TEXT_DOMAIN)),
98
- 2025 => array('type' => WPPH_E_WARNING_TEXT, 'text' => __('User changed the visibility of a blog post',WPPH_PLUGIN_TEXT_DOMAIN)),
99
- 2027 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed the date of a blog post',WPPH_PLUGIN_TEXT_DOMAIN)),
100
- ),
101
- 'Custom_Posts' => array(
102
- 2029 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User created a new custom blog post and saved it as draft',WPPH_PLUGIN_TEXT_DOMAIN)),
103
- 2030 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User published a custom blog post',WPPH_PLUGIN_TEXT_DOMAIN)),
104
- 2031 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User modified a published custom blog post',WPPH_PLUGIN_TEXT_DOMAIN)),
105
- 2032 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User modified a draft custom blog post',WPPH_PLUGIN_TEXT_DOMAIN)),
106
- 2033 => array('type' => WPPH_E_WARNING_TEXT, 'text' => __('User permanently deleted a custom blog post from the trash',WPPH_PLUGIN_TEXT_DOMAIN)),
107
- 2034 => array('type' => WPPH_E_WARNING_TEXT, 'text' => __('User moved a custom blog post to the trash',WPPH_PLUGIN_TEXT_DOMAIN)),
108
- 2035 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('User restored a custom blog post from trash',WPPH_PLUGIN_TEXT_DOMAIN)),
109
- 2036 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed custom blog post category',WPPH_PLUGIN_TEXT_DOMAIN)),
110
- 2037 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed custom blog post URL',WPPH_PLUGIN_TEXT_DOMAIN)),
111
- 2038 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed custom blog post author',WPPH_PLUGIN_TEXT_DOMAIN)),
112
- 2039 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed custom blog post status',WPPH_PLUGIN_TEXT_DOMAIN)),
113
- 2040 => array('type' => WPPH_E_WARNING_TEXT, 'text' => __('User changed the visibility of a custom blog post',WPPH_PLUGIN_TEXT_DOMAIN)),
114
- 2041 => array('type' => WPPH_E_NOTICE_TEXT, 'text' => __('User changed the date of a custom blog post',WPPH_PLUGIN_TEXT_DOMAIN)),
115
- ),
116
- 'Users_Profiles' => array(
117
- 4000 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('A new user was created on WordPress',WPPH_PLUGIN_TEXT_DOMAIN)),
118
- 4001 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('A user created another WordPress user',WPPH_PLUGIN_TEXT_DOMAIN)),
119
- 4002 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('The role of a user was changed by another WordPress user',WPPH_PLUGIN_TEXT_DOMAIN)),
120
- 4003 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('User has changed his or her password',WPPH_PLUGIN_TEXT_DOMAIN)),
121
- 4004 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('A user changed another user\'s password',WPPH_PLUGIN_TEXT_DOMAIN)),
122
- 4005 => array('type' => WPPH_E_NOTICE_TEXT,'text' => __('User changed his or her email address',WPPH_PLUGIN_TEXT_DOMAIN)),
123
- 4006 => array('type' => WPPH_E_NOTICE_TEXT,'text' => __('A user changed another user\'s email address',WPPH_PLUGIN_TEXT_DOMAIN)),
124
- 4007 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('A user was deleted by another user',WPPH_PLUGIN_TEXT_DOMAIN)),
125
- ),
126
- 'Plugins' => array(
127
- 5000 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('User installed a plugin',WPPH_PLUGIN_TEXT_DOMAIN)),
128
- 5001 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('User activated a WordPress plugin',WPPH_PLUGIN_TEXT_DOMAIN)),
129
- 5002 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('User deactivated a WordPress plugin',WPPH_PLUGIN_TEXT_DOMAIN)),
130
- 5003 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('User uninstalled a plugin',WPPH_PLUGIN_TEXT_DOMAIN)),
131
- 5004 => array('type' => WPPH_E_WARNING_TEXT, 'text' => __('User upgraded a plugin',WPPH_PLUGIN_TEXT_DOMAIN)),
132
- ),
133
- 'Settings_And_System_Activity' => array(
134
- 6000 => array('type' => WPPH_E_NOTICE_TEXT,'text' => __('Events automatically pruned by system',WPPH_PLUGIN_TEXT_DOMAIN)),
135
- 6001 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('Option Anyone Can Register in WordPress settings changed',WPPH_PLUGIN_TEXT_DOMAIN)),
136
- 6002 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('New User Default Role changed',WPPH_PLUGIN_TEXT_DOMAIN)),
137
- 6003 => array('type' => WPPH_E_HIGH_TEXT, 'text' => __('WordPress Administrator Notification email changed',WPPH_PLUGIN_TEXT_DOMAIN))
138
- ),
139
- );
33
  {
34
  if(empty($event)){ return false; }
35
  if(empty($events)){
36
+ $events = get_option(WPPH_PLUGIN_EVENTS_LIST_OPTION_NAME, array());
37
+ if(empty($events)){
38
+ wpphLog("Error retrieving the list of events from database. option: WPPH_PLUGIN_EVENTS_LIST_OPTION_NAME was either not found or empty.");
39
+ return false;
40
+ }
41
  }
42
  foreach($events as $k=>$entries){
43
  foreach($entries as $_event => $enabled){
55
  function wpphLoadTextDomain() { load_plugin_textdomain(WPPH_PLUGIN_TEXT_DOMAIN, false, 'wp-security-audit-log/languages/'); }
56
 
57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/wpphSettings.php CHANGED
@@ -24,13 +24,7 @@ define('WPPH_E_WARNING_TEXT', __('WARNING',WPPH_PLUGIN_TEXT_DOMAIN));
24
  /**@since 0.4*/
25
  define('WPPH_KEEP_MAX_EVENTS', 5000);
26
 
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
24
  /**@since 0.4*/
25
  define('WPPH_KEEP_MAX_EVENTS', 5000);
26
 
27
+ //since v0.5
28
+ define('WPPH_PLUGIN_ALLOW_ACCESS_OPTION_NAME','WPPH_PLUGIN_ALLOW_ACCESS');
29
+ define('WPPH_PLUGIN_ALLOW_CHANGE_OPTION_NAME','WPPH_PLUGIN_ALLOW_CHANGE');
30
+ define('WPPH_PLUGIN_EVENTS_LIST_OPTION_NAME', 'WPPH_PLUGIN_EVENTS_LIST');
 
 
 
 
 
 
pages/about.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php if(! WPPH::canRun()){ return; } ?>
2
  <?php
3
  if(! WPPH::ready())
4
  {
1
+ <?php if(! WPPHUtil::canViewPage()){ return; } ?>
2
  <?php
3
  if(! WPPH::ready())
4
  {
pages/alerts.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php if(! WPPH::canRun()){ return; } ?>
2
  <?php
3
  if(! WPPH::ready())
4
  {
@@ -15,10 +15,10 @@ if(! WPPH::ready())
15
  ?>
16
  <?php
17
  // defaults
18
- $opt = WPPH::getPluginSettings();
19
- $logEvents = $opt->logEvents;
20
  $validationMessage = array();
21
- $sectionNames = array_keys($logEvents);
22
  $activeTab = 0;
23
  $rm = strtoupper($_SERVER['REQUEST_METHOD']);
24
  if('POST' == $rm)
@@ -45,7 +45,7 @@ if('POST' == $rm)
45
  if(!$hasErrors)
46
  {
47
  $logEvents = array();
48
- global $wpphEvents;
49
  foreach($wpphEvents as $category=>$entries){
50
  $logEvents[$category] = array();
51
  foreach($entries as $event=>$entry){
@@ -61,9 +61,7 @@ if('POST' == $rm)
61
  }
62
  }
63
  }
64
- $opt->logEvents = $logEvents;
65
- $opt->cleanupRan = 0;
66
- WPPH::updatePluginSettings($opt,null,null,true);
67
  $validationMessage['success'] = __('Your settings have been saved.',WPPH_PLUGIN_TEXT_DOMAIN);
68
  }
69
  }
@@ -73,7 +71,7 @@ if('POST' == $rm)
73
  <h2 class="pageTitle pageTitle-settings"><?php echo __('Enable/Disable Alerts',WPPH_PLUGIN_TEXT_DOMAIN);?></h2>
74
 
75
  <div id="optionsDescription">
76
- <p id="description">
77
  <?php
78
  echo __('From this page you can enable or disable WordPress security alerts. If a security alert is disabled, an alert will not be generated in the Audit Log Viewer once such action happens.',WPPH_PLUGIN_TEXT_DOMAIN);
79
  echo '<br/>'.__('To disable a security alert, select the category tab and untick the alert. Click Save Settings when ready.',WPPH_PLUGIN_TEXT_DOMAIN);
@@ -88,50 +86,48 @@ if('POST' == $rm)
88
  ?>
89
  <?php endif;?>
90
 
91
- <div id="logEventsTabControl" style="margin: 20px 0;">
 
92
  <form id="updateSettingsForm" method="post">
93
  <?php wp_nonce_field('wpph_update_settings','wpph_update_settings_field_nonce'); ?>
94
  <?php
95
- $sectionNames = array_keys($logEvents);
96
- echo '<ul id="tabControlNavBar">';
97
- foreach($sectionNames as $item){
98
- if($item == 'Login_Logout'){
99
- echo '<li data-id="'.$item.'"><a href="#'.$item.'"/>Login / Logout</a></li>';
100
  }
101
- else { echo '<li data-id="'.$item.'"><a href="#'.$item.'"/>'.str_replace('_',' ', $item).'</a></li>'; }
102
- }
103
- echo '</ul>';
104
 
105
- global $wpphEvents;
106
- foreach($logEvents as $sectionName => $items){
107
- echo '<div id="'.$sectionName.'">';
108
- echo '<table class="wp-list-table widefat" cellspacing="0" cellpadding="0">';
109
- echo '<thead>';
110
- echo '<th class="manage-column column-cb check-column item-cb" scope="col"><input type="checkbox" class="js-select-all"/></th>';
111
- echo '<th class="manage-column column-cb check-column item-event" scope="col">'.__('Event',WPPH_PLUGIN_TEXT_DOMAIN).'</th>';
112
- echo '<th class="manage-column column-cb check-column item-type" scope="col">'.__('Type',WPPH_PLUGIN_TEXT_DOMAIN).'</th>';
113
- echo '<th class="manage-column column-cb check-column item-description" scope="col">'.__('Description',WPPH_PLUGIN_TEXT_DOMAIN).'</th>';
114
- echo '</thead>';
115
- echo '<tbody>';
116
- foreach($items as $item => $enabled){
117
- echo '<tr class="row">';
118
- echo '<th class="manage-column column-cb check-column" scope="row"><input class="item_cb" type="checkbox" '.($enabled ? 'checked="checked"' : '').' value="'.$item.'"/></th>';
119
- echo '<td>'.$item.'</td>';
120
- echo '<td>'.$wpphEvents[$sectionName][$item]['type'].'</td>';
121
- echo '<td>'.$wpphEvents[$sectionName][$item]['text'].'</td>';
122
- echo '</tr>';
 
 
 
123
  }
124
- echo '</tbody>';
125
- echo '</table>';
126
- echo '</div>';
127
- }
128
- // Events deletion tab
129
  ?>
130
- <input type="submit" id="submitButton" class="button button-primary" value="<?php echo __('Save settings',WPPH_PLUGIN_TEXT_DOMAIN);?>"/>
131
  <input type="hidden" id="inputEvents" name="inputEvents" value=""/>
132
  <input type="hidden" id="activeTab" name="activeTab" value=""/>
133
  </form>
134
  </div>
 
 
 
135
  </div>
136
  <br class="clear"/>
137
 
@@ -141,6 +137,7 @@ if('POST' == $rm)
141
  var activeTab = $('#activeTab');
142
  tabControl.tabs();
143
  tabControl.tabs("option", "active", <?php echo $activeTab;?>);
 
144
  // update select all checkbox
145
  $('#tabControlNavBar li').each(function(){
146
  var sectionName = $(this).data('id');
1
+ <?php if(! WPPHUtil::canViewPage()){ return; } ?>
2
  <?php
3
  if(! WPPH::ready())
4
  {
15
  ?>
16
  <?php
17
  // defaults
18
+ $defaultEvents = WPPH::getDefaultEvents();
19
+ $logEvents = WPPH::getEvents();
20
  $validationMessage = array();
21
+ $sectionNames = (empty($logEvents)) ? array(): array_keys($logEvents);
22
  $activeTab = 0;
23
  $rm = strtoupper($_SERVER['REQUEST_METHOD']);
24
  if('POST' == $rm)
45
  if(!$hasErrors)
46
  {
47
  $logEvents = array();
48
+ $wpphEvents = WPPH::getEvents();
49
  foreach($wpphEvents as $category=>$entries){
50
  $logEvents[$category] = array();
51
  foreach($entries as $event=>$entry){
61
  }
62
  }
63
  }
64
+ update_option(WPPH_PLUGIN_EVENTS_LIST_OPTION_NAME, $logEvents);
 
 
65
  $validationMessage['success'] = __('Your settings have been saved.',WPPH_PLUGIN_TEXT_DOMAIN);
66
  }
67
  }
71
  <h2 class="pageTitle pageTitle-settings"><?php echo __('Enable/Disable Alerts',WPPH_PLUGIN_TEXT_DOMAIN);?></h2>
72
 
73
  <div id="optionsDescription">
74
+ <p id="description" style="background: none repeat scroll 0 0 #EEEEEE;border: 1px solid #AAAAAA;border-radius: 4px 4px 4px 4px;box-shadow: 2px 2px 3px #DDDDDD;">
75
  <?php
76
  echo __('From this page you can enable or disable WordPress security alerts. If a security alert is disabled, an alert will not be generated in the Audit Log Viewer once such action happens.',WPPH_PLUGIN_TEXT_DOMAIN);
77
  echo '<br/>'.__('To disable a security alert, select the category tab and untick the alert. Click Save Settings when ready.',WPPH_PLUGIN_TEXT_DOMAIN);
86
  ?>
87
  <?php endif;?>
88
 
89
+ <?php if(!empty($sectionNames)) : ?>
90
+ <div id="logEventsTabControl" style="margin: 20px 0; opacity: 0;">
91
  <form id="updateSettingsForm" method="post">
92
  <?php wp_nonce_field('wpph_update_settings','wpph_update_settings_field_nonce'); ?>
93
  <?php
94
+ echo '<ul id="tabControlNavBar">';
95
+ foreach($sectionNames as $item){
96
+ echo '<li data-id="'.$item.'"><a href="#'.$item.'"/>'.str_replace('_',' ', $item).'</a></li>';
 
 
97
  }
98
+ echo '</ul>';
 
 
99
 
100
+ foreach($logEvents as $sectionName => $items){
101
+ echo '<div id="'.$sectionName.'">';
102
+ echo '<table class="wp-list-table widefat" cellspacing="0" cellpadding="0">';
103
+ echo '<thead>';
104
+ echo '<th class="manage-column column-cb check-column item-cb" scope="col"><input type="checkbox" class="js-select-all"/></th>';
105
+ echo '<th class="manage-column column-cb check-column item-event" scope="col">'.__('Event',WPPH_PLUGIN_TEXT_DOMAIN).'</th>';
106
+ echo '<th class="manage-column column-cb check-column item-type" scope="col">'.__('Type',WPPH_PLUGIN_TEXT_DOMAIN).'</th>';
107
+ echo '<th class="manage-column column-cb check-column item-description" scope="col">'.__('Description',WPPH_PLUGIN_TEXT_DOMAIN).'</th>';
108
+ echo '</thead>';
109
+ echo '<tbody>';
110
+ foreach($items as $item => $enabled){
111
+ echo '<tr class="row">';
112
+ echo '<th class="manage-column column-cb check-column" scope="row"><input class="item_cb" type="checkbox" '.($enabled ? 'checked="checked"' : '').' value="'.$item.'"/></th>';
113
+ echo '<td>'.$item.'</td>';
114
+ echo '<td>'.(isset($defaultEvents[$sectionName][$item]['type']) ? $defaultEvents[$sectionName][$item]['type'] : '').'</td>';
115
+ echo '<td>'.(isset($defaultEvents[$sectionName][$item]['text']) ? $defaultEvents[$sectionName][$item]['text'] : '').'</td>';
116
+ echo '</tr>';
117
+ }
118
+ echo '</tbody>';
119
+ echo '</table>';
120
+ echo '</div>';
121
  }
 
 
 
 
 
122
  ?>
123
+ <input type="submit" id="submitButton" class="button button-primary" style="margin: 0 0 12px 19px;" value="<?php echo __('Save settings',WPPH_PLUGIN_TEXT_DOMAIN);?>"/>
124
  <input type="hidden" id="inputEvents" name="inputEvents" value=""/>
125
  <input type="hidden" id="activeTab" name="activeTab" value=""/>
126
  </form>
127
  </div>
128
+ <?php else : ?>
129
+ <div class="error"><p><?php echo __('Error retrieving the list of events from database. Please inform the plugin author about this.',WPPH_PLUGIN_TEXT_DOMAIN);?></p></div>
130
+ <?php endif; ?>
131
  </div>
132
  <br class="clear"/>
133
 
137
  var activeTab = $('#activeTab');
138
  tabControl.tabs();
139
  tabControl.tabs("option", "active", <?php echo $activeTab;?>);
140
+ tabControl.css('opacity',1);
141
  // update select all checkbox
142
  $('#tabControlNavBar li').each(function(){
143
  var sectionName = $(this).data('id');
pages/dashboard.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php //if(! WPPH::canRun()){ return; } ?>
2
  <?php
3
  if(! WPPH::ready())
4
  {
@@ -21,19 +21,19 @@ if(! WPPH::ready())
21
  <div class="tablenav top" style="overflow: hidden; padding: 4px 0;">
22
  <div class="alignleft">
23
  <div style="overflow: hidden;">
24
- <input type="button" class="buttonRefreshEventsList button" value="<?php echo __('Refresh Events List',WPPH_PLUGIN_TEXT_DOMAIN);?>"
25
  style="float: left; display: block;" data-bind="disable: loading, click: cleanRefresh"/>
26
  <span class="ajaxLoaderWrapper" style="float: left; display: block; width: 20px; height: 20px; padding: 7px 7px;"><img/></span>
27
  </div>
28
  </div>
29
  <div class="alignleft actions" style="overflow: hidden;">
30
- <label class="alignleft" style="margin: 5px 5px 0 0;"><?php echo __('Number of events per page:',WPPH_PLUGIN_TEXT_DOMAIN);?></label>
31
  <select name="actionLimit1" class="actionLimit" data-bind="options: availablePageSize, value: selectedPageSize"></select>
32
  <input type="button" value="Apply" class="button action" data-bind="disable: loading, click: applyPageSize">
33
  </div>
34
 
35
  <div class="tablenav-pages">
36
- <span class="displaying-num" data-bind="text: totalEventsCount()+' events'"></span>
37
  <span class="pagination-links"><a href="#" title="Go to the first page" class="first-page" data-bind="click: firstPage, css: {disabled: offset() <= 0}">«</a>
38
  <a href="#" title="Go to the previous page" class="prev-page" data-bind="click: prevPage, disable: loading, click: prevPage, css: {disabled: offset() <= 0}">‹</a>
39
  <span class="paging-input">
@@ -70,7 +70,7 @@ if(! WPPH::ready())
70
  </tr>
71
  </tfoot>
72
  <tbody id="the-list">
73
- <tr data-bind="if: events().length == 0"><td style="padding: 4px !important;" colspan="7"><?php echo __('No events',WPPH_PLUGIN_TEXT_DOMAIN);?></td></tr>
74
  <!-- ko foreach: events -->
75
  <tr data-bind="css: {'row-0': ($index() % 2) == 0, 'row-1': ($index() % 2) != 0}">
76
  <td class="column-event_number"><span data-bind="text: eventNumber"></span></td>
@@ -88,18 +88,18 @@ if(! WPPH::ready())
88
  <div class="tablenav top" style="overflow: hidden; padding: 4px 0;">
89
  <div class="alignleft">
90
  <div style="overflow: hidden;">
91
- <input type="button" class="buttonRefreshEventsList button" value="<?php echo __('Refresh Events List',WPPH_PLUGIN_TEXT_DOMAIN);?>"
92
  style="float: left; display: block;" data-bind="disable: loading, click: cleanRefresh"/>
93
  <span class="ajaxLoaderWrapper" style="float: left; display: block; width: 20px; height: 20px; padding: 7px 7px;"><img/></span>
94
  </div>
95
  </div>
96
  <div class="alignleft actions" style="overflow: hidden;">
97
- <label class="alignleft" style="margin: 5px 5px 0 0;"><?php echo __('Number of events per page:',WPPH_PLUGIN_TEXT_DOMAIN);?></label>
98
  <select name="actionLimit1" class="actionLimit" data-bind="options: availablePageSize, value: selectedPageSize"></select>
99
  <input type="button" value="Apply" class="button action" data-bind="disable: loading, click: applyPageSize">
100
  </div>
101
  <div class="tablenav-pages">
102
- <span class="displaying-num" data-bind="text: totalEventsCount()+' events'"></span>
103
  <span class="pagination-links"><a href="#" title="Go to the first page" class="first-page" data-bind="click: firstPage, css: {disabled: offset() <= 0}">«</a>
104
  <a href="#" title="Go to the previous page" class="prev-page" data-bind="click: prevPage, disable: loading, click: prevPage, css: {disabled: offset() <= 0}">‹</a>
105
  <span class="paging-input">
1
+ <?php if(! WPPHUtil::canViewPage()){ return; } ?>
2
  <?php
3
  if(! WPPH::ready())
4
  {
21
  <div class="tablenav top" style="overflow: hidden; padding: 4px 0;">
22
  <div class="alignleft">
23
  <div style="overflow: hidden;">
24
+ <input type="button" class="buttonRefreshEventsList button" value="<?php echo __('Refresh Security Alerts List',WPPH_PLUGIN_TEXT_DOMAIN);?>"
25
  style="float: left; display: block;" data-bind="disable: loading, click: cleanRefresh"/>
26
  <span class="ajaxLoaderWrapper" style="float: left; display: block; width: 20px; height: 20px; padding: 7px 7px;"><img/></span>
27
  </div>
28
  </div>
29
  <div class="alignleft actions" style="overflow: hidden;">
30
+ <label class="alignleft" style="margin: 5px 5px 0 0;"><?php echo __('Number of security alerts per page:',WPPH_PLUGIN_TEXT_DOMAIN);?></label>
31
  <select name="actionLimit1" class="actionLimit" data-bind="options: availablePageSize, value: selectedPageSize"></select>
32
  <input type="button" value="Apply" class="button action" data-bind="disable: loading, click: applyPageSize">
33
  </div>
34
 
35
  <div class="tablenav-pages">
36
+ <span class="displaying-num" data-bind="text: totalEventsCount()+' security alerts'"></span>
37
  <span class="pagination-links"><a href="#" title="Go to the first page" class="first-page" data-bind="click: firstPage, css: {disabled: offset() <= 0}">«</a>
38
  <a href="#" title="Go to the previous page" class="prev-page" data-bind="click: prevPage, disable: loading, click: prevPage, css: {disabled: offset() <= 0}">‹</a>
39
  <span class="paging-input">
70
  </tr>
71
  </tfoot>
72
  <tbody id="the-list">
73
+ <tr data-bind="if: events().length == 0"><td style="padding: 4px !important;" colspan="7"><?php echo __('No security alerts',WPPH_PLUGIN_TEXT_DOMAIN);?></td></tr>
74
  <!-- ko foreach: events -->
75
  <tr data-bind="css: {'row-0': ($index() % 2) == 0, 'row-1': ($index() % 2) != 0}">
76
  <td class="column-event_number"><span data-bind="text: eventNumber"></span></td>
88
  <div class="tablenav top" style="overflow: hidden; padding: 4px 0;">
89
  <div class="alignleft">
90
  <div style="overflow: hidden;">
91
+ <input type="button" class="buttonRefreshEventsList button" value="<?php echo __('Refresh security alerts List',WPPH_PLUGIN_TEXT_DOMAIN);?>"
92
  style="float: left; display: block;" data-bind="disable: loading, click: cleanRefresh"/>
93
  <span class="ajaxLoaderWrapper" style="float: left; display: block; width: 20px; height: 20px; padding: 7px 7px;"><img/></span>
94
  </div>
95
  </div>
96
  <div class="alignleft actions" style="overflow: hidden;">
97
+ <label class="alignleft" style="margin: 5px 5px 0 0;"><?php echo __('Number of security alerts per page:',WPPH_PLUGIN_TEXT_DOMAIN);?></label>
98
  <select name="actionLimit1" class="actionLimit" data-bind="options: availablePageSize, value: selectedPageSize"></select>
99
  <input type="button" value="Apply" class="button action" data-bind="disable: loading, click: applyPageSize">
100
  </div>
101
  <div class="tablenav-pages">
102
+ <span class="displaying-num" data-bind="text: totalEventsCount()+' security alerts'"></span>
103
  <span class="pagination-links"><a href="#" title="Go to the first page" class="first-page" data-bind="click: firstPage, css: {disabled: offset() <= 0}">«</a>
104
  <a href="#" title="Go to the previous page" class="prev-page" data-bind="click: prevPage, disable: loading, click: prevPage, css: {disabled: offset() <= 0}">‹</a>
105
  <span class="paging-input">
pages/settings.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php if(! WPPH::canRun()){ return; } ?>
2
  <?php
3
  if(! WPPH::ready())
4
  {
@@ -24,6 +24,9 @@ $showDW = (empty($opt->showDW) ? false : true);
24
  // active delete option for events
25
  if(!empty($opt->daysToKeep)){ $daysInput = $opt->daysToKeep; $activeOption = 1; }
26
  if(! empty($opt->eventsToKeep)){ $eventsNumber = $opt->eventsToKeep; $activeOption = 2; }
 
 
 
27
  // end defaults
28
 
29
  $rm = strtoupper($_SERVER['REQUEST_METHOD']);
@@ -44,6 +47,25 @@ if('POST' == $rm)
44
  $deleteEventsBy = intval($_POST['deleteEventsBy']);
45
  $deleteEventsValue = intval($_POST['deleteEventsValue']);
46
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  // if Delete events older than ... days
48
  if($deleteEventsBy == 1)
49
  {
@@ -76,11 +98,11 @@ if('POST' == $rm)
76
 
77
  // Validate
78
  if(!preg_match('/^\d+$/',$deleteEventsValue)){
79
- $validationMessage['error'] = sprintf(__('Incorrect number of events. Please specify a value between 1 and %d.',WPPH_PLUGIN_TEXT_DOMAIN), WPPH_KEEP_MAX_EVENTS);
80
  $hasErrors = true;
81
  }
82
  elseif($deleteEventsValue < 1 || $deleteEventsValue > WPPH_KEEP_MAX_EVENTS){
83
- $validationMessage['error'] = sprintf(__('Incorrect number of events. Please specify a value between 1 and %d.',WPPH_PLUGIN_TEXT_DOMAIN), WPPH_KEEP_MAX_EVENTS);
84
  $hasErrors = true;
85
  }
86
  else {
@@ -108,6 +130,26 @@ if('POST' == $rm)
108
  }
109
  // end $post
110
  ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  <div id="wpph-pageWrapper" class="wrap">
112
  <h2 class="pageTitle pageTitle-settings"><?php echo __('WP Security Audit Log Settings',WPPH_PLUGIN_TEXT_DOMAIN);?></h2>
113
 
@@ -119,17 +161,17 @@ if('POST' == $rm)
119
  <?php else : ?>
120
  <div id="errMessage" style="display: none;"></div>
121
  <?php endif;?>
122
-
123
  <div style="margin: 20px 0;">
124
  <form id="updateSettingsForm" method="post">
125
  <?php wp_nonce_field('wpph_update_settings','wpph_update_settings_field_nonce'); ?>
126
  <div id="eventsDeletion">
127
  <div id="section-holder">
 
128
  <table cellspacing="0" cellpadding="0" class="form-table">
129
  <tbody>
130
  <tr valign="top">
131
  <td rowspan="4" class="section-left">
132
- <label style="display:block;margin: 30px 0 0 0;"><?php echo __('Security Alerts Pruning',WPPH_PLUGIN_TEXT_DOMAIN);?></label>
133
  </td>
134
  </tr>
135
  <tr>
@@ -162,7 +204,7 @@ if('POST' == $rm)
162
  </tr>
163
  <tr><td style="height: 10px;"></td></tr>
164
  <tr>
165
- <td rowspan="2" class="section-left"><label><?php echo __('Security Alerts Dashboard Widget',WPPH_PLUGIN_TEXT_DOMAIN);?></label></td>
166
  </tr>
167
  <tr>
168
  <td class="section-right">
@@ -172,7 +214,189 @@ if('POST' == $rm)
172
  </tr>
173
  </tbody>
174
  </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  </div>
 
 
176
  </div>
177
  <p style="margin-top: 40px;">
178
  <input type="submit" id="submitButton" class="button button-primary" value="<?php echo __('Save settings',WPPH_PLUGIN_TEXT_DOMAIN);?>"/>
@@ -180,6 +404,8 @@ if('POST' == $rm)
180
  <input type="hidden" id="deleteEventsBy" name="deleteEventsBy" value=""/>
181
  <input type="hidden" id="deleteEventsValue" name="deleteEventsValue" value=""/>
182
  <input type="hidden" id="optionDW" name="optionDW" value=""/>
 
 
183
  </form>
184
  </div>
185
  </div>
@@ -247,7 +473,7 @@ if('POST' == $rm)
247
  return false;
248
  }
249
  if(eniVal > <?php echo WPPH_KEEP_MAX_EVENTS;?>){
250
- showErrorMessage("<?php echo sprintf(__('Incorrect number of alerts. Please specify a value between 1 and %d.',WPPH_PLUGIN_TEXT_DOMAIN),WPPH_KEEP_MAX_EVENTS);?>");
251
  setFocusOn($eventsNumberInput);
252
  return false;
253
  }
@@ -262,7 +488,9 @@ if('POST' == $rm)
262
  ,daysInput = $('#daysInput')
263
  ,eventsNumber = $('#eventsNumberInput')
264
  ,showDW = $('#optionDW_on')
265
- ,hideDW = $('#optionDW_off');
 
 
266
  option1.on('click', function(){ option2.removeAttr('checked'); $(this).attr('checked','checked'); setFocusOn(daysInput); });
267
  option2.on('click', function(){ option1.removeAttr('checked'); $(this).attr('checked','checked'); setFocusOn(eventsNumber); });
268
  daysInput.on('click', function(){ option2.removeAttr('checked'); option1.attr('checked','checked'); });
@@ -314,6 +542,17 @@ if('POST' == $rm)
314
  $('#optionDW').val('1');
315
  }
316
  else { $('#optionDW').val('0') }
 
 
 
 
 
 
 
 
 
 
 
317
  return true;
318
  });
319
  });
1
+ <?php //if(! WPPHUtil::canViewPage()){ return; } ?>
2
  <?php
3
  if(! WPPH::ready())
4
  {
24
  // active delete option for events
25
  if(!empty($opt->daysToKeep)){ $daysInput = $opt->daysToKeep; $activeOption = 1; }
26
  if(! empty($opt->eventsToKeep)){ $eventsNumber = $opt->eventsToKeep; $activeOption = 2; }
27
+ $allowedAccess = get_option(WPPH_PLUGIN_ALLOW_ACCESS_OPTION_NAME, array());
28
+ $allowedChange = get_option(WPPH_PLUGIN_ALLOW_CHANGE_OPTION_NAME, array());
29
+ if(! isset($activeOption)){ $activeOption = 2; }
30
  // end defaults
31
 
32
  $rm = strtoupper($_SERVER['REQUEST_METHOD']);
47
  $deleteEventsBy = intval($_POST['deleteEventsBy']);
48
  $deleteEventsValue = intval($_POST['deleteEventsValue']);
49
 
50
+ // pre-validate access rules if any
51
+ if(! empty($_POST['accessListInput'])){
52
+ $set = $_POST['accessListInput'];
53
+ $set = str_replace('\\','', $set);
54
+ $set = json_decode($set);
55
+ $allowedAccess = $set;
56
+ // Allowed Access
57
+ WPPHUtil::saveAllowAccessUserList($allowedAccess);
58
+ }
59
+ // pre-validate change rules if any
60
+ if(! empty($_POST['changeListInput'])){
61
+ $set = $_POST['changeListInput'];
62
+ $set = str_replace('\\','', $set);
63
+ $set = json_decode($set);
64
+ $allowedChange = $set;
65
+ // Allowed Change
66
+ WPPHUtil::saveAllowedChangeUserList($allowedChange);
67
+ }
68
+
69
  // if Delete events older than ... days
70
  if($deleteEventsBy == 1)
71
  {
98
 
99
  // Validate
100
  if(!preg_match('/^\d+$/',$deleteEventsValue)){
101
+ $validationMessage['error'] = sprintf(__('Incorrect number of security alerts. Please specify a value between 1 and %d.',WPPH_PLUGIN_TEXT_DOMAIN), WPPH_KEEP_MAX_EVENTS);
102
  $hasErrors = true;
103
  }
104
  elseif($deleteEventsValue < 1 || $deleteEventsValue > WPPH_KEEP_MAX_EVENTS){
105
+ $validationMessage['error'] = sprintf(__('Incorrect number of security alerts. Please specify a value between 1 and %d.',WPPH_PLUGIN_TEXT_DOMAIN), WPPH_KEEP_MAX_EVENTS);
106
  $hasErrors = true;
107
  }
108
  else {
130
  }
131
  // end $post
132
  ?>
133
+ <style type="text/css">
134
+ .widefat td p { margin: 13px 0 0.8em !important; }
135
+ .message {
136
+ background-color: #FFFFE0 !important;
137
+ border-radius: 3px 3px 3px 3px;
138
+ border-style: solid;
139
+ border-width: 1px;
140
+ border-color: #E6DB55;
141
+ margin: 5px 0 15px !important;
142
+ padding: 0 0.6em !important;
143
+ }
144
+ .message p { margin: 0 0; padding: 7px 0; font-style: italic; }
145
+ p.description span { text-decoration: underline;}
146
+ .the-list th, .the-list tr td {padding: 7px 0 0 0 !important;}
147
+ .the-list th p, .the-list tr td p {padding: 0 0 !important; margin: 0 0 !important;}
148
+ .the-list td.column-username p,
149
+ .the-list td.column-name p,
150
+ .the-list td.column-role p { padding-left: 7px !important;}
151
+
152
+ </style>
153
  <div id="wpph-pageWrapper" class="wrap">
154
  <h2 class="pageTitle pageTitle-settings"><?php echo __('WP Security Audit Log Settings',WPPH_PLUGIN_TEXT_DOMAIN);?></h2>
155
 
161
  <?php else : ?>
162
  <div id="errMessage" style="display: none;"></div>
163
  <?php endif;?>
 
164
  <div style="margin: 20px 0;">
165
  <form id="updateSettingsForm" method="post">
166
  <?php wp_nonce_field('wpph_update_settings','wpph_update_settings_field_nonce'); ?>
167
  <div id="eventsDeletion">
168
  <div id="section-holder">
169
+
170
  <table cellspacing="0" cellpadding="0" class="form-table">
171
  <tbody>
172
  <tr valign="top">
173
  <td rowspan="4" class="section-left">
174
+ <label style="display:block;margin: 30px 0 0 0;" for="eventsNumberInput"><?php echo __('Security Alerts Pruning',WPPH_PLUGIN_TEXT_DOMAIN);?></label>
175
  </td>
176
  </tr>
177
  <tr>
204
  </tr>
205
  <tr><td style="height: 10px;"></td></tr>
206
  <tr>
207
+ <td rowspan="2" class="section-left" style=""><label style="display:block;margin: 0 0 0;" for="optionDW_on"><?php echo __('Security Alerts Dashboard Widget',WPPH_PLUGIN_TEXT_DOMAIN);?></label></td>
208
  </tr>
209
  <tr>
210
  <td class="section-right">
214
  </tr>
215
  </tbody>
216
  </table>
217
+
218
+ <style type="text/css">
219
+ .divTarget { padding: 10px 0;}
220
+ .tagElement { padding: 2px 4px; margin: 2px 0 0 2px; border: solid 1px #E6DB55; background: #FFFFE0; }
221
+ .tagElement .tagDelete { cursor: pointer; font-weight: 900; }
222
+ .tagElement .tagDelete:hover { color: #d00000; }
223
+ #section-holder #c-list p.description { margin-top: 0 !important; margin-bottom: 0 !important; }
224
+ </style>
225
+ <table cellspacing="0" cellpadding="0" class="form-table" style="margin-top: 30px;">
226
+ <tbody>
227
+ <tr valign="top">
228
+ <td valign="top" class="section-left">
229
+ <label style="display:block;margin: 12px 0 0 0;" for="inputUser1"><?php echo __('Can view Security Alerts',WPPH_PLUGIN_TEXT_DOMAIN);?></label>
230
+ </td>
231
+ <td class="section-right">
232
+ <div id="a-list">
233
+ <input type="text" id="inputUser1" style="float: left; display: block; width: 250px;"/>
234
+ <input type="button" id="inputAdd1" style="float: left; display: block;" class="button-primary" value="<?php echo __('Add',WPPH_PLUGIN_TEXT_DOMAIN);?>"/>
235
+ <p class="description" style="clear:both; padding-top: 3px;"><?php echo __('Users and Roles in this list can view the security alerts via the Audit Log Viewer (Read Only)',WPPH_PLUGIN_TEXT_DOMAIN);?></p>
236
+ <div id="accessListTarget" class="divTarget" style="float: none; clear: both;"></div>
237
+ </div>
238
+ </td>
239
+ </tr>
240
+ <tr><td></td><td></td></tr>
241
+ <tr><td></td><td></td></tr>
242
+ <tr valign="top">
243
+ <td valign="top" class="section-left">
244
+ <label style="display:block;margin: 12px 0 0 0;" for="inputUser2"><?php echo __('Can Manage Plugin ',WPPH_PLUGIN_TEXT_DOMAIN);?></label>
245
+ </td>
246
+ <td class="section-right">
247
+ <div id="c-list">
248
+ <input type="text" id="inputUser2" style="float: left; display: block; width: 250px;"/>
249
+ <input type="button" id="inputAdd2" style="float: left; display: block;" class="button-primary" value="<?php echo __('Add',WPPH_PLUGIN_TEXT_DOMAIN);?>"/>
250
+ <p class="description" style="clear:both; padding-top: 3px;"><?php echo __('Users and Roles in this list can manage the plugin settings.',WPPH_PLUGIN_TEXT_DOMAIN);?></p>
251
+ <div id="changeListTarget" class="divTarget" style="float: none; clear: both;"></div>
252
+ </div>
253
+ </td>
254
+ </tr>
255
+ </tbody>
256
+ </table>
257
+ <script type="text/javascript">
258
+ jQuery(document).ready(function($)
259
+ {
260
+ var mainContainer1 = $('#a-list'),
261
+ inputUser1 = $('#inputUser1'),
262
+ inputAdd1 = $('#inputAdd1'),
263
+ divTarget1 = $('#accessListTarget'),
264
+ tagElement1 = $('.tagElement', mainContainer1),
265
+
266
+ mainContainer2 = $('#c-list'),
267
+ inputUser2 = $('#inputUser2'),
268
+ inputAdd2 = $('#inputAdd2'),
269
+ divTarget2 = $('#changeListTarget'),
270
+ tagElement2 = $('.tagElement', mainContainer2)
271
+ ;
272
+
273
+ function showDefaultEntries(data, divTarget){
274
+ if(data.length > 0){
275
+ $.each(data, function(i,v){
276
+ createTag($, v, divTarget);
277
+ });
278
+ }
279
+ }
280
+
281
+ // Display the default list
282
+ <?php
283
+ if(!empty($allowedAccess)){ echo 'showDefaultEntries(["'.implode('","',$allowedAccess).'"],divTarget1);'; }
284
+ if(!empty($allowedChange)){ echo 'showDefaultEntries(["'.implode('","',$allowedChange).'"],divTarget2);'; }
285
+ ?>
286
+
287
+ function _ajax(string)
288
+ {
289
+ if(string.length > 0){
290
+ var data = {
291
+ 'action': 'wpph_check_user_role',
292
+ 'check_input' : string
293
+ };
294
+ }
295
+ else {
296
+ alert('Please add a user name or role.');
297
+ return false;
298
+ }
299
+ var result;
300
+ $.ajax({
301
+ url: ajaxurl,
302
+ cache: false,
303
+ type: 'POST',
304
+ data: data,
305
+ async : false,
306
+ success: function(response) {
307
+ result = response;
308
+ },
309
+ error: function() {
310
+ result = 'An error occurred. Please try again in a few moments.';
311
+ }
312
+ });
313
+ return result;
314
+ }
315
+ function createTag($, value, parentElement){ parentElement.append($('<span class="tagElement"><span class="tagName">'+value+'</span> <span class="tagDelete" title="Delete">x</span></span>')); }
316
+ function isValidEntry($, value, targetDiv){
317
+ var elements = $('.tagName', targetDiv);
318
+ var result = true;
319
+ if(elements.length > 0){
320
+ $.each(elements,function(i,v){
321
+ var val = $.trim($(this).text());
322
+ if($.trim(value) == val){
323
+ result = false;
324
+ return false;
325
+ }
326
+ });
327
+ }
328
+ return result;
329
+ }
330
+ $('.tagDelete', tagElement1).live('click', function(){ $(this).parent().remove(); });
331
+ $('.tagDelete', tagElement2).live('click', function(){ $(this).parent().remove(); });
332
+ inputAdd1.on('click', function(){
333
+ var val = $.trim(inputUser1.val());
334
+ if(val.length == 0){
335
+ alert('Please add a user name or role.');
336
+ return false;
337
+ }
338
+ if( false == isValidEntry($, val, divTarget1)){
339
+ alert('The user or role has been already added.');
340
+ return false;
341
+ }
342
+ else {
343
+ var result = _ajax(val);
344
+ if(result.length > 5){
345
+ alert('Error: '+result);
346
+ return false;
347
+ }
348
+ else if (parseInt(result) == 0){
349
+ alert('user or role '+val+' was not found');
350
+ return false;
351
+ }
352
+ createTag($, val, divTarget1);
353
+ inputUser1.val('');
354
+ return true;
355
+ }
356
+ });
357
+ inputUser1.keypress(function(event){
358
+ if (event.keyCode == 10 || event.keyCode == 13) {
359
+ event.preventDefault();
360
+ inputAdd1.click();
361
+ }
362
+ });
363
+ inputAdd2.on('click', function(){
364
+ var val = $.trim(inputUser2.val());
365
+ if(val.length == 0){
366
+ alert('Please add a user name or role.');
367
+ return false;
368
+ }
369
+ if( false == isValidEntry($, val, divTarget2)){
370
+ alert('The user or role has been already added.');
371
+ return false;
372
+ }
373
+ else {
374
+ var result = _ajax(val);
375
+ if(result.length > 5){
376
+ alert('Error: '+result);
377
+ return false;
378
+ }
379
+ else if (parseInt(result) == 0){
380
+ alert('user or role '+val+' was not found');
381
+ return false;
382
+ }
383
+ createTag($, val, divTarget2);
384
+ inputUser2.val('');
385
+ return true;
386
+ }
387
+ });
388
+ inputUser2.keypress(function(event){
389
+ if (event.keyCode == 10 || event.keyCode == 13) {
390
+ event.preventDefault();
391
+ inputAdd2.click();
392
+ }
393
+ });
394
+ });
395
+ </script>
396
+
397
  </div>
398
+
399
+
400
  </div>
401
  <p style="margin-top: 40px;">
402
  <input type="submit" id="submitButton" class="button button-primary" value="<?php echo __('Save settings',WPPH_PLUGIN_TEXT_DOMAIN);?>"/>
404
  <input type="hidden" id="deleteEventsBy" name="deleteEventsBy" value=""/>
405
  <input type="hidden" id="deleteEventsValue" name="deleteEventsValue" value=""/>
406
  <input type="hidden" id="optionDW" name="optionDW" value=""/>
407
+ <input type="hidden" id="accessListInput" name="accessListInput" value=""/>
408
+ <input type="hidden" id="changeListInput" name="changeListInput" value=""/>
409
  </form>
410
  </div>
411
  </div>
473
  return false;
474
  }
475
  if(eniVal > <?php echo WPPH_KEEP_MAX_EVENTS;?>){
476
+ showErrorMessage("<?php echo sprintf(__('Incorrect number of security alerts. Please specify a value between 1 and %d.',WPPH_PLUGIN_TEXT_DOMAIN),WPPH_KEEP_MAX_EVENTS);?>");
477
  setFocusOn($eventsNumberInput);
478
  return false;
479
  }
488
  ,daysInput = $('#daysInput')
489
  ,eventsNumber = $('#eventsNumberInput')
490
  ,showDW = $('#optionDW_on')
491
+ ,hideDW = $('#optionDW_off')
492
+ ,accessListInput = $('#accessListInput')
493
+ ,changeListInput = $('#changeListInput');
494
  option1.on('click', function(){ option2.removeAttr('checked'); $(this).attr('checked','checked'); setFocusOn(daysInput); });
495
  option2.on('click', function(){ option1.removeAttr('checked'); $(this).attr('checked','checked'); setFocusOn(eventsNumber); });
496
  daysInput.on('click', function(){ option2.removeAttr('checked'); option1.attr('checked','checked'); });
542
  $('#optionDW').val('1');
543
  }
544
  else { $('#optionDW').val('0') }
545
+
546
+ //#! build the access list
547
+ var a = [];
548
+ $('.tagName', $('#a-list')).each(function(){a.push($(this).text());});
549
+ accessListInput.val(JSON.stringify(a));
550
+
551
+ // build the change list
552
+ var b = [];
553
+ $('.tagName', $('#c-list')).each(function(){b.push($(this).text());});
554
+ changeListInput.val(JSON.stringify(b));
555
+
556
  return true;
557
  });
558
  });
pages/support.php CHANGED
@@ -1,6 +1,4 @@
1
-
2
- <?php if(! WPPH::canRun()){ return; } ?>
3
- <?php
4
  if(! WPPH::ready())
5
  {
6
  $errors = WPPH::getPluginErrors();
1
+ <?php if(! WPPHUtil::canViewPage()){ return; } ?><?php
 
 
2
  if(! WPPH::ready())
3
  {
4
  $errors = WPPH::getPluginErrors();
readme.txt CHANGED
@@ -4,8 +4,8 @@ License: GPLv3
4
  License URI: http://www.gnu.org/licenses/gpl.html
5
  Tags: wordpress security plugin, wordpress security audit log, audit 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
6
  Requires at least: 3.0
7
- Tested up to: 3.6.1
8
- Stable tag: 0.4
9
 
10
  Identify WordPress security issues before they become a problem. Keep an audit log of everything that happens on WordPress including WordPress user activity.
11
 
@@ -17,8 +17,9 @@ WP Security Audit Log keeps a log of everything happening on your WordPress blog
17
 
18
  * New user is created via registration or created by another user
19
  * Existing user changes the role or password of another user
20
- * User uploads a file, changes a password or email
21
  * User installs, activates, deactivates, upgrades or uninstalls a plugin
 
22
  * WordPress settings are changed
23
  * Failed login attempt
24
  * and much more...
@@ -28,12 +29,13 @@ Refer to the complete list of [WordPress Security Audit Alerts](http://www.wpwhi
28
  = Monitor WordPress Users Activity & Productivity =
29
  If you own a multi user WordPress blog or website you can use the WP Security Audit Log plugin to monitor your users' activity and productivity. With this WordPress security plugin you can monitor:
30
 
31
- * When users logged in or out
32
- * From where users are logging in
33
  * Users who created or deleted categories
34
  * Users who created a blog post or a page
35
  * Users who published a blog post or a page
36
  * Users who modified published WordPress content such as a page or a blog post
 
37
  * and much more...
38
 
39
  Refer to the complete list of [WordPress Security Audit Alerts](http://www.wpwhitesecurity.com/wordpress-security-plugins/wp-security-audit-log/security-audit-alerts-logs/) for more information.
@@ -69,16 +71,34 @@ Yes. A complete list can be found [here](http://www.wpwhitesecurity.com/wordpres
69
 
70
  = Can I disable some WordPress security alerts? =
71
 
72
- Yes it is possible to disable (and re-enable later) specific WordPress security alerts. To do so navigate to the Enable/Disable Alerts node in the plugin, select the category tab and untick the WordPress security alert. Tick back the alert to re-enable it.
73
 
74
  == Screenshots ==
75
 
76
  1. The Audit Log Viewer from where the WordPress administrator can see all the security events generated by WP Security Audit Log WordPress plugin.
77
- 2. The WP Security Audit Log plugin options from where WordPress administrator can configure the auto pruning of security alerts.
78
  3. The Enable/Disable Alerts settings node from where Administrators can disable or enable WordPress security alerts.
79
 
80
  == Changelog ==
81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
 
83
  = 0.4 =
84
  * New WordPress Security Alerts for Custom Post Types
@@ -104,7 +124,7 @@ Yes it is possible to disable (and re-enable later) specific WordPress security
104
  * Plugin Improvements
105
  * Updated settings page to have the same look and feel of WordPress
106
  * Improved the upgrade procedure of the plugin
107
- * Updated the Audit Log Viewer display to support more resultions such as those of tables and smartphones
108
 
109
  = 0.3 =
110
 
4
  License URI: http://www.gnu.org/licenses/gpl.html
5
  Tags: wordpress security plugin, wordpress security audit log, audit 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
6
  Requires at least: 3.0
7
+ Tested up to: 3.7.1
8
+ Stable tag: 0.5
9
 
10
  Identify WordPress security issues before they become a problem. Keep an audit log of everything that happens on WordPress including WordPress user activity.
11
 
17
 
18
  * New user is created via registration or created by another user
19
  * Existing user changes the role or password of another user
20
+ * User uploads a file, changes a password or email address
21
  * User installs, activates, deactivates, upgrades or uninstalls a plugin
22
+ * User adds, modifies or deletes a widget
23
  * WordPress settings are changed
24
  * Failed login attempt
25
  * and much more...
29
  = Monitor WordPress Users Activity & Productivity =
30
  If you own a multi user WordPress blog or website you can use the WP Security Audit Log plugin to monitor your users' activity and productivity. With this WordPress security plugin you can monitor:
31
 
32
+ * When WordPress users logged in or out
33
+ * From where WordPress users are logging in
34
  * Users who created or deleted categories
35
  * Users who created a blog post or a page
36
  * Users who published a blog post or a page
37
  * Users who modified published WordPress content such as a page or a blog post
38
+ * Users who modify WordPress widgets
39
  * and much more...
40
 
41
  Refer to the complete list of [WordPress Security Audit Alerts](http://www.wpwhitesecurity.com/wordpress-security-plugins/wp-security-audit-log/security-audit-alerts-logs/) for more information.
71
 
72
  = Can I disable some WordPress security alerts? =
73
 
74
+ Yes it is possible to disable (and re-enable later) specific WordPress security alerts. To do so navigate to the "Enable/Disable Alerts" node in the plugin, select the category tab and untick the WordPress security alert. Tick back the alert to re-enable it.
75
 
76
  == Screenshots ==
77
 
78
  1. The Audit Log Viewer from where the WordPress administrator can see all the security events generated by WP Security Audit Log WordPress plugin.
79
+ 2. The WP Security Audit Log plugin options from where WordPress administrator can configure the auto pruning of security alerts and specific user access.
80
  3. The Enable/Disable Alerts settings node from where Administrators can disable or enable WordPress security alerts.
81
 
82
  == Changelog ==
83
 
84
+ = 0.5 =
85
+ * New WordPress Security Alerts for monitoring of Widgets
86
+ * Alert 2042: New widget was added
87
+ * Alert 2043: A widget was modified
88
+ * Alert 2044: A widget was deleted
89
+ * Alert 2045: A widget was moved
90
+
91
+ * New Plugin Features
92
+ * New setting to allow specific user(s) and role(s) to view the Audit Log Viewer (read only)
93
+ * New setting to allow specific user(s) and role(s) to manage the WP Security Audit Log plugin (can change plugin settings, enable disable WordPress security alerts etc)
94
+
95
+ * Plugin Improvements
96
+ * Renamed "login/logout" tab in "Enable/Disable Alerts" section to plugins to "Other User Activity"
97
+ * Added the files alerts (uploaded / delete files) to the "Enable/Disable Alerts" (previously unavailable)
98
+
99
+ * Bug Fixes
100
+ * Fixed issue where all users were able to see the Dashboard widgets with security alerts - now restricted only to users who have access to the plugin
101
+ * Fixed user reported issue (http://wordpress.org/support/topic/errors-on-enabledisable-alerts-page)
102
 
103
  = 0.4 =
104
  * New WordPress Security Alerts for Custom Post Types
124
  * Plugin Improvements
125
  * Updated settings page to have the same look and feel of WordPress
126
  * Improved the upgrade procedure of the plugin
127
+ * Updated the Audit Log Viewer display to support more resultions such as those of tables and smartphones
128
 
129
  = 0.3 =
130
 
res/css/styles.base.css CHANGED
@@ -45,6 +45,7 @@ h2.pageTitle-about { background: url("../img/page-about-logo.png") no-repeat lef
45
  #section-holder p label, #section-holder p span { float: left; margin-top: 4px !important; margin-left: 10px !important; font-size: 12px !important; }
46
  #section-holder p input[type="text"] { float: left; margin-left: 10px !important; }
47
 
 
48
  .form-table td { line-height: normal !important;; }
49
  .form-table td.section-left { width: 190px; padding: 0 30px 0 0; }
50
  .form-table td.section-right p { padding: 0 0 !important; margin: 0 0 !important; }
45
  #section-holder p label, #section-holder p span { float: left; margin-top: 4px !important; margin-left: 10px !important; font-size: 12px !important; }
46
  #section-holder p input[type="text"] { float: left; margin-left: 10px !important; }
47
 
48
+ .form-table, .form-table td { border: none 0;}
49
  .form-table td { line-height: normal !important;; }
50
  .form-table td.section-left { width: 190px; padding: 0 30px 0 0; }
51
  .form-table td.section-right p { padding: 0 0 !important; margin: 0 0 !important; }
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 and keep track of everything happening on your WordPress, including WordPress users activity. Similar to Windows Event Log and Linux Syslog, WP Security Audit Log will generate a security alert for everything that happens on your WordPress blog or website. Use the Audit Log Viewer included in the plugin to see all the security alerts.
6
  Author: WP White Security
7
- Version: 0.4
8
  Author URI: http://www.wpwhitesecurity.com/
9
  License: GPL2
10
  Text Domain: wp-security-audit-log
@@ -26,8 +26,7 @@ Domain Path: languages/
26
  along with this program; if not, write to the Free Software
27
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28
  */
29
- // Holds the plugin option name
30
- define('WPPH_PLUGIN_VERSION','0.4');
31
  define('WPPH_PLUGIN_PREFIX', 'wpph_');
32
  define('WPPH_PLUGIN_NAME', 'WP Security Audit Log');
33
  define('WPPH_PLUGIN_URL', trailingslashit(plugins_url('', __FILE__)));
@@ -65,6 +64,9 @@ function onPluginUninstall()
65
  delete_option(WPPH_PLUGIN_DB_UPDATED);
66
  delete_option(WPPH_PLUGIN_VERSION_OPTION_NAME);
67
  delete_option(WPPH_USERS_CAN_REGISTER_OPT_NAME);
 
 
 
68
  $wpdb->query("DROP TABLE IF EXISTS ".WPPHDatabase::getFullTableName('main'));
69
  $wpdb->query("DROP TABLE IF EXISTS ".WPPHDatabase::getFullTableName('events'));
70
  }
@@ -80,12 +82,16 @@ add_action('plugins_loaded', 'wpphLoadTextDomain');
80
  // create dashboard widget
81
  add_action('wp_dashboard_setup', array('WPPHUtil','addDashboardWidget'));
82
 
83
-
84
  // $GLOBALS['WPPH_CAN_RUN']
85
  // @since v0.3
86
  // @see WPPH::onPluginActivate()
87
  if($GLOBALS['WPPH_CAN_RUN'])
88
  {
 
 
 
 
 
89
  // Load the pluggable.php file if needed
90
  add_action('admin_init', array('WPPHUtil','loadPluggable'));
91
  // Load resources
@@ -121,6 +127,7 @@ if($GLOBALS['WPPH_CAN_RUN'])
121
  }
122
  }
123
  }
 
124
  WPPHEvent::hookWatchPostStateBefore();
125
  WPPHEvent::hookWatchBlogActivity();
126
  WPPHEvent::hookWatchCategoryAdd();
@@ -141,6 +148,7 @@ if($GLOBALS['WPPH_CAN_RUN'])
141
  WPPHEvent::hookWatchPluginActivity();
142
  /* Enable ajax functionality in the dashboard page */
143
  add_action('wp_ajax_wpph_get_events', array('WPPHUtil','get_events_html'));
 
144
  }
145
  WPPHEvent::hookLoginEvent();
146
  WPPHEvent::hookLogoutEvent();
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 and keep track of everything happening on your WordPress, including WordPress users activity. Similar to Windows Event Log and Linux Syslog, WP Security Audit Log will generate a security alert for everything that happens on your WordPress blog or website. Use the Audit Log Viewer included in the plugin to see all the security alerts.
6
  Author: WP White Security
7
+ Version: 0.5
8
  Author URI: http://www.wpwhitesecurity.com/
9
  License: GPL2
10
  Text Domain: wp-security-audit-log
26
  along with this program; if not, write to the Free Software
27
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28
  */
29
+ define('WPPH_PLUGIN_VERSION','0.5');
 
30
  define('WPPH_PLUGIN_PREFIX', 'wpph_');
31
  define('WPPH_PLUGIN_NAME', 'WP Security Audit Log');
32
  define('WPPH_PLUGIN_URL', trailingslashit(plugins_url('', __FILE__)));
64
  delete_option(WPPH_PLUGIN_DB_UPDATED);
65
  delete_option(WPPH_PLUGIN_VERSION_OPTION_NAME);
66
  delete_option(WPPH_USERS_CAN_REGISTER_OPT_NAME);
67
+ delete_option(WPPH_PLUGIN_ALLOW_ACCESS_OPTION_NAME);
68
+ delete_option(WPPH_PLUGIN_ALLOW_CHANGE_OPTION_NAME);
69
+ delete_option(WPPH_PLUGIN_SETTING_NAME);
70
  $wpdb->query("DROP TABLE IF EXISTS ".WPPHDatabase::getFullTableName('main'));
71
  $wpdb->query("DROP TABLE IF EXISTS ".WPPHDatabase::getFullTableName('events'));
72
  }
82
  // create dashboard widget
83
  add_action('wp_dashboard_setup', array('WPPHUtil','addDashboardWidget'));
84
 
 
85
  // $GLOBALS['WPPH_CAN_RUN']
86
  // @since v0.3
87
  // @see WPPH::onPluginActivate()
88
  if($GLOBALS['WPPH_CAN_RUN'])
89
  {
90
+ //Create default settings
91
+ WPPH::getPluginSettings();
92
+ // Watch widget activity
93
+ add_action('widgets_init',array('WPPHEventWatcher','watchWidgetMove'));
94
+ add_action('sidebar_admin_setup', array('WPPHEventWatcher','watchWidgetActivity'));
95
  // Load the pluggable.php file if needed
96
  add_action('admin_init', array('WPPHUtil','loadPluggable'));
97
  // Load resources
127
  }
128
  }
129
  }
130
+ WPPHEventWatcher::triggerWidgetMoveEvent();
131
  WPPHEvent::hookWatchPostStateBefore();
132
  WPPHEvent::hookWatchBlogActivity();
133
  WPPHEvent::hookWatchCategoryAdd();
148
  WPPHEvent::hookWatchPluginActivity();
149
  /* Enable ajax functionality in the dashboard page */
150
  add_action('wp_ajax_wpph_get_events', array('WPPHUtil','get_events_html'));
151
+ add_action('wp_ajax_wpph_check_user_role', array('WPPHUtil','check_user_role'));
152
  }
153
  WPPHEvent::hookLoginEvent();
154
  WPPHEvent::hookLogoutEvent();