Simple Login Log - Version 0.3

Version Description

Download this release

Release Info

Developer maxchirkov
Plugin Icon wp plugin Simple Login Log
Version 0.3
Comparing to
See all releases

Code changes from version 0.2 to 0.3

Files changed (4) hide show
  1. readme.txt +18 -6
  2. screenshot-1.jpg +0 -0
  3. screenshot-2.jpg +0 -0
  4. 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.2.1
7
- Stable tag: 0.2
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 CVS file form the same page.
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.2
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
- //Action on successfull loging
38
- add_action( 'wp_login', array(&$this, 'login_success') );
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'] != 'login_log')
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 login_success($user_login){
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
- return;
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 OFFSET $offset";
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, $_GET['datefilter'], false) . '>' . date('F', $timestamp) . ' ' . $row->year . '</option>';
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
- $data = unserialize($item[$column_name]);
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;