Bans and locks work by username too

Now, when a user logs into a registered username that was previously
locked/banned, that user is also locked/banned.

The main reason this matters is because users who log in under an
autoconfirmed username are permanently autoconfirmed, even if they
log out and in to a new username. So when they're banned, they can
switch IP and regain autoconfirmed status. This change bans the
username that was autoconfirmed as well, so attempting to use it
to regain autoconfirmed status will result in an automatic re-ban.
This commit is contained in:
Guangcong Luo 2014-03-16 02:40:16 -04:00
parent 60e8bbf044
commit 47e902266b

View File

@ -30,7 +30,9 @@ var prevUsers = {};
var numUsers = 0;
var bannedIps = {};
var bannedUsers = {};
var lockedIps = {};
var lockedUsers = {};
/**
* Get a user.
@ -499,10 +501,23 @@ var User = (function () {
var oldid = this.userid;
delete users[oldid];
this.userid = userid;
users[this.userid] = this;
users[userid] = this;
this.authenticated = !!authenticated;
this.forceRenamed = !!forcible;
if (authenticated && userid in bannedUsers) {
var bannedUnder = '';
if (bannedUsers[userid] !== userid) bannedUnder = ' under the username '+bannedUsers[userid];
this.send("|popup|Your username ("+name+") is banned"+bannedUnder+"'. Your ban will expire in a few days."+(config.appealurl ? " Or you can appeal at:\n" + config.appealurl:""));
this.ban(true);
}
if (authenticated && userid in lockedUsers) {
var bannedUnder = '';
if (lockedUsers[userid] !== userid) bannedUnder = ' under the username '+lockedUsers[userid];
this.send("|popup|Your username ("+name+") is locked"+bannedUnder+"'. Your lock will expire in a few days."+(config.appealurl ? " Or you can appeal at:\n" + config.appealurl:""));
this.lock(true);
}
for (var i=0; i<this.connections.length; i++) {
//console.log(''+name+' renaming: socket '+i+' of '+this.connections.length);
var initdata = '|updateuser|'+this.name+'|'+(true?'1':'0')+'|'+this.avatar;
@ -1007,18 +1022,24 @@ var User = (function () {
this.updateIdentity(roomid);
}
};
User.prototype.ban = function(noRecurse) {
User.prototype.ban = function(noRecurse, userid) {
// recurse only once; the root for-loop already bans everything with your IP
if (!userid) userid = this.userid;
if (!noRecurse) for (var i in users) {
if (users[i] === this) continue;
if (Object.isEmpty(Object.select(this.ips, users[i].ips))) continue;
users[i].ban(true);
users[i].ban(true, userid);
}
for (var ip in this.ips) {
bannedIps[ip] = this.userid;
bannedIps[ip] = userid;
}
if (this.autoconfirmed) bannedUsers[this.autoconfirmed] = userid;
if (this.authenticated) {
bannedUsers[this.userid] = userid;
this.locked = true; // in case of merging into a recently banned account
this.autoconfirmed = '';
}
this.locked = true; // in case of merging into a recently banned account
this.disconnectAll();
};
User.prototype.lock = function(noRecurse) {
@ -1032,14 +1053,19 @@ var User = (function () {
for (var ip in this.ips) {
lockedIps[ip] = this.userid;
}
if (this.autoconfirmed) lockedUsers[this.autoconfirmed] = this.userid;
if (this.authenticated) lockedUsers[this.userid] = this.userid;
this.locked = true;
this.autoconfirmed = '';
this.updateIdentity();
};
User.prototype.joinRoom = function(room, connection) {
room = Rooms.get(room);
if (!room) return false;
if (room.staffRoom && !this.isStaff) return false;
if (this.userid && room.bannedUsers && this.userid in room.bannedUsers) return false;
if (room.bannedUsers) {
if (this.userid in room.bannedUsers || this.autoconfirmed in room.bannedUsers) return false;
}
if (this.ips && room.bannedIps) {
for (var ip in this.ips) {
if (ip in room.bannedIps) return false;
@ -1399,6 +1425,12 @@ function unban(name) {
success = true;
}
}
for (var id in bannedUsers) {
if (bannedUsers[id] === userid || id === userid) {
delete bannedUsers[id];
success = true;
}
}
if (success) return name;
return false;
}
@ -1426,6 +1458,12 @@ function unlock(name, unlocked, noRecurse) {
unlocked[name] = 1;
}
}
for (var id in lockedUsers) {
if (lockedUsers[id] === userid || id === userid) {
delete lockedUsers[id];
unlocked[name] = 1;
}
}
return unlocked;
}
exports.unban = unban;