Version Description
Download this release
Release Info
Developer | maxchirkov |
Plugin | Simple Login Log |
Version | 0.3 |
Comparing to | |
See all releases |
Code changes from version 0.2 to 0.3
- readme.txt +18 -6
- screenshot-1.jpg +0 -0
- screenshot-2.jpg +0 -0
- simple-login-log.php +57 -20
readme.txt
CHANGED
@@ -3,8 +3,8 @@ Contributors: Max Chirkov
|
|
3 |
Donate link: http://www.ibsteam.net/donate
|
4 |
Tags: login, log, users
|
5 |
Requires at least: 3.0
|
6 |
-
Tested up to: 3.
|
7 |
-
Stable tag: 0.
|
8 |
|
9 |
This plugin keeps a log of WordPress user logins. Offers user and date filtering, and export features.
|
10 |
|
@@ -12,19 +12,31 @@ This plugin keeps a log of WordPress user logins. Offers user and date filtering
|
|
12 |
|
13 |
Simple log of user logins. Tracks username, time of login, IP address and browser user agent.
|
14 |
|
|
|
|
|
|
|
|
|
15 |
**Features include:**
|
16 |
|
17 |
1. ability to filter by username, month and year;
|
18 |
2. export into CSV file;
|
19 |
-
3. log auto-truncation
|
|
|
20 |
|
21 |
== Installation ==
|
22 |
|
23 |
1. Install and activate like any other basic plugin.
|
24 |
-
2. If you wish to set log trancation, go to Settings => General. Scroll down to Simple Login Log.
|
25 |
-
3. To view login log, go to Users => Login Log. You can export the log to
|
26 |
|
27 |
== Screenshots ==
|
28 |
|
29 |
1. Simple Login Log Settings.
|
30 |
-
2. Login Log Management Screen.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
Donate link: http://www.ibsteam.net/donate
|
4 |
Tags: login, log, users
|
5 |
Requires at least: 3.0
|
6 |
+
Tested up to: 3.3
|
7 |
+
Stable tag: 0.3
|
8 |
|
9 |
This plugin keeps a log of WordPress user logins. Offers user and date filtering, and export features.
|
10 |
|
12 |
|
13 |
Simple log of user logins. Tracks username, time of login, IP address and browser user agent.
|
14 |
|
15 |
+
* Author: Max Chirkov
|
16 |
+
* Author URI: [http://simplerealtytheme.com/](http://simplerealtytheme.com/ "Real Estate Themes & Plugins for WordPress")
|
17 |
+
* Copyright: Released under GNU GENERAL PUBLIC LICENSE
|
18 |
+
|
19 |
**Features include:**
|
20 |
|
21 |
1. ability to filter by username, month and year;
|
22 |
2. export into CSV file;
|
23 |
+
3. log auto-truncation;
|
24 |
+
4. option to record failed login attempts.
|
25 |
|
26 |
== Installation ==
|
27 |
|
28 |
1. Install and activate like any other basic plugin.
|
29 |
+
2. If you wish to set log trancation or opt-in to record failed login attemtps, go to Settings => General. Scroll down to Simple Login Log.
|
30 |
+
3. To view login log, go to Users => Login Log. You can export the log to CSV file form the same page.
|
31 |
|
32 |
== Screenshots ==
|
33 |
|
34 |
1. Simple Login Log Settings.
|
35 |
+
2. Login Log Management Screen.
|
36 |
+
|
37 |
+
== Changelog ==
|
38 |
+
|
39 |
+
**Version 0.3**
|
40 |
+
|
41 |
+
- Added support for third-party login plugins.
|
42 |
+
- Added option to log Failed Login Attempts.
|
screenshot-1.jpg
CHANGED
Binary file
|
screenshot-2.jpg
CHANGED
Binary file
|
simple-login-log.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
Plugin URI: http://simplerealtytheme.com
|
5 |
Description: This plugin keeps a log of WordPress user logins. Offers user filtering and export features.
|
6 |
Author: Max Chirkov
|
7 |
-
Version: 0.
|
8 |
Author URI: http://SimpleRealtyTheme.com
|
9 |
*/
|
10 |
|
@@ -18,6 +18,7 @@ if( !class_exists( 'SimpleLoginLog' ) )
|
|
18 |
private $log_duration = null; //days
|
19 |
private $opt_name = 'simple_login_log';
|
20 |
private $opt = false;
|
|
|
21 |
|
22 |
function __construct()
|
23 |
{
|
@@ -34,8 +35,8 @@ if( !class_exists( 'SimpleLoginLog' ) )
|
|
34 |
add_action( 'admin_menu', array(&$this, 'sll_admin_menu') );
|
35 |
add_action('admin_init', array(&$this, 'settings_api_init') );
|
36 |
|
37 |
-
//
|
38 |
-
add_action( '
|
39 |
|
40 |
//Style the log table
|
41 |
add_action( 'admin_head', array(&$this, 'admin_header') );
|
@@ -44,6 +45,29 @@ if( !class_exists( 'SimpleLoginLog' ) )
|
|
44 |
add_action( 'wp', array(&$this, 'init_scheduled_events') );
|
45 |
}
|
46 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
function init_scheduled_events()
|
48 |
{
|
49 |
if ( $this->opt['log_duration'] && !wp_next_scheduled( 'truncate_log' ) )
|
@@ -92,6 +116,7 @@ if( !class_exists( 'SimpleLoginLog' ) )
|
|
92 |
{
|
93 |
add_settings_section('simple_login_log', 'Simple Login Log', array(&$this, 'sll_settings'), 'general');
|
94 |
add_settings_field('field_log_duration', 'Truncate Log Entries', array(&$this, 'field_log_duration'), 'general', 'simple_login_log');
|
|
|
95 |
register_setting( 'general', 'simple_login_log' );
|
96 |
}
|
97 |
|
@@ -107,15 +132,20 @@ if( !class_exists( 'SimpleLoginLog' ) )
|
|
107 |
|
108 |
function field_log_duration()
|
109 |
{
|
110 |
-
$duration = (null !== $this->opt['log_duration']) ? $this->opt['log_duration'] : $this->log_duration;
|
111 |
$output = '<input type="text" value="' . $duration . '" name="simple_login_log[log_duration]" size="10" class="code" /> days and older.';
|
112 |
echo $output;
|
113 |
echo "<p>Leave empty or enter 0 if you don't want the log to be truncated.</p>";
|
114 |
}
|
115 |
|
|
|
|
|
|
|
|
|
|
|
116 |
function admin_header()
|
117 |
{
|
118 |
-
if($_GET['page']
|
119 |
return;
|
120 |
|
121 |
echo '<style type="text/css">';
|
@@ -125,28 +155,30 @@ if( !class_exists( 'SimpleLoginLog' ) )
|
|
125 |
echo '.wp-list-table .column-name { width: 15%; }';
|
126 |
echo '.wp-list-table .column-time { width: 15%; }';
|
127 |
echo '.wp-list-table .column-ip { width: 10%; }';
|
|
|
128 |
echo '</style>';
|
129 |
}
|
130 |
|
131 |
//Catch messages on successful login
|
132 |
-
function
|
133 |
|
134 |
$userdata = get_user_by('login', $user_login);
|
135 |
|
136 |
$uid = ($userdata->ID) ? $userdata->ID : 0;
|
137 |
|
138 |
//Stop if login form wasn't submitted
|
139 |
-
if( !$_REQUEST['wp-submit'] )
|
140 |
-
|
141 |
|
|
|
142 |
if ( isset( $_REQUEST['redirect_to'] ) ) { $data['Login Redirect'] = $_REQUEST['redirect_to']; }
|
143 |
-
$data['User Agent'] = $_SERVER['HTTP_USER_AGENT'];
|
144 |
|
145 |
$serialized_data = serialize($data);
|
146 |
|
147 |
$values = array(
|
148 |
'uid' => $uid,
|
149 |
-
'user_login' => $user_login,
|
150 |
'time' => current_time('mysql'),
|
151 |
'ip' => $_SERVER['REMOTE_ADDR'],
|
152 |
'data' => $serialized_data,
|
@@ -155,7 +187,7 @@ if( !class_exists( 'SimpleLoginLog' ) )
|
|
155 |
$format = array('%d', '%s', '%s', '%s', '%s');
|
156 |
|
157 |
$this->save_data($values, $format);
|
158 |
-
}
|
159 |
|
160 |
function save_data($values, $format){
|
161 |
global $wpdb;
|
@@ -170,20 +202,21 @@ if( !class_exists( 'SimpleLoginLog' ) )
|
|
170 |
$log_table = new SLL_List_Table;
|
171 |
|
172 |
$limit = 20;
|
173 |
-
$offset = ( isset($_REQUEST['page']) ) ? $limit * $_REQUEST['page'] : 0;
|
|
|
174 |
|
175 |
-
if($_GET['filter'])
|
176 |
{
|
177 |
$where = "WHERE user_login = '{$_GET['filter']}'";
|
178 |
}
|
179 |
-
if($_GET['datefilter'])
|
180 |
{
|
181 |
$year = substr($_GET['datefilter'], 0, 4);
|
182 |
$month = substr($_GET['datefilter'], -2);
|
183 |
$where = "WHERE YEAR(time) = {$year} AND MONTH(time) = {$month}";
|
184 |
}
|
185 |
|
186 |
-
$sql = "SELECT * FROM $this->table $where ORDER BY time DESC LIMIT $limit
|
187 |
$data = $wpdb->get_results($sql, 'ARRAY_A');
|
188 |
|
189 |
$log_table->items = $data;
|
@@ -221,14 +254,14 @@ if( !class_exists( 'SimpleLoginLog' ) )
|
|
221 |
return;
|
222 |
|
223 |
|
224 |
-
|
225 |
foreach($results as $row)
|
226 |
{
|
227 |
//represent month in double digits
|
228 |
$timestamp = mktime(0, 0, 0, $row->month, 1, $row->year);
|
229 |
$month = (strlen($row->month) == 1) ? '0' . $row->month : $row->month;
|
230 |
-
|
231 |
-
$option .= '<option value="' . $row->year . $month . '" ' . selected($row->year . $month, $
|
232 |
}
|
233 |
|
234 |
$output = '<form method="get">';
|
@@ -312,15 +345,19 @@ class SLL_List_Table extends WP_List_Table
|
|
312 |
return "<a href='" . get_admin_url() . "users.php?page=login_log&filter={$item[$column_name]}' title='Filter log by this name'>{$item[$column_name]}</a>";
|
313 |
case 'name';
|
314 |
$user_info = get_userdata($item['uid']);
|
315 |
-
return $user_info->first_name . " " . $user_info->last_name;
|
316 |
case 'data':
|
317 |
-
|
318 |
if(is_array($data))
|
319 |
{
|
|
|
320 |
foreach($data as $k => $v)
|
321 |
{
|
322 |
$output .= $k .': '. $v .'<br />';
|
323 |
}
|
|
|
|
|
|
|
324 |
return $output;
|
325 |
}
|
326 |
break;
|
4 |
Plugin URI: http://simplerealtytheme.com
|
5 |
Description: This plugin keeps a log of WordPress user logins. Offers user filtering and export features.
|
6 |
Author: Max Chirkov
|
7 |
+
Version: 0.3
|
8 |
Author URI: http://SimpleRealtyTheme.com
|
9 |
*/
|
10 |
|
18 |
private $log_duration = null; //days
|
19 |
private $opt_name = 'simple_login_log';
|
20 |
private $opt = false;
|
21 |
+
private $login_success = 1;
|
22 |
|
23 |
function __construct()
|
24 |
{
|
35 |
add_action( 'admin_menu', array(&$this, 'sll_admin_menu') );
|
36 |
add_action('admin_init', array(&$this, 'settings_api_init') );
|
37 |
|
38 |
+
//Init login actions
|
39 |
+
add_action( 'init', array(&$this, 'init_login_actions') );
|
40 |
|
41 |
//Style the log table
|
42 |
add_action( 'admin_head', array(&$this, 'admin_header') );
|
45 |
add_action( 'wp', array(&$this, 'init_scheduled_events') );
|
46 |
}
|
47 |
|
48 |
+
function init_login_actions(){
|
49 |
+
//condition to check if "log failed attemts" option is selected
|
50 |
+
|
51 |
+
//Action on successfull login
|
52 |
+
add_action( 'wp_login', array(&$this, 'login_success') );
|
53 |
+
|
54 |
+
//Action on failed login
|
55 |
+
if( isset($this->opt['failed_attempts']) ){
|
56 |
+
add_action( 'wp_login_failed', array(&$this, 'login_failed') );
|
57 |
+
}
|
58 |
+
|
59 |
+
}
|
60 |
+
|
61 |
+
function login_success( $user_login ){
|
62 |
+
$this->login_success = 1;
|
63 |
+
$this->login_action( $user_login );
|
64 |
+
}
|
65 |
+
|
66 |
+
function login_failed( $user_login ){
|
67 |
+
$this->login_success = 0;
|
68 |
+
$this->login_action( $user_login );
|
69 |
+
}
|
70 |
+
|
71 |
function init_scheduled_events()
|
72 |
{
|
73 |
if ( $this->opt['log_duration'] && !wp_next_scheduled( 'truncate_log' ) )
|
116 |
{
|
117 |
add_settings_section('simple_login_log', 'Simple Login Log', array(&$this, 'sll_settings'), 'general');
|
118 |
add_settings_field('field_log_duration', 'Truncate Log Entries', array(&$this, 'field_log_duration'), 'general', 'simple_login_log');
|
119 |
+
add_settings_field('field_log_failed_attempts', 'Log Failed Attempts', array(&$this, 'field_log_failed_attempts'), 'general', 'simple_login_log');
|
120 |
register_setting( 'general', 'simple_login_log' );
|
121 |
}
|
122 |
|
132 |
|
133 |
function field_log_duration()
|
134 |
{
|
135 |
+
$duration = (null !== $this->opt['log_duration']) ? $this->opt['log_duration'] : $this->log_duration;
|
136 |
$output = '<input type="text" value="' . $duration . '" name="simple_login_log[log_duration]" size="10" class="code" /> days and older.';
|
137 |
echo $output;
|
138 |
echo "<p>Leave empty or enter 0 if you don't want the log to be truncated.</p>";
|
139 |
}
|
140 |
|
141 |
+
function field_log_failed_attempts(){
|
142 |
+
$failed_attempts = ( isset($this->opt['failed_attempts']) ) ? $this->opt['failed_attempts'] : false;
|
143 |
+
echo '<input type="checkbox" name="simple_login_log[failed_attempts]" value="1" ' . checked( $failed_attempts, 1, false ) . ' /> Logs failed attempts where user name and password are entered. Will not log if at least one of the mentioned fields is empty.';
|
144 |
+
}
|
145 |
+
|
146 |
function admin_header()
|
147 |
{
|
148 |
+
if( isset($_GET['page']) && 'login_log' != $_GET['page'] )
|
149 |
return;
|
150 |
|
151 |
echo '<style type="text/css">';
|
155 |
echo '.wp-list-table .column-name { width: 15%; }';
|
156 |
echo '.wp-list-table .column-time { width: 15%; }';
|
157 |
echo '.wp-list-table .column-ip { width: 10%; }';
|
158 |
+
echo '.wp-list-table .login-failed { background: #ffd5d1; }';
|
159 |
echo '</style>';
|
160 |
}
|
161 |
|
162 |
//Catch messages on successful login
|
163 |
+
function login_action($user_login){
|
164 |
|
165 |
$userdata = get_user_by('login', $user_login);
|
166 |
|
167 |
$uid = ($userdata->ID) ? $userdata->ID : 0;
|
168 |
|
169 |
//Stop if login form wasn't submitted
|
170 |
+
//if( !$_REQUEST['wp-submit'] )
|
171 |
+
// return;
|
172 |
|
173 |
+
$data['Login'] = ( 1 == $this->login_success ) ? 'Successful' : 'Failed';
|
174 |
if ( isset( $_REQUEST['redirect_to'] ) ) { $data['Login Redirect'] = $_REQUEST['redirect_to']; }
|
175 |
+
$data['User Agent'] = $_SERVER['HTTP_USER_AGENT'];
|
176 |
|
177 |
$serialized_data = serialize($data);
|
178 |
|
179 |
$values = array(
|
180 |
'uid' => $uid,
|
181 |
+
'user_login' => $user_login,
|
182 |
'time' => current_time('mysql'),
|
183 |
'ip' => $_SERVER['REMOTE_ADDR'],
|
184 |
'data' => $serialized_data,
|
187 |
$format = array('%d', '%s', '%s', '%s', '%s');
|
188 |
|
189 |
$this->save_data($values, $format);
|
190 |
+
}
|
191 |
|
192 |
function save_data($values, $format){
|
193 |
global $wpdb;
|
202 |
$log_table = new SLL_List_Table;
|
203 |
|
204 |
$limit = 20;
|
205 |
+
$offset = ( isset($_REQUEST['page']) ) ? 'OFFSET ' . $limit * $_REQUEST['page'] : 0;
|
206 |
+
$where = '';
|
207 |
|
208 |
+
if( isset($_GET['filter']) && '' != $_GET['filter'] )
|
209 |
{
|
210 |
$where = "WHERE user_login = '{$_GET['filter']}'";
|
211 |
}
|
212 |
+
if( isset($_GET['datefilter']) && '' != $_GET['datefilter'] )
|
213 |
{
|
214 |
$year = substr($_GET['datefilter'], 0, 4);
|
215 |
$month = substr($_GET['datefilter'], -2);
|
216 |
$where = "WHERE YEAR(time) = {$year} AND MONTH(time) = {$month}";
|
217 |
}
|
218 |
|
219 |
+
$sql = "SELECT * FROM $this->table $where ORDER BY time DESC LIMIT $limit $offset";
|
220 |
$data = $wpdb->get_results($sql, 'ARRAY_A');
|
221 |
|
222 |
$log_table->items = $data;
|
254 |
return;
|
255 |
|
256 |
|
257 |
+
$option = '';
|
258 |
foreach($results as $row)
|
259 |
{
|
260 |
//represent month in double digits
|
261 |
$timestamp = mktime(0, 0, 0, $row->month, 1, $row->year);
|
262 |
$month = (strlen($row->month) == 1) ? '0' . $row->month : $row->month;
|
263 |
+
$datefilter = ( isset($_GET['datefilter']) ) ? $_GET['datefilter'] : false;
|
264 |
+
$option .= '<option value="' . $row->year . $month . '" ' . selected($row->year . $month, $datefilter, false) . '>' . date('F', $timestamp) . ' ' . $row->year . '</option>';
|
265 |
}
|
266 |
|
267 |
$output = '<form method="get">';
|
345 |
return "<a href='" . get_admin_url() . "users.php?page=login_log&filter={$item[$column_name]}' title='Filter log by this name'>{$item[$column_name]}</a>";
|
346 |
case 'name';
|
347 |
$user_info = get_userdata($item['uid']);
|
348 |
+
return ( is_object($user_info) ) ? $user_info->first_name . " " . $user_info->last_name : false;
|
349 |
case 'data':
|
350 |
+
$data = unserialize($item[$column_name]);
|
351 |
if(is_array($data))
|
352 |
{
|
353 |
+
$output = '';
|
354 |
foreach($data as $k => $v)
|
355 |
{
|
356 |
$output .= $k .': '. $v .'<br />';
|
357 |
}
|
358 |
+
if( isset($data['Login']) && $data['Login'] == 'Failed' ){
|
359 |
+
return '<div class="login-failed">' . $output . '</div>';
|
360 |
+
}
|
361 |
return $output;
|
362 |
}
|
363 |
break;
|