Changeset

653:c08b0e4b7b38

mod_register_web: Extremely rough web registration page, with captcha
author Matthew Wild <mwild1@gmail.com>
date Sun, 29 Apr 2012 17:36:31 +0100
parents 652:3e6f43ab7e22
children 654:7e444de959bb
files mod_register_web/mod_register_web.lua
diffstat 1 files changed, 102 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_register_web/mod_register_web.lua	Sun Apr 29 17:36:31 2012 +0100
@@ -0,0 +1,102 @@
+local captcha_options = module:get_option("captcha_options", {});
+
+function generate_captcha(display_options)
+	return (([[
+		<script type="text/javascript"
+     		src="http://www.google.com/recaptcha/api/challenge?k=$$recaptcha_public_key$$">
+  		</script>
+  		<noscript>
+     		<iframe src="http://www.google.com/recaptcha/api/noscript?k=$$recaptcha_public_key$$$$recaptcha_display_error$$"
+         		height="300" width="500" frameborder="0"></iframe><br>
+     		<textarea name="recaptcha_challenge_field" rows="3" cols="40">
+     		</textarea>
+     		<input type="hidden" name="recaptcha_response_field"
+         		value="manual_challenge">
+  		</noscript>
+  	]]):gsub("$$([^$]+)$%$", setmetatable({
+  		recaptcha_display_error = display_options and display_options.recaptcha_error
+  			and ("&error="..display_options.recaptcha_error) or "";
+  	}, {
+  		__index = function (t, k)
+  			if captcha_options[k] then return captcha_options[k]; end
+  			module:log("error", "Missing parameter from captcha_options: %s", k);
+  		end })
+  	));
+end
+
+function generate_page(event, display_options)
+	local request = event.request;
+	return [[<!DOCTYPE html>
+	<html><body>
+	<h1>XMPP Account Registration</h1>
+	<form action="]]..request.path..[[" method="POST">]]
+	..("<p>%s</p>\n"):format((display_options or {}).register_error or "")..
+	[[	<table>
+		<tr>
+			<td>Username:</td>
+			<td><input type="text" name="username">@server</td>
+		</tr>
+		<tr>
+			<td>Password:</td>
+			<td><input type="password" name="password"></td>
+		</tr>
+		<tr>
+			<td colspan='2'>]]..generate_captcha(display_options)..[[</td>
+		</tr>
+		</table>
+		<input type="submit" value="Register!">
+	</form>
+	</body></html>]];
+end
+
+function register_user(form)
+	if usermanager.user_exists(form.username, module.host) then
+		return nil, "user-exists";
+	end
+	return usermanager.create_user(form.username, form.password, module.host);
+end
+
+function generate_success(event, form)
+	return [[<!DOCTYPE html>
+	<html><body><p>Registration succeeded! Your account is <pre>]]
+		..form.username.."@"..module.host..
+	[[</pre> - happy chatting!</p></body></html>]];
+end
+
+function generate_register_response(event, form, ok, err)
+	local message;
+	if ok then
+		return generate_success(event, form);
+	else
+		return generate_page(event, { register_error = err });
+	end
+end
+
+function handle_form(event)
+	local request, response = event.request, event.response;
+	local form = http.formdecode(request.body);
+	http.request("http://www.google.com/recaptcha/api/verify", {
+		body = http.formencode {
+			privatekey = captcha_options.recaptcha_private_key;
+			remoteip = request.conn:ip();
+			challenge = form.recaptcha_challenge_field;
+			response = form.recaptcha_response_field;
+		};
+	}, function (verify_result, code)
+		local verify_ok, verify_err = verify_result:match("^([^\n]+)\n([^\n]+)");
+		if verify_ok == "true" then
+			local register_ok, register_err = register_user(form);
+			response:send(generate_register_response(event, form, register_ok, register_err));
+		else
+			response:send(generate_page(event, { register_error = verify_err }));
+		end
+	end);
+	return true; -- Leave connection open until we respond above
+end
+
+module:provides("http", {
+	route = {
+		GET = generate_page;
+		POST = handle_form;
+	};
+});