Version Description
(2014-09-26) = * New Feature * New option "Restrict Plugin Access" that allows WordPress administrators to further restrict access to the plugin and the WordPress security alerts
-
Improvements
- Updated the Audit Log Viewer backend to retriev WordPress security alerts much faster and consume less resources on large websites
- Moved the Audit Log plugin menu entry underneath the dashboard entry for better access
- Several minor enhancements to the plugin to perform better on large WordPress installations
-
Bug Fixes
- Fixed an uncaught exception with Logout Alert 1001 support ticket
Download this release
Release Info
Developer | WPWhiteSecurity |
Plugin | WP Security Audit Log |
Version | 1.2.7 |
Comparing to | |
See all releases |
Code changes from version 1.2.6 to 1.2.7
- classes/AbstractView.php +21 -0
- classes/AlertManager.php +6 -2
- classes/AuditLogListView.php +327 -0
- classes/Autoloader.php +2 -0
- classes/DB/ActiveRecord.php +25 -1
- classes/DB/OccurrenceQuery.php +90 -0
- classes/DB/Query.php +68 -4
- classes/LicenseManager.php +9 -6
- classes/Loggers/Database.php +11 -21
- classes/Sensors/LogInOut.php +2 -2
- classes/Sensors/System.php +4 -3
- classes/Settings.php +48 -16
- classes/SimpleProfiler.php +44 -0
- classes/ViewManager.php +7 -6
- classes/Views/AuditLog.php +19 -330
- classes/Views/Licensing.php +2 -2
- classes/Views/Sandbox.php +13 -2
- classes/Views/Settings.php +37 -6
- classes/WidgetManager.php +1 -1
- defaults.php +1 -1
- js/auditlog.js +6 -1
- js/settings.js +12 -0
- languages/wp-security-audit-log.pot +79 -111
- readme.txt +14 -2
- wp-security-audit-log.php +38 -7
classes/AbstractView.php
CHANGED
@@ -59,6 +59,27 @@ abstract class WSAL_AbstractView {
|
|
59 |
*/
|
60 |
abstract public function Render();
|
61 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
/**
|
63 |
* @return boolean Whether page should appear in menu or not.
|
64 |
*/
|
59 |
*/
|
60 |
abstract public function Render();
|
61 |
|
62 |
+
/**
|
63 |
+
* Renders the view icon (this has been deprecated in newwer WP versions).
|
64 |
+
*/
|
65 |
+
public function RenderIcon(){
|
66 |
+
?><div id="icon-plugins" class="icon32"><br></div><?php
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Renders the view title.
|
71 |
+
*/
|
72 |
+
public function RenderTitle(){
|
73 |
+
?><h2><?php echo esc_html($this->GetTitle()); ?></h2><?php
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* @link self::Render()
|
78 |
+
*/
|
79 |
+
public function RenderContent(){
|
80 |
+
$this->Render();
|
81 |
+
}
|
82 |
+
|
83 |
/**
|
84 |
* @return boolean Whether page should appear in menu or not.
|
85 |
*/
|
classes/AlertManager.php
CHANGED
@@ -95,13 +95,17 @@ final class WSAL_AlertManager {
|
|
95 |
/**
|
96 |
* @internal Commit an alert now.
|
97 |
*/
|
98 |
-
protected function _CommitItem($type, $data, $cond){
|
99 |
if(!$cond || !!call_user_func($cond, $this)){
|
100 |
if($this->IsEnabled($type)){
|
101 |
if(isset($this->_alerts[$type])){
|
102 |
// ok, convert alert to a log entry
|
103 |
$this->_triggered_types[] = $type;
|
104 |
$this->Log($type, $data);
|
|
|
|
|
|
|
|
|
105 |
}else{
|
106 |
// in general this shouldn't happen, but it could, so we handle it here :)
|
107 |
throw new Exception('Alert with code "' . $type . '" has not be registered.');
|
@@ -215,7 +219,7 @@ final class WSAL_AlertManager {
|
|
215 |
if(!isset($data['Username']) && !isset($data['CurrentUserID']))
|
216 |
$data['CurrentUserID'] = function_exists('get_current_user_id') ? get_current_user_id() : 0;
|
217 |
if(!isset($data['CurrentUserRoles']) && function_exists('is_user_logged_in') && is_user_logged_in())
|
218 |
-
$data['CurrentUserRoles'] =
|
219 |
|
220 |
//if(isset($_SERVER['REMOTE_HOST']) && $_SERVER['REMOTE_HOST'] != $data['ClientIP'])
|
221 |
// $data['ClientHost'] = $_SERVER['REMOTE_HOST'];
|
95 |
/**
|
96 |
* @internal Commit an alert now.
|
97 |
*/
|
98 |
+
protected function _CommitItem($type, $data, $cond, $_retry = true){
|
99 |
if(!$cond || !!call_user_func($cond, $this)){
|
100 |
if($this->IsEnabled($type)){
|
101 |
if(isset($this->_alerts[$type])){
|
102 |
// ok, convert alert to a log entry
|
103 |
$this->_triggered_types[] = $type;
|
104 |
$this->Log($type, $data);
|
105 |
+
}elseif($_retry){
|
106 |
+
// this is the last attempt at loading alerts from default file
|
107 |
+
$this->plugin->LoadDefaults();
|
108 |
+
return $this->_CommitItem($type, $data, $cond, false);
|
109 |
}else{
|
110 |
// in general this shouldn't happen, but it could, so we handle it here :)
|
111 |
throw new Exception('Alert with code "' . $type . '" has not be registered.');
|
219 |
if(!isset($data['Username']) && !isset($data['CurrentUserID']))
|
220 |
$data['CurrentUserID'] = function_exists('get_current_user_id') ? get_current_user_id() : 0;
|
221 |
if(!isset($data['CurrentUserRoles']) && function_exists('is_user_logged_in') && is_user_logged_in())
|
222 |
+
$data['CurrentUserRoles'] = $this->plugin->settings->GetCurrentUserRoles();
|
223 |
|
224 |
//if(isset($_SERVER['REMOTE_HOST']) && $_SERVER['REMOTE_HOST'] != $data['ClientIP'])
|
225 |
// $data['ClientHost'] = $_SERVER['REMOTE_HOST'];
|
classes/AuditLogListView.php
ADDED
@@ -0,0 +1,327 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once(ABSPATH . 'wp-admin/includes/admin.php');
|
4 |
+
require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
|
5 |
+
|
6 |
+
class WSAL_AuditLogListView extends WP_List_Table {
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @var WpSecurityAuditLog
|
10 |
+
*/
|
11 |
+
protected $_plugin;
|
12 |
+
|
13 |
+
public function __construct($plugin){
|
14 |
+
$this->_plugin = $plugin;
|
15 |
+
|
16 |
+
$this->_gmt_offset_sec = get_option('gmt_offset') * HOUR_IN_SECONDS;
|
17 |
+
|
18 |
+
parent::__construct(array(
|
19 |
+
'singular' => 'log',
|
20 |
+
'plural' => 'logs',
|
21 |
+
'ajax' => true,
|
22 |
+
'screen' => 'interval-list',
|
23 |
+
));
|
24 |
+
}
|
25 |
+
|
26 |
+
protected $_gmt_offset_sec = 0;
|
27 |
+
|
28 |
+
public function no_items(){
|
29 |
+
_e('No events so far.', 'wp-security-audit-log');
|
30 |
+
}
|
31 |
+
|
32 |
+
public function extra_tablenav($which){
|
33 |
+
// items-per-page widget
|
34 |
+
$o = __('Other', 'wp-security-audit-log');
|
35 |
+
$p = $this->_plugin->settings->GetViewPerPage();
|
36 |
+
$items = array($o, 5, 10, 15, 30, 50);
|
37 |
+
if (!in_array($p, $items)) $items[] = $p;
|
38 |
+
if ($p == $o || $p == 0) $p = $o[1]; // a sane default if things goes bust
|
39 |
+
|
40 |
+
?><div class="wsal-ipp wsal-ipp-<?php echo $which; ?>">
|
41 |
+
<?php _e('Show ', 'wp-security-audit-log'); ?>
|
42 |
+
<select class="wsal-ipps" onfocus="WsalIppsFocus(value);" onchange="WsalIppsChange(value);">
|
43 |
+
<?php foreach($items as $item){ ?>
|
44 |
+
<option
|
45 |
+
value="<?php echo is_string($item) ? '' : $item; ?>"
|
46 |
+
<?php if($item == $p)echo 'selected="selected"'; ?>><?php
|
47 |
+
echo $item;
|
48 |
+
?></option>
|
49 |
+
<?php } ?>
|
50 |
+
</select>
|
51 |
+
<?php _e(' Items', 'wp-security-audit-log'); ?>
|
52 |
+
</div><?php
|
53 |
+
|
54 |
+
// show site alerts widget
|
55 |
+
if($this->is_multisite() && $this->is_main_blog()){
|
56 |
+
$curr = $this->get_view_site_id();
|
57 |
+
?><div class="wsal-ssa wsal-ssa-<?php echo $which; ?>">
|
58 |
+
<?php if($this->get_site_count() > 15){ ?>
|
59 |
+
<?php $curr = $curr ? get_blog_details($curr) : null; ?>
|
60 |
+
<?php $curr = $curr ? ($curr->blogname . ' (' . $curr->domain . ')') : 'All Sites'; ?>
|
61 |
+
<input type="text" class="wsal-ssas" value="<?php echo esc_attr($curr); ?>"/>
|
62 |
+
<?php }else{ ?>
|
63 |
+
<select class="wsal-ssas" onchange="WsalSsasChange(value);">
|
64 |
+
<option value="0"><?php _e('All Sites', 'wp-security-audit-log'); ?></option>
|
65 |
+
<?php foreach($this->get_sites() as $info){ ?>
|
66 |
+
<option value="<?php echo $info->blog_id; ?>"
|
67 |
+
<?php if($info->blog_id == $curr)echo 'selected="selected"'; ?>><?php
|
68 |
+
echo esc_html($info->blogname) . ' (' . esc_html($info->domain) . ')';
|
69 |
+
?></option>
|
70 |
+
<?php } ?>
|
71 |
+
</select>
|
72 |
+
<?php } ?>
|
73 |
+
</div><?php
|
74 |
+
}
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* @param int|null $limit Maximum number of sites to return (null = no limit).
|
79 |
+
* @return object Object with keys: blog_id, blogname, domain
|
80 |
+
*/
|
81 |
+
public function get_sites($limit = null){
|
82 |
+
global $wpdb;
|
83 |
+
|
84 |
+
// build query
|
85 |
+
$sql = 'SELECT blog_id, domain FROM ' . $wpdb->blogs;
|
86 |
+
if(!is_null($limit))$sql .= ' LIMIT ' . $limit;
|
87 |
+
|
88 |
+
// execute query
|
89 |
+
$res = $wpdb->get_results($sql);
|
90 |
+
|
91 |
+
// modify result
|
92 |
+
foreach($res as $row){
|
93 |
+
$row->blogname = get_blog_option($row->blog_id, 'blogname');
|
94 |
+
}
|
95 |
+
|
96 |
+
// return result
|
97 |
+
return $res;
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* @return int The number of sites on the network.
|
102 |
+
*/
|
103 |
+
public function get_site_count(){
|
104 |
+
global $wpdb;
|
105 |
+
$sql = 'SELECT COUNT(*) FROM ' . $wpdb->blogs;
|
106 |
+
return (int)$wpdb->get_var($sql);
|
107 |
+
}
|
108 |
+
|
109 |
+
public function get_columns(){
|
110 |
+
$cols = array(
|
111 |
+
//'cb' => '<input type="checkbox" />',
|
112 |
+
//'read' => __('Read', 'wp-security-audit-log'),
|
113 |
+
'type' => __('Code', 'wp-security-audit-log'),
|
114 |
+
'code' => __('Type', 'wp-security-audit-log'),
|
115 |
+
'crtd' => __('Date', 'wp-security-audit-log'),
|
116 |
+
'user' => __('Username', 'wp-security-audit-log'),
|
117 |
+
'scip' => __('Source IP', 'wp-security-audit-log'),
|
118 |
+
);
|
119 |
+
if($this->is_multisite() && $this->is_main_blog() && !$this->is_specific_view()){
|
120 |
+
$cols['site'] = __('Site', 'wp-security-audit-log');
|
121 |
+
}
|
122 |
+
$cols['mesg'] = __('Message', 'wp-security-audit-log');
|
123 |
+
if($this->_plugin->settings->IsDataInspectorEnabled()){
|
124 |
+
$cols['data'] = '';
|
125 |
+
}
|
126 |
+
return $cols;
|
127 |
+
}
|
128 |
+
|
129 |
+
public function column_cb(WSAL_DB_Occurrence $item){
|
130 |
+
return '<input type="checkbox" value="'.$item->id.'" '
|
131 |
+
. 'name="'.esc_attr($this->_args['singular']).'[]"/>';
|
132 |
+
}
|
133 |
+
|
134 |
+
public function get_sortable_columns(){
|
135 |
+
return array(
|
136 |
+
'read' => array('is_read', false),
|
137 |
+
'code' => array('code', false),
|
138 |
+
'type' => array('alert_id', false),
|
139 |
+
'crtd' => array('created_on', true),
|
140 |
+
'user' => array('user', false),
|
141 |
+
'scip' => array('scip', false),
|
142 |
+
'site' => array('site', false),
|
143 |
+
);
|
144 |
+
}
|
145 |
+
|
146 |
+
public function column_default(WSAL_DB_Occurrence $item, $column_name){
|
147 |
+
switch($column_name){
|
148 |
+
case 'read':
|
149 |
+
return '<span class="log-read log-read-'
|
150 |
+
. ($item->is_read ? 'old' : 'new')
|
151 |
+
. '" title="' . __('Click to toggle.', 'wp-security-audit-log') . '"></span>';
|
152 |
+
case 'type':
|
153 |
+
return str_pad($item->alert_id, 4, '0', STR_PAD_LEFT);
|
154 |
+
case 'code':
|
155 |
+
$code = $this->_plugin->alerts->GetAlert($item->alert_id);
|
156 |
+
$code = $code ? $code->code : 0;
|
157 |
+
$const = (object)array('name' => 'E_UNKNOWN', 'value' => 0, 'description' => __('Unknown error code.', 'wp-security-audit-log'));
|
158 |
+
$const = $this->_plugin->constants->GetConstantBy('value', $code, $const);
|
159 |
+
return '<span class="log-type log-type-' . $const->value
|
160 |
+
. '" title="' . esc_html($const->name . ': ' . $const->description) . '"></span>';
|
161 |
+
case 'crtd':
|
162 |
+
return $item->created_on ? (
|
163 |
+
str_replace(
|
164 |
+
'$$$',
|
165 |
+
substr(number_format(fmod($item->created_on + $this->_gmt_offset_sec, 1), 3), 2),
|
166 |
+
date('Y-m-d<\b\r>h:i:s.$$$&\n\b\s\p;A', $item->created_on + $this->_gmt_offset_sec)
|
167 |
+
)
|
168 |
+
) : '<i>unknown</i>';
|
169 |
+
case 'user':
|
170 |
+
$username = $item->GetUsername();
|
171 |
+
if($username && ($user = get_user_by('login', $username))){
|
172 |
+
$image = get_avatar($user->ID, 32);
|
173 |
+
$uhtml = '<a href="' . admin_url('user-edit.php?user_id=' . $user->ID)
|
174 |
+
. '" target="_blank">' . esc_html($user->display_name) . '</a>';
|
175 |
+
$roles = $item->GetUserRoles();
|
176 |
+
$roles = (is_array($roles) && count($roles))
|
177 |
+
? __(esc_html(ucwords(implode(', ', $roles))))
|
178 |
+
: '<i>' . __('Unknown', 'wp-security-audit-log') . '</i>';
|
179 |
+
}else{
|
180 |
+
$image = get_avatar(0, 32);
|
181 |
+
$uhtml = '<i>' . __('Unknown', 'wp-security-audit-log') . '</i>';
|
182 |
+
$roles = '<i>' . __('System', 'wp-security-audit-log') . '</i>';
|
183 |
+
}
|
184 |
+
return $image . $uhtml . '<br/>' . $roles;
|
185 |
+
case 'scip':
|
186 |
+
return !is_null($item->GetSourceIP()) ? esc_html($item->GetSourceIP()) : '<i>unknown</i>';
|
187 |
+
case 'site':
|
188 |
+
$info = get_blog_details($item->site_id, true);
|
189 |
+
return !$info ? ('Unknown Site '.$item->site_id)
|
190 |
+
: ('<a href="' . esc_attr($info->siteurl) . '">' . esc_html($info->blogname) . '</a>');
|
191 |
+
case 'mesg':
|
192 |
+
return '<div id="Event' . $item->id . '">' . $item->GetMessage(array($this, 'meta_formatter')) . '</div>';
|
193 |
+
case 'data':
|
194 |
+
$url = admin_url('admin-ajax.php') . '?action=AjaxInspector&occurrence=' . $item->id;
|
195 |
+
return '<a class="more-info thickbox" title="' . __('Alert Data Inspector', 'wp-security-audit-log') . '"'
|
196 |
+
. ' href="' . $url . '&TB_iframe=true&width=600&height=550">…</a>';
|
197 |
+
default:
|
198 |
+
return isset($item->$column_name)
|
199 |
+
? esc_html($item->$column_name)
|
200 |
+
: 'Column "' . esc_html($column_name) . '" not found';
|
201 |
+
}
|
202 |
+
}
|
203 |
+
|
204 |
+
public function reorder_items_str($a, $b){
|
205 |
+
$result = strcmp($a->{$this->_orderby}, $b->{$this->_orderby});
|
206 |
+
return ($this->_order === 'asc') ? $result : -$result;
|
207 |
+
}
|
208 |
+
|
209 |
+
public function reorder_items_int($a, $b){
|
210 |
+
$result = $a->{$this->_orderby} - $b->{$this->_orderby};
|
211 |
+
return ($this->_order === 'asc') ? $result : -$result;
|
212 |
+
}
|
213 |
+
|
214 |
+
public function meta_formatter($name, $value){
|
215 |
+
switch(true){
|
216 |
+
|
217 |
+
case $name == '%Message%':
|
218 |
+
return esc_html($value);
|
219 |
+
|
220 |
+
case in_array($name, array('%MetaValue%', '%MetaValueOld%', '%MetaValueNew%')):
|
221 |
+
return '<strong>' . (
|
222 |
+
strlen($value) > 50 ? (esc_html(substr($value, 0, 50)) . '…') : esc_html($value)
|
223 |
+
) . '</strong>';
|
224 |
+
|
225 |
+
case strncmp($value, 'http://', 7) === 0:
|
226 |
+
case strncmp($value, 'https://', 7) === 0:
|
227 |
+
return '<a href="' . esc_html($value) . '"'
|
228 |
+
. ' title="' . esc_html($value) . '"'
|
229 |
+
. ' target="_blank">'
|
230 |
+
. esc_html(parse_url($value, PHP_URL_HOST)) . '/…/'
|
231 |
+
. esc_html(basename(parse_url($value, PHP_URL_PATH)))
|
232 |
+
. '</a>';
|
233 |
+
|
234 |
+
default:
|
235 |
+
return '<strong>' . esc_html($value) . '</strong>';
|
236 |
+
}
|
237 |
+
}
|
238 |
+
|
239 |
+
protected function is_multisite(){
|
240 |
+
return $this->_plugin->IsMultisite();
|
241 |
+
}
|
242 |
+
|
243 |
+
protected function is_main_blog(){
|
244 |
+
return get_current_blog_id() == 1;
|
245 |
+
}
|
246 |
+
|
247 |
+
protected function is_specific_view(){
|
248 |
+
return isset($_REQUEST['wsal-cbid']) && $_REQUEST['wsal-cbid'] != '0';
|
249 |
+
}
|
250 |
+
|
251 |
+
protected function get_specific_view(){
|
252 |
+
return isset($_REQUEST['wsal-cbid']) ? (int)$_REQUEST['wsal-cbid'] : 0;
|
253 |
+
}
|
254 |
+
|
255 |
+
protected function get_view_site_id(){
|
256 |
+
switch(true){
|
257 |
+
|
258 |
+
// non-multisite
|
259 |
+
case !$this->is_multisite():
|
260 |
+
return 0;
|
261 |
+
|
262 |
+
// multisite + main site view
|
263 |
+
case $this->is_main_blog() && !$this->is_specific_view():
|
264 |
+
return 0;
|
265 |
+
|
266 |
+
// multisite + switched site view
|
267 |
+
case $this->is_main_blog() && $this->is_specific_view():
|
268 |
+
return $this->get_specific_view();
|
269 |
+
|
270 |
+
// multisite + local site view
|
271 |
+
default:
|
272 |
+
return get_current_blog_id();
|
273 |
+
|
274 |
+
}
|
275 |
+
}
|
276 |
+
|
277 |
+
public function prepare_items() {
|
278 |
+
$per_page = $this->_plugin->settings->GetViewPerPage();
|
279 |
+
|
280 |
+
$columns = $this->get_columns();
|
281 |
+
$hidden = array();
|
282 |
+
$sortable = $this->get_sortable_columns();
|
283 |
+
|
284 |
+
$this->_column_headers = array($columns, $hidden, $sortable);
|
285 |
+
|
286 |
+
//$this->process_bulk_action();
|
287 |
+
|
288 |
+
$query = new WSAL_DB_OccurrenceQuery('WSAL_DB_Occurrence');
|
289 |
+
$bid = (int)$this->get_view_site_id();
|
290 |
+
if ($bid) $query->where[] = 'site_id = '.$bid;
|
291 |
+
$query->order[] = 'created_on DESC';
|
292 |
+
|
293 |
+
$query = apply_filters('wsal_auditlog_query', $query);
|
294 |
+
|
295 |
+
$total_items = $query->Count();
|
296 |
+
|
297 |
+
/** @deprecated */
|
298 |
+
//$data = $query->Execute();
|
299 |
+
|
300 |
+
if($total_items){
|
301 |
+
$this->_orderby = (!empty($_REQUEST['orderby']) && isset($sortable[$_REQUEST['orderby']])) ? $_REQUEST['orderby'] : 'created_on';
|
302 |
+
$this->_order = (!empty($_REQUEST['order']) && $_REQUEST['order']=='asc') ? 'ASC' : 'DESC';
|
303 |
+
$tmp = new WSAL_DB_Occurrence();
|
304 |
+
if(isset($tmp->{$this->_orderby})){
|
305 |
+
// TODO we used to use a custom comparator ... is it safe to let MySQL do the ordering now?
|
306 |
+
$query->order[] = $this->_orderby . ' ' . $this->_order;
|
307 |
+
/** @deprecated */
|
308 |
+
//$numorder = in_array($this->_orderby, array('code', 'type', 'created_on'));
|
309 |
+
//usort($data, array($this, $numorder ? 'reorder_items_int' : 'reorder_items_str'));
|
310 |
+
}
|
311 |
+
}
|
312 |
+
|
313 |
+
/** @todo Modify $query instead */
|
314 |
+
/** @deprecated */
|
315 |
+
//$data = array_slice($data, ($this->get_pagenum() - 1) * $per_page, $per_page);
|
316 |
+
$query->offset = ($this->get_pagenum() - 1) * $per_page;
|
317 |
+
$query->length = $per_page;
|
318 |
+
|
319 |
+
$this->items = $query->Execute();
|
320 |
+
|
321 |
+
$this->set_pagination_args( array(
|
322 |
+
'total_items' => $total_items,
|
323 |
+
'per_page' => $per_page,
|
324 |
+
'total_pages' => ceil($total_items / $per_page)
|
325 |
+
) );
|
326 |
+
}
|
327 |
+
}
|
classes/Autoloader.php
CHANGED
@@ -32,7 +32,9 @@ class WSAL_Autoloader {
|
|
32 |
if(strstr($class, $prefix) !== false){
|
33 |
$file = $path . str_replace('_', DIRECTORY_SEPARATOR, substr($class, strlen($prefix))) . '.php';
|
34 |
if(file_exists($file)){
|
|
|
35 |
require_once($file);
|
|
|
36 |
return class_exists($class, false) || interface_exists($class, false);
|
37 |
}
|
38 |
}
|
32 |
if(strstr($class, $prefix) !== false){
|
33 |
$file = $path . str_replace('_', DIRECTORY_SEPARATOR, substr($class, strlen($prefix))) . '.php';
|
34 |
if(file_exists($file)){
|
35 |
+
$s = $this->plugin->profiler->Start('Autoload ' . basename($file));
|
36 |
require_once($file);
|
37 |
+
$s->Stop();
|
38 |
return class_exists($class, false) || interface_exists($class, false);
|
39 |
}
|
40 |
}
|
classes/DB/ActiveRecord.php
CHANGED
@@ -272,6 +272,17 @@ abstract class WSAL_DB_ActiveRecord {
|
|
272 |
return $result;
|
273 |
}
|
274 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
275 |
/**
|
276 |
* Load multiple records from DB.
|
277 |
* @param string $cond (Optional) Load condition (eg: 'some_id = %d' ).
|
@@ -315,12 +326,25 @@ abstract class WSAL_DB_ActiveRecord {
|
|
315 |
* If no parameters are given, this counts the number of records in the DB table.
|
316 |
* @param string $cond (Optional) Query condition.
|
317 |
* @param array $args (Optional) Condition arguments.
|
|
|
318 |
*/
|
319 |
public static function Count($cond = '%d', $args = array(1)){
|
320 |
global $wpdb;
|
321 |
$class = get_called_class();
|
322 |
$temp = new $class();
|
323 |
-
$sql = $wpdb->prepare('SELECT COUNT(*) FROM ' . $temp->GetTable() . ' WHERE '
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
324 |
return (int)$wpdb->get_var($sql);
|
325 |
}
|
326 |
|
272 |
return $result;
|
273 |
}
|
274 |
|
275 |
+
/**
|
276 |
+
* Delete records in DB matching a query.
|
277 |
+
* @param string $query Full SQL query.
|
278 |
+
* @param array $args (Optional) Query arguments.
|
279 |
+
*/
|
280 |
+
public static function DeleteQuery($query, $args = array()){
|
281 |
+
global $wpdb;
|
282 |
+
$sql = count($args) ? $wpdb->prepare($query, $args) : $query;
|
283 |
+
$wpdb->query($sql);
|
284 |
+
}
|
285 |
+
|
286 |
/**
|
287 |
* Load multiple records from DB.
|
288 |
* @param string $cond (Optional) Load condition (eg: 'some_id = %d' ).
|
326 |
* If no parameters are given, this counts the number of records in the DB table.
|
327 |
* @param string $cond (Optional) Query condition.
|
328 |
* @param array $args (Optional) Condition arguments.
|
329 |
+
* @return int Number of matching records.
|
330 |
*/
|
331 |
public static function Count($cond = '%d', $args = array(1)){
|
332 |
global $wpdb;
|
333 |
$class = get_called_class();
|
334 |
$temp = new $class();
|
335 |
+
$sql = $wpdb->prepare('SELECT COUNT(*) FROM ' . $temp->GetTable() . ' WHERE ' . $cond, $args);
|
336 |
+
return (int)$wpdb->get_var($sql);
|
337 |
+
}
|
338 |
+
|
339 |
+
/**
|
340 |
+
* Count records in the DB matching a query.
|
341 |
+
* @param string $query Full SQL query.
|
342 |
+
* @param array $args (Optional) Query arguments.
|
343 |
+
* @return int Number of matching records.
|
344 |
+
*/
|
345 |
+
public static function CountQuery($query, $args = array()){
|
346 |
+
global $wpdb;
|
347 |
+
$sql = count($args) ? $wpdb->prepare($query, $args) : $query;
|
348 |
return (int)$wpdb->get_var($sql);
|
349 |
}
|
350 |
|
classes/DB/OccurrenceQuery.php
ADDED
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_DB_OccurrenceQuery extends WSAL_DB_Query {
|
4 |
+
const LIKE_LEFT = 'l';
|
5 |
+
const LIKE_RIGHT = 'r';
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Contains meta-specific arguments to be AND'ed together
|
9 |
+
* @var array
|
10 |
+
*/
|
11 |
+
public $meta_where = array();
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Contains arguments to be used in meta conditions.
|
15 |
+
* @var array
|
16 |
+
*/
|
17 |
+
public $meta_args = array();
|
18 |
+
|
19 |
+
public function GetCond(){
|
20 |
+
$cond = parent::GetCond();
|
21 |
+
if (count($this->meta_where)) {
|
22 |
+
$tmp = new WSAL_DB_Meta();
|
23 |
+
$cond[] = 'id IN (
|
24 |
+
SELECT DISTINCT occurrence_id
|
25 |
+
FROM ' . $tmp->GetTable() . '
|
26 |
+
WHERE ' . implode(' AND ', $this->meta_where) . '
|
27 |
+
)';
|
28 |
+
}
|
29 |
+
return $cond;
|
30 |
+
}
|
31 |
+
|
32 |
+
public function GetArgs(){
|
33 |
+
$args = parent::GetArgs();
|
34 |
+
foreach ($this->meta_args as $arg) $args[] = $arg;
|
35 |
+
return $args;
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Find occurrences matching an exact named meta value.
|
40 |
+
* @param string $name Meta name.
|
41 |
+
* @param string $value Meta value.
|
42 |
+
*/
|
43 |
+
public function WhereMetaIs($name, $value){
|
44 |
+
$this->meta_where[] = 'name = %s AND value = %s';
|
45 |
+
$this->meta_args[] = $name;
|
46 |
+
$this->meta_args[] = $value;
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Find occurrences matching a named meta containing a value.
|
51 |
+
* @param string $name Meta name.
|
52 |
+
* @param string $value Meta value.
|
53 |
+
* @param string $type Where to check for (left, right, both or none) see LIKE_* constants
|
54 |
+
*/
|
55 |
+
public function WhereMetaLike($name, $value, $type){
|
56 |
+
$this->meta_where[] = 'name = %s AND value LIKE %s';
|
57 |
+
$this->meta_args[] = $name;
|
58 |
+
$value = esc_sql($value);
|
59 |
+
if (strpos($type, self::LIKE_LEFT) !== false) $value = '%' . $value;
|
60 |
+
if (strpos($type, self::LIKE_RIGHT) !== false) $value = $value . '%';
|
61 |
+
$this->meta_args[] = $value;
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Find occurrences matching a meta condition.
|
66 |
+
* @param string $cond Meta condition.
|
67 |
+
* @param array $args Condition arguments.
|
68 |
+
*/
|
69 |
+
public function WhereMeta($cond, $args){
|
70 |
+
$this->meta_where[] = $cond;
|
71 |
+
foreach ($args as $arg) $this->meta_args[] = $arg;
|
72 |
+
}
|
73 |
+
|
74 |
+
public function Delete(){
|
75 |
+
// delete meta data: back up columns, remove them for DELETE and generate sql
|
76 |
+
$cols = $this->columns;
|
77 |
+
$this->columns = array('occurrence_id');
|
78 |
+
$tmp = new WSAL_DB_Meta();
|
79 |
+
$sql = 'DELETE FROM ' . $tmp->GetTable() . ' WHERE occurrence_id IN (' . $this->GetSql('select') . ')';
|
80 |
+
|
81 |
+
// restore columns
|
82 |
+
$this->columns = $cols;
|
83 |
+
|
84 |
+
// execute query
|
85 |
+
call_user_func(array($this->ar_cls, 'DeleteQuery'), $sql, $this->GetArgs());
|
86 |
+
|
87 |
+
// delete occurrences
|
88 |
+
parent::Delete();
|
89 |
+
}
|
90 |
+
}
|
classes/DB/Query.php
CHANGED
@@ -2,7 +2,6 @@
|
|
2 |
|
3 |
/**
|
4 |
* @todo Add group-by support
|
5 |
-
* @todo Add limit/top support
|
6 |
*/
|
7 |
class WSAL_DB_Query {
|
8 |
/**
|
@@ -51,6 +50,18 @@ class WSAL_DB_Query {
|
|
51 |
*/
|
52 |
public $args = array();
|
53 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
/**
|
55 |
* @param string $ar_class Name of class that extends ActiveRecord class.
|
56 |
*/
|
@@ -68,20 +79,31 @@ class WSAL_DB_Query {
|
|
68 |
/**
|
69 |
* @return string Generated sql.
|
70 |
*/
|
71 |
-
public function GetSql(){
|
|
|
72 |
switch($this->GetDbType()){
|
73 |
case 'mysql':
|
74 |
-
return '
|
75 |
. ' FROM ' . implode(',', $this->from)
|
76 |
. (count($this->joins) ? implode(' ', $this->where) : '')
|
77 |
-
. (count($
|
|
|
|
|
78 |
. (count($this->order) ? (' ORDER BY ' . implode(', ', $this->order)) : '')
|
|
|
79 |
;
|
80 |
default:
|
81 |
throw new Exception('SQL generation for "' . $this->GetDbType() . '" databases is not supported.');
|
82 |
}
|
83 |
}
|
84 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
85 |
/**
|
86 |
* @return array Arguments used in query.
|
87 |
*/
|
@@ -95,4 +117,46 @@ class WSAL_DB_Query {
|
|
95 |
public function Execute(){
|
96 |
return call_user_func(array($this->ar_cls, 'LoadMultiQuery'), $this->GetSql(), $this->GetArgs());
|
97 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
}
|
2 |
|
3 |
/**
|
4 |
* @todo Add group-by support
|
|
|
5 |
*/
|
6 |
class WSAL_DB_Query {
|
7 |
/**
|
50 |
*/
|
51 |
public $args = array();
|
52 |
|
53 |
+
/**
|
54 |
+
* The amount of records to skip in result.
|
55 |
+
* @var int
|
56 |
+
*/
|
57 |
+
public $offset = 0;
|
58 |
+
|
59 |
+
/**
|
60 |
+
* The maximum number of records in result.
|
61 |
+
* @var int
|
62 |
+
*/
|
63 |
+
public $length = 0;
|
64 |
+
|
65 |
/**
|
66 |
* @param string $ar_class Name of class that extends ActiveRecord class.
|
67 |
*/
|
79 |
/**
|
80 |
* @return string Generated sql.
|
81 |
*/
|
82 |
+
public function GetSql($verb = 'select'){
|
83 |
+
$where = $this->GetCond();
|
84 |
switch($this->GetDbType()){
|
85 |
case 'mysql':
|
86 |
+
return strtoupper($verb) . ' ' . implode(',', $this->columns)
|
87 |
. ' FROM ' . implode(',', $this->from)
|
88 |
. (count($this->joins) ? implode(' ', $this->where) : '')
|
89 |
+
. (count($where) ? (' WHERE ' . implode(' AND ', $where)) : '')
|
90 |
+
// @todo GROUP BY goes here
|
91 |
+
// @todo HAVING goes here
|
92 |
. (count($this->order) ? (' ORDER BY ' . implode(', ', $this->order)) : '')
|
93 |
+
. ($this->length ? (' LIMIT ' . ($this->offset ? ($this->offset . ', ') : '') . ' ' . $this->length) : '')
|
94 |
;
|
95 |
default:
|
96 |
throw new Exception('SQL generation for "' . $this->GetDbType() . '" databases is not supported.');
|
97 |
}
|
98 |
}
|
99 |
|
100 |
+
/**
|
101 |
+
* @return array Array of conditions.
|
102 |
+
*/
|
103 |
+
public function GetCond(){
|
104 |
+
return $this->where;
|
105 |
+
}
|
106 |
+
|
107 |
/**
|
108 |
* @return array Arguments used in query.
|
109 |
*/
|
117 |
public function Execute(){
|
118 |
return call_user_func(array($this->ar_cls, 'LoadMultiQuery'), $this->GetSql(), $this->GetArgs());
|
119 |
}
|
120 |
+
|
121 |
+
/**
|
122 |
+
* @return int Use query for counting records.
|
123 |
+
*/
|
124 |
+
public function Count(){
|
125 |
+
// back up columns, use COUNT as default column and generate sql
|
126 |
+
$cols = $this->columns;
|
127 |
+
$this->columns = array('COUNT(*)');
|
128 |
+
$sql = $this->GetSql();
|
129 |
+
|
130 |
+
// restore columns
|
131 |
+
$this->columns = $cols;
|
132 |
+
|
133 |
+
// execute query and return result
|
134 |
+
return call_user_func(array($this->ar_cls, 'CountQuery'), $sql, $this->GetArgs());
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Find occurrences matching a condition.
|
139 |
+
* @param string $cond The condition.
|
140 |
+
* @param array $args Condition arguments.
|
141 |
+
*/
|
142 |
+
public function Where($cond, $args){
|
143 |
+
$this->where[] = $cond;
|
144 |
+
foreach ($args as $arg) $this->args[] = $arg;
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* Use query for deleting records.
|
149 |
+
*/
|
150 |
+
public function Delete(){
|
151 |
+
// back up columns, remove them for DELETE and generate sql
|
152 |
+
$cols = $this->columns;
|
153 |
+
$this->columns = array();
|
154 |
+
$sql = $this->GetSql('delete');
|
155 |
+
|
156 |
+
// restore columns
|
157 |
+
$this->columns = $cols;
|
158 |
+
|
159 |
+
// execute query
|
160 |
+
call_user_func(array($this->ar_cls, 'DeleteQuery'), $sql, $this->GetArgs());
|
161 |
+
}
|
162 |
}
|
classes/LicenseManager.php
CHANGED
@@ -49,9 +49,9 @@ class WSAL_LicenseManager {
|
|
49 |
|
50 |
$api_params = array(
|
51 |
'edd_action'=> 'activate_license',
|
52 |
-
'license' => $license,
|
53 |
-
'item_name' => urlencode($name),
|
54 |
-
'url' => home_url()
|
55 |
);
|
56 |
|
57 |
$response = wp_remote_get(
|
@@ -60,7 +60,7 @@ class WSAL_LicenseManager {
|
|
60 |
);
|
61 |
|
62 |
if (is_wp_error($response)) {
|
63 |
-
$this->plugin->settings->SetLicenseErrors($name, 'Invalid Licensing Server Response');
|
64 |
return false;
|
65 |
}
|
66 |
|
@@ -68,8 +68,11 @@ class WSAL_LicenseManager {
|
|
68 |
|
69 |
if(is_object($license_data)){
|
70 |
$this->plugin->settings->SetLicenseStatus($name, $license_data->license);
|
71 |
-
if($license_data->license !== 'valid')
|
72 |
-
$
|
|
|
|
|
|
|
73 |
}else{
|
74 |
$this->plugin->settings->SetLicenseErrors($name, 'Unexpected Licensing Server Response');
|
75 |
}
|
49 |
|
50 |
$api_params = array(
|
51 |
'edd_action'=> 'activate_license',
|
52 |
+
'license' => urlencode($license),
|
53 |
+
'item_name' => urlencode($this->plugins[$name]['PluginData']['Name']),
|
54 |
+
'url' => urlencode(home_url())
|
55 |
);
|
56 |
|
57 |
$response = wp_remote_get(
|
60 |
);
|
61 |
|
62 |
if (is_wp_error($response)) {
|
63 |
+
$this->plugin->settings->SetLicenseErrors($name, 'Invalid Licensing Server Response: ' . $response->get_error_message());
|
64 |
return false;
|
65 |
}
|
66 |
|
68 |
|
69 |
if(is_object($license_data)){
|
70 |
$this->plugin->settings->SetLicenseStatus($name, $license_data->license);
|
71 |
+
if($license_data->license !== 'valid'){
|
72 |
+
$error = 'License Not Valid';
|
73 |
+
if (isset($license_data->error)) $error .= ': ' . ucfirst(str_replace('_', ' ', $license_data->error));
|
74 |
+
$this->plugin->settings->SetLicenseErrors($name, $error);
|
75 |
+
}
|
76 |
}else{
|
77 |
$this->plugin->settings->SetLicenseErrors($name, 'Unexpected Licensing Server Response');
|
78 |
}
|
classes/Loggers/Database.php
CHANGED
@@ -32,30 +32,20 @@ class WSAL_Loggers_Database extends WSAL_AbstractLogger {
|
|
32 |
|
33 |
$is_date_e = $this->plugin->settings->IsPruningDateEnabled();
|
34 |
$is_limt_e = $this->plugin->settings->IsPruningLimitEnabled();
|
|
|
35 |
|
36 |
-
|
37 |
-
|
38 |
-
$cond = 'created_on < %d ORDER BY created_on ASC LIMIT %d';
|
39 |
-
$args = array($max_stamp, $max_items);
|
40 |
-
break;
|
41 |
-
case $is_date_e && !$is_limt_e:
|
42 |
-
$cond = 'created_on < %d';
|
43 |
-
$args = array($max_stamp);
|
44 |
-
break;
|
45 |
-
case !$is_date_e && $is_limt_e:
|
46 |
-
$cond = '1 ORDER BY created_on ASC LIMIT %d';
|
47 |
-
$args = array($max_items);
|
48 |
-
break;
|
49 |
-
case !$is_date_e && !$is_limt_e:
|
50 |
-
return;
|
51 |
-
}
|
52 |
-
if(!isset($cond))return;
|
53 |
|
54 |
-
$
|
55 |
-
if(
|
56 |
|
57 |
-
|
58 |
-
|
|
|
|
|
|
|
|
|
59 |
}
|
60 |
|
61 |
}
|
32 |
|
33 |
$is_date_e = $this->plugin->settings->IsPruningDateEnabled();
|
34 |
$is_limt_e = $this->plugin->settings->IsPruningLimitEnabled();
|
35 |
+
if (!$is_date_e && !$is_limt_e) return; // pruning disabled
|
36 |
|
37 |
+
$query = new WSAL_DB_OccurrenceQuery('WSAL_DB_Occurrence');
|
38 |
+
$query->order[] = 'created_on ASC';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
|
40 |
+
if ($is_date_e) $query->Where('created_on < %d', array($max_stamp));
|
41 |
+
if ($is_limt_e) $query->length = (int)$max_items;
|
42 |
|
43 |
+
$count = $query->Count();
|
44 |
+
if (!$count) return; // nothing to delete
|
45 |
+
|
46 |
+
// delete data and notify system
|
47 |
+
$query->Delete();
|
48 |
+
do_action('wsal_prune', $count, vsprintf($query->GetSql(), $query->GetArgs()));
|
49 |
}
|
50 |
|
51 |
}
|
classes/Sensors/LogInOut.php
CHANGED
@@ -18,14 +18,14 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
18 |
public function EventLogin($user_login, $user){
|
19 |
$this->plugin->alerts->Trigger(1000, array(
|
20 |
'Username' => $user_login,
|
21 |
-
'CurrentUserRoles' => $user->roles,
|
22 |
), true);
|
23 |
}
|
24 |
|
25 |
public function EventLogout(){
|
26 |
$this->plugin->alerts->Trigger(1001, array(
|
27 |
'CurrentUserID' => $this->_current_user->ID,
|
28 |
-
'CurrentUserRoles' => $this->_current_user->roles,
|
29 |
), true);
|
30 |
}
|
31 |
|
18 |
public function EventLogin($user_login, $user){
|
19 |
$this->plugin->alerts->Trigger(1000, array(
|
20 |
'Username' => $user_login,
|
21 |
+
'CurrentUserRoles' => $this->plugin->settings->GetCurrentUserRoles($user->roles),
|
22 |
), true);
|
23 |
}
|
24 |
|
25 |
public function EventLogout(){
|
26 |
$this->plugin->alerts->Trigger(1001, array(
|
27 |
'CurrentUserID' => $this->_current_user->ID,
|
28 |
+
'CurrentUserRoles' => $this->plugin->settings->GetCurrentUserRoles($this->_current_user->roles),
|
29 |
), true);
|
30 |
}
|
31 |
|
classes/Sensors/System.php
CHANGED
@@ -8,11 +8,12 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
8 |
}
|
9 |
|
10 |
/**
|
11 |
-
* @param
|
|
|
12 |
*/
|
13 |
-
public function EventPruneEvents($
|
14 |
$this->plugin->alerts->Trigger(6000, array(
|
15 |
-
'EventCount' => count
|
16 |
'PruneQuery' => $query,
|
17 |
));
|
18 |
}
|
8 |
}
|
9 |
|
10 |
/**
|
11 |
+
* @param int $count The number of deleted events.
|
12 |
+
* @param string $query Query that selected events for deletion.
|
13 |
*/
|
14 |
+
public function EventPruneEvents($count, $query){
|
15 |
$this->plugin->alerts->Trigger(6000, array(
|
16 |
+
'EventCount' => $count,
|
17 |
'PruneQuery' => $query,
|
18 |
));
|
19 |
}
|
classes/Settings.php
CHANGED
@@ -217,6 +217,14 @@ class WSAL_Settings {
|
|
217 |
return $this->_plugin->GetGlobalOption('pruning-limit-e', true);
|
218 |
}
|
219 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
220 |
protected $_disabled = null;
|
221 |
|
222 |
public function GetDefaultDisabledAlerts(){
|
@@ -325,42 +333,60 @@ class WSAL_Settings {
|
|
325 |
}
|
326 |
|
327 |
/**
|
328 |
-
*
|
329 |
-
* @param string $action Type of action
|
330 |
-
* @return
|
331 |
*/
|
332 |
-
public function
|
333 |
-
if(is_int($user))$user = get_userdata($user);
|
334 |
$allowed = array();
|
335 |
|
336 |
switch($action){
|
337 |
case 'view':
|
338 |
$allowed = $this->GetAllowedPluginViewers();
|
339 |
$allowed = array_merge($allowed, $this->GetAllowedPluginEditors());
|
340 |
-
|
341 |
-
|
|
|
|
|
342 |
break;
|
343 |
case 'edit':
|
344 |
$allowed = $this->GetAllowedPluginEditors();
|
345 |
-
|
346 |
-
|
347 |
-
|
|
|
|
|
348 |
break;
|
349 |
default:
|
350 |
throw new Exception('Unknown action "'.$action.'".');
|
351 |
}
|
352 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
353 |
$check = array_merge(
|
354 |
$user->roles,
|
355 |
array($user->user_login)
|
356 |
);
|
357 |
|
358 |
-
if(is_multisite()){
|
359 |
-
$allowed = array_merge($allowed, get_super_admins());
|
360 |
-
}else{
|
361 |
-
$allowed[] = 'administrator';
|
362 |
-
}
|
363 |
-
|
364 |
foreach($check as $item){
|
365 |
if(in_array($item, $allowed)){
|
366 |
return true;
|
@@ -370,6 +396,12 @@ class WSAL_Settings {
|
|
370 |
return false;
|
371 |
}
|
372 |
|
|
|
|
|
|
|
|
|
|
|
|
|
373 |
public function IsIncognito(){
|
374 |
return $this->_plugin->GetGlobalOption('hide-plugin');
|
375 |
}
|
217 |
return $this->_plugin->GetGlobalOption('pruning-limit-e', true);
|
218 |
}
|
219 |
|
220 |
+
public function IsRestrictAdmins(){
|
221 |
+
return $this->_plugin->GetGlobalOption('restrict-admins', false);
|
222 |
+
}
|
223 |
+
|
224 |
+
public function SetRestrictAdmins($enable){
|
225 |
+
$this->_plugin->SetGlobalOption('restrict-admins', (bool)$enable);
|
226 |
+
}
|
227 |
+
|
228 |
protected $_disabled = null;
|
229 |
|
230 |
public function GetDefaultDisabledAlerts(){
|
333 |
}
|
334 |
|
335 |
/**
|
336 |
+
* Returns access tokens for a particular action.
|
337 |
+
* @param string $action Type of action.
|
338 |
+
* @return string[] List of tokens (usernames, roles etc).
|
339 |
*/
|
340 |
+
public function GetAccessTokens($action){
|
|
|
341 |
$allowed = array();
|
342 |
|
343 |
switch($action){
|
344 |
case 'view':
|
345 |
$allowed = $this->GetAllowedPluginViewers();
|
346 |
$allowed = array_merge($allowed, $this->GetAllowedPluginEditors());
|
347 |
+
if (!$this->IsRestrictAdmins()) {
|
348 |
+
$allowed = array_merge($allowed, $this->GetSuperAdmins());
|
349 |
+
$allowed = array_merge($allowed, $this->GetAdmins());
|
350 |
+
}
|
351 |
break;
|
352 |
case 'edit':
|
353 |
$allowed = $this->GetAllowedPluginEditors();
|
354 |
+
if (!$this->IsRestrictAdmins()) {
|
355 |
+
$allowed = array_merge($allowed, $this->_plugin->IsMultisite() ?
|
356 |
+
$this->GetSuperAdmins() : $this->GetAdmins()
|
357 |
+
);
|
358 |
+
}
|
359 |
break;
|
360 |
default:
|
361 |
throw new Exception('Unknown action "'.$action.'".');
|
362 |
}
|
363 |
|
364 |
+
if (!$this->IsRestrictAdmins()) {
|
365 |
+
if(is_multisite()){
|
366 |
+
$allowed = array_merge($allowed, get_super_admins());
|
367 |
+
}else{
|
368 |
+
$allowed[] = 'administrator';
|
369 |
+
}
|
370 |
+
}
|
371 |
+
|
372 |
+
return array_unique($allowed);
|
373 |
+
}
|
374 |
+
|
375 |
+
/**
|
376 |
+
* @param integer|WP_user $user User object to check.
|
377 |
+
* @param string $action Type of action, either 'view' or 'edit'.
|
378 |
+
* @return boolean If user has access or not.
|
379 |
+
*/
|
380 |
+
public function UserCan($user, $action){
|
381 |
+
if(is_int($user))$user = get_userdata($user);
|
382 |
+
|
383 |
+
$allowed = $this->GetAccessTokens($action);
|
384 |
+
|
385 |
$check = array_merge(
|
386 |
$user->roles,
|
387 |
array($user->user_login)
|
388 |
);
|
389 |
|
|
|
|
|
|
|
|
|
|
|
|
|
390 |
foreach($check as $item){
|
391 |
if(in_array($item, $allowed)){
|
392 |
return true;
|
396 |
return false;
|
397 |
}
|
398 |
|
399 |
+
public function GetCurrentUserRoles($baseRoles = null){
|
400 |
+
if ($baseRoles == null) $baseRoles = wp_get_current_user()->roles;
|
401 |
+
if (function_exists('is_super_admin') && is_super_admin()) $baseRoles[] = 'superadmin';
|
402 |
+
return $baseRoles;
|
403 |
+
}
|
404 |
+
|
405 |
public function IsIncognito(){
|
406 |
return $this->_plugin->GetGlobalOption('hide-plugin');
|
407 |
}
|
classes/SimpleProfiler.php
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_SimpleProfiler {
|
4 |
+
protected $_items = array();
|
5 |
+
|
6 |
+
public function Start($name) {
|
7 |
+
$item = new WSAL_SimpleProfiler_Item($name);
|
8 |
+
$this->_items[] = $item;
|
9 |
+
return $item;
|
10 |
+
}
|
11 |
+
|
12 |
+
public function AsComment(){
|
13 |
+
echo '<!-- ' . PHP_EOL;
|
14 |
+
foreach($this->_items as $item){
|
15 |
+
echo ' ' . $item . PHP_EOL;
|
16 |
+
}
|
17 |
+
echo '-->' . PHP_EOL;
|
18 |
+
}
|
19 |
+
|
20 |
+
public function GetItems(){
|
21 |
+
return $this->_items;
|
22 |
+
}
|
23 |
+
}
|
24 |
+
|
25 |
+
class WSAL_SimpleProfiler_Item{
|
26 |
+
public function __construct($name){
|
27 |
+
$this->name = $name;
|
28 |
+
$this->t_bgn = microtime(true);
|
29 |
+
$this->m_bgn = memory_get_usage();
|
30 |
+
}
|
31 |
+
|
32 |
+
public function Stop(){
|
33 |
+
$this->t_end = microtime(true);
|
34 |
+
$this->m_end = memory_get_usage();
|
35 |
+
}
|
36 |
+
|
37 |
+
public function __toString(){
|
38 |
+
$t_diff = $this->t_end - $this->t_bgn;
|
39 |
+
$m_diff = $this->m_end - $this->m_bgn;
|
40 |
+
return number_format($t_diff, 6) . 's '
|
41 |
+
. str_pad(number_format($m_diff, 0), 12, ' ', STR_PAD_LEFT) . 'b '
|
42 |
+
. $this->name;
|
43 |
+
}
|
44 |
+
}
|
classes/ViewManager.php
CHANGED
@@ -97,7 +97,8 @@ class WSAL_ViewManager {
|
|
97 |
'read', // no capability requirement
|
98 |
$this->views[0]->GetSafeViewName(),
|
99 |
array($this, 'RenderViewBody'),
|
100 |
-
$this->views[0]->GetIcon()
|
|
|
101 |
);
|
102 |
|
103 |
// add menu items
|
@@ -192,11 +193,11 @@ class WSAL_ViewManager {
|
|
192 |
*/
|
193 |
public function RenderViewBody(){
|
194 |
$view = $this->GetActiveView();
|
195 |
-
?><div class="wrap"
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
}
|
201 |
|
202 |
/**
|
97 |
'read', // no capability requirement
|
98 |
$this->views[0]->GetSafeViewName(),
|
99 |
array($this, 'RenderViewBody'),
|
100 |
+
$this->views[0]->GetIcon(),
|
101 |
+
'2.5' // right after dashboard
|
102 |
);
|
103 |
|
104 |
// add menu items
|
193 |
*/
|
194 |
public function RenderViewBody(){
|
195 |
$view = $this->GetActiveView();
|
196 |
+
?><div class="wrap"><?php
|
197 |
+
$view->RenderIcon();
|
198 |
+
$view->RenderTitle();
|
199 |
+
$view->RenderContent();
|
200 |
+
?></div><?php
|
201 |
}
|
202 |
|
203 |
/**
|
classes/Views/AuditLog.php
CHANGED
@@ -1,12 +1,13 @@
|
|
1 |
<?php
|
2 |
|
3 |
class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
4 |
-
|
|
|
|
|
5 |
protected $_listview;
|
6 |
|
7 |
public function __construct(WpSecurityAuditLog $plugin) {
|
8 |
parent::__construct($plugin);
|
9 |
-
$this->_listview = new WSAL_Views_AuditLogList_Internal($plugin);
|
10 |
add_action('wp_ajax_AjaxInspector', array($this, 'AjaxInspector'));
|
11 |
add_action('wp_ajax_AjaxRefresh', array($this, 'AjaxRefresh'));
|
12 |
add_action('wp_ajax_AjaxSetIpp', array($this, 'AjaxSetIpp'));
|
@@ -35,19 +36,26 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
35 |
return 1;
|
36 |
}
|
37 |
|
|
|
|
|
|
|
|
|
|
|
38 |
public function Render(){
|
39 |
if(!$this->_plugin->settings->CurrentUserCan('view')){
|
40 |
wp_die( __( 'You do not have sufficient permissions to access this page.' , 'wp-security-audit-log') );
|
41 |
}
|
42 |
|
43 |
-
$this->
|
44 |
|
45 |
?><form id="audit-log-viewer" method="post">
|
46 |
-
<
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
|
|
|
|
51 |
</form><?php
|
52 |
|
53 |
?><script type="text/javascript">
|
@@ -100,6 +108,8 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
100 |
$old = (int)$_REQUEST['logcount'];
|
101 |
$max = 40; // 40*500msec = 20sec
|
102 |
|
|
|
|
|
103 |
do{
|
104 |
$new = WSAL_DB_Occurrence::Count();
|
105 |
usleep(500000); // 500msec
|
@@ -129,7 +139,7 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
129 |
|
130 |
$search = $_REQUEST['search'];
|
131 |
|
132 |
-
foreach($this->
|
133 |
if(stripos($site->blogname, $search) !== false)
|
134 |
$grp1[] = $site;
|
135 |
else
|
@@ -160,325 +170,4 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
160 |
filemtime($this->_plugin->GetBaseDir() . '/js/auditlog.js')
|
161 |
);
|
162 |
}
|
163 |
-
|
164 |
-
}
|
165 |
-
|
166 |
-
require_once(ABSPATH . 'wp-admin/includes/admin.php');
|
167 |
-
require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
|
168 |
-
|
169 |
-
class WSAL_Views_AuditLogList_Internal extends WP_List_Table {
|
170 |
-
|
171 |
-
/**
|
172 |
-
* @var WpSecurityAuditLog
|
173 |
-
*/
|
174 |
-
protected $_plugin;
|
175 |
-
|
176 |
-
public function __construct($plugin){
|
177 |
-
$this->_plugin = $plugin;
|
178 |
-
|
179 |
-
$this->_gmt_offset_sec = get_option('gmt_offset') * HOUR_IN_SECONDS;
|
180 |
-
|
181 |
-
parent::__construct(array(
|
182 |
-
'singular' => 'log',
|
183 |
-
'plural' => 'logs',
|
184 |
-
'ajax' => true,
|
185 |
-
'screen' => 'interval-list',
|
186 |
-
));
|
187 |
-
}
|
188 |
-
|
189 |
-
protected $_gmt_offset_sec = 0;
|
190 |
-
|
191 |
-
public function no_items(){
|
192 |
-
_e('No events so far.', 'wp-security-audit-log');
|
193 |
-
}
|
194 |
-
|
195 |
-
public function extra_tablenav($which){
|
196 |
-
// items-per-page widget
|
197 |
-
$o = __('Other', 'wp-security-audit-log');
|
198 |
-
$p = $this->_plugin->settings->GetViewPerPage();
|
199 |
-
$items = array($o, 5, 10, 15, 30, 50);
|
200 |
-
if (!in_array($p, $items)) $items[] = $p;
|
201 |
-
if ($p == $o || $p == 0) $p = $o[1]; // a sane default if things goes bust
|
202 |
-
|
203 |
-
?><div class="wsal-ipp wsal-ipp-<?php echo $which; ?>">
|
204 |
-
<?php _e('Show ', 'wp-security-audit-log'); ?>
|
205 |
-
<select class="wsal-ipps" onfocus="WsalIppsFocus(value);" onchange="WsalIppsChange(value);">
|
206 |
-
<?php foreach($items as $item){ ?>
|
207 |
-
<option
|
208 |
-
value="<?php echo is_string($item) ? '' : $item; ?>"
|
209 |
-
<?php if($item == $p)echo 'selected="selected"'; ?>><?php
|
210 |
-
echo $item;
|
211 |
-
?></option>
|
212 |
-
<?php } ?>
|
213 |
-
</select>
|
214 |
-
<?php _e(' Items', 'wp-security-audit-log'); ?>
|
215 |
-
</div><?php
|
216 |
-
|
217 |
-
// show site alerts widget
|
218 |
-
if($this->is_multisite() && $this->is_main_blog()){
|
219 |
-
$curr = $this->get_view_site_id();
|
220 |
-
?><div class="wsal-ssa wsal-ssa-<?php echo $which; ?>">
|
221 |
-
<?php if($this->get_site_count() > 15){ ?>
|
222 |
-
<?php $curr = $curr ? get_blog_details($curr) : null; ?>
|
223 |
-
<?php $curr = $curr ? ($curr->blogname . ' (' . $curr->domain . ')') : 'All Sites'; ?>
|
224 |
-
<input type="text" class="wsal-ssas" value="<?php echo esc_attr($curr); ?>"/>
|
225 |
-
<?php }else{ ?>
|
226 |
-
<select class="wsal-ssas" onchange="WsalSsasChange(value);">
|
227 |
-
<option value="0"><?php _e('All Sites', 'wp-security-audit-log'); ?></option>
|
228 |
-
<?php foreach($this->get_sites() as $info){ ?>
|
229 |
-
<option value="<?php echo $info->blog_id; ?>"
|
230 |
-
<?php if($info->blog_id == $curr)echo 'selected="selected"'; ?>><?php
|
231 |
-
echo esc_html($info->blogname) . ' (' . esc_html($info->domain) . ')';
|
232 |
-
?></option>
|
233 |
-
<?php } ?>
|
234 |
-
</select>
|
235 |
-
<?php } ?>
|
236 |
-
</div><?php
|
237 |
-
}
|
238 |
-
}
|
239 |
-
|
240 |
-
/**
|
241 |
-
* @param int|null $limit Maximum number of sites to return (null = no limit).
|
242 |
-
* @return object Object with keys: blog_id, blogname, domain
|
243 |
-
*/
|
244 |
-
public function get_sites($limit = null){
|
245 |
-
global $wpdb;
|
246 |
-
|
247 |
-
// build query
|
248 |
-
$sql = 'SELECT blog_id, domain FROM ' . $wpdb->blogs;
|
249 |
-
if(!is_null($limit))$sql .= ' LIMIT ' . $limit;
|
250 |
-
|
251 |
-
// execute query
|
252 |
-
$res = $wpdb->get_results($sql);
|
253 |
-
|
254 |
-
// modify result
|
255 |
-
foreach($res as $row){
|
256 |
-
$row->blogname = get_blog_option($row->blog_id, 'blogname');
|
257 |
-
}
|
258 |
-
|
259 |
-
// return result
|
260 |
-
return $res;
|
261 |
-
}
|
262 |
-
|
263 |
-
/**
|
264 |
-
* @return int The number of sites on the network.
|
265 |
-
*/
|
266 |
-
public function get_site_count(){
|
267 |
-
global $wpdb;
|
268 |
-
$sql = 'SELECT COUNT(*) FROM ' . $wpdb->blogs;
|
269 |
-
return (int)$wpdb->get_var($sql);
|
270 |
-
}
|
271 |
-
|
272 |
-
public function get_columns(){
|
273 |
-
$cols = array(
|
274 |
-
//'cb' => '<input type="checkbox" />',
|
275 |
-
//'read' => __('Read', 'wp-security-audit-log'),
|
276 |
-
'type' => __('Code', 'wp-security-audit-log'),
|
277 |
-
'code' => __('Type', 'wp-security-audit-log'),
|
278 |
-
'crtd' => __('Date', 'wp-security-audit-log'),
|
279 |
-
'user' => __('Username', 'wp-security-audit-log'),
|
280 |
-
'scip' => __('Source IP', 'wp-security-audit-log'),
|
281 |
-
);
|
282 |
-
if($this->is_multisite() && $this->is_main_blog() && !$this->is_specific_view()){
|
283 |
-
$cols['site'] = __('Site', 'wp-security-audit-log');
|
284 |
-
}
|
285 |
-
$cols['mesg'] = __('Message', 'wp-security-audit-log');
|
286 |
-
if($this->_plugin->settings->IsDataInspectorEnabled()){
|
287 |
-
$cols['data'] = '';
|
288 |
-
}
|
289 |
-
return $cols;
|
290 |
-
}
|
291 |
-
|
292 |
-
public function column_cb(WSAL_DB_Occurrence $item){
|
293 |
-
return '<input type="checkbox" value="'.$item->id.'" '
|
294 |
-
. 'name="'.esc_attr($this->_args['singular']).'[]"/>';
|
295 |
-
}
|
296 |
-
|
297 |
-
public function get_sortable_columns(){
|
298 |
-
return array(
|
299 |
-
'read' => array('is_read', false),
|
300 |
-
'code' => array('code', false),
|
301 |
-
'type' => array('alert_id', false),
|
302 |
-
'crtd' => array('created_on', true),
|
303 |
-
'user' => array('user', false),
|
304 |
-
'scip' => array('scip', false),
|
305 |
-
'site' => array('site', false),
|
306 |
-
);
|
307 |
-
}
|
308 |
-
|
309 |
-
public function column_default(WSAL_DB_Occurrence $item, $column_name){
|
310 |
-
switch($column_name){
|
311 |
-
case 'read':
|
312 |
-
return '<span class="log-read log-read-'
|
313 |
-
. ($item->is_read ? 'old' : 'new')
|
314 |
-
. '" title="' . __('Click to toggle.', 'wp-security-audit-log') . '"></span>';
|
315 |
-
case 'type':
|
316 |
-
return str_pad($item->alert_id, 4, '0', STR_PAD_LEFT);
|
317 |
-
case 'code':
|
318 |
-
$code = $this->_plugin->alerts->GetAlert($item->alert_id);
|
319 |
-
$code = $code ? $code->code : 0;
|
320 |
-
$const = (object)array('name' => 'E_UNKNOWN', 'value' => 0, 'description' => __('Unknown error code.', 'wp-security-audit-log'));
|
321 |
-
$const = $this->_plugin->constants->GetConstantBy('value', $code, $const);
|
322 |
-
return '<span class="log-type log-type-' . $const->value
|
323 |
-
. '" title="' . esc_html($const->name . ': ' . $const->description) . '"></span>';
|
324 |
-
case 'crtd':
|
325 |
-
return $item->created_on ? (
|
326 |
-
str_replace(
|
327 |
-
'$$$',
|
328 |
-
substr(number_format(fmod($item->created_on + $this->_gmt_offset_sec, 1), 3), 2),
|
329 |
-
date('Y-m-d<\b\r>h:i:s.$$$&\n\b\s\p;A', $item->created_on + $this->_gmt_offset_sec)
|
330 |
-
)
|
331 |
-
) : '<i>unknown</i>';
|
332 |
-
case 'user':
|
333 |
-
$username = $item->GetUsername();
|
334 |
-
if($username && ($user = get_user_by('login', $username))){
|
335 |
-
$image = get_avatar($user->ID, 32);
|
336 |
-
$uhtml = '<a href="' . admin_url('user-edit.php?user_id=' . $user->ID)
|
337 |
-
. '" target="_blank">' . esc_html($user->display_name) . '</a>';
|
338 |
-
$roles = $item->GetUserRoles();
|
339 |
-
$roles = (is_array($roles) && count($roles))
|
340 |
-
? __(esc_html(ucwords(implode(', ', $roles))))
|
341 |
-
: '<i>' . __('Unknown', 'wp-security-audit-log') . '</i>';
|
342 |
-
}else{
|
343 |
-
$image = get_avatar(0, 32);
|
344 |
-
$uhtml = '<i>' . __('Unknown', 'wp-security-audit-log') . '</i>';
|
345 |
-
$roles = '<i>' . __('System', 'wp-security-audit-log') . '</i>';
|
346 |
-
}
|
347 |
-
return $image . $uhtml . '<br/>' . $roles;
|
348 |
-
case 'scip':
|
349 |
-
return !is_null($item->GetSourceIP()) ? esc_html($item->GetSourceIP()) : '<i>unknown</i>';
|
350 |
-
case 'site':
|
351 |
-
$info = get_blog_details($item->site_id, true);
|
352 |
-
return !$info ? ('Unknown Site '.$item->site_id)
|
353 |
-
: ('<a href="' . esc_attr($info->siteurl) . '">' . esc_html($info->blogname) . '</a>');
|
354 |
-
case 'mesg':
|
355 |
-
return '<div id="Event' . $item->id . '">' . $item->GetMessage(array($this, 'meta_formatter')) . '</div>';
|
356 |
-
case 'data':
|
357 |
-
$url = admin_url('admin-ajax.php') . '?action=AjaxInspector&occurrence=' . $item->id;
|
358 |
-
return '<a class="more-info thickbox" title="' . __('Alert Data Inspector', 'wp-security-audit-log') . '"'
|
359 |
-
. ' href="' . $url . '&TB_iframe=true&width=600&height=550">…</a>';
|
360 |
-
default:
|
361 |
-
return isset($item->$column_name)
|
362 |
-
? esc_html($item->$column_name)
|
363 |
-
: 'Column "' . esc_html($column_name) . '" not found';
|
364 |
-
}
|
365 |
-
}
|
366 |
-
|
367 |
-
public function reorder_items_str($a, $b){
|
368 |
-
$result = strcmp($a->{$this->_orderby}, $b->{$this->_orderby});
|
369 |
-
return ($this->_order === 'asc') ? $result : -$result;
|
370 |
-
}
|
371 |
-
|
372 |
-
public function reorder_items_int($a, $b){
|
373 |
-
$result = $a->{$this->_orderby} - $b->{$this->_orderby};
|
374 |
-
return ($this->_order === 'asc') ? $result : -$result;
|
375 |
-
}
|
376 |
-
|
377 |
-
public function meta_formatter($name, $value){
|
378 |
-
switch(true){
|
379 |
-
|
380 |
-
case $name == '%Message%':
|
381 |
-
return esc_html($value);
|
382 |
-
|
383 |
-
case in_array($name, array('%MetaValue%', '%MetaValueOld%', '%MetaValueNew%')):
|
384 |
-
return '<strong>' . (
|
385 |
-
strlen($value) > 50 ? (esc_html(substr($value, 0, 50)) . '…') : esc_html($value)
|
386 |
-
) . '</strong>';
|
387 |
-
|
388 |
-
case strncmp($value, 'http://', 7) === 0:
|
389 |
-
case strncmp($value, 'https://', 7) === 0:
|
390 |
-
return '<a href="' . esc_html($value) . '"'
|
391 |
-
. ' title="' . esc_html($value) . '"'
|
392 |
-
. ' target="_blank">'
|
393 |
-
. esc_html(parse_url($value, PHP_URL_HOST)) . '/…/'
|
394 |
-
. esc_html(basename(parse_url($value, PHP_URL_PATH)))
|
395 |
-
. '</a>';
|
396 |
-
|
397 |
-
default:
|
398 |
-
return '<strong>' . esc_html($value) . '</strong>';
|
399 |
-
}
|
400 |
-
}
|
401 |
-
|
402 |
-
protected function is_multisite(){
|
403 |
-
return $this->_plugin->IsMultisite();
|
404 |
-
}
|
405 |
-
|
406 |
-
protected function is_main_blog(){
|
407 |
-
return get_current_blog_id() == 1;
|
408 |
-
}
|
409 |
-
|
410 |
-
protected function is_specific_view(){
|
411 |
-
return isset($_REQUEST['wsal-cbid']) && $_REQUEST['wsal-cbid'] != '0';
|
412 |
-
}
|
413 |
-
|
414 |
-
protected function get_specific_view(){
|
415 |
-
return isset($_REQUEST['wsal-cbid']) ? (int)$_REQUEST['wsal-cbid'] : 0;
|
416 |
-
}
|
417 |
-
|
418 |
-
protected function get_view_site_id(){
|
419 |
-
switch(true){
|
420 |
-
|
421 |
-
// non-multisite
|
422 |
-
case !$this->is_multisite():
|
423 |
-
return 0;
|
424 |
-
|
425 |
-
// multisite + main site view
|
426 |
-
case $this->is_main_blog() && !$this->is_specific_view():
|
427 |
-
return 0;
|
428 |
-
|
429 |
-
// multisite + switched site view
|
430 |
-
case $this->is_main_blog() && $this->is_specific_view():
|
431 |
-
return $this->get_specific_view();
|
432 |
-
|
433 |
-
// multisite + local site view
|
434 |
-
default:
|
435 |
-
return get_current_blog_id();
|
436 |
-
|
437 |
-
}
|
438 |
-
}
|
439 |
-
|
440 |
-
public function prepare_items() {
|
441 |
-
$per_page = $this->_plugin->settings->GetViewPerPage();
|
442 |
-
|
443 |
-
$columns = $this->get_columns();
|
444 |
-
$hidden = array();
|
445 |
-
$sortable = $this->get_sortable_columns();
|
446 |
-
|
447 |
-
$this->_column_headers = array($columns, $hidden, $sortable);
|
448 |
-
|
449 |
-
//$this->process_bulk_action();
|
450 |
-
|
451 |
-
$query = new WSAL_DB_Query('WSAL_DB_Occurrence');
|
452 |
-
$bid = (int)$this->get_view_site_id();
|
453 |
-
if ($bid) $query->where[] = 'site_id = '.$bid;
|
454 |
-
$query->order[] = 'created_on DESC';
|
455 |
-
|
456 |
-
$data = apply_filters('wsal_auditlog_query', $query);
|
457 |
-
|
458 |
-
$data = $query->Execute();
|
459 |
-
|
460 |
-
if(count($data)){
|
461 |
-
$this->_orderby = (!empty($_REQUEST['orderby']) && isset($sortable[$_REQUEST['orderby']])) ? $_REQUEST['orderby'] : 'created_on';
|
462 |
-
$this->_order = (!empty($_REQUEST['order']) && $_REQUEST['order']=='asc') ? 'asc' : 'desc';
|
463 |
-
if(isset($data[0]->{$this->_orderby})){
|
464 |
-
$numorder = in_array($this->_orderby, array('code', 'type', 'created_on'));
|
465 |
-
usort($data, array($this, $numorder ? 'reorder_items_int' : 'reorder_items_str'));
|
466 |
-
}
|
467 |
-
}
|
468 |
-
|
469 |
-
$current_page = $this->get_pagenum();
|
470 |
-
|
471 |
-
$total_items = count($data);
|
472 |
-
|
473 |
-
$data = array_slice($data, ($current_page - 1) * $per_page, $per_page);
|
474 |
-
|
475 |
-
$this->items = $data;
|
476 |
-
|
477 |
-
$this->set_pagination_args( array(
|
478 |
-
'total_items' => $total_items,
|
479 |
-
'per_page' => $per_page,
|
480 |
-
'total_pages' => ceil($total_items / $per_page)
|
481 |
-
) );
|
482 |
-
}
|
483 |
-
|
484 |
}
|
1 |
<?php
|
2 |
|
3 |
class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
4 |
+
/**
|
5 |
+
* @var WSAL_AuditLogListView
|
6 |
+
*/
|
7 |
protected $_listview;
|
8 |
|
9 |
public function __construct(WpSecurityAuditLog $plugin) {
|
10 |
parent::__construct($plugin);
|
|
|
11 |
add_action('wp_ajax_AjaxInspector', array($this, 'AjaxInspector'));
|
12 |
add_action('wp_ajax_AjaxRefresh', array($this, 'AjaxRefresh'));
|
13 |
add_action('wp_ajax_AjaxSetIpp', array($this, 'AjaxSetIpp'));
|
36 |
return 1;
|
37 |
}
|
38 |
|
39 |
+
protected function GetListView(){
|
40 |
+
if (is_null($this->_listview)) $this->_listview = new WSAL_AuditLogListView($this->_plugin);
|
41 |
+
return $this->_listview;
|
42 |
+
}
|
43 |
+
|
44 |
public function Render(){
|
45 |
if(!$this->_plugin->settings->CurrentUserCan('view')){
|
46 |
wp_die( __( 'You do not have sufficient permissions to access this page.' , 'wp-security-audit-log') );
|
47 |
}
|
48 |
|
49 |
+
$this->GetListView()->prepare_items();
|
50 |
|
51 |
?><form id="audit-log-viewer" method="post">
|
52 |
+
<div id="audit-log-viewer-content">
|
53 |
+
<input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>" />
|
54 |
+
<input type="hidden" id="wsal-cbid" name="wsal-cbid" value="<?php echo esc_attr(isset($_REQUEST['wsal-cbid']) ? $_REQUEST['wsal-cbid'] : ''); ?>" />
|
55 |
+
<?php do_action('wsal_auditlog_before_view', $this->GetListView()); ?>
|
56 |
+
<?php $this->GetListView()->display(); ?>
|
57 |
+
<?php do_action('wsal_auditlog_after_view', $this->GetListView()); ?>
|
58 |
+
</div>
|
59 |
</form><?php
|
60 |
|
61 |
?><script type="text/javascript">
|
108 |
$old = (int)$_REQUEST['logcount'];
|
109 |
$max = 40; // 40*500msec = 20sec
|
110 |
|
111 |
+
session_write_close(); // fixes session lock issue
|
112 |
+
|
113 |
do{
|
114 |
$new = WSAL_DB_Occurrence::Count();
|
115 |
usleep(500000); // 500msec
|
139 |
|
140 |
$search = $_REQUEST['search'];
|
141 |
|
142 |
+
foreach($this->GetListView()->get_sites() as $site){
|
143 |
if(stripos($site->blogname, $search) !== false)
|
144 |
$grp1[] = $site;
|
145 |
else
|
170 |
filemtime($this->_plugin->GetBaseDir() . '/js/auditlog.js')
|
171 |
);
|
172 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
173 |
}
|
classes/Views/Licensing.php
CHANGED
@@ -65,13 +65,13 @@ class WSAL_Views_Licensing extends WSAL_AbstractView {
|
|
65 |
<input type="text" style="width: 360px; margin: 6px 0;"
|
66 |
name="license[<?php echo esc_attr($name); ?>]"
|
67 |
value="<?php echo esc_attr($licenseKey); ?>"/>
|
68 |
-
</td><td>
|
69 |
<?php if($licenseKey){ ?>
|
70 |
<?php if($licenseStatus === 'valid'){ ?>
|
71 |
<?php _e('Active', 'wp-security-audit-log'); ?>
|
72 |
<?php }else{ ?>
|
73 |
<?php _e('Inactive', 'wp-security-audit-log'); ?><br/>
|
74 |
-
|
75 |
<?php } ?>
|
76 |
<?php } ?>
|
77 |
</td>
|
65 |
<input type="text" style="width: 360px; margin: 6px 0;"
|
66 |
name="license[<?php echo esc_attr($name); ?>]"
|
67 |
value="<?php echo esc_attr($licenseKey); ?>"/>
|
68 |
+
</td><td style="vertical-align: middle;">
|
69 |
<?php if($licenseKey){ ?>
|
70 |
<?php if($licenseStatus === 'valid'){ ?>
|
71 |
<?php _e('Active', 'wp-security-audit-log'); ?>
|
72 |
<?php }else{ ?>
|
73 |
<?php _e('Inactive', 'wp-security-audit-log'); ?><br/>
|
74 |
+
<small><?php echo esc_html($licenseErrors); ?></small>
|
75 |
<?php } ?>
|
76 |
<?php } ?>
|
77 |
</td>
|
classes/Views/Sandbox.php
CHANGED
@@ -77,6 +77,12 @@ class DummySiteCreatorTask extends WSAL_AbstractSandboxTask {
|
|
77 |
}
|
78 |
}
|
79 |
new DummySiteCreatorTask();',
|
|
|
|
|
|
|
|
|
|
|
|
|
80 |
);
|
81 |
|
82 |
public function HandleError($code, $message, $filename = 'unknown', $lineno = 0){
|
@@ -192,8 +198,7 @@ new DummySiteCreatorTask();',
|
|
192 |
</div>
|
193 |
<label for="sandbox-snippet" style="float: left; line-height: 26px; display: inline-block; margin-right: 32px; border-right: 1px dotted #CCC; padding-right: 32px;">
|
194 |
Use Snippet:
|
195 |
-
|
196 |
-
<select id="sandbox-snippet" onchange="location = <?php echo esc_attr($code); ?> + encodeURIComponent(this.value);"><?php
|
197 |
foreach(array_keys($this->snippets) as $name){
|
198 |
?><option value="<?php echo esc_attr($name); ?>"<?php if($name == $snpt)echo ' selected="selected"'; ?>><?php echo $name; ?></option><?php
|
199 |
}
|
@@ -262,6 +267,12 @@ new DummySiteCreatorTask();',
|
|
262 |
//jQuery('#sandbox').submit();
|
263 |
});
|
264 |
|
|
|
|
|
|
|
|
|
|
|
|
|
265 |
function SandboxUpdateState(data){
|
266 |
var ul = jQuery('<ul/>');
|
267 |
for(var key in data)
|
77 |
}
|
78 |
}
|
79 |
new DummySiteCreatorTask();',
|
80 |
+
'Get Access Tokens' => '$settings = WpSecurityAuditLog::GetInstance()->settings;
|
81 |
+
return array(
|
82 |
+
\'view\' => $settings->GetAccessTokens(\'view\'),
|
83 |
+
\'edit\' => $settings->GetAccessTokens(\'edit\'),
|
84 |
+
);',
|
85 |
+
'Show Profiler Results' => 'return array_map(\'strval\', WpSecurityAuditLog::GetInstance()->profiler->GetItems());'
|
86 |
);
|
87 |
|
88 |
public function HandleError($code, $message, $filename = 'unknown', $lineno = 0){
|
198 |
</div>
|
199 |
<label for="sandbox-snippet" style="float: left; line-height: 26px; display: inline-block; margin-right: 32px; border-right: 1px dotted #CCC; padding-right: 32px;">
|
200 |
Use Snippet:
|
201 |
+
<select id="sandbox-snippet" onchange="SandboxUseSnippet(this.value);"><?php
|
|
|
202 |
foreach(array_keys($this->snippets) as $name){
|
203 |
?><option value="<?php echo esc_attr($name); ?>"<?php if($name == $snpt)echo ' selected="selected"'; ?>><?php echo $name; ?></option><?php
|
204 |
}
|
267 |
//jQuery('#sandbox').submit();
|
268 |
});
|
269 |
|
270 |
+
function SandboxUseSnippet(value){
|
271 |
+
jQuery('#sandbox-submit').attr('disabled', true);
|
272 |
+
location = <?php echo json_encode(admin_url('admin.php?page=wsal-sandbox')); ?>
|
273 |
+
+ '&snippet=' + encodeURIComponent(value);
|
274 |
+
}
|
275 |
+
|
276 |
function SandboxUpdateState(data){
|
277 |
var ul = jQuery('<ul/>');
|
278 |
for(var key in data)
|
classes/Views/Settings.php
CHANGED
@@ -4,7 +4,10 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
4 |
|
5 |
public function __construct(WpSecurityAuditLog $plugin) {
|
6 |
parent::__construct($plugin);
|
7 |
-
|
|
|
|
|
|
|
8 |
}
|
9 |
|
10 |
public function HasPluginShortcutLink(){
|
@@ -47,6 +50,7 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
47 |
$this->_plugin->settings->SetWidgetsEnabled($_REQUEST['EnableDashboardWidgets']);
|
48 |
$this->_plugin->settings->SetAllowedPluginViewers(isset($_REQUEST['Viewers']) ? $_REQUEST['Viewers'] : array());
|
49 |
$this->_plugin->settings->SetAllowedPluginEditors(isset($_REQUEST['Editors']) ? $_REQUEST['Editors'] : array());
|
|
|
50 |
$this->_plugin->settings->SetRefreshAlertsEnabled($_REQUEST['EnableAuditViewRefresh']);
|
51 |
$this->_plugin->settings->SetIncognito(isset($_REQUEST['Incognito']));
|
52 |
$this->_plugin->settings->ClearDevOptions();
|
@@ -63,6 +67,14 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
63 |
die($this->GetTokenType($_REQUEST['token']));
|
64 |
}
|
65 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
public function Render(){
|
67 |
if(!$this->_plugin->settings->CurrentUserCan('edit')){
|
68 |
wp_die( __( 'You do not have sufficient permissions to access this page.' , 'wp-security-audit-log') );
|
@@ -97,11 +109,6 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
97 |
value="<?php echo esc_attr($this->_plugin->settings->GetPruningDate()); ?>"/>
|
98 |
<span> <?php echo $text; ?></span>
|
99 |
</fieldset>
|
100 |
-
</td>
|
101 |
-
</tr>
|
102 |
-
<tr>
|
103 |
-
<th></th>
|
104 |
-
<td>
|
105 |
<fieldset>
|
106 |
<?php $text = __('(eg: 80)', 'wp-security-audit-log'); ?>
|
107 |
<?php $nbld = $this->_plugin->settings->IsPruningLimitEnabled(); ?>
|
@@ -115,6 +122,15 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
115 |
<?php echo __('alerts', 'wp-security-audit-log'); ?>
|
116 |
<span><?php echo $text; ?></span>
|
117 |
</fieldset>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
118 |
</td>
|
119 |
</tr>
|
120 |
<tr>
|
@@ -185,6 +201,21 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
185 |
</fieldset>
|
186 |
</td>
|
187 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
188 |
<tr>
|
189 |
<th><label for="aroption_on"><?php _e('Refresh Audit View', 'wp-security-audit-log'); ?></label></th>
|
190 |
<td>
|
4 |
|
5 |
public function __construct(WpSecurityAuditLog $plugin) {
|
6 |
parent::__construct($plugin);
|
7 |
+
if (is_admin()) {
|
8 |
+
add_action('wp_ajax_AjaxCheckSecurityToken', array($this, 'AjaxCheckSecurityToken'));
|
9 |
+
add_action('wp_ajax_AjaxRunCleanup', array($this, 'AjaxRunCleanup'));
|
10 |
+
}
|
11 |
}
|
12 |
|
13 |
public function HasPluginShortcutLink(){
|
50 |
$this->_plugin->settings->SetWidgetsEnabled($_REQUEST['EnableDashboardWidgets']);
|
51 |
$this->_plugin->settings->SetAllowedPluginViewers(isset($_REQUEST['Viewers']) ? $_REQUEST['Viewers'] : array());
|
52 |
$this->_plugin->settings->SetAllowedPluginEditors(isset($_REQUEST['Editors']) ? $_REQUEST['Editors'] : array());
|
53 |
+
$this->_plugin->settings->SetRestrictAdmins(isset($_REQUEST['RestrictAdmins']));
|
54 |
$this->_plugin->settings->SetRefreshAlertsEnabled($_REQUEST['EnableAuditViewRefresh']);
|
55 |
$this->_plugin->settings->SetIncognito(isset($_REQUEST['Incognito']));
|
56 |
$this->_plugin->settings->ClearDevOptions();
|
67 |
die($this->GetTokenType($_REQUEST['token']));
|
68 |
}
|
69 |
|
70 |
+
public function AjaxRunCleanup(){
|
71 |
+
if(!$this->_plugin->settings->CurrentUserCan('view'))
|
72 |
+
die('Access Denied.');
|
73 |
+
$this->_plugin->CleanUp();
|
74 |
+
wp_redirect($this->GetUrl());
|
75 |
+
exit;
|
76 |
+
}
|
77 |
+
|
78 |
public function Render(){
|
79 |
if(!$this->_plugin->settings->CurrentUserCan('edit')){
|
80 |
wp_die( __( 'You do not have sufficient permissions to access this page.' , 'wp-security-audit-log') );
|
109 |
value="<?php echo esc_attr($this->_plugin->settings->GetPruningDate()); ?>"/>
|
110 |
<span> <?php echo $text; ?></span>
|
111 |
</fieldset>
|
|
|
|
|
|
|
|
|
|
|
112 |
<fieldset>
|
113 |
<?php $text = __('(eg: 80)', 'wp-security-audit-log'); ?>
|
114 |
<?php $nbld = $this->_plugin->settings->IsPruningLimitEnabled(); ?>
|
122 |
<?php echo __('alerts', 'wp-security-audit-log'); ?>
|
123 |
<span><?php echo $text; ?></span>
|
124 |
</fieldset>
|
125 |
+
<p class="description"><?php
|
126 |
+
echo __('Next Scheduled Cleanup is in ', 'wp-security-audit-log');
|
127 |
+
echo human_time_diff(current_time('timestamp'), $next = wp_next_scheduled('wsal_cleanup'));
|
128 |
+
echo '<!-- ' . date('dMy H:i:s', $next) . ' --> ';
|
129 |
+
echo sprintf(
|
130 |
+
__('(or %s)', 'wp-security-audit-log'),
|
131 |
+
'<a href="' . admin_url('admin-ajax.php?action=AjaxRunCleanup') . '">' . __('Run Manually', 'wp-security-audit-log') . '</a>'
|
132 |
+
);
|
133 |
+
?></p>
|
134 |
</td>
|
135 |
</tr>
|
136 |
<tr>
|
201 |
</fieldset>
|
202 |
</td>
|
203 |
</tr>
|
204 |
+
<tr>
|
205 |
+
<th><label for="RestrictAdmins"><?php _e('Restrict Plugin Access', 'wp-security-audit-log'); ?></label></th>
|
206 |
+
<td>
|
207 |
+
<fieldset>
|
208 |
+
<input type="hidden" id="RestrictAdminsDefaultUser" value="<?php echo esc_attr(wp_get_current_user()->user_login); ?>"/>
|
209 |
+
<label for="RestrictAdmins">
|
210 |
+
<?php $ira = $this->_plugin->settings->IsRestrictAdmins(); ?>
|
211 |
+
<input type="checkbox" name="RestrictAdmins" id="RestrictAdmins"<?php if($ira)echo ' checked="checked"'; ?>/>
|
212 |
+
<span class="description">
|
213 |
+
<?php _e('By default all the administrators on this WordPress have access to manage this plugin.<br/>By enabling this option only the users specified in the two options above and your username will have access to view alerts and manage this plugin.', 'wp-security-audit-log'); ?>
|
214 |
+
</span>
|
215 |
+
</label>
|
216 |
+
</fieldset>
|
217 |
+
</td>
|
218 |
+
</tr>
|
219 |
<tr>
|
220 |
<th><label for="aroption_on"><?php _e('Refresh Audit View', 'wp-security-audit-log'); ?></label></th>
|
221 |
<td>
|
classes/WidgetManager.php
CHANGED
@@ -39,7 +39,7 @@ class WSAL_WidgetManager {
|
|
39 |
</thead>
|
40 |
<tbody><?php
|
41 |
$url = 'admin.php?page=' . $this->_plugin->views->views[0]->GetSafeViewName();
|
42 |
-
$fmt = array(new
|
43 |
foreach($results as $entry){
|
44 |
?><tr>
|
45 |
<td><?php
|
39 |
</thead>
|
40 |
<tbody><?php
|
41 |
$url = 'admin.php?page=' . $this->_plugin->views->views[0]->GetSafeViewName();
|
42 |
+
$fmt = array(new WSAL_AuditLogListView($this->_plugin), 'meta_formatter');
|
43 |
foreach($results as $entry){
|
44 |
?><tr>
|
45 |
<td><?php
|
defaults.php
CHANGED
@@ -71,7 +71,7 @@ function wsaldefaults_wsal_init(WpSecurityAuditLog $wsal){
|
|
71 |
array(2004, E_NOTICE, __('User created a new WordPress page and saved it as draft', 'wp-security-audit-log'), __('Created a new page called %PostTitle%. Page ID is %PostID%', 'wp-security-audit-log')),
|
72 |
array(2005, E_NOTICE, __('User published a WorPress page', 'wp-security-audit-log'), __('Published a page called %PostTitle%. Page URL is %PostUrl%', 'wp-security-audit-log')),
|
73 |
array(2006, E_NOTICE, __('User modified a published WordPress page', 'wp-security-audit-log'), __('Modified the published page %PostTitle%. Page URL is %PostUrl%', 'wp-security-audit-log')),
|
74 |
-
array(2007, E_NOTICE, __('User modified a draft WordPress page', 'wp-security-audit-log'), __('Modified the draft page %PostTitle%.
|
75 |
array(2009, E_NOTICE, __('User permanently deleted a page from the trash', 'wp-security-audit-log'), __('Deleted the page %PostTitle%. Page ID is %PostID%', 'wp-security-audit-log')),
|
76 |
array(2013, E_WARNING, __('User moved WordPress page to the trash', 'wp-security-audit-log'), __('Moved the page %PostTitle% to trash', 'wp-security-audit-log')),
|
77 |
array(2015, E_CRITICAL, __('User restored a WordPress page from trash', 'wp-security-audit-log'), __('Restored page %PostTitle% from trash', 'wp-security-audit-log')),
|
71 |
array(2004, E_NOTICE, __('User created a new WordPress page and saved it as draft', 'wp-security-audit-log'), __('Created a new page called %PostTitle%. Page ID is %PostID%', 'wp-security-audit-log')),
|
72 |
array(2005, E_NOTICE, __('User published a WorPress page', 'wp-security-audit-log'), __('Published a page called %PostTitle%. Page URL is %PostUrl%', 'wp-security-audit-log')),
|
73 |
array(2006, E_NOTICE, __('User modified a published WordPress page', 'wp-security-audit-log'), __('Modified the published page %PostTitle%. Page URL is %PostUrl%', 'wp-security-audit-log')),
|
74 |
+
array(2007, E_NOTICE, __('User modified a draft WordPress page', 'wp-security-audit-log'), __('Modified the draft page %PostTitle%. Page ID is %PostID%', 'wp-security-audit-log')),
|
75 |
array(2009, E_NOTICE, __('User permanently deleted a page from the trash', 'wp-security-audit-log'), __('Deleted the page %PostTitle%. Page ID is %PostID%', 'wp-security-audit-log')),
|
76 |
array(2013, E_WARNING, __('User moved WordPress page to the trash', 'wp-security-audit-log'), __('Moved the page %PostTitle% to trash', 'wp-security-audit-log')),
|
77 |
array(2015, E_CRITICAL, __('User restored a WordPress page from trash', 'wp-security-audit-log'), __('Restored page %PostTitle% from trash', 'wp-security-audit-log')),
|
js/auditlog.js
CHANGED
@@ -1,5 +1,7 @@
|
|
1 |
var WsalData;
|
2 |
|
|
|
|
|
3 |
function WsalAuditLogInit(_WsalData){
|
4 |
WsalData = _WsalData;
|
5 |
var WsalTkn = WsalData.autorefresh.token;
|
@@ -15,7 +17,10 @@ function WsalAuditLogInit(_WsalData){
|
|
15 |
WsalAjx = null;
|
16 |
if(data && data !== 'false'){
|
17 |
WsalTkn = data;
|
18 |
-
jQuery('#audit-log-viewer').load(
|
|
|
|
|
|
|
19 |
}
|
20 |
WsalChk();
|
21 |
});
|
1 |
var WsalData;
|
2 |
|
3 |
+
window['WsalAuditLogRefreshed'] = function(){};
|
4 |
+
|
5 |
function WsalAuditLogInit(_WsalData){
|
6 |
WsalData = _WsalData;
|
7 |
var WsalTkn = WsalData.autorefresh.token;
|
17 |
WsalAjx = null;
|
18 |
if(data && data !== 'false'){
|
19 |
WsalTkn = data;
|
20 |
+
jQuery('#audit-log-viewer').load(
|
21 |
+
location.href + ' #audit-log-viewer-content',
|
22 |
+
window['WsalAuditLogRefreshed']
|
23 |
+
);
|
24 |
}
|
25 |
WsalChk();
|
26 |
});
|
js/settings.js
CHANGED
@@ -34,4 +34,16 @@ jQuery(document).ready(function(){
|
|
34 |
});
|
35 |
|
36 |
jQuery('#ViewerList>span>a, #EditorList>span>a').click(RemoveSecToken);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
});
|
34 |
});
|
35 |
|
36 |
jQuery('#ViewerList>span>a, #EditorList>span>a').click(RemoveSecToken);
|
37 |
+
|
38 |
+
jQuery('#RestrictAdmins').change(function(){
|
39 |
+
var user = jQuery('#RestrictAdminsDefaultUser').val();
|
40 |
+
var fltr = function() { return this.value === user; };
|
41 |
+
if (this.checked && jQuery('#EditorList input').filter(fltr).length === 0) {
|
42 |
+
jQuery('#EditorList').append(
|
43 |
+
jQuery('<span class="sectoken-user"/>').text(user)
|
44 |
+
.prepend(jQuery('<input type="hidden" name="Editors[]"/>').val(user))
|
45 |
+
.append(jQuery('<a href="javascript:;" title="Remove">×</a>').click(RemoveSecToken))
|
46 |
+
);
|
47 |
+
}
|
48 |
+
});
|
49 |
});
|
languages/wp-security-audit-log.pot
CHANGED
@@ -2,9 +2,9 @@
|
|
2 |
# This file is distributed under the same license as the WP Security Audit Log package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
-
"Project-Id-Version: WP Security Audit Log 1.2.
|
6 |
"Report-Msgid-Bugs-To: http://wordpress.org/tag/wp-security-audit-log\n"
|
7 |
-
"POT-Creation-Date: 2014-
|
8 |
"MIME-Version: 1.0\n"
|
9 |
"Content-Type: text/plain; charset=UTF-8\n"
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
@@ -136,91 +136,27 @@ msgstr ""
|
|
136 |
msgid "Professional WordPress security services provided by WP White Security"
|
137 |
msgstr ""
|
138 |
|
139 |
-
#: classes/Views/AuditLog.php:
|
140 |
msgid "Audit Log Viewer"
|
141 |
msgstr ""
|
142 |
|
143 |
-
#: classes/Views/AuditLog.php:
|
144 |
-
#: classes/Views/Settings.php:
|
145 |
msgid "You do not have sufficient permissions to access this page."
|
146 |
msgstr ""
|
147 |
|
148 |
-
#: classes/Views/AuditLog.php:
|
149 |
msgid "Please enter the number of alerts you would like to see on one page:"
|
150 |
msgstr ""
|
151 |
|
152 |
-
#: classes/Views/AuditLog.php:
|
153 |
msgid "All Sites"
|
154 |
msgstr ""
|
155 |
|
156 |
-
#: classes/Views/AuditLog.php:
|
157 |
msgid "No Results"
|
158 |
msgstr ""
|
159 |
|
160 |
-
#: classes/Views/AuditLog.php:192
|
161 |
-
msgid "No events so far."
|
162 |
-
msgstr ""
|
163 |
-
|
164 |
-
#: classes/Views/AuditLog.php:197
|
165 |
-
msgid "Other"
|
166 |
-
msgstr ""
|
167 |
-
|
168 |
-
#: classes/Views/AuditLog.php:204
|
169 |
-
msgid "Show "
|
170 |
-
msgstr ""
|
171 |
-
|
172 |
-
#: classes/Views/AuditLog.php:214
|
173 |
-
msgid " Items"
|
174 |
-
msgstr ""
|
175 |
-
|
176 |
-
#: classes/Views/AuditLog.php:276 classes/Views/ToggleAlerts.php:69
|
177 |
-
msgid "Code"
|
178 |
-
msgstr ""
|
179 |
-
|
180 |
-
#: classes/Views/AuditLog.php:277 classes/Views/ToggleAlerts.php:70
|
181 |
-
msgid "Type"
|
182 |
-
msgstr ""
|
183 |
-
|
184 |
-
#: classes/Views/AuditLog.php:278
|
185 |
-
msgid "Date"
|
186 |
-
msgstr ""
|
187 |
-
|
188 |
-
#: classes/Views/AuditLog.php:279
|
189 |
-
msgid "Username"
|
190 |
-
msgstr ""
|
191 |
-
|
192 |
-
#: classes/Views/AuditLog.php:280
|
193 |
-
msgid "Source IP"
|
194 |
-
msgstr ""
|
195 |
-
|
196 |
-
#: classes/Views/AuditLog.php:283
|
197 |
-
msgid "Site"
|
198 |
-
msgstr ""
|
199 |
-
|
200 |
-
#: classes/Views/AuditLog.php:285
|
201 |
-
msgid "Message"
|
202 |
-
msgstr ""
|
203 |
-
|
204 |
-
#: classes/Views/AuditLog.php:314
|
205 |
-
msgid "Click to toggle."
|
206 |
-
msgstr ""
|
207 |
-
|
208 |
-
#: classes/Views/AuditLog.php:320
|
209 |
-
msgid "Unknown error code."
|
210 |
-
msgstr ""
|
211 |
-
|
212 |
-
#: classes/Views/AuditLog.php:341 classes/Views/AuditLog.php:344
|
213 |
-
msgid "Unknown"
|
214 |
-
msgstr ""
|
215 |
-
|
216 |
-
#: classes/Views/AuditLog.php:345
|
217 |
-
msgid "System"
|
218 |
-
msgstr ""
|
219 |
-
|
220 |
-
#: classes/Views/AuditLog.php:358
|
221 |
-
msgid "Alert Data Inspector"
|
222 |
-
msgstr ""
|
223 |
-
|
224 |
#: classes/Views/Help.php:6 classes/Views/Help.php:14
|
225 |
#: classes/Views/Help.php:25
|
226 |
msgid "Help"
|
@@ -332,12 +268,12 @@ msgstr ""
|
|
332 |
msgid "Licensing"
|
333 |
msgstr ""
|
334 |
|
335 |
-
#: classes/Views/Licensing.php:39 classes/Views/Settings.php:
|
336 |
#: classes/Views/ToggleAlerts.php:44
|
337 |
msgid "Settings have been saved."
|
338 |
msgstr ""
|
339 |
|
340 |
-
#: classes/Views/Licensing.php:41 classes/Views/Settings.php:
|
341 |
#: classes/Views/ToggleAlerts.php:46
|
342 |
msgid "Error: "
|
343 |
msgstr ""
|
@@ -355,146 +291,170 @@ msgid "Inactive"
|
|
355 |
msgstr ""
|
356 |
|
357 |
#: classes/Views/Sandbox.php:11 classes/Views/Sandbox.php:19
|
358 |
-
#: classes/Views/Settings.php:
|
359 |
msgid "Sandbox"
|
360 |
msgstr ""
|
361 |
|
362 |
-
#: classes/Views/Sandbox.php:
|
363 |
msgid "Ready."
|
364 |
msgstr ""
|
365 |
|
366 |
-
#: classes/Views/Settings.php:
|
367 |
msgid "Settings"
|
368 |
msgstr ""
|
369 |
|
370 |
-
#: classes/Views/Settings.php:
|
371 |
msgid "Security Alerts Pruning"
|
372 |
msgstr ""
|
373 |
|
374 |
-
#: classes/Views/Settings.php:
|
375 |
msgid "(eg: 1 month)"
|
376 |
msgstr ""
|
377 |
|
378 |
-
#: classes/Views/Settings.php:
|
379 |
msgid "Delete alerts older than"
|
380 |
msgstr ""
|
381 |
|
382 |
-
#: classes/Views/Settings.php:
|
383 |
msgid "(eg: 80)"
|
384 |
msgstr ""
|
385 |
|
386 |
-
#: classes/Views/Settings.php:
|
387 |
msgid "Keep up to"
|
388 |
msgstr ""
|
389 |
|
390 |
-
#: classes/Views/Settings.php:
|
391 |
msgid "alerts"
|
392 |
msgstr ""
|
393 |
|
394 |
-
#: classes/Views/Settings.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
395 |
msgid "Alerts Dashboard Widget"
|
396 |
msgstr ""
|
397 |
|
398 |
-
#: classes/Views/Settings.php:
|
399 |
msgid "On"
|
400 |
msgstr ""
|
401 |
|
402 |
-
#: classes/Views/Settings.php:
|
403 |
msgid "Off"
|
404 |
msgstr ""
|
405 |
|
406 |
-
#: classes/Views/Settings.php:
|
407 |
msgid "Display a dashboard widget with the latest %d security alerts."
|
408 |
msgstr ""
|
409 |
|
410 |
-
#: classes/Views/Settings.php:
|
411 |
msgid "Can View Alerts"
|
412 |
msgstr ""
|
413 |
|
414 |
-
#: classes/Views/Settings.php:
|
415 |
msgid "Users and Roles in this list can view the security alerts"
|
416 |
msgstr ""
|
417 |
|
418 |
-
#: classes/Views/Settings.php:
|
419 |
msgid "Can Manage Plugin"
|
420 |
msgstr ""
|
421 |
|
422 |
-
#: classes/Views/Settings.php:
|
423 |
msgid "Users and Roles in this list can manage the plugin settings"
|
424 |
msgstr ""
|
425 |
|
426 |
-
#: classes/Views/Settings.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
427 |
msgid "Refresh Audit View"
|
428 |
msgstr ""
|
429 |
|
430 |
-
#: classes/Views/Settings.php:
|
431 |
msgid "Automatic"
|
432 |
msgstr ""
|
433 |
|
434 |
-
#: classes/Views/Settings.php:
|
435 |
msgid "Refresh Audit View as soon as there are new events."
|
436 |
msgstr ""
|
437 |
|
438 |
-
#: classes/Views/Settings.php:
|
439 |
msgid "Manual"
|
440 |
msgstr ""
|
441 |
|
442 |
-
#: classes/Views/Settings.php:
|
443 |
msgid "Refresh Audit View only when page is reloaded."
|
444 |
msgstr ""
|
445 |
|
446 |
-
#: classes/Views/Settings.php:
|
447 |
msgid "Developer Options"
|
448 |
msgstr ""
|
449 |
|
450 |
-
#: classes/Views/Settings.php:
|
451 |
msgid ""
|
452 |
"Only enable these options on testing, staging and development websites. "
|
453 |
"Enabling any of the settings below on LIVE websites may cause unintended "
|
454 |
"side-effects including degraded performance."
|
455 |
msgstr ""
|
456 |
|
457 |
-
#: classes/Views/Settings.php:
|
458 |
msgid "Data Inspector"
|
459 |
msgstr ""
|
460 |
|
461 |
-
#: classes/Views/Settings.php:
|
462 |
msgid "View data logged for each triggered alert."
|
463 |
msgstr ""
|
464 |
|
465 |
-
#: classes/Views/Settings.php:
|
466 |
msgid "PHP Errors"
|
467 |
msgstr ""
|
468 |
|
469 |
-
#: classes/Views/Settings.php:
|
470 |
msgid "Enables sensor for alerts generated from PHP."
|
471 |
msgstr ""
|
472 |
|
473 |
-
#: classes/Views/Settings.php:
|
474 |
msgid "Request Log"
|
475 |
msgstr ""
|
476 |
|
477 |
-
#: classes/Views/Settings.php:
|
478 |
msgid "Enables logging request to file."
|
479 |
msgstr ""
|
480 |
|
481 |
-
#: classes/Views/Settings.php:
|
482 |
msgid "Enables sandbox for testing PHP code."
|
483 |
msgstr ""
|
484 |
|
485 |
-
#: classes/Views/Settings.php:
|
486 |
msgid "Backtrace"
|
487 |
msgstr ""
|
488 |
|
489 |
-
#: classes/Views/Settings.php:
|
490 |
msgid "Log full backtrace for PHP-generated alerts."
|
491 |
msgstr ""
|
492 |
|
493 |
-
#: classes/Views/Settings.php:
|
494 |
msgid "Hide Plugin from Plugins Page"
|
495 |
msgstr ""
|
496 |
|
497 |
-
#: classes/Views/Settings.php:
|
498 |
msgid "Hide"
|
499 |
msgstr ""
|
500 |
|
@@ -502,6 +462,14 @@ msgstr ""
|
|
502 |
msgid "Enable/Disable Alerts"
|
503 |
msgstr ""
|
504 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
505 |
#: classes/Views/ToggleAlerts.php:71 classes/WidgetManager.php:38
|
506 |
msgid "Description"
|
507 |
msgstr ""
|
@@ -874,7 +842,7 @@ msgid "User modified a draft WordPress page"
|
|
874 |
msgstr ""
|
875 |
|
876 |
#: defaults.php:74
|
877 |
-
msgid "Modified the draft page %PostTitle%.
|
878 |
msgstr ""
|
879 |
|
880 |
#: defaults.php:75
|
@@ -1553,7 +1521,7 @@ msgid ""
|
|
1553 |
">get_template_directory%"
|
1554 |
msgstr ""
|
1555 |
|
1556 |
-
#: wp-security-audit-log.php:
|
1557 |
msgid ""
|
1558 |
"You are using a version of PHP that is older than %s, which is no longer "
|
1559 |
"supported.<br/>Contact us on <a href=\"mailto:plugins@wpwhitesecurity.com"
|
2 |
# This file is distributed under the same license as the WP Security Audit Log package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
+
"Project-Id-Version: WP Security Audit Log 1.2.7\n"
|
6 |
"Report-Msgid-Bugs-To: http://wordpress.org/tag/wp-security-audit-log\n"
|
7 |
+
"POT-Creation-Date: 2014-09-26 09:43:13+00:00\n"
|
8 |
"MIME-Version: 1.0\n"
|
9 |
"Content-Type: text/plain; charset=UTF-8\n"
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
136 |
msgid "Professional WordPress security services provided by WP White Security"
|
137 |
msgstr ""
|
138 |
|
139 |
+
#: classes/Views/AuditLog.php:22 classes/Views/AuditLog.php:32
|
140 |
msgid "Audit Log Viewer"
|
141 |
msgstr ""
|
142 |
|
143 |
+
#: classes/Views/AuditLog.php:46 classes/Views/Licensing.php:34
|
144 |
+
#: classes/Views/Settings.php:80 classes/Views/ToggleAlerts.php:29
|
145 |
msgid "You do not have sufficient permissions to access this page."
|
146 |
msgstr ""
|
147 |
|
148 |
+
#: classes/Views/AuditLog.php:66
|
149 |
msgid "Please enter the number of alerts you would like to see on one page:"
|
150 |
msgstr ""
|
151 |
|
152 |
+
#: classes/Views/AuditLog.php:67
|
153 |
msgid "All Sites"
|
154 |
msgstr ""
|
155 |
|
156 |
+
#: classes/Views/AuditLog.php:68
|
157 |
msgid "No Results"
|
158 |
msgstr ""
|
159 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
160 |
#: classes/Views/Help.php:6 classes/Views/Help.php:14
|
161 |
#: classes/Views/Help.php:25
|
162 |
msgid "Help"
|
268 |
msgid "Licensing"
|
269 |
msgstr ""
|
270 |
|
271 |
+
#: classes/Views/Licensing.php:39 classes/Views/Settings.php:85
|
272 |
#: classes/Views/ToggleAlerts.php:44
|
273 |
msgid "Settings have been saved."
|
274 |
msgstr ""
|
275 |
|
276 |
+
#: classes/Views/Licensing.php:41 classes/Views/Settings.php:87
|
277 |
#: classes/Views/ToggleAlerts.php:46
|
278 |
msgid "Error: "
|
279 |
msgstr ""
|
291 |
msgstr ""
|
292 |
|
293 |
#: classes/Views/Sandbox.php:11 classes/Views/Sandbox.php:19
|
294 |
+
#: classes/Views/Settings.php:264
|
295 |
msgid "Sandbox"
|
296 |
msgstr ""
|
297 |
|
298 |
+
#: classes/Views/Sandbox.php:197
|
299 |
msgid "Ready."
|
300 |
msgstr ""
|
301 |
|
302 |
+
#: classes/Views/Settings.php:18 classes/Views/Settings.php:26
|
303 |
msgid "Settings"
|
304 |
msgstr ""
|
305 |
|
306 |
+
#: classes/Views/Settings.php:98
|
307 |
msgid "Security Alerts Pruning"
|
308 |
msgstr ""
|
309 |
|
310 |
+
#: classes/Views/Settings.php:101
|
311 |
msgid "(eg: 1 month)"
|
312 |
msgstr ""
|
313 |
|
314 |
+
#: classes/Views/Settings.php:106
|
315 |
msgid "Delete alerts older than"
|
316 |
msgstr ""
|
317 |
|
318 |
+
#: classes/Views/Settings.php:113
|
319 |
msgid "(eg: 80)"
|
320 |
msgstr ""
|
321 |
|
322 |
+
#: classes/Views/Settings.php:118
|
323 |
msgid "Keep up to"
|
324 |
msgstr ""
|
325 |
|
326 |
+
#: classes/Views/Settings.php:122
|
327 |
msgid "alerts"
|
328 |
msgstr ""
|
329 |
|
330 |
+
#: classes/Views/Settings.php:126
|
331 |
+
msgid "Next Scheduled Cleanup is in "
|
332 |
+
msgstr ""
|
333 |
+
|
334 |
+
#: classes/Views/Settings.php:130
|
335 |
+
msgid "(or %s)"
|
336 |
+
msgstr ""
|
337 |
+
|
338 |
+
#: classes/Views/Settings.php:131
|
339 |
+
msgid "Run Manually"
|
340 |
+
msgstr ""
|
341 |
+
|
342 |
+
#: classes/Views/Settings.php:137
|
343 |
msgid "Alerts Dashboard Widget"
|
344 |
msgstr ""
|
345 |
|
346 |
+
#: classes/Views/Settings.php:143
|
347 |
msgid "On"
|
348 |
msgstr ""
|
349 |
|
350 |
+
#: classes/Views/Settings.php:148
|
351 |
msgid "Off"
|
352 |
msgstr ""
|
353 |
|
354 |
+
#: classes/Views/Settings.php:153
|
355 |
msgid "Display a dashboard widget with the latest %d security alerts."
|
356 |
msgstr ""
|
357 |
|
358 |
+
#: classes/Views/Settings.php:161
|
359 |
msgid "Can View Alerts"
|
360 |
msgstr ""
|
361 |
|
362 |
+
#: classes/Views/Settings.php:168
|
363 |
msgid "Users and Roles in this list can view the security alerts"
|
364 |
msgstr ""
|
365 |
|
366 |
+
#: classes/Views/Settings.php:183
|
367 |
msgid "Can Manage Plugin"
|
368 |
msgstr ""
|
369 |
|
370 |
+
#: classes/Views/Settings.php:190
|
371 |
msgid "Users and Roles in this list can manage the plugin settings"
|
372 |
msgstr ""
|
373 |
|
374 |
+
#: classes/Views/Settings.php:205
|
375 |
+
msgid "Restrict Plugin Access"
|
376 |
+
msgstr ""
|
377 |
+
|
378 |
+
#: classes/Views/Settings.php:213
|
379 |
+
msgid ""
|
380 |
+
"By default all the administrators on this WordPress have access to manage "
|
381 |
+
"this plugin.<br/>By enabling this option only the users specified in the two "
|
382 |
+
"options above and your username will have access to view alerts and manage "
|
383 |
+
"this plugin."
|
384 |
+
msgstr ""
|
385 |
+
|
386 |
+
#: classes/Views/Settings.php:220
|
387 |
msgid "Refresh Audit View"
|
388 |
msgstr ""
|
389 |
|
390 |
+
#: classes/Views/Settings.php:226
|
391 |
msgid "Automatic"
|
392 |
msgstr ""
|
393 |
|
394 |
+
#: classes/Views/Settings.php:228
|
395 |
msgid "Refresh Audit View as soon as there are new events."
|
396 |
msgstr ""
|
397 |
|
398 |
+
#: classes/Views/Settings.php:232
|
399 |
msgid "Manual"
|
400 |
msgstr ""
|
401 |
|
402 |
+
#: classes/Views/Settings.php:234
|
403 |
msgid "Refresh Audit View only when page is reloaded."
|
404 |
msgstr ""
|
405 |
|
406 |
+
#: classes/Views/Settings.php:240
|
407 |
msgid "Developer Options"
|
408 |
msgstr ""
|
409 |
|
410 |
+
#: classes/Views/Settings.php:248
|
411 |
msgid ""
|
412 |
"Only enable these options on testing, staging and development websites. "
|
413 |
"Enabling any of the settings below on LIVE websites may cause unintended "
|
414 |
"side-effects including degraded performance."
|
415 |
msgstr ""
|
416 |
|
417 |
+
#: classes/Views/Settings.php:252
|
418 |
msgid "Data Inspector"
|
419 |
msgstr ""
|
420 |
|
421 |
+
#: classes/Views/Settings.php:253
|
422 |
msgid "View data logged for each triggered alert."
|
423 |
msgstr ""
|
424 |
|
425 |
+
#: classes/Views/Settings.php:256
|
426 |
msgid "PHP Errors"
|
427 |
msgstr ""
|
428 |
|
429 |
+
#: classes/Views/Settings.php:257
|
430 |
msgid "Enables sensor for alerts generated from PHP."
|
431 |
msgstr ""
|
432 |
|
433 |
+
#: classes/Views/Settings.php:260
|
434 |
msgid "Request Log"
|
435 |
msgstr ""
|
436 |
|
437 |
+
#: classes/Views/Settings.php:261
|
438 |
msgid "Enables logging request to file."
|
439 |
msgstr ""
|
440 |
|
441 |
+
#: classes/Views/Settings.php:265
|
442 |
msgid "Enables sandbox for testing PHP code."
|
443 |
msgstr ""
|
444 |
|
445 |
+
#: classes/Views/Settings.php:268
|
446 |
msgid "Backtrace"
|
447 |
msgstr ""
|
448 |
|
449 |
+
#: classes/Views/Settings.php:269
|
450 |
msgid "Log full backtrace for PHP-generated alerts."
|
451 |
msgstr ""
|
452 |
|
453 |
+
#: classes/Views/Settings.php:287
|
454 |
msgid "Hide Plugin from Plugins Page"
|
455 |
msgstr ""
|
456 |
|
457 |
+
#: classes/Views/Settings.php:293
|
458 |
msgid "Hide"
|
459 |
msgstr ""
|
460 |
|
462 |
msgid "Enable/Disable Alerts"
|
463 |
msgstr ""
|
464 |
|
465 |
+
#: classes/Views/ToggleAlerts.php:69
|
466 |
+
msgid "Code"
|
467 |
+
msgstr ""
|
468 |
+
|
469 |
+
#: classes/Views/ToggleAlerts.php:70
|
470 |
+
msgid "Type"
|
471 |
+
msgstr ""
|
472 |
+
|
473 |
#: classes/Views/ToggleAlerts.php:71 classes/WidgetManager.php:38
|
474 |
msgid "Description"
|
475 |
msgstr ""
|
842 |
msgstr ""
|
843 |
|
844 |
#: defaults.php:74
|
845 |
+
msgid "Modified the draft page %PostTitle%. Page ID is %PostID%"
|
846 |
msgstr ""
|
847 |
|
848 |
#: defaults.php:75
|
1521 |
">get_template_directory%"
|
1522 |
msgstr ""
|
1523 |
|
1524 |
+
#: wp-security-audit-log.php:169
|
1525 |
msgid ""
|
1526 |
"You are using a version of PHP that is older than %s, which is no longer "
|
1527 |
"supported.<br/>Contact us on <a href=\"mailto:plugins@wpwhitesecurity.com"
|
readme.txt
CHANGED
@@ -6,8 +6,8 @@ License: GPLv3
|
|
6 |
License URI: http://www.gnu.org/licenses/gpl.html
|
7 |
Tags: wordpress security plugin, wordpress security audit log, audit log, wordpress log, event log wordpress, wordpress user tracking, wordpress activity log, wordpress audit, security event log, audit trail, security audit trail, wordpress security alerts, wordpress monitor, wordpress security monitor, wordpress admin, wordpress admin monitoring, analytics, activity, admin, multisite, wordpress multisite
|
8 |
Requires at least: 3.6
|
9 |
-
Tested up to: 4
|
10 |
-
Stable tag: 1.2.
|
11 |
|
12 |
Identify WordPress issues before they become a security problem by keeping an audit log of users and all of the under the hood WordPress activity.
|
13 |
|
@@ -131,6 +131,18 @@ Yes, WP Security Audit Log works on WordPress Multisite networks, i.e. it can mo
|
|
131 |
|
132 |
== Changelog ==
|
133 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
= 1.2.6 (2014-08-20) =
|
135 |
* Improvements
|
136 |
* Several performance improvements and tweaks applied
|
6 |
License URI: http://www.gnu.org/licenses/gpl.html
|
7 |
Tags: wordpress security plugin, wordpress security audit log, audit log, wordpress log, event log wordpress, wordpress user tracking, wordpress activity log, wordpress audit, security event log, audit trail, security audit trail, wordpress security alerts, wordpress monitor, wordpress security monitor, wordpress admin, wordpress admin monitoring, analytics, activity, admin, multisite, wordpress multisite
|
8 |
Requires at least: 3.6
|
9 |
+
Tested up to: 4
|
10 |
+
Stable tag: 1.2.7
|
11 |
|
12 |
Identify WordPress issues before they become a security problem by keeping an audit log of users and all of the under the hood WordPress activity.
|
13 |
|
131 |
|
132 |
== Changelog ==
|
133 |
|
134 |
+
= 1.2.7 (2014-09-26) =
|
135 |
+
* New Feature
|
136 |
+
* New option "Restrict Plugin Access" that allows WordPress administrators to further restrict access to the plugin and the WordPress security alerts
|
137 |
+
|
138 |
+
* Improvements
|
139 |
+
* Updated the Audit Log Viewer backend to retriev WordPress security alerts much faster and consume less resources on large websites
|
140 |
+
* Moved the Audit Log plugin menu entry underneath the dashboard entry for better access
|
141 |
+
* Several minor enhancements to the plugin to perform better on large WordPress installations
|
142 |
+
|
143 |
+
* Bug Fixes
|
144 |
+
* Fixed an uncaught exception with Logout Alert 1001 [support ticket](https://wordpress.org/support/topic/uncaught-exception-2)
|
145 |
+
|
146 |
= 1.2.6 (2014-08-20) =
|
147 |
* Improvements
|
148 |
* Several performance improvements and tweaks applied
|
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: 1.2.
|
8 |
Text Domain: wp-security-audit-log
|
9 |
Author URI: http://www.wpwhitesecurity.com/
|
10 |
License: GPL2
|
@@ -78,6 +78,12 @@ class WpSecurityAuditLog {
|
|
78 |
*/
|
79 |
public $licensing;
|
80 |
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
/**
|
82 |
* Contains a list of cleanup callbacks.
|
83 |
* @var callable[]
|
@@ -104,6 +110,10 @@ class WpSecurityAuditLog {
|
|
104 |
* Initialize plugin.
|
105 |
*/
|
106 |
public function __construct(){
|
|
|
|
|
|
|
|
|
107 |
// load autoloader and register base paths
|
108 |
require_once('classes/Autoloader.php');
|
109 |
$this->autoloader = new WSAL_Autoloader($this);
|
@@ -138,7 +148,9 @@ class WpSecurityAuditLog {
|
|
138 |
load_plugin_textdomain('wp-security-audit-log', false, basename( dirname( __FILE__ ) ) . '/languages/');
|
139 |
|
140 |
// tell the world we've just finished loading
|
|
|
141 |
do_action('wsal_init', $this);
|
|
|
142 |
}
|
143 |
|
144 |
/**
|
@@ -174,8 +186,9 @@ class WpSecurityAuditLog {
|
|
174 |
// if system wasn't installed, try migration now
|
175 |
if (!$PreInstalled && $this->CanMigrate()) $this->Migrate();
|
176 |
|
177 |
-
// install cleanup hook
|
178 |
-
|
|
|
179 |
}
|
180 |
|
181 |
/**
|
@@ -201,7 +214,7 @@ class WpSecurityAuditLog {
|
|
201 |
*/
|
202 |
public function Uninstall(){
|
203 |
WSAL_DB_ActiveRecord::UninstallAll();
|
204 |
-
|
205 |
}
|
206 |
|
207 |
/**
|
@@ -356,8 +369,10 @@ class WpSecurityAuditLog {
|
|
356 |
* Run cleanup routines.
|
357 |
*/
|
358 |
public function CleanUp(){
|
359 |
-
|
360 |
-
|
|
|
|
|
361 |
}
|
362 |
|
363 |
/**
|
@@ -417,16 +432,32 @@ class WpSecurityAuditLog {
|
|
417 |
return plugin_basename(__FILE__);
|
418 |
}
|
419 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
420 |
// </editor-fold>
|
421 |
}
|
422 |
|
|
|
|
|
|
|
|
|
423 |
add_action('plugins_loaded', array(WpSecurityAuditLog::GetInstance(), 'Load'));
|
424 |
|
425 |
// Load extra files
|
426 |
-
|
427 |
|
428 |
// Start listening to events
|
429 |
WpSecurityAuditLog::GetInstance()->sensors->HookEvents();
|
430 |
|
|
|
|
|
|
|
431 |
// Create & Run the plugin
|
432 |
return WpSecurityAuditLog::GetInstance();
|
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: 1.2.7
|
8 |
Text Domain: wp-security-audit-log
|
9 |
Author URI: http://www.wpwhitesecurity.com/
|
10 |
License: GPL2
|
78 |
*/
|
79 |
public $licensing;
|
80 |
|
81 |
+
/**
|
82 |
+
* Simple profiler.
|
83 |
+
* @var WSAL_SimpleProfiler
|
84 |
+
*/
|
85 |
+
public $profiler;
|
86 |
+
|
87 |
/**
|
88 |
* Contains a list of cleanup callbacks.
|
89 |
* @var callable[]
|
110 |
* Initialize plugin.
|
111 |
*/
|
112 |
public function __construct(){
|
113 |
+
// profiler has to be loaded manually
|
114 |
+
require_once('classes/SimpleProfiler.php');
|
115 |
+
$this->profiler = new WSAL_SimpleProfiler();
|
116 |
+
|
117 |
// load autoloader and register base paths
|
118 |
require_once('classes/Autoloader.php');
|
119 |
$this->autoloader = new WSAL_Autoloader($this);
|
148 |
load_plugin_textdomain('wp-security-audit-log', false, basename( dirname( __FILE__ ) ) . '/languages/');
|
149 |
|
150 |
// tell the world we've just finished loading
|
151 |
+
$s = $this->profiler->Start('WSAL Init Hook');
|
152 |
do_action('wsal_init', $this);
|
153 |
+
$s->Stop();
|
154 |
}
|
155 |
|
156 |
/**
|
186 |
// if system wasn't installed, try migration now
|
187 |
if (!$PreInstalled && $this->CanMigrate()) $this->Migrate();
|
188 |
|
189 |
+
// install cleanup hook (remove older one if it exists)
|
190 |
+
wp_clear_scheduled_hook('wsal_cleanup');
|
191 |
+
wp_schedule_event(current_time('timestamp') + 600, 'hourly', 'wsal_cleanup');
|
192 |
}
|
193 |
|
194 |
/**
|
214 |
*/
|
215 |
public function Uninstall(){
|
216 |
WSAL_DB_ActiveRecord::UninstallAll();
|
217 |
+
wp_clear_scheduled_hook('wsal_cleanup');
|
218 |
}
|
219 |
|
220 |
/**
|
369 |
* Run cleanup routines.
|
370 |
*/
|
371 |
public function CleanUp(){
|
372 |
+
$s = $this->profiler->Start('Clean Up');
|
373 |
+
//foreach($this->_cleanup_hooks as $hook)
|
374 |
+
// call_user_func($hook);
|
375 |
+
$s->Stop();
|
376 |
}
|
377 |
|
378 |
/**
|
432 |
return plugin_basename(__FILE__);
|
433 |
}
|
434 |
|
435 |
+
/**
|
436 |
+
* Load default configuration / data.
|
437 |
+
*/
|
438 |
+
public function LoadDefaults(){
|
439 |
+
$s = $this->profiler->Start('Load Defaults');
|
440 |
+
require_once('defaults.php');
|
441 |
+
$s->Stop();
|
442 |
+
}
|
443 |
+
|
444 |
// </editor-fold>
|
445 |
}
|
446 |
|
447 |
+
// Profile WSAL load time
|
448 |
+
$s = WpSecurityAuditLog::GetInstance()->profiler->Start('WSAL Init');
|
449 |
+
|
450 |
+
// Begin load sequence
|
451 |
add_action('plugins_loaded', array(WpSecurityAuditLog::GetInstance(), 'Load'));
|
452 |
|
453 |
// Load extra files
|
454 |
+
WpSecurityAuditLog::GetInstance()->LoadDefaults();
|
455 |
|
456 |
// Start listening to events
|
457 |
WpSecurityAuditLog::GetInstance()->sensors->HookEvents();
|
458 |
|
459 |
+
// End profile snapshot
|
460 |
+
$s->Stop();
|
461 |
+
|
462 |
// Create & Run the plugin
|
463 |
return WpSecurityAuditLog::GetInstance();
|