fix(ip_record): Correctly total bad logins by unique email address.

This commit is contained in:
Ryan Kelly 2016-10-25 15:51:17 +11:00
Родитель 6828d49337
Коммит 4f20fadca6
2 изменённых файлов: 44 добавлений и 16 удалений

Просмотреть файл

@ -39,17 +39,21 @@ module.exports = function (limits, now) {
IpRecord.prototype.isOverBadLogins = function () { IpRecord.prototype.isOverBadLogins = function () {
this.trimBadLogins(now()) this.trimBadLogins(now())
// IPs are limited based on the number of unique email // IPs are limited based on the number of unique email
// addresses they access. Take the highest-weighted // addresses they access. Sum the highest-weighted
// bad-login event for each email address. // bad-login event for each user account to determine
var total = 0 // the overall bad-logins score.
var seen = {} var weights = {}
this.lf.forEach(function(info) { this.lf.forEach(function(info) {
var incr = limits.badLoginErrnoWeights[info.e] || 1 var user = info.u
if (info.u in seen && seen[info.u] < incr) { var errno = info.e
total -= seen[info.u] weights[user] = Math.max(
seen[info.u] = incr limits.badLoginErrnoWeights[errno] || 1,
} weights[user] || 0
total += incr )
})
var total = 0
Object.keys(weights).forEach(function(user) {
total += weights[user]
}) })
return total > limits.maxBadLoginsPerIp return total > limits.maxBadLoginsPerIp
} }

Просмотреть файл

@ -169,19 +169,43 @@ test(
'addBadLogins works per IP', 'addBadLogins works per IP',
function (t) { function (t) {
var ir = simpleIpRecord() var ir = simpleIpRecord()
ir.addBadLogin({ errno: 999 }) ir.addBadLogin({ email: 'test1@example.com', errno: 999 })
t.equal(ir.isOverBadLogins(), false, 'one record is not over') t.equal(ir.isOverBadLogins(), false, 'one record is not over')
ir.addBadLogin({ errno: 555 }) ir.addBadLogin({ email: 'test2@example.com', errno: 555 })
ir.addBadLogin({ errno: 444 }) ir.addBadLogin({ email: 'test3@example.com', errno: 444 })
t.equal(ir.isOverBadLogins(), false, 'three records is not over') t.equal(ir.isOverBadLogins(), false, 'three records is not over')
ir.addBadLogin({ errno: 777 }) ir.addBadLogin({ email: 'test4@example.com', errno: 777 })
t.equal(ir.isOverBadLogins(), true, 'four records is over') t.equal(ir.isOverBadLogins(), true, 'four records is over')
var ir2 = simpleIpRecord() var ir2 = simpleIpRecord()
ir2.addBadLogin({ errno: 102 }) ir2.addBadLogin({ email: 'test1@example.com', errno: 102 })
t.equal(ir2.isOverBadLogins(), false, 'one unknown record is not over') t.equal(ir2.isOverBadLogins(), false, 'one unknown record is not over')
ir2.addBadLogin({ errno: 102 }) ir2.addBadLogin({ email: 'test2@example.com', errno: 102 })
t.equal(ir2.isOverBadLogins(), true, 'two unknown records is over') t.equal(ir2.isOverBadLogins(), true, 'two unknown records is over')
t.end() t.end()
} }
) )
test(
'isOverBadLogins counts max per unique email addresses',
function (t) {
var ir = simpleIpRecord()
ir.addBadLogin({ email: 'test1@example.com' })
ir.addBadLogin({ email: 'test1@example.com' })
ir.addBadLogin({ email: 'test1@example.com' })
ir.addBadLogin({ email: 'test1@example.com' })
ir.addBadLogin({ email: 'test1@example.com' })
t.equal(ir.isOverBadLogins(), false, 'one email does not put it over')
ir.addBadLogin({ email: 'test2@example.com' })
t.equal(ir.isOverBadLogins(), false, 'two emails does not put it over')
ir.addBadLogin({ email: 'test3@example.com' })
t.equal(ir.isOverBadLogins(), false, 'three emails does not put it over')
ir.addBadLogin({ email: 'test1@example.com', errno: 102 })
t.equal(ir.isOverBadLogins(), true, 'extra score for first email puts it over')
t.end()
}
)