MDL-42891 administration: Replace use of logtable in notify_login_failures() with new logging apis
This commit is contained in:
+1
-1
@@ -1323,7 +1323,7 @@ $string['notice'] = 'Notice';
|
||||
$string['noticenewerbackup'] = 'This backup file has been created with Moodle {$a->backuprelease} ({$a->backupversion}) and it\'s newer than your currently installed Moodle {$a->serverrelease} ({$a->serverversion}). This could cause some inconsistencies because backwards compatibility of backup files cannot be guaranteed.';
|
||||
$string['notifications'] = 'Notifications';
|
||||
$string['notifyloginfailuresmessage'] = '{$a->time}, IP: {$a->ip}, User: {$a->info}';
|
||||
$string['notifyloginfailuresmessageend'] = 'You can view these logs at {$a}/report/log/index.php?id=1&chooselog=1&modid=site_errors.';
|
||||
$string['notifyloginfailuresmessageend'] = 'You can view these logs at {$a}';
|
||||
$string['notifyloginfailuresmessagestart'] = 'Here is a list of failed login attempts at {$a} since you were last notified';
|
||||
$string['notifyloginfailuressubject'] = '{$a} :: Failed logins notification';
|
||||
$string['notincluded'] = 'Not included';
|
||||
|
||||
@@ -42,7 +42,7 @@ class send_failed_login_notifications_task extends scheduled_task {
|
||||
* Throw exceptions on errors (the job will be retried).
|
||||
*/
|
||||
public function execute() {
|
||||
global $CFG, $DB, $OUTPUT;
|
||||
global $CFG, $DB;
|
||||
|
||||
if (empty($CFG->notifyloginfailures)) {
|
||||
return;
|
||||
@@ -66,13 +66,23 @@ class send_failed_login_notifications_task extends scheduled_task {
|
||||
|
||||
// Get all the IPs with more than notifyloginthreshold failures since lastnotifyfailure
|
||||
// and insert them into the cache_flags temp table.
|
||||
$logmang = get_log_manager();
|
||||
$readers = $logmang->get_readers('\core\log\sql_internal_reader');
|
||||
$reader = reset($readers);
|
||||
$readername = key($readers);
|
||||
if (empty($reader) || empty($readername)) {
|
||||
// No readers, no processing.
|
||||
return true;
|
||||
}
|
||||
$logtable = $reader->get_internal_log_table_name();
|
||||
|
||||
$sql = "SELECT ip, COUNT(*)
|
||||
FROM {log}
|
||||
WHERE module = 'login' AND action = 'error'
|
||||
AND time > ?
|
||||
GROUP BY ip
|
||||
HAVING COUNT(*) >= ?";
|
||||
$params = array($CFG->lastnotifyfailure, $CFG->notifyloginthreshold);
|
||||
FROM {" . $logtable . "}
|
||||
WHERE eventname = ?
|
||||
AND timecreated > ?
|
||||
GROUP BY ip
|
||||
HAVING COUNT(*) >= ?";
|
||||
$params = array('\core\event\user_login_failed', $CFG->lastnotifyfailure, $CFG->notifyloginthreshold);
|
||||
$rs = $DB->get_recordset_sql($sql, $params);
|
||||
foreach ($rs as $iprec) {
|
||||
if (!empty($iprec->ip)) {
|
||||
@@ -83,17 +93,17 @@ class send_failed_login_notifications_task extends scheduled_task {
|
||||
|
||||
// Get all the INFOs with more than notifyloginthreshold failures since lastnotifyfailure
|
||||
// and insert them into the cache_flags temp table.
|
||||
$sql = "SELECT info, count(*)
|
||||
FROM {log}
|
||||
WHERE module = 'login' AND action = 'error'
|
||||
AND time > ?
|
||||
GROUP BY info
|
||||
$sql = "SELECT userid, count(*)
|
||||
FROM {" . $logtable . "}
|
||||
WHERE eventname = ?
|
||||
AND timecreated > ?
|
||||
GROUP BY userid
|
||||
HAVING count(*) >= ?";
|
||||
$params = array($CFG->lastnotifyfailure, $CFG->notifyloginthreshold);
|
||||
$params = array('\core\event\user_login_failed', $CFG->lastnotifyfailure, $CFG->notifyloginthreshold);
|
||||
$rs = $DB->get_recordset_sql($sql, $params);
|
||||
foreach ($rs as $inforec) {
|
||||
if (!empty($inforec->info)) {
|
||||
set_cache_flag('login_failure_by_info', $inforec->info, '1', 0);
|
||||
set_cache_flag('login_failure_by_id', $inforec->userid, '1', 0);
|
||||
}
|
||||
}
|
||||
$rs->close();
|
||||
@@ -101,23 +111,23 @@ class send_failed_login_notifications_task extends scheduled_task {
|
||||
// Now, select all the login error logged records belonging to the ips and infos
|
||||
// since lastnotifyfailure, that we have stored in the cache_flags table.
|
||||
$sql = "SELECT * FROM (
|
||||
SELECT l.*, u.firstname, u.lastname
|
||||
FROM {log} l
|
||||
JOIN {cache_flags} cf ON l.ip = cf.name
|
||||
LEFT JOIN {user} u ON l.userid = u.id
|
||||
WHERE l.module = 'login' AND l.action = 'error'
|
||||
AND l.time > ?
|
||||
AND cf.flagtype = 'login_failure_by_ip'
|
||||
UNION ALL
|
||||
SELECT l.*, u.firstname, u.lastname
|
||||
FROM {log} l
|
||||
JOIN {cache_flags} cf ON l.info = cf.name
|
||||
LEFT JOIN {user} u ON l.userid = u.id
|
||||
WHERE l.module = 'login' AND l.action = 'error'
|
||||
AND l.time > ?
|
||||
AND cf.flagtype = 'login_failure_by_info') t
|
||||
ORDER BY t.time DESC";
|
||||
$params = array($CFG->lastnotifyfailure, $CFG->lastnotifyfailure);
|
||||
SELECT l.*, u.username
|
||||
FROM {" . $logtable . "} l
|
||||
JOIN {cache_flags} cf ON l.ip = cf.name
|
||||
LEFT JOIN {user} u ON l.userid = u.id
|
||||
WHERE l.eventname = ?
|
||||
AND l.timecreated > ?
|
||||
AND cf.flagtype = 'login_failure_by_ip'
|
||||
UNION ALL
|
||||
SELECT l.*, u.username
|
||||
FROM {" . $logtable . "} l
|
||||
JOIN {cache_flags} cf ON l.userid = " . $DB->sql_cast_char2int('cf.name') . "
|
||||
LEFT JOIN {user} u ON l.userid = u.id
|
||||
WHERE l.eventname = ?
|
||||
AND l.timecreated > ?
|
||||
AND cf.flagtype = 'login_failure_by_info') t
|
||||
ORDER BY t.timecreated DESC";
|
||||
$params = array('\core\event\user_login_failed', $CFG->lastnotifyfailure, '\core\event\user_login_failed', $CFG->lastnotifyfailure);
|
||||
|
||||
// Init some variables.
|
||||
$count = 0;
|
||||
@@ -125,8 +135,17 @@ class send_failed_login_notifications_task extends scheduled_task {
|
||||
// Iterate over the logs recordset.
|
||||
$rs = $DB->get_recordset_sql($sql, $params);
|
||||
foreach ($rs as $log) {
|
||||
$log->time = userdate($log->time);
|
||||
$messages .= get_string('notifyloginfailuresmessage', '', $log) . "\n";
|
||||
$a = new \stdClass();
|
||||
$a->time = userdate($log->timecreated);
|
||||
if (empty($log->username)) {
|
||||
// Entries with no valid username. We get attempted username from the event's other field.
|
||||
$other = unserialize($log->other);
|
||||
$a->info = empty($other['username']) ? '' : $other['username'];
|
||||
} else {
|
||||
$a->info = $log->username;
|
||||
}
|
||||
$a->ip = $log->ip;
|
||||
$messages .= get_string('notifyloginfailuresmessage', '', $a)."\n";
|
||||
$count++;
|
||||
}
|
||||
$rs->close();
|
||||
@@ -136,10 +155,12 @@ class send_failed_login_notifications_task extends scheduled_task {
|
||||
$site = get_site();
|
||||
$subject = get_string('notifyloginfailuressubject', '', format_string($site->fullname));
|
||||
// Calculate the complete body of notification (start + messages + end).
|
||||
$params = array('id' => 0, 'modid' => 'site_errors', 'chooselog' => '1', 'logreader' => $readername);
|
||||
$url = new \moodle_url('/report/log/index.php', $params);
|
||||
$body = get_string('notifyloginfailuresmessagestart', '', $CFG->wwwroot) .
|
||||
(($CFG->lastnotifyfailure != 0) ? '('.userdate($CFG->lastnotifyfailure).')' : '')."\n\n" .
|
||||
$messages .
|
||||
"\n\n" . get_string('notifyloginfailuresmessageend', '', $CFG->wwwroot) . "\n\n";
|
||||
"\n\n".get_string('notifyloginfailuresmessageend', '', $url->out(false).' ')."\n\n";
|
||||
|
||||
// For each destination, send mail.
|
||||
mtrace('Emailing admins about '. $count .' failed login attempts');
|
||||
|
||||
Reference in New Issue
Block a user