Version Description
Download this release
Release Info
Developer | WPWhiteSecurity |
Plugin | WP Security Audit Log |
Version | 3.1.2 |
Comparing to | |
See all releases |
Code changes from version 3.1.1 to 3.1.2
- classes/Adapters/MySQL/OccurrenceAdapter.php +17 -0
- classes/AuditLogListView.php +11 -37
- classes/Loggers/Database.php +8 -6
- classes/Models/Meta.php +2 -2
- classes/Models/Occurrence.php +10 -0
- classes/Sensors/LogInOut.php +42 -83
- classes/Sensors/System.php +42 -19
- classes/Settings.php +85 -0
- classes/Views/AuditLog.php +54 -0
- classes/Views/ToggleAlerts.php +0 -24
- defaults.php +1 -1
- js/auditlog.js +47 -0
- readme.txt +12 -24
- wp-security-audit-log.php +41 -2
classes/Adapters/MySQL/OccurrenceAdapter.php
CHANGED
@@ -239,6 +239,23 @@ class WSAL_Adapters_MySQL_Occurrence extends WSAL_Adapters_MySQL_ActiveRecord im
|
|
239 |
);
|
240 |
}
|
241 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
242 |
/**
|
243 |
* Add conditions to the Query
|
244 |
*
|
239 |
);
|
240 |
}
|
241 |
|
242 |
+
/**
|
243 |
+
* Gets occurences of the alert 1003.
|
244 |
+
*
|
245 |
+
* @param array $args - User arguments.
|
246 |
+
* @return WSAL_Occurrence[]
|
247 |
+
*/
|
248 |
+
public function check_alert_1003( $args = array() ) {
|
249 |
+
return self::LoadMultiQuery(
|
250 |
+
'SELECT occurrence.* FROM `' . $this->GetTable() . '` occurrence
|
251 |
+
WHERE (occurrence.alert_id = %d)
|
252 |
+
AND (occurrence.site_id = %d)
|
253 |
+
AND (occurrence.created_on BETWEEN %d AND %d)
|
254 |
+
GROUP BY occurrence.id',
|
255 |
+
$args
|
256 |
+
);
|
257 |
+
}
|
258 |
+
|
259 |
/**
|
260 |
* Add conditions to the Query
|
261 |
*
|
classes/AuditLogListView.php
CHANGED
@@ -90,12 +90,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
90 |
<?php foreach ( $items as $item ) { ?>
|
91 |
<option
|
92 |
value="<?php echo is_string( $item ) ? '' : esc_attr( $item ); ?>"
|
93 |
-
<?php
|
94 |
-
if ( $item == $p ) {
|
95 |
-
echo 'selected="selected"';
|
96 |
-
}
|
97 |
-
?>
|
98 |
-
>
|
99 |
<?php echo esc_html( $item ); ?>
|
100 |
</option>
|
101 |
<?php } ?>
|
@@ -118,12 +113,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
118 |
<option value="0"><?php esc_html_e( 'All Sites', 'wp-security-audit-log' ); ?></option>
|
119 |
<?php foreach ( $this->get_sites() as $info ) { ?>
|
120 |
<option value="<?php echo esc_attr( $info->blog_id ); ?>"
|
121 |
-
<?php
|
122 |
-
if ( $info->blog_id == $curr ) {
|
123 |
-
echo 'selected="selected"';
|
124 |
-
}
|
125 |
-
?>
|
126 |
-
>
|
127 |
<?php echo esc_html( $info->blogname ) . ' (' . esc_html( $info->domain ) . ')'; ?>
|
128 |
</option>
|
129 |
<?php } ?>
|
@@ -143,22 +133,10 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
143 |
?>
|
144 |
<div class="wsal-ssa wsal-db">
|
145 |
<select class="wsal-db" onchange="WsalDBChange(value);">
|
146 |
-
<option value="live"
|
147 |
-
<?php
|
148 |
-
if ( 'live' == $selected ) {
|
149 |
-
echo 'selected="selected"';
|
150 |
-
}
|
151 |
-
?>
|
152 |
-
>
|
153 |
<?php esc_html_e( 'Live Database', 'wp-security-audit-log' ); ?>
|
154 |
</option>
|
155 |
-
<option value="archive"
|
156 |
-
<?php
|
157 |
-
if ( 'archive' == $selected ) {
|
158 |
-
echo 'selected="selected"';
|
159 |
-
}
|
160 |
-
?>
|
161 |
-
>
|
162 |
<?php esc_html_e( 'Archive Database', 'wp-security-audit-log' ); ?>
|
163 |
</option>
|
164 |
</select>
|
@@ -558,21 +536,17 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
558 |
|
559 |
case '%LinkFile%' == $name:
|
560 |
if ( 'NULL' != $value ) {
|
561 |
-
return
|
562 |
} else {
|
563 |
return 'Click <a href="' . esc_url( admin_url( 'admin.php?page=wsal-togglealerts#tab-system-activity' ) ) . '">here</a> to log such requests to file';
|
564 |
}
|
565 |
|
566 |
-
case '%LogFileLink%' === $name:
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
// Failed login file link.
|
573 |
-
case '%LogFileText%' === $name:
|
574 |
-
return esc_html( $value );
|
575 |
-
// Failed login file text.
|
576 |
case strncmp( $value, 'http://', 7 ) === 0:
|
577 |
case strncmp( $value, 'https://', 7 ) === 0:
|
578 |
return '<a href="' . esc_html( $value ) . '" title="' . esc_html( $value ) . '" target="_blank">' . esc_html( $value ) . '</a>';
|
90 |
<?php foreach ( $items as $item ) { ?>
|
91 |
<option
|
92 |
value="<?php echo is_string( $item ) ? '' : esc_attr( $item ); ?>"
|
93 |
+
<?php echo ( $item == $p ) ? 'selected="selected"' : false; ?>>
|
|
|
|
|
|
|
|
|
|
|
94 |
<?php echo esc_html( $item ); ?>
|
95 |
</option>
|
96 |
<?php } ?>
|
113 |
<option value="0"><?php esc_html_e( 'All Sites', 'wp-security-audit-log' ); ?></option>
|
114 |
<?php foreach ( $this->get_sites() as $info ) { ?>
|
115 |
<option value="<?php echo esc_attr( $info->blog_id ); ?>"
|
116 |
+
<?php echo ( $info->blog_id == $curr ) ? 'selected="selected"' : false; ?>>
|
|
|
|
|
|
|
|
|
|
|
117 |
<?php echo esc_html( $info->blogname ) . ' (' . esc_html( $info->domain ) . ')'; ?>
|
118 |
</option>
|
119 |
<?php } ?>
|
133 |
?>
|
134 |
<div class="wsal-ssa wsal-db">
|
135 |
<select class="wsal-db" onchange="WsalDBChange(value);">
|
136 |
+
<option value="live" <?php echo ( 'live' == $selected ) ? 'selected="selected"' : false; ?>>
|
|
|
|
|
|
|
|
|
|
|
|
|
137 |
<?php esc_html_e( 'Live Database', 'wp-security-audit-log' ); ?>
|
138 |
</option>
|
139 |
+
<option value="archive" <?php echo ( 'archive' == $selected ) ? 'selected="selected"' : false; ?>>
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
<?php esc_html_e( 'Archive Database', 'wp-security-audit-log' ); ?>
|
141 |
</option>
|
142 |
</select>
|
536 |
|
537 |
case '%LinkFile%' == $name:
|
538 |
if ( 'NULL' != $value ) {
|
539 |
+
return esc_html__( 'View the 404 error log file from the /wp-content/uploads/wp-security-audit-log/404s/ directory', 'wp-security-audit-log' );
|
540 |
} else {
|
541 |
return 'Click <a href="' . esc_url( admin_url( 'admin.php?page=wsal-togglealerts#tab-system-activity' ) ) . '">here</a> to log such requests to file';
|
542 |
}
|
543 |
|
544 |
+
case '%LogFileLink%' === $name: // Failed login file link.
|
545 |
+
return '';
|
546 |
+
|
547 |
+
case '%LogFileText%' === $name: // Failed login file text.
|
548 |
+
return '<a href="#" class="wsal_download_failed_logins" data-download-nonce="' . esc_attr( wp_create_nonce( 'wsal-download-failed-logins' ) ) . '" title="' . esc_html__( 'Download the log file.', 'wp-security-audit-log' ) . '">' . esc_html__( 'Download the log file.', 'wp-security-audit-log' ) . '</a>';
|
549 |
+
|
|
|
|
|
|
|
|
|
550 |
case strncmp( $value, 'http://', 7 ) === 0:
|
551 |
case strncmp( $value, 'https://', 7 ) === 0:
|
552 |
return '<a href="' . esc_html( $value ) . '" title="' . esc_html( $value ) . '" target="_blank">' . esc_html( $value ) . '</a>';
|
classes/Loggers/Database.php
CHANGED
@@ -60,6 +60,12 @@ class WSAL_Loggers_Database extends WSAL_AbstractLogger {
|
|
60 |
|
61 |
// Set up meta data.
|
62 |
$occ->SetMeta( $data );
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
}
|
64 |
|
65 |
/**
|
@@ -122,8 +128,7 @@ class WSAL_Loggers_Database extends WSAL_AbstractLogger {
|
|
122 |
/**
|
123 |
* Inject Promo alert every $count alerts if no Add-ons are activated.
|
124 |
*
|
125 |
-
* @param
|
126 |
-
* @deprecated 3.1.0
|
127 |
*/
|
128 |
private function AlertInject( $occurrence ) {
|
129 |
$count = $this->CheckPromoToShow();
|
@@ -161,7 +166,6 @@ class WSAL_Loggers_Database extends WSAL_AbstractLogger {
|
|
161 |
* keeping the last id saved in the DB.
|
162 |
*
|
163 |
* @return integer $promoToSend - The array index.
|
164 |
-
* @deprecated 3.1.0
|
165 |
*/
|
166 |
private function GetPromoAlert() {
|
167 |
$last_promo_sent_id = $this->plugin->GetGlobalOption( 'promo-send-id' );
|
@@ -185,7 +189,6 @@ class WSAL_Loggers_Database extends WSAL_AbstractLogger {
|
|
185 |
* Array of promo.
|
186 |
*
|
187 |
* @return array $promo_alerts - The array of promo.
|
188 |
-
* @deprecated 3.1.0
|
189 |
*/
|
190 |
private function GetActivePromoText() {
|
191 |
$promo_alerts = array();
|
@@ -204,7 +207,6 @@ class WSAL_Loggers_Database extends WSAL_AbstractLogger {
|
|
204 |
* Check condition to show promo.
|
205 |
*
|
206 |
* @return integer|null - Counter alert.
|
207 |
-
* @deprecated 3.1.0
|
208 |
*/
|
209 |
private function CheckPromoToShow() {
|
210 |
// If the package is free, show the promo.
|
@@ -213,7 +215,7 @@ class WSAL_Loggers_Database extends WSAL_AbstractLogger {
|
|
213 |
&& ! class_exists( 'WSAL_Rep_Plugin' )
|
214 |
&& ! class_exists( 'WSAL_SearchExtension' )
|
215 |
&& ! class_exists( 'WSAL_User_Management_Plugin' ) ) {
|
216 |
-
return
|
217 |
}
|
218 |
return null;
|
219 |
}
|
60 |
|
61 |
// Set up meta data.
|
62 |
$occ->SetMeta( $data );
|
63 |
+
|
64 |
+
// Inject for promoting the paid add-ons.
|
65 |
+
$type = (int) $type;
|
66 |
+
if ( 9999 !== $type ) {
|
67 |
+
$this->AlertInject( $occ );
|
68 |
+
}
|
69 |
}
|
70 |
|
71 |
/**
|
128 |
/**
|
129 |
* Inject Promo alert every $count alerts if no Add-ons are activated.
|
130 |
*
|
131 |
+
* @param WSAL_Models_Occurrence $occurrence - Occurrence, instance of WSAL_Models_Occurrence.
|
|
|
132 |
*/
|
133 |
private function AlertInject( $occurrence ) {
|
134 |
$count = $this->CheckPromoToShow();
|
166 |
* keeping the last id saved in the DB.
|
167 |
*
|
168 |
* @return integer $promoToSend - The array index.
|
|
|
169 |
*/
|
170 |
private function GetPromoAlert() {
|
171 |
$last_promo_sent_id = $this->plugin->GetGlobalOption( 'promo-send-id' );
|
189 |
* Array of promo.
|
190 |
*
|
191 |
* @return array $promo_alerts - The array of promo.
|
|
|
192 |
*/
|
193 |
private function GetActivePromoText() {
|
194 |
$promo_alerts = array();
|
207 |
* Check condition to show promo.
|
208 |
*
|
209 |
* @return integer|null - Counter alert.
|
|
|
210 |
*/
|
211 |
private function CheckPromoToShow() {
|
212 |
// If the package is free, show the promo.
|
215 |
&& ! class_exists( 'WSAL_Rep_Plugin' )
|
216 |
&& ! class_exists( 'WSAL_SearchExtension' )
|
217 |
&& ! class_exists( 'WSAL_User_Management_Plugin' ) ) {
|
218 |
+
return 150;
|
219 |
}
|
220 |
return null;
|
221 |
}
|
classes/Models/Meta.php
CHANGED
@@ -87,12 +87,12 @@ class WSAL_Models_Meta extends WSAL_Models_ActiveRecord {
|
|
87 |
$this->id = $meta['id'];
|
88 |
$this->occurrence_id = $meta['occurrence_id'];
|
89 |
$this->name = $meta['name'];
|
90 |
-
$this->value = $value;
|
91 |
$this->saveMeta();
|
92 |
} else {
|
93 |
$this->occurrence_id = $occurrence_id;
|
94 |
$this->name = $name;
|
95 |
-
$this->value = $value;
|
96 |
$this->SaveMeta();
|
97 |
}
|
98 |
}
|
87 |
$this->id = $meta['id'];
|
88 |
$this->occurrence_id = $meta['occurrence_id'];
|
89 |
$this->name = $meta['name'];
|
90 |
+
$this->value = maybe_serialize( $value );
|
91 |
$this->saveMeta();
|
92 |
} else {
|
93 |
$this->occurrence_id = $occurrence_id;
|
94 |
$this->name = $name;
|
95 |
+
$this->value = maybe_serialize( $value );
|
96 |
$this->SaveMeta();
|
97 |
}
|
98 |
}
|
classes/Models/Occurrence.php
CHANGED
@@ -270,6 +270,16 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
270 |
return $this->getAdapter()->CheckUnKnownUsers( $args );
|
271 |
}
|
272 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
273 |
/**
|
274 |
* Gets occurrence by Post_id
|
275 |
*
|
270 |
return $this->getAdapter()->CheckUnKnownUsers( $args );
|
271 |
}
|
272 |
|
273 |
+
/**
|
274 |
+
* Finds occurences of the alert 1003.
|
275 |
+
*
|
276 |
+
* @param array $args - Query args.
|
277 |
+
* @return WSAL_Occurrence[]
|
278 |
+
*/
|
279 |
+
public function check_alert_1003( $args = array() ) {
|
280 |
+
return $this->getAdapter()->check_alert_1003( $args );
|
281 |
+
}
|
282 |
+
|
283 |
/**
|
284 |
* Gets occurrence by Post_id
|
285 |
*
|
classes/Sensors/LogInOut.php
CHANGED
@@ -54,10 +54,32 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
54 |
add_filter( 'wp_login_blocked', array( $this, 'EventLoginBlocked' ), 10, 1 );
|
55 |
|
56 |
// Directory for logged in users log files.
|
57 |
-
$user_upload_dir
|
58 |
-
$
|
59 |
-
|
60 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
}
|
62 |
}
|
63 |
|
@@ -228,7 +250,7 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
228 |
|
229 |
$obj_occurrence = new WSAL_Models_Occurrence();
|
230 |
|
231 |
-
if ( 1002
|
232 |
if ( ! $this->plugin->alerts->CheckEnableUserRoles( $username, $user_roles ) ) {
|
233 |
return;
|
234 |
}
|
@@ -283,42 +305,30 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
283 |
|
284 |
$occ_unknown = count( $occ_unknown ) ? $occ_unknown[0] : null;
|
285 |
if ( ! empty( $occ_unknown ) ) {
|
286 |
-
//
|
287 |
-
$
|
288 |
-
$new = $occ_unknown->GetMetaValue( 'Attempts', 0 ) + 1;
|
289 |
|
290 |
-
if
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
if ( -1 !== (int) $this->GetVisitorLoginFailureLogLimit()
|
295 |
-
&& $new > $this->GetVisitorLoginFailureLogLimit() ) {
|
296 |
-
$new = $this->GetVisitorLoginFailureLogLimit() . '+';
|
297 |
-
}
|
298 |
-
|
299 |
-
$occ_unknown->UpdateMetaValue( 'Attempts', $new );
|
300 |
-
if ( ! empty( $link_file ) && 'on' === $this->plugin->GetGlobalOption( 'log-visitor-failed-login' ) ) {
|
301 |
-
$occ_unknown->UpdateMetaValue( 'LogFileLink', $link_file );
|
302 |
} else {
|
303 |
-
|
304 |
-
$
|
|
|
305 |
}
|
|
|
306 |
$occ_unknown->created_on = null;
|
307 |
$occ_unknown->Save();
|
308 |
} else {
|
309 |
-
|
310 |
-
$
|
311 |
-
if ( 'on' === $this->plugin->GetGlobalOption( 'log-visitor-failed-login' ) ) {
|
312 |
-
$link_file = $this->WriteLog( 1, $username );
|
313 |
-
$log_file_text = ' with the usernames used during these failed login attempts';
|
314 |
-
}
|
315 |
|
316 |
-
//
|
317 |
$this->plugin->alerts->Trigger(
|
318 |
$new_alert_code, array(
|
319 |
-
'
|
320 |
-
'
|
321 |
-
'LogFileText' => $log_file_text,
|
322 |
)
|
323 |
);
|
324 |
}
|
@@ -363,57 +373,6 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
363 |
);
|
364 |
}
|
365 |
|
366 |
-
/**
|
367 |
-
* Write log file.
|
368 |
-
*
|
369 |
-
* @param int $attempts - Number of attempt.
|
370 |
-
* @param string $username - Username.
|
371 |
-
* @author Ashar Irfan
|
372 |
-
* @since 2.6.9
|
373 |
-
*/
|
374 |
-
private function WriteLog( $attempts, $username = '' ) {
|
375 |
-
$name_file = null;
|
376 |
-
|
377 |
-
// Create/Append to the log file.
|
378 |
-
$data = 'Attempts: ' . $attempts . ' — Username: ' . $username;
|
379 |
-
|
380 |
-
$upload_dir = wp_upload_dir();
|
381 |
-
$uploads_dir_path = trailingslashit( $upload_dir['basedir'] ) . 'wp-security-audit-log/failed-logins/';
|
382 |
-
$uploads_url = trailingslashit( $upload_dir['baseurl'] ) . 'wp-security-audit-log/failed-logins/';
|
383 |
-
|
384 |
-
// Check directory.
|
385 |
-
if ( $this->CheckDirectory( $uploads_dir_path ) ) {
|
386 |
-
$filename = 'failed_logins_usernames_' . date( 'Ymd' ) . '.log';
|
387 |
-
$fp = $uploads_dir_path . $filename;
|
388 |
-
$name_file = $uploads_url . $filename;
|
389 |
-
if ( ! $file = fopen( $fp, 'a' ) ) {
|
390 |
-
$i = 1;
|
391 |
-
$file_opened = false;
|
392 |
-
do {
|
393 |
-
$fp2 = substr( $fp, 0, -4 ) . '_' . $i . '.log';
|
394 |
-
if ( ! file_exists( $fp2 ) ) {
|
395 |
-
if ( $file = fopen( $fp2, 'a' ) ) {
|
396 |
-
$file_opened = true;
|
397 |
-
$name_file = $uploads_url . substr( $name_file, 0, -4 ) . '_' . $i . '.log';
|
398 |
-
}
|
399 |
-
} else {
|
400 |
-
$latest_filename = $this->GetLastModified( $uploads_dir_path, $filename );
|
401 |
-
$fp_last = $uploads_dir_path . $latest_filename;
|
402 |
-
if ( $file = fopen( $fp_last, 'a' ) ) {
|
403 |
-
$file_opened = true;
|
404 |
-
$name_file = $uploads_url . $latest_filename;
|
405 |
-
}
|
406 |
-
}
|
407 |
-
$i++;
|
408 |
-
} while ( ! $file_opened );
|
409 |
-
}
|
410 |
-
fwrite( $file, sprintf( "%s\n", $data ) );
|
411 |
-
fclose( $file );
|
412 |
-
}
|
413 |
-
|
414 |
-
return $name_file;
|
415 |
-
}
|
416 |
-
|
417 |
/**
|
418 |
* Get the latest file modified.
|
419 |
*
|
54 |
add_filter( 'wp_login_blocked', array( $this, 'EventLoginBlocked' ), 10, 1 );
|
55 |
|
56 |
// Directory for logged in users log files.
|
57 |
+
$user_upload_dir = wp_upload_dir();
|
58 |
+
$failed_login_dir = trailingslashit( $user_upload_dir['basedir'] . '/wp-security-audit-log/failed-logins/' );
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Check if failed login directory exists then
|
62 |
+
* delete all files within this directory and
|
63 |
+
* remove the directory itself.
|
64 |
+
*
|
65 |
+
* @since 3.1.2
|
66 |
+
*/
|
67 |
+
if ( is_dir( $failed_login_dir ) ) {
|
68 |
+
// Get all files inside failed logins folder.
|
69 |
+
$files = glob( $failed_login_dir . '*', GLOB_BRACE );
|
70 |
+
|
71 |
+
if ( ! empty( $files ) ) {
|
72 |
+
// Unlink each file.
|
73 |
+
foreach ( $files as $file ) {
|
74 |
+
// Check if valid file.
|
75 |
+
if ( is_file( $file ) ) {
|
76 |
+
// Delete the file.
|
77 |
+
unlink( $file );
|
78 |
+
}
|
79 |
+
}
|
80 |
+
}
|
81 |
+
// Remove the directory.
|
82 |
+
rmdir( $failed_login_dir );
|
83 |
}
|
84 |
}
|
85 |
|
250 |
|
251 |
$obj_occurrence = new WSAL_Models_Occurrence();
|
252 |
|
253 |
+
if ( 1002 === $new_alert_code ) {
|
254 |
if ( ! $this->plugin->alerts->CheckEnableUserRoles( $username, $user_roles ) ) {
|
255 |
return;
|
256 |
}
|
305 |
|
306 |
$occ_unknown = count( $occ_unknown ) ? $occ_unknown[0] : null;
|
307 |
if ( ! empty( $occ_unknown ) ) {
|
308 |
+
// Get users from alert.
|
309 |
+
$users = $occ_unknown->GetMetaValue( 'Users' );
|
|
|
310 |
|
311 |
+
// Update it if username is not already present in the array.
|
312 |
+
if ( ! empty( $users ) && is_array( $users ) && ! in_array( $username, $users, true ) ) {
|
313 |
+
$users[] = $username;
|
314 |
+
$occ_unknown->UpdateMetaValue( 'Users', $users );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
315 |
} else {
|
316 |
+
// In this case the value doesn't exist so set the value to array.
|
317 |
+
$users = array();
|
318 |
+
$users[] = $username;
|
319 |
}
|
320 |
+
|
321 |
$occ_unknown->created_on = null;
|
322 |
$occ_unknown->Save();
|
323 |
} else {
|
324 |
+
// Make an array of usernames.
|
325 |
+
$users = array( $username );
|
|
|
|
|
|
|
|
|
326 |
|
327 |
+
// Log an alert for a login attempt with unknown username.
|
328 |
$this->plugin->alerts->Trigger(
|
329 |
$new_alert_code, array(
|
330 |
+
'Users' => $users,
|
331 |
+
'LogFileText' => '',
|
|
|
332 |
)
|
333 |
);
|
334 |
}
|
373 |
);
|
374 |
}
|
375 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
376 |
/**
|
377 |
* Get the latest file modified.
|
378 |
*
|
classes/Sensors/System.php
CHANGED
@@ -65,25 +65,21 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
65 |
add_action( 'automatic_updates_complete', array( $this, 'WPUpdate' ), 10, 1 );
|
66 |
add_filter( 'template_redirect', array( $this, 'Event404' ) );
|
67 |
|
68 |
-
$upload_dir
|
69 |
$uploads_dir_path = trailingslashit( $upload_dir['basedir'] ) . 'wp-security-audit-log/404s/';
|
70 |
if ( ! $this->CheckDirectory( $uploads_dir_path ) ) {
|
71 |
wp_mkdir_p( $uploads_dir_path );
|
72 |
}
|
73 |
|
74 |
// Directory for logged in users log files.
|
75 |
-
$user_upload_dir
|
76 |
-
$user_upload_path
|
77 |
-
|
78 |
-
wp_mkdir_p( $user_upload_path );
|
79 |
-
}
|
80 |
|
81 |
// Directory for visitor log files.
|
82 |
-
$visitor_upload_dir
|
83 |
-
$visitor_upload_path
|
84 |
-
|
85 |
-
wp_mkdir_p( $visitor_upload_path );
|
86 |
-
}
|
87 |
|
88 |
// Cron Job 404 log files pruning.
|
89 |
add_action( 'log_files_pruning', array( $this, 'LogFilesPruning' ) );
|
@@ -97,6 +93,33 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
97 |
add_action( 'update_option_admin_email', array( $this, 'admin_email_changed' ), 10, 3 );
|
98 |
}
|
99 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
/**
|
101 |
* Alert: Admin email changed.
|
102 |
*
|
@@ -612,12 +635,12 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
612 |
public function LogFilesPruning() {
|
613 |
if ( $this->plugin->GetGlobalOption( 'purge-404-log', 'off' ) == 'on' ) {
|
614 |
$upload_dir = wp_upload_dir();
|
615 |
-
$uploads_dir_path = trailingslashit( $upload_dir['basedir'] ) . 'wp-security-audit-log/404s/
|
616 |
if ( is_dir( $uploads_dir_path ) ) {
|
617 |
if ( $handle = opendir( $uploads_dir_path ) ) {
|
618 |
while ( false !== ($entry = readdir( $handle )) ) {
|
619 |
if ( '.' != $entry && '..' != $entry ) {
|
620 |
-
if ( file_exists( $uploads_dir_path . $entry ) ) {
|
621 |
$modified = filemtime( $uploads_dir_path . $entry );
|
622 |
if ( $modified < strtotime( '-4 weeks' ) ) {
|
623 |
// Delete file.
|
@@ -632,12 +655,12 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
632 |
}
|
633 |
if ( 'on' == $this->plugin->GetGlobalOption( 'purge-visitor-404-log', 'off' ) ) {
|
634 |
$upload_dir = wp_upload_dir();
|
635 |
-
$uploads_dir_path = trailingslashit( $upload_dir['basedir'] ) . 'wp-security-audit-log/404s/
|
636 |
if ( is_dir( $uploads_dir_path ) ) {
|
637 |
if ( $handle = opendir( $uploads_dir_path ) ) {
|
638 |
while ( false !== ( $entry = readdir( $handle ) ) ) {
|
639 |
if ( $entry != '.' && $entry != '..' ) {
|
640 |
-
if ( file_exists( $uploads_dir_path . $entry ) ) {
|
641 |
$modified = filemtime( $uploads_dir_path . $entry );
|
642 |
if ( $modified < strtotime( '-4 weeks' ) ) {
|
643 |
// Delete file.
|
@@ -835,8 +858,8 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
835 |
}
|
836 |
|
837 |
$upload_dir = wp_upload_dir();
|
838 |
-
$uploads_dir_path = trailingslashit( $upload_dir['basedir'] ) . 'wp-security-audit-log/404s/
|
839 |
-
$uploads_url = trailingslashit( $upload_dir['baseurl'] ) . 'wp-security-audit-log/404s/
|
840 |
|
841 |
// Check directory.
|
842 |
if ( $this->CheckDirectory( $uploads_dir_path ) ) {
|
@@ -910,8 +933,8 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
910 |
|
911 |
$username = '';
|
912 |
$upload_dir = wp_upload_dir();
|
913 |
-
$uploads_dir_path = trailingslashit( $upload_dir['basedir'] ) . 'wp-security-audit-log/404s/
|
914 |
-
$uploads_url = trailingslashit( $upload_dir['baseurl'] ) . 'wp-security-audit-log/404s/
|
915 |
|
916 |
// Check directory.
|
917 |
if ( $this->CheckDirectory( $uploads_dir_path ) ) {
|
65 |
add_action( 'automatic_updates_complete', array( $this, 'WPUpdate' ), 10, 1 );
|
66 |
add_filter( 'template_redirect', array( $this, 'Event404' ) );
|
67 |
|
68 |
+
$upload_dir = wp_upload_dir();
|
69 |
$uploads_dir_path = trailingslashit( $upload_dir['basedir'] ) . 'wp-security-audit-log/404s/';
|
70 |
if ( ! $this->CheckDirectory( $uploads_dir_path ) ) {
|
71 |
wp_mkdir_p( $uploads_dir_path );
|
72 |
}
|
73 |
|
74 |
// Directory for logged in users log files.
|
75 |
+
$user_upload_dir = wp_upload_dir();
|
76 |
+
$user_upload_path = trailingslashit( $user_upload_dir['basedir'] . '/wp-security-audit-log/404s/users/' );
|
77 |
+
$this->remove_sub_directories( $user_upload_path ); // Remove it.
|
|
|
|
|
78 |
|
79 |
// Directory for visitor log files.
|
80 |
+
$visitor_upload_dir = wp_upload_dir();
|
81 |
+
$visitor_upload_path = trailingslashit( $visitor_upload_dir['basedir'] . '/wp-security-audit-log/404s/visitors/' );
|
82 |
+
$this->remove_sub_directories( $visitor_upload_path ); // Remove it.
|
|
|
|
|
83 |
|
84 |
// Cron Job 404 log files pruning.
|
85 |
add_action( 'log_files_pruning', array( $this, 'LogFilesPruning' ) );
|
93 |
add_action( 'update_option_admin_email', array( $this, 'admin_email_changed' ), 10, 3 );
|
94 |
}
|
95 |
|
96 |
+
/**
|
97 |
+
* Check if failed login directory exists then delete all
|
98 |
+
* files within this directory and remove the directory itself.
|
99 |
+
*
|
100 |
+
* @param string $sub_dir - Subdirectory.
|
101 |
+
*/
|
102 |
+
public function remove_sub_directories( $sub_dir ) {
|
103 |
+
// Check if subdirectory exists.
|
104 |
+
if ( is_dir( $sub_dir ) ) {
|
105 |
+
// Get all files inside failed logins folder.
|
106 |
+
$files = glob( $sub_dir . '*', GLOB_BRACE );
|
107 |
+
|
108 |
+
if ( ! empty( $files ) ) {
|
109 |
+
// Unlink each file.
|
110 |
+
foreach ( $files as $file ) {
|
111 |
+
// Check if valid file.
|
112 |
+
if ( is_file( $file ) ) {
|
113 |
+
// Delete the file.
|
114 |
+
unlink( $file );
|
115 |
+
}
|
116 |
+
}
|
117 |
+
}
|
118 |
+
// Remove the directory.
|
119 |
+
rmdir( $sub_dir );
|
120 |
+
}
|
121 |
+
}
|
122 |
+
|
123 |
/**
|
124 |
* Alert: Admin email changed.
|
125 |
*
|
635 |
public function LogFilesPruning() {
|
636 |
if ( $this->plugin->GetGlobalOption( 'purge-404-log', 'off' ) == 'on' ) {
|
637 |
$upload_dir = wp_upload_dir();
|
638 |
+
$uploads_dir_path = trailingslashit( $upload_dir['basedir'] ) . 'wp-security-audit-log/404s/';
|
639 |
if ( is_dir( $uploads_dir_path ) ) {
|
640 |
if ( $handle = opendir( $uploads_dir_path ) ) {
|
641 |
while ( false !== ($entry = readdir( $handle )) ) {
|
642 |
if ( '.' != $entry && '..' != $entry ) {
|
643 |
+
if ( strpos( $entry, '6007' ) && file_exists( $uploads_dir_path . $entry ) ) {
|
644 |
$modified = filemtime( $uploads_dir_path . $entry );
|
645 |
if ( $modified < strtotime( '-4 weeks' ) ) {
|
646 |
// Delete file.
|
655 |
}
|
656 |
if ( 'on' == $this->plugin->GetGlobalOption( 'purge-visitor-404-log', 'off' ) ) {
|
657 |
$upload_dir = wp_upload_dir();
|
658 |
+
$uploads_dir_path = trailingslashit( $upload_dir['basedir'] ) . 'wp-security-audit-log/404s/';
|
659 |
if ( is_dir( $uploads_dir_path ) ) {
|
660 |
if ( $handle = opendir( $uploads_dir_path ) ) {
|
661 |
while ( false !== ( $entry = readdir( $handle ) ) ) {
|
662 |
if ( $entry != '.' && $entry != '..' ) {
|
663 |
+
if ( strpos( $entry, '6023' ) && file_exists( $uploads_dir_path . $entry ) ) {
|
664 |
$modified = filemtime( $uploads_dir_path . $entry );
|
665 |
if ( $modified < strtotime( '-4 weeks' ) ) {
|
666 |
// Delete file.
|
858 |
}
|
859 |
|
860 |
$upload_dir = wp_upload_dir();
|
861 |
+
$uploads_dir_path = trailingslashit( $upload_dir['basedir'] ) . 'wp-security-audit-log/404s/';
|
862 |
+
$uploads_url = trailingslashit( $upload_dir['baseurl'] ) . 'wp-security-audit-log/404s/';
|
863 |
|
864 |
// Check directory.
|
865 |
if ( $this->CheckDirectory( $uploads_dir_path ) ) {
|
933 |
|
934 |
$username = '';
|
935 |
$upload_dir = wp_upload_dir();
|
936 |
+
$uploads_dir_path = trailingslashit( $upload_dir['basedir'] ) . 'wp-security-audit-log/404s/';
|
937 |
+
$uploads_url = trailingslashit( $upload_dir['baseurl'] ) . 'wp-security-audit-log/404s/';
|
938 |
|
939 |
// Check directory.
|
940 |
if ( $this->CheckDirectory( $uploads_dir_path ) ) {
|
classes/Settings.php
CHANGED
@@ -1078,4 +1078,89 @@ class WSAL_Settings {
|
|
1078 |
$this->_plugin->getConnector( $config )->getAdapter( 'Occurrence' );
|
1079 |
}
|
1080 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1081 |
}
|
1078 |
$this->_plugin->getConnector( $config )->getAdapter( 'Occurrence' );
|
1079 |
}
|
1080 |
}
|
1081 |
+
|
1082 |
+
/**
|
1083 |
+
* Generate index.php file for each wsal sub-directory
|
1084 |
+
* present in the uploads directory.
|
1085 |
+
*
|
1086 |
+
* @since 3.1.2
|
1087 |
+
*/
|
1088 |
+
public function generate_index_files() {
|
1089 |
+
// Get uploads directory.
|
1090 |
+
$uploads_dir = wp_upload_dir();
|
1091 |
+
$wsal_uploads_dir = trailingslashit( $uploads_dir['basedir'] . '/wp-security-audit-log/' );
|
1092 |
+
|
1093 |
+
// If the directory exists then generate index.php file for every sub-directory.
|
1094 |
+
if ( ! empty( $wsal_uploads_dir ) && is_dir( $wsal_uploads_dir ) ) {
|
1095 |
+
// Generate index.php for the main directory.
|
1096 |
+
if ( ! file_exists( $wsal_uploads_dir . '/index.php' ) ) {
|
1097 |
+
// Generate index.php file.
|
1098 |
+
$this->create_index_file( $wsal_uploads_dir );
|
1099 |
+
}
|
1100 |
+
|
1101 |
+
// Generate .htaccess for the main directory.
|
1102 |
+
if ( ! file_exists( $wsal_uploads_dir . '/.htaccess' ) ) {
|
1103 |
+
// Generate .htaccess file.
|
1104 |
+
$this->create_htaccess_file( $wsal_uploads_dir );
|
1105 |
+
}
|
1106 |
+
|
1107 |
+
// Fetch all files in the uploads directory.
|
1108 |
+
$sub_directories = glob( $wsal_uploads_dir . '*', GLOB_BRACE );
|
1109 |
+
foreach ( $sub_directories as $sub_dir ) {
|
1110 |
+
// index.php file.
|
1111 |
+
if ( is_dir( $sub_dir ) && ! file_exists( $sub_dir . '/index.php' ) ) {
|
1112 |
+
// Generate index.php file.
|
1113 |
+
$this->create_index_file( $sub_dir . '/' );
|
1114 |
+
}
|
1115 |
+
|
1116 |
+
// .htaccess file.
|
1117 |
+
if ( is_dir( $sub_dir ) && ! file_exists( $sub_dir . '/.htaccess' ) ) {
|
1118 |
+
// Check for failed-logins, users, visitors and don't create file in it.
|
1119 |
+
if ( strpos( $sub_dir, 'failed-logins' )
|
1120 |
+
|| strpos( $sub_dir, 'users' )
|
1121 |
+
|| strpos( $sub_dir, 'visitors' ) ) {
|
1122 |
+
continue;
|
1123 |
+
}
|
1124 |
+
// Generate .htaccess file.
|
1125 |
+
$this->create_htaccess_file( $sub_dir . '/' );
|
1126 |
+
}
|
1127 |
+
}
|
1128 |
+
}
|
1129 |
+
}
|
1130 |
+
|
1131 |
+
/**
|
1132 |
+
* Create an index.php file, if none exists, in order to
|
1133 |
+
* avoid directory listing in the specified directory.
|
1134 |
+
*
|
1135 |
+
* @param string $dir_path - Directory Path.
|
1136 |
+
* @return bool
|
1137 |
+
* @since 3.1.2
|
1138 |
+
*/
|
1139 |
+
final public function create_index_file( $dir_path ) {
|
1140 |
+
// Check if index.php file exists.
|
1141 |
+
$dir_path = trailingslashit( $dir_path );
|
1142 |
+
$result = 0;
|
1143 |
+
if ( ! is_file( $dir_path . 'index.php' ) ) {
|
1144 |
+
$result = @file_put_contents( $dir_path . 'index.php', '<?php // Silence is golden' );
|
1145 |
+
}
|
1146 |
+
return ($result > 0);
|
1147 |
+
}
|
1148 |
+
|
1149 |
+
/**
|
1150 |
+
* Create an .htaccess file, if none exists, in order to
|
1151 |
+
* block access to directory listing in the specified directory.
|
1152 |
+
*
|
1153 |
+
* @param string $dir_path - Directory Path.
|
1154 |
+
* @return bool
|
1155 |
+
* @since 3.1.2
|
1156 |
+
*/
|
1157 |
+
final public function create_htaccess_file( $dir_path ) {
|
1158 |
+
// Check if .htaccess file exists.
|
1159 |
+
$dir_path = trailingslashit( $dir_path );
|
1160 |
+
$result = 0;
|
1161 |
+
if ( ! is_file( $dir_path . '.htaccess' ) ) {
|
1162 |
+
$result = @file_put_contents( $dir_path . '.htaccess', 'Deny from all' );
|
1163 |
+
}
|
1164 |
+
return ($result > 0);
|
1165 |
+
}
|
1166 |
}
|
classes/Views/AuditLog.php
CHANGED
@@ -48,6 +48,7 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
48 |
add_action( 'wp_ajax_AjaxSetIpp', array( $this, 'AjaxSetIpp' ) );
|
49 |
add_action( 'wp_ajax_AjaxSearchSite', array( $this, 'AjaxSearchSite' ) );
|
50 |
add_action( 'wp_ajax_AjaxSwitchDB', array( $this, 'AjaxSwitchDB' ) );
|
|
|
51 |
add_action( 'all_admin_notices', array( $this, 'AdminNoticesPremium' ) );
|
52 |
// Check plugin version for to dismiss the notice only until upgrade.
|
53 |
$this->_version = WSAL_VERSION;
|
@@ -242,6 +243,9 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
242 |
endif;
|
243 |
}
|
244 |
|
|
|
|
|
|
|
245 |
public function AjaxInspector() {
|
246 |
if ( ! $this->_plugin->settings->CurrentUserCan( 'view' ) ) {
|
247 |
die( 'Access Denied.' );
|
@@ -271,6 +275,9 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
271 |
die;
|
272 |
}
|
273 |
|
|
|
|
|
|
|
274 |
public function AjaxRefresh() {
|
275 |
if ( ! $this->_plugin->settings->CurrentUserCan( 'view' ) ) {
|
276 |
die( 'Access Denied.' );
|
@@ -308,6 +315,10 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
308 |
die;
|
309 |
}
|
310 |
|
|
|
|
|
|
|
|
|
311 |
public function AjaxSetIpp() {
|
312 |
if ( ! $this->_plugin->settings->CurrentUserCan( 'view' ) ) {
|
313 |
die( 'Access Denied.' );
|
@@ -323,6 +334,9 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
323 |
die;
|
324 |
}
|
325 |
|
|
|
|
|
|
|
326 |
public function AjaxSearchSite() {
|
327 |
if ( ! $this->_plugin->settings->CurrentUserCan( 'view' ) ) {
|
328 |
die( 'Access Denied.' );
|
@@ -349,6 +363,9 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
349 |
die( json_encode( array_slice( $grp1 + $grp2, 0, 7 ) ) );
|
350 |
}
|
351 |
|
|
|
|
|
|
|
352 |
public function AjaxSwitchDB() {
|
353 |
// Filter $_POST array for security.
|
354 |
$post_array = filter_input_array( INPUT_POST );
|
@@ -358,6 +375,40 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
358 |
}
|
359 |
}
|
360 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
361 |
public function Header() {
|
362 |
add_thickbox();
|
363 |
wp_enqueue_style( 'darktooltip', $this->_plugin->GetBaseUrl() . '/css/darktooltip.css', array(), '' );
|
@@ -369,6 +420,9 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
369 |
);
|
370 |
}
|
371 |
|
|
|
|
|
|
|
372 |
public function Footer() {
|
373 |
wp_enqueue_script( 'jquery' );
|
374 |
wp_enqueue_script( 'darktooltip', $this->_plugin->GetBaseUrl() . '/js/jquery.darktooltip.js', array( 'jquery' ), '' );
|
48 |
add_action( 'wp_ajax_AjaxSetIpp', array( $this, 'AjaxSetIpp' ) );
|
49 |
add_action( 'wp_ajax_AjaxSearchSite', array( $this, 'AjaxSearchSite' ) );
|
50 |
add_action( 'wp_ajax_AjaxSwitchDB', array( $this, 'AjaxSwitchDB' ) );
|
51 |
+
add_action( 'wp_ajax_wsal_download_failed_login_log', array( $this, 'wsal_download_failed_login_log' ) );
|
52 |
add_action( 'all_admin_notices', array( $this, 'AdminNoticesPremium' ) );
|
53 |
// Check plugin version for to dismiss the notice only until upgrade.
|
54 |
$this->_version = WSAL_VERSION;
|
243 |
endif;
|
244 |
}
|
245 |
|
246 |
+
/**
|
247 |
+
* Ajax callback to display meta data inspector.
|
248 |
+
*/
|
249 |
public function AjaxInspector() {
|
250 |
if ( ! $this->_plugin->settings->CurrentUserCan( 'view' ) ) {
|
251 |
die( 'Access Denied.' );
|
275 |
die;
|
276 |
}
|
277 |
|
278 |
+
/**
|
279 |
+
* Ajax callback to refrest the view.
|
280 |
+
*/
|
281 |
public function AjaxRefresh() {
|
282 |
if ( ! $this->_plugin->settings->CurrentUserCan( 'view' ) ) {
|
283 |
die( 'Access Denied.' );
|
315 |
die;
|
316 |
}
|
317 |
|
318 |
+
/**
|
319 |
+
* Ajax callback to set number of alerts to
|
320 |
+
* show on a single page.
|
321 |
+
*/
|
322 |
public function AjaxSetIpp() {
|
323 |
if ( ! $this->_plugin->settings->CurrentUserCan( 'view' ) ) {
|
324 |
die( 'Access Denied.' );
|
334 |
die;
|
335 |
}
|
336 |
|
337 |
+
/**
|
338 |
+
* Ajax callback to search.
|
339 |
+
*/
|
340 |
public function AjaxSearchSite() {
|
341 |
if ( ! $this->_plugin->settings->CurrentUserCan( 'view' ) ) {
|
342 |
die( 'Access Denied.' );
|
363 |
die( json_encode( array_slice( $grp1 + $grp2, 0, 7 ) ) );
|
364 |
}
|
365 |
|
366 |
+
/**
|
367 |
+
* Ajax callback to switch database.
|
368 |
+
*/
|
369 |
public function AjaxSwitchDB() {
|
370 |
// Filter $_POST array for security.
|
371 |
$post_array = filter_input_array( INPUT_POST );
|
375 |
}
|
376 |
}
|
377 |
|
378 |
+
/**
|
379 |
+
* Ajax callback to download failed login log.
|
380 |
+
*/
|
381 |
+
public function wsal_download_failed_login_log() {
|
382 |
+
// Get post array through filter.
|
383 |
+
$download_nonce = filter_input( INPUT_POST, 'download_nonce', FILTER_SANITIZE_STRING );
|
384 |
+
$alert_id = filter_input( INPUT_POST, 'alert_id', FILTER_SANITIZE_NUMBER_INT );
|
385 |
+
|
386 |
+
// Verify nonce.
|
387 |
+
if ( ! empty( $download_nonce ) && wp_verify_nonce( $download_nonce, 'wsal-download-failed-logins' ) ) {
|
388 |
+
// Get alert by id.
|
389 |
+
$alert = new WSAL_Models_Occurrence();
|
390 |
+
$alert->id = (int) $alert_id;
|
391 |
+
|
392 |
+
// Get users using alert meta.
|
393 |
+
$users = $alert->GetMetaValue( 'Users', array() );
|
394 |
+
|
395 |
+
// Check if there are any users.
|
396 |
+
if ( ! empty( $users ) && is_array( $users ) ) {
|
397 |
+
// Prepare content.
|
398 |
+
$content = implode( ', ', $users );
|
399 |
+
echo esc_html( $content );
|
400 |
+
} else {
|
401 |
+
echo esc_html__( 'No users found.', 'wp-security-audit-log' );
|
402 |
+
}
|
403 |
+
} else {
|
404 |
+
echo esc_html__( 'Nonce verification failed.', 'wp-security-audit-log' );
|
405 |
+
}
|
406 |
+
die();
|
407 |
+
}
|
408 |
+
|
409 |
+
/**
|
410 |
+
* Method: Render header of the view.
|
411 |
+
*/
|
412 |
public function Header() {
|
413 |
add_thickbox();
|
414 |
wp_enqueue_style( 'darktooltip', $this->_plugin->GetBaseUrl() . '/css/darktooltip.css', array(), '' );
|
420 |
);
|
421 |
}
|
422 |
|
423 |
+
/**
|
424 |
+
* Method: Render footer of the view.
|
425 |
+
*/
|
426 |
public function Footer() {
|
427 |
wp_enqueue_script( 'jquery' );
|
428 |
wp_enqueue_script( 'darktooltip', $this->_plugin->GetBaseUrl() . '/js/jquery.darktooltip.js', array( 'jquery' ), '' );
|
classes/Views/ToggleAlerts.php
CHANGED
@@ -110,10 +110,7 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
110 |
$this->_plugin->settings->Set404LogLimit( $post_array['user_404Limit'] );
|
111 |
$this->_plugin->settings->SetVisitor404LogLimit( $post_array['visitor_404Limit'] );
|
112 |
|
113 |
-
$this->_plugin->SetGlobalOption( 'log-visitor-failed-login', isset( $post_array['log_visitor_failed_login'] ) ? 'on' : 'off' );
|
114 |
-
|
115 |
$this->_plugin->settings->set_failed_login_limit( $post_array['log_failed_login_limit'] );
|
116 |
-
$this->_plugin->settings->set_visitor_failed_login_limit( $post_array['log_visitor_failed_login_limit'] );
|
117 |
}
|
118 |
?>
|
119 |
<h2 id="wsal-tabs" class="nav-tab-wrapper">
|
@@ -287,27 +284,6 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
287 |
</tr>
|
288 |
<?php
|
289 |
}
|
290 |
-
if ( 1003 === $alert->type ) {
|
291 |
-
$log_visitor_failed_login = $this->_plugin->GetGlobalOption( 'log-visitor-failed-login', 'on' );
|
292 |
-
$log_visitor_failed_login_limit = (int) $this->_plugin->GetGlobalOption( 'log-visitor-failed-login-limit', 10 );
|
293 |
-
$log_visitor_failed_login_limit = ( -1 === $log_visitor_failed_login_limit ) ? '0' : $log_visitor_failed_login_limit;
|
294 |
-
?>
|
295 |
-
<tr>
|
296 |
-
<td></td>
|
297 |
-
<td><input name="log_visitor_failed_login" type="checkbox" class="check_visitor_log" value="1" <?php checked( $log_visitor_failed_login, 'on' ); ?>></td>
|
298 |
-
<td colspan="2">
|
299 |
-
<p><?php esc_html_e( 'Keep a log of the usernames used in the failed logins in a log file. The log file is stored in /wp-content/uploads/wp-security-audit-log/failed-logins/', 'wp-security-audit-log' ); ?></p>
|
300 |
-
</td>
|
301 |
-
</tr>
|
302 |
-
<tr>
|
303 |
-
<td></td>
|
304 |
-
<td><input name="log_visitor_failed_login_limit" type="number" class="check_visitor_log" value="<?php echo esc_attr( $log_visitor_failed_login_limit ); ?>"></td>
|
305 |
-
<td colspan="2">
|
306 |
-
<p><?php esc_html_e( 'Number of login attempts to log. Enter 0 to log all failed login attempts. (By default the plugin only logs up to 10 failed login because the process can be very resource intensive in case of a brute force attack)', 'wp-security-audit-log' ); ?></p>
|
307 |
-
</td>
|
308 |
-
</tr>
|
309 |
-
<?php
|
310 |
-
}
|
311 |
}
|
312 |
?>
|
313 |
</tbody>
|
110 |
$this->_plugin->settings->Set404LogLimit( $post_array['user_404Limit'] );
|
111 |
$this->_plugin->settings->SetVisitor404LogLimit( $post_array['visitor_404Limit'] );
|
112 |
|
|
|
|
|
113 |
$this->_plugin->settings->set_failed_login_limit( $post_array['log_failed_login_limit'] );
|
|
|
114 |
}
|
115 |
?>
|
116 |
<h2 id="wsal-tabs" class="nav-tab-wrapper">
|
284 |
</tr>
|
285 |
<?php
|
286 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
287 |
}
|
288 |
?>
|
289 |
</tbody>
|
defaults.php
CHANGED
@@ -418,7 +418,7 @@ function wsaldefaults_wsal_init( WpSecurityAuditLog $wsal ) {
|
|
418 |
array( 1000, E_NOTICE, __( 'User logged in', 'wp-security-audit-log' ), __( 'Successfully logged in.', 'wp-security-audit-log' ) ),
|
419 |
array( 1001, E_NOTICE, __( 'User logged out', 'wp-security-audit-log' ), __( 'Successfully logged out.', 'wp-security-audit-log' ) ),
|
420 |
array( 1002, E_WARNING, __( 'Login failed', 'wp-security-audit-log' ), __( '%Attempts% failed login(s) detected.', 'wp-security-audit-log' ) ),
|
421 |
-
array( 1003, E_WARNING, __( 'Login failed / non existing user', 'wp-security-audit-log' ), __( '
|
422 |
array( 1004, E_WARNING, __( 'Login blocked', 'wp-security-audit-log' ), __( 'Blocked from logging in because the same WordPress user is logged in from %ClientIP%.', 'wp-security-audit-log' ) ),
|
423 |
array( 1005, E_WARNING, __( 'User logged in with existing session(s)', 'wp-security-audit-log' ), __( 'Successfully logged in. Another session from %IPAddress% for this user already exist.', 'wp-security-audit-log' ) ),
|
424 |
array( 1006, E_CRITICAL, __( 'User logged out all other sessions with the same username', 'wp-security-audit-log' ), __( 'Logged out all other sessions with the same username.', 'wp-security-audit-log' ) ),
|
418 |
array( 1000, E_NOTICE, __( 'User logged in', 'wp-security-audit-log' ), __( 'Successfully logged in.', 'wp-security-audit-log' ) ),
|
419 |
array( 1001, E_NOTICE, __( 'User logged out', 'wp-security-audit-log' ), __( 'Successfully logged out.', 'wp-security-audit-log' ) ),
|
420 |
array( 1002, E_WARNING, __( 'Login failed', 'wp-security-audit-log' ), __( '%Attempts% failed login(s) detected.', 'wp-security-audit-log' ) ),
|
421 |
+
array( 1003, E_WARNING, __( 'Login failed / non existing user', 'wp-security-audit-log' ), __( 'Failed login(s) detected using non existing user. %LogFileText%', 'wp-security-audit-log' ) ),
|
422 |
array( 1004, E_WARNING, __( 'Login blocked', 'wp-security-audit-log' ), __( 'Blocked from logging in because the same WordPress user is logged in from %ClientIP%.', 'wp-security-audit-log' ) ),
|
423 |
array( 1005, E_WARNING, __( 'User logged in with existing session(s)', 'wp-security-audit-log' ), __( 'Successfully logged in. Another session from %IPAddress% for this user already exist.', 'wp-security-audit-log' ) ),
|
424 |
array( 1006, E_CRITICAL, __( 'User logged out all other sessions with the same username', 'wp-security-audit-log' ), __( 'Logged out all other sessions with the same username.', 'wp-security-audit-log' ) ),
|
js/auditlog.js
CHANGED
@@ -215,3 +215,50 @@ function WsalDisableByCode( code, nonce ) {
|
|
215 |
}
|
216 |
} );
|
217 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
215 |
}
|
216 |
} );
|
217 |
}
|
218 |
+
|
219 |
+
/**
|
220 |
+
* Create and download a temporary file.
|
221 |
+
*
|
222 |
+
* @param {string} filename - File name.
|
223 |
+
* @param {string} text - File content.
|
224 |
+
*/
|
225 |
+
function download( filename, text ) {
|
226 |
+
// Create temporary element.
|
227 |
+
var element = document.createElement('a');
|
228 |
+
element.setAttribute( 'href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text) );
|
229 |
+
element.setAttribute( 'download', filename );
|
230 |
+
|
231 |
+
// Set the element to not display.
|
232 |
+
element.style.display = 'none';
|
233 |
+
document.body.appendChild( element );
|
234 |
+
|
235 |
+
// Simlate click on the element.
|
236 |
+
element.click();
|
237 |
+
|
238 |
+
// Remove temporary element.
|
239 |
+
document.body.removeChild( element );
|
240 |
+
}
|
241 |
+
|
242 |
+
jQuery( document ).ready( function( $ ) {
|
243 |
+
// Failed logins link click.
|
244 |
+
$( '.wsal_download_failed_logins' ).click( function ( event ) {
|
245 |
+
event.preventDefault();
|
246 |
+
nonce = $( this ).data( 'download-nonce' ); // Nonce.
|
247 |
+
alert = $( this ).parent().attr( 'id' ).substring( 5 );
|
248 |
+
|
249 |
+
jQuery.ajax( {
|
250 |
+
type: 'POST',
|
251 |
+
url: ajaxurl,
|
252 |
+
async: true,
|
253 |
+
data: {
|
254 |
+
action: 'wsal_download_failed_login_log',
|
255 |
+
download_nonce: nonce,
|
256 |
+
alert_id: alert
|
257 |
+
},
|
258 |
+
success: function( data ) {
|
259 |
+
// Start file download.
|
260 |
+
download( 'failed_logins.log', data );
|
261 |
+
}
|
262 |
+
} );
|
263 |
+
} );
|
264 |
+
} );
|
readme.txt
CHANGED
@@ -6,10 +6,10 @@ License URI: http://www.gnu.org/licenses/gpl.html
|
|
6 |
Tags: wordpress security plugin, wordpress security audit log, audit log, event log wordpress, wordpress user tracking, wordpress activity log, wordpress audit, security event log, audit trail, wordpress security monitor, wordpress admin, wordpress admin monitoring, user activity, admin, multisite, dashboard, notification, wordpress monitoring, email notification, wordpress email alerts, tracking, user tracking, user activity report, wordpress audit trail
|
7 |
Requires at least: 3.6
|
8 |
Tested up to: 4.9.4
|
9 |
-
Stable tag: 3.1.
|
10 |
Requires PHP: 5.3
|
11 |
|
12 |
-
|
13 |
|
14 |
== Description ==
|
15 |
|
@@ -80,7 +80,7 @@ See our [premium features page](https://www.wpsecurityauditlog.com/premium-featu
|
|
80 |
|
81 |
Support for the WP Security Audit Log plugin on the WordPress forums is free.
|
82 |
|
83 |
-
Premium world-class support is available via email to all [WP Security Audit Log Premium](https://www.wpsecurityauditlog.com/premium-features/) customers.
|
84 |
|
85 |
> <strong>Note</strong>: paid customers support is always given priority over free support. Paid customers support is provided via one-to-one email and over the phone. [Upgrade to Premium](https://www.wpsecurityauditlog.com/premium-features/) to benefit from priority support.
|
86 |
>
|
@@ -91,7 +91,7 @@ WP Security Audit Log plugin also has a number of features that make WordPress a
|
|
91 |
* Built-in [support for reverse proxies and web application firewalls](http://www.wpsecurityauditlog.com/documentation/automatically-retrieve-originating-wordpress-user-ip-address/)
|
92 |
* Full [WordPress multisite support](http://www.wpsecurityauditlog.com/documentation/wordpress-multisite-plugin-features-support/)
|
93 |
* Easily [create your custom alerts](https://www.wpsecurityauditlog.com/support-documentation/create-custom-alerts-wordpress-audit-trail/) to monitor additional functionality
|
94 |
-
* Developer tools including the logging of all HTTP GET and POST requests
|
95 |
* Integration with WhatIsMyIpAddress.com so you can get all information about an IP address with just a mouse click
|
96 |
* Limit who can view the WordPress audit trail by either users or roles
|
97 |
* Limit who can manage the plugin by either users or roles
|
@@ -101,7 +101,7 @@ WP Security Audit Log plugin also has a number of features that make WordPress a
|
|
101 |
* Enable or disable any security alerts
|
102 |
* and much more...
|
103 |
|
104 |
-
### As Featured On:
|
105 |
|
106 |
* [GoDaddy](https://www.godaddy.com/garage/decode-security-logs-wordpress/)
|
107 |
* [Pagely](https://pagely.com/blog/2015/01/log-wordpress-dashboard-activity-improved-security-auditing/)
|
@@ -179,23 +179,11 @@ Please refer to our [Support & Documentation pages](https://www.wpsecurityauditl
|
|
179 |
|
180 |
== Changelog ==
|
181 |
|
182 |
-
= 3.1.
|
183 |
-
|
184 |
-
* **
|
185 |
-
*
|
186 |
-
|
187 |
-
*
|
188 |
-
|
189 |
-
* New site selection menu for opting-in to sending diagnostic data or activating licenses on WordPress multisite network installations.
|
190 |
-
* New account page for installs on multisite network.
|
191 |
-
|
192 |
-
* **Improvements**
|
193 |
-
* Logging of posting of comments from logged in users and website visitors now reported by different alerts.
|
194 |
-
* Improved the logging of multiple post changes that were done at the same time on a post / page / post with custom post type - previously only the last change was being reported.
|
195 |
-
* Post Type selection menu in Email Notifications is not automatically populated on multisite network install so users can specify their custom post type.
|
196 |
-
* Changed severity of alerts 6007 and 6023 (404 errors) from High to Notification.
|
197 |
-
* Improved the plugin menu node for sites on multisite network (added messages on nodes users do not have access to, removed nodes that admins on sites should not have access to).
|
198 |
-
* Added responsiveness to the Archive Now and Mirror Now buttons in the integration tools.
|
199 |
-
* Added product name in alert 9019 (when product stock quantity is updated in WooCommerce).
|
200 |
-
|
201 |
Refer to the [WP Security Audit Log change log](https://www.wpsecurityauditlog.com/plugin-change-log/) page for the complete change log.
|
6 |
Tags: wordpress security plugin, wordpress security audit log, audit log, event log wordpress, wordpress user tracking, wordpress activity log, wordpress audit, security event log, audit trail, wordpress security monitor, wordpress admin, wordpress admin monitoring, user activity, admin, multisite, dashboard, notification, wordpress monitoring, email notification, wordpress email alerts, tracking, user tracking, user activity report, wordpress audit trail
|
7 |
Requires at least: 3.6
|
8 |
Tested up to: 4.9.4
|
9 |
+
Stable tag: 3.1.2
|
10 |
Requires PHP: 5.3
|
11 |
|
12 |
+
An easy to use and comprehensive monitoring & activity log solution that keeps a log of all changes & user activity on your WordPress site.
|
13 |
|
14 |
== Description ==
|
15 |
|
80 |
|
81 |
Support for the WP Security Audit Log plugin on the WordPress forums is free.
|
82 |
|
83 |
+
Premium world-class support is available via email to all [WP Security Audit Log Premium](https://www.wpsecurityauditlog.com/premium-features/) customers.
|
84 |
|
85 |
> <strong>Note</strong>: paid customers support is always given priority over free support. Paid customers support is provided via one-to-one email and over the phone. [Upgrade to Premium](https://www.wpsecurityauditlog.com/premium-features/) to benefit from priority support.
|
86 |
>
|
91 |
* Built-in [support for reverse proxies and web application firewalls](http://www.wpsecurityauditlog.com/documentation/automatically-retrieve-originating-wordpress-user-ip-address/)
|
92 |
* Full [WordPress multisite support](http://www.wpsecurityauditlog.com/documentation/wordpress-multisite-plugin-features-support/)
|
93 |
* Easily [create your custom alerts](https://www.wpsecurityauditlog.com/support-documentation/create-custom-alerts-wordpress-audit-trail/) to monitor additional functionality
|
94 |
+
* Developer tools including the logging of all HTTP GET and POST requests
|
95 |
* Integration with WhatIsMyIpAddress.com so you can get all information about an IP address with just a mouse click
|
96 |
* Limit who can view the WordPress audit trail by either users or roles
|
97 |
* Limit who can manage the plugin by either users or roles
|
101 |
* Enable or disable any security alerts
|
102 |
* and much more...
|
103 |
|
104 |
+
### As Featured On:
|
105 |
|
106 |
* [GoDaddy](https://www.godaddy.com/garage/decode-security-logs-wordpress/)
|
107 |
* [Pagely](https://pagely.com/blog/2015/01/log-wordpress-dashboard-activity-improved-security-auditing/)
|
179 |
|
180 |
== Changelog ==
|
181 |
|
182 |
+
= 3.1.2(2018-03-16) =
|
183 |
+
|
184 |
+
* **Security improvement**
|
185 |
+
* Move log for failed logins in the database
|
186 |
+
* Added index.php and .htaccess files to the plugin upload directory (restricting directory listing)
|
187 |
+
* Above fixes applied to address potential information disclosure issue reported by Colette Chamberland, Defiant, Inc.
|
188 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
189 |
Refer to the [WP Security Audit Log change log](https://www.wpsecurityauditlog.com/plugin-change-log/) page for the complete change log.
|
wp-security-audit-log.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
* Plugin URI: http://www.wpsecurityauditlog.com/
|
5 |
* Description: Identify WordPress security issues before they become a problem. Keep track of everything happening on your WordPress including WordPress users activity. Similar to Windows Event Log and Linux Syslog, WP Security Audit Log generates a security alert for everything that happens on your WordPress blogs and websites. Use the Audit Log Viewer included in the plugin to see all the security alerts.
|
6 |
* Author: WP White Security
|
7 |
-
* Version: 3.1.
|
8 |
* Text Domain: wp-security-audit-log
|
9 |
* Author URI: http://www.wpsecurityauditlog.com/
|
10 |
* License: GPL2
|
@@ -54,7 +54,7 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
|
|
54 |
*
|
55 |
* @var string
|
56 |
*/
|
57 |
-
public $version = '3.1.
|
58 |
|
59 |
// Plugin constants.
|
60 |
const PLG_CLS_PRFX = 'WSAL_';
|
@@ -219,6 +219,12 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
|
|
219 |
// Render Login Page Notification.
|
220 |
add_filter( 'login_message', array( $this, 'render_login_page_message' ), 10, 1 );
|
221 |
|
|
|
|
|
|
|
|
|
|
|
|
|
222 |
// Register freemius uninstall event.
|
223 |
wsal_freemius()->add_action( 'after_uninstall', array( $this, 'wsal_freemius_uninstall_cleanup' ) );
|
224 |
|
@@ -501,6 +507,9 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
|
|
501 |
if ( $old_version !== $new_version ) {
|
502 |
$this->Update( $old_version, $new_version );
|
503 |
}
|
|
|
|
|
|
|
504 |
}
|
505 |
|
506 |
/**
|
@@ -920,6 +929,36 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
|
|
920 |
$s->Stop();
|
921 |
}
|
922 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
923 |
/**
|
924 |
* Add callback to be called when a cleanup operation is required.
|
925 |
*
|
4 |
* Plugin URI: http://www.wpsecurityauditlog.com/
|
5 |
* Description: Identify WordPress security issues before they become a problem. Keep track of everything happening on your WordPress including WordPress users activity. Similar to Windows Event Log and Linux Syslog, WP Security Audit Log generates a security alert for everything that happens on your WordPress blogs and websites. Use the Audit Log Viewer included in the plugin to see all the security alerts.
|
6 |
* Author: WP White Security
|
7 |
+
* Version: 3.1.2
|
8 |
* Text Domain: wp-security-audit-log
|
9 |
* Author URI: http://www.wpsecurityauditlog.com/
|
10 |
* License: GPL2
|
54 |
*
|
55 |
* @var string
|
56 |
*/
|
57 |
+
public $version = '3.1.2';
|
58 |
|
59 |
// Plugin constants.
|
60 |
const PLG_CLS_PRFX = 'WSAL_';
|
219 |
// Render Login Page Notification.
|
220 |
add_filter( 'login_message', array( $this, 'render_login_page_message' ), 10, 1 );
|
221 |
|
222 |
+
// Cron job to delete alert 1003 for the last day.
|
223 |
+
add_action( 'wsal_delete_logins', array( $this, 'delete_failed_logins' ) );
|
224 |
+
if ( ! wp_next_scheduled( 'wsal_delete_logins' ) ) {
|
225 |
+
wp_schedule_event( time(), 'daily', 'wsal_delete_logins' );
|
226 |
+
}
|
227 |
+
|
228 |
// Register freemius uninstall event.
|
229 |
wsal_freemius()->add_action( 'after_uninstall', array( $this, 'wsal_freemius_uninstall_cleanup' ) );
|
230 |
|
507 |
if ( $old_version !== $new_version ) {
|
508 |
$this->Update( $old_version, $new_version );
|
509 |
}
|
510 |
+
|
511 |
+
// Generate index.php for uploads directory.
|
512 |
+
$this->settings->generate_index_files();
|
513 |
}
|
514 |
|
515 |
/**
|
929 |
$s->Stop();
|
930 |
}
|
931 |
|
932 |
+
/**
|
933 |
+
* Clear last day's failed login alert.
|
934 |
+
*/
|
935 |
+
public function delete_failed_logins() {
|
936 |
+
// Set the dates.
|
937 |
+
list( $y, $m, $d ) = explode( '-', date( 'Y-m-d' ) );
|
938 |
+
|
939 |
+
// Site id.
|
940 |
+
$site_id = (function_exists( 'get_current_blog_id' ) ? get_current_blog_id() : 0);
|
941 |
+
|
942 |
+
// New occurrence object.
|
943 |
+
$occurrence = new WSAL_Models_Occurrence();
|
944 |
+
$alerts = $occurrence->check_alert_1003(
|
945 |
+
array(
|
946 |
+
1003,
|
947 |
+
$site_id,
|
948 |
+
mktime( 0, 0, 0, $m, $d - 1, $y ) + 1,
|
949 |
+
mktime( 0, 0, 0, $m, $d, $y ),
|
950 |
+
)
|
951 |
+
);
|
952 |
+
|
953 |
+
// Alerts exists then continue.
|
954 |
+
if ( ! empty( $alerts ) ) {
|
955 |
+
foreach ( $alerts as $alert ) {
|
956 |
+
// Flush the usernames meta data.
|
957 |
+
$alert->UpdateMetaValue( 'Users', array() );
|
958 |
+
}
|
959 |
+
}
|
960 |
+
}
|
961 |
+
|
962 |
/**
|
963 |
* Add callback to be called when a cleanup operation is required.
|
964 |
*
|