Better channel bans

This commit is contained in:
calzoneman 2013-04-29 18:59:51 -05:00
parent e315407a48
commit d43f39caa1
10 changed files with 125 additions and 4 deletions

View file

@ -62,6 +62,7 @@ var Channel = function(name) {
html: "" html: ""
}; };
this.ipbans = {}; this.ipbans = {};
this.logins = {};
this.logger = new Logger.Logger("chanlogs/" + this.name + ".log"); this.logger = new Logger.Logger("chanlogs/" + this.name + ".log");
this.i = 0; this.i = 0;
this.time = new Date().getTime(); this.time = new Date().getTime();
@ -132,6 +133,10 @@ Channel.prototype.loadDump = function() {
if(data.motd) { if(data.motd) {
this.motd = data.motd; this.motd = data.motd;
} }
data.logins = data.logins || {};
for(var ip in data.logins) {
this.logins[ip] = data.logins[ip];
}
} }
catch(e) { catch(e) {
Logger.errlog.log("Channel dump load failed: "); Logger.errlog.log("Channel dump load failed: ");
@ -151,7 +156,8 @@ Channel.prototype.saveDump = function() {
queue: this.queue, queue: this.queue,
opts: this.opts, opts: this.opts,
filters: filts, filters: filts,
motd: this.motd motd: this.motd,
logins: this.logins
}; };
var text = JSON.stringify(dump); var text = JSON.stringify(dump);
fs.writeFileSync("chandump/" + this.name, text); fs.writeFileSync("chandump/" + this.name, text);
@ -285,8 +291,14 @@ Channel.prototype.search = function(query, callback) {
/* REGION User interaction */ /* REGION User interaction */
Channel.prototype.userJoin = function(user) { Channel.prototype.userJoin = function(user) {
if(!(user.ip in this.logins)) {
this.logins[user.ip] = [];
}
var parts = user.ip.split(".");
var slash24 = parts[0] + "." + parts[1] + "." + parts[2];
// GTFO // GTFO
if(user.ip in this.ipbans && this.ipbans[user.ip] != null) { if((user.ip in this.ipbans && this.ipbans[user.ip] != null) ||
(slash24 in this.ipbans && this.ipbans[slash24] != null)) {
this.logger.log("--- Kicking " + user.ip + " - banned"); this.logger.log("--- Kicking " + user.ip + " - banned");
this.kick(user, "You're banned!"); this.kick(user, "You're banned!");
user.socket.disconnect(true); user.socket.disconnect(true);
@ -402,6 +414,16 @@ Channel.prototype.sendRankStuff = function(user) {
} }
user.socket.emit("banlist", {entries: ents}); user.socket.emit("banlist", {entries: ents});
} }
if(Rank.hasPermission(user, "seenlogins")) {
var ents = [];
for(var ip in this.logins) {
ents.push({
ip: ip,
name: this.logins[ip].join(",")
});
}
user.socket.emit("seenlogins", {entries: ents});
}
if(Rank.hasPermission(user, "chatFilter")) { if(Rank.hasPermission(user, "chatFilter")) {
var filts = new Array(this.filters.length); var filts = new Array(this.filters.length);
for(var i = 0; i < this.filters.length; i++) { for(var i = 0; i < this.filters.length; i++) {
@ -484,6 +506,9 @@ Channel.prototype.broadcastUsercount = function() {
} }
Channel.prototype.broadcastNewUser = function(user) { Channel.prototype.broadcastNewUser = function(user) {
if(this.logins[user.ip].join("").indexOf(user.name) == -1) {
this.logins[user.ip].push(user.name);
}
this.sendAll("addUser", { this.sendAll("addUser", {
name: user.name, name: user.name,
rank: user.rank, rank: user.rank,

View file

@ -38,6 +38,9 @@ function handle(chan, user, msg, data) {
else if(msg.indexOf("/ban ") == 0) { else if(msg.indexOf("/ban ") == 0) {
handleBan(chan, user, msg.substring(5).split(" ")); handleBan(chan, user, msg.substring(5).split(" "));
} }
else if(msg.indexOf("/ipban ") == 0) {
handleIpban(chan, user, msg.substring(7).split(" "));
}
else if(msg.indexOf("/unban ") == 0) { else if(msg.indexOf("/unban ") == 0) {
handleUnban(chan, user, msg.substring(7).split(" ")); handleUnban(chan, user, msg.substring(7).split(" "));
} }
@ -87,6 +90,29 @@ function handleBan(chan, user, args) {
} }
} }
function handleIpban(chan, user, args) {
if(Rank.hasPermission(user, "ipban") && args.length > 0) {
var name = "";
for(var ip in chan.logins) {
if(ip.indexOf(args[0]) == 0) {
var names = chan.logins[ip];
for(var i = 0; i < names.length; i++) {
var r = chan.getRank(names[i]);
if(r >= user.rank) {
return;
}
}
name = names[names.length - 1];
}
}
chan.logger.log("*** " + user.name + " banned " + args[0]);
chan.banIP(user, {
ip: args[0],
name: name
});
}
}
function handleUnban(chan, user, args) { function handleUnban(chan, user, args) {
if(Rank.hasPermission(user, "ipban") && args.length > 0) { if(Rank.hasPermission(user, "ipban") && args.length > 0) {
chan.logger.log("*** " + user.name + " unbanned " + args[0]); chan.logger.log("*** " + user.name + " unbanned " + args[0]);

View file

@ -2,7 +2,7 @@
"author": "Calvin Montgomery", "author": "Calvin Montgomery",
"name": "CyTube", "name": "CyTube",
"description": "Online media synchronizer and chat", "description": "Online media synchronizer and chat",
"version": "1.4.5", "version": "1.5.0",
"repository": { "repository": {
"url": "http://github.com/calzoneman/sync" "url": "http://github.com/calzoneman/sync"
}, },

View file

@ -35,6 +35,7 @@ var permissions = {
drink : exports.Moderator, drink : exports.Moderator,
seeVoteskip : exports.Moderator, seeVoteskip : exports.Moderator,
uncache : exports.Moderator, uncache : exports.Moderator,
seenlogins : exports.Moderator,
search : exports.Guest, search : exports.Guest,
chat : exports.Guest, chat : exports.Guest,
}; };

View file

@ -9,7 +9,7 @@ The above copyright notice and this permission notice shall be included in all c
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
const VERSION = "1.4.5"; const VERSION = "1.5.0";
var fs = require("fs"); var fs = require("fs");
var Logger = require("./logger.js"); var Logger = require("./logger.js");

View file

@ -303,6 +303,12 @@ User.prototype.initCallbacks = function() {
} }
}.bind(this)); }.bind(this));
this.socket.on("requestSeenlogins", function() {
if(this.channel != null) {
this.channel.sendRankStuff(this);
}
}.bind(this));
this.socket.on("voteskip", function(data) { this.socket.on("voteskip", function(data) {
if(this.channel != null) { if(this.channel != null) {
this.channel.tryVoteskip(this); this.channel.tryVoteskip(this);

View file

@ -111,6 +111,10 @@ function initCallbacks() {
updateBanlist(data.entries); updateBanlist(data.entries);
}); });
socket.on("seenlogins", function(data) {
updateSeenLogins(data.entries);
});
socket.on("acl", updateACL); socket.on("acl", updateACL);
socket.on("voteskip", function(data) { socket.on("voteskip", function(data) {

View file

@ -419,6 +419,16 @@ $("#show_banlist").click(function() {
$("#banlist").show(); $("#banlist").show();
}); });
$("#show_loginlog").click(function() {
$("#modnav li").each(function() {
$(this).removeClass("active");
});
$(".modonly").hide();
$("#show_loginlog").parent().addClass("active");
$("#loginlog").show();
socket.emit("requestSeenlogins");
});
$("#show_motdeditor").click(function() { $("#show_motdeditor").click(function() {
$("#modnav li").each(function() { $("#modnav li").each(function() {
$(this).removeClass("active"); $(this).removeClass("active");

View file

@ -612,6 +612,41 @@ function updateBanlist(entries) {
} }
} }
function updateSeenLogins(entries) {
console.log(entries);
var tbl = $("#loginlog table");
if(tbl.children().length > 1) {
$(tbl.children()[1]).remove();
}
for(var i = 0; i < entries.length; i++) {
var tr = $("<tr/>").appendTo(tbl);
var bantd = $("<td/>").appendTo(tr);
var ban = $("<button/>").addClass("btn btn-mini btn-danger")
.text("Ban")
.appendTo(bantd);
var banrange = $("<button/>").addClass("btn btn-mini btn-danger")
.text("Ban Range")
.appendTo(bantd);
var ip = $("<td/>").text(entries[i].ip).appendTo(tr);
var name = $("<td/>").text(entries[i].name).appendTo(tr);
var callback = (function(ip) { return function() {
socket.emit("chatMsg", {
msg: "/ipban " + ip
});
} })(entries[i].ip);
ban.click(callback);
var callback2 = (function(ip) { return function() {
var parts = ip.split(".");
var slash24 = parts[0] + "." + parts[1] + "." + parts[2];
socket.emit("chatMsg", {
msg: "/ipban " + slash24
});
} })(entries[i].ip);
banrange.click(callback2);
}
}
function updateChatFilters(entries) { function updateChatFilters(entries) {
var tbl = $("#filtereditor table"); var tbl = $("#filtereditor table");
if(tbl.children().length > 1) { if(tbl.children().length > 1) {

View file

@ -132,6 +132,9 @@
<li> <li>
<a href="javascript:void(0)" id="show_banlist">Ban List</a> <a href="javascript:void(0)" id="show_banlist">Ban List</a>
</li> </li>
<li>
<a href="javascript:void(0)" id="show_loginlog">Connection Log</a>
</li>
<li> <li>
<a href="javascript:void(0)" id="show_motdeditor">MOTD</a> <a href="javascript:void(0)" id="show_motdeditor">MOTD</a>
</li> </li>
@ -214,6 +217,17 @@
</table> </table>
</div> </div>
</div> </div>
<div class="row modonly" id="loginlog" style="display: none;">
<div class="span12">
<table class="table table-striped">
<thead>
<th></th>
<th>IP</th>
<th>Names</th>
</thead>
</table>
</div>
</div>
<div class="row modonly" id="motdeditor" style="display: none;"> <div class="row modonly" id="motdeditor" style="display: none;">
<div class="span12"> <div class="span12">
<textarea rows="10" id="motdtext"></textarea> <textarea rows="10" id="motdtext"></textarea>