Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Porter <slug@qwebirc.org>2011-02-20 02:43:27 (GMT)
committer Chris Porter <slug@qwebirc.org>2011-02-20 02:43:27 (GMT)
commitf5d3c401f8a649bbf7ee150cdc3fbe2851364c8c (patch)
tree2d1e43d110aca5317498d32ca5820df9d6071c14
parentfef44cde4b20e0b538a5ce9d54653788ed644337 (diff)
Add nickname validation.
-rw-r--r--bin/optionsgen.py20
-rw-r--r--bin/pages.py2
-rw-r--r--config.py.example30
-rw-r--r--js/irc/nicknamevalidator.js31
-rw-r--r--js/qwebircinterface.js10
-rw-r--r--js/ui/panes/connect.js9
-rw-r--r--js/ui/panes/embed.js7
7 files changed, 104 insertions, 5 deletions
diff --git a/bin/optionsgen.py b/bin/optionsgen.py
index 584c884..f998283 100644
--- a/bin/optionsgen.py
+++ b/bin/optionsgen.py
@@ -2,5 +2,23 @@ import config
import qwebirc.util.qjson as json
def get_options():
- options = dict(networkName=config.NETWORK_NAME, networkServices=[config.AUTH_SERVICE], loginRegex=config. AUTH_OK_REGEX, appTitle=config.APP_TITLE, baseURL=config.BASE_URL, staticBaseURL=config.STATIC_BASE_URL, dynamicBaseURL=config.DYNAMIC_BASE_URL)
+ options = dict(
+ networkName=config.NETWORK_NAME,
+ networkServices=[config.AUTH_SERVICE],
+ loginRegex=config.AUTH_OK_REGEX,
+ appTitle=config.APP_TITLE,
+ baseURL=config.BASE_URL,
+ staticBaseURL=config.STATIC_BASE_URL,
+ dynamicBaseURL=config.DYNAMIC_BASE_URL,
+ validateNickname=False
+ )
+
+ if hasattr(config, "NICKNAME_VALIDATE") and config.NICKNAME_VALIDATE:
+ options["nickValidation"] = dict(
+ minLen=config.NICKNAME_MINIMUM_LENGTH,
+ maxLen=config.NICKNAME_MAXIMUM_LENGTH,
+ validFirstChar=config.NICKNAME_VALID_FIRST_CHAR,
+ validSubChars=config.NICKNAME_VALID_SUBSEQUENT_CHARS
+ )
+
return json.dumps(options)
diff --git a/bin/pages.py b/bin/pages.py
index 7d62b33..105d771 100644
--- a/bin/pages.py
+++ b/bin/pages.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python
-IRC_BASE = ["ircconnection", "irclib", "numerics", "baseircclient", "irctracker", "commandparser", "commands", "ircclient", "commandhistory"]
+IRC_BASE = ["ircconnection", "irclib", "numerics", "baseircclient", "irctracker", "commandparser", "commands", "ircclient", "commandhistory", "nicknamevalidator"]
PANES = ["connect", "embed", "options", "about", "privacypolicy", "feedback", "faq"]
UI_BASE = ["menuitems", "baseui", "baseuiwindow", "colour", "url", "theme", "notifications", "tabcompleter", "style"]
UI_BASE.extend(["panes/%s" % x for x in PANES])
diff --git a/config.py.example b/config.py.example
index 485b0f3..ff33b11 100644
--- a/config.py.example
+++ b/config.py.example
@@ -96,6 +96,36 @@ NETWORK_NAME = "FooNet"
# The title of the application in the web browser.
APP_TITLE = NETWORK_NAME + " Web IRC"
+# NICKNAME VALIDATION OPTIONS
+# ---------------------------------------------------------------------
+#
+# OPTION: NICKNAME_VALIDATE
+# If True then user nicknames will be validated according to
+# the configuration below, otherwise they will be passed
+# directly to the ircd.
+NICKNAME_VALIDATE = True
+
+# OPTION: NICKNAME_VALID_FIRST_CHAR
+# A string containing valid characters for the first letter of
+# a nickname.
+# Default is as in RFC1459.
+import string
+NICKNAME_VALID_FIRST_CHAR = string.letters + "_[]{}`^\\|"
+
+# OPTION: NICKNAME_VALID_SUBSEQUENT_CHAR
+# A string containing valid characters for the rest of the
+# nickname.
+NICKNAME_VALID_SUBSEQUENT_CHARS = NICKNAME_VALID_FIRST_CHAR + string.digits + "-"
+
+# OPTION: NICKNAME_MINIMUM_LENGTH
+# Minimum characters permitted in a nickname on your network.
+NICKNAME_MINIMUM_LENGTH = 2
+
+# OPTION: NICKNAME_MAXIMUM_LENGTH
+# Maximum characters permitted in a nickname on your network.
+# Ideally we'd extract this from the ircd, but we need to know
+# before we connect.
+NICKNAME_MAXIMUM_LENGTH = 15
# FEEDBACK OPTIONS
# ---------------------------------------------------------------------
diff --git a/js/irc/nicknamevalidator.js b/js/irc/nicknamevalidator.js
new file mode 100644
index 0000000..b751b90
--- /dev/null
+++ b/js/irc/nicknamevalidator.js
@@ -0,0 +1,31 @@
+qwebirc.irc.DummyNicknameValidator = new Class({
+ validate: function(x) {
+ return x;
+ }
+});
+
+qwebirc.irc.NicknameValidator = new Class({
+ initialize: function(options) {
+ this.options = options;
+ },
+ validate: function(nick, permitDot) {
+ var r = [];
+
+ var max = Math.min(this.options.maxLen, nick.length);
+ var exploded = nick.split("");
+ for(var i=0;i<max;i++) {
+ var c = exploded[i];
+
+ var valid = i == 0 ? this.options.validFirstChar : this.options.validSubChars;
+ if(valid.indexOf(c) != -1 || permitDot && c == ".") {
+ r.push(c);
+ } else {
+ r.push("_"); /* yeah we assume this is valid... */
+ }
+ }
+
+ while(r.length < this.options.minLen)
+ r.push("_"); /* yeah we assume this is valid... */
+ return r.join("");
+ }
+});
diff --git a/js/qwebircinterface.js b/js/qwebircinterface.js
index 046ddc6..5d5035b 100644
--- a/js/qwebircinterface.js
+++ b/js/qwebircinterface.js
@@ -22,13 +22,19 @@ qwebirc.ui.Interface = new Class({
saturation: null,
lightness: null,
uiOptionsArg: null,
+ nickValidation: null,
dynamicBaseURL: "/",
staticBaseURL: "/"
},
initialize: function(element, ui, options) {
- qwebirc.global = {dynamicBaseURL: options.dynamicBaseURL, staticBaseURL: options.staticBaseURL}; /* HACK */
-
this.setOptions(options);
+
+ /* HACK */
+ qwebirc.global = {
+ dynamicBaseURL: options.dynamicBaseURL,
+ staticBaseURL: options.staticBaseURL,
+ nicknameValidator: $defined(options.nickValidation) ? new qwebirc.irc.NicknameValidator(options.nickValidation) : new qwebirc.irc.DummyNicknameValidator()
+ };
window.addEvent("domready", function() {
var callback = function(options) {
diff --git a/js/ui/panes/connect.js b/js/ui/panes/connect.js
index fe12800..c7004d7 100644
--- a/js/ui/panes/connect.js
+++ b/js/ui/panes/connect.js
@@ -202,7 +202,14 @@ qwebirc.ui.LoginBox = function(parentElement, callback, initialNickname, initial
nick.focus();
return;
}
-
+ var stripped = qwebirc.global.nicknameValidator.validate(nickname);
+ if(stripped != nickname) {
+ nick.value = stripped;
+ alert("Your nickname was invalid and has been corrected; please check your altered nickname and press Connect again.");
+ nick.focus();
+ return;
+ }
+
var data = {"nickname": nickname, "autojoin": chans};
if(qwebirc.auth.enabled()) {
if(qwebirc.auth.passAuth() && authCheckBox.checked) {
diff --git a/js/ui/panes/embed.js b/js/ui/panes/embed.js
index 56518a2..baf4cba 100644
--- a/js/ui/panes/embed.js
+++ b/js/ui/panes/embed.js
@@ -184,6 +184,13 @@ qwebirc.ui.EmbedWizard = new Class({
this.nicknameBox.focus();
return false;
}
+ var v = qwebirc.global.nicknameValidator.validate(this.nicknameBox.value, true);
+ if(v != this.nicknameBox.value) {
+ this.nicknameBox.value = v;
+ alert("The supplied nickname was invalid and has been corrected.");
+ this.nicknameBox.focus();
+ return false;
+ }
return true;
}.bind(this),
middle: this.nicknameBox,