Mercurial > prosody-modules
comparison mod_register_web/mod_register_web.lua @ 1228:db85ff22ae97
mod_register_web: Add a simple fallback captcha
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sat, 30 Nov 2013 19:00:38 +0100 |
parents | 6015434f0e05 |
children | 12e3bc0fd6ed |
comparison
equal
deleted
inserted
replaced
1227:6015434f0e05 | 1228:db85ff22ae97 |
---|---|
19 return tostring(template.apply(data)); | 19 return tostring(template.apply(data)); |
20 end | 20 end |
21 | 21 |
22 local register_tpl = get_template "register"; | 22 local register_tpl = get_template "register"; |
23 local success_tpl = get_template "success"; | 23 local success_tpl = get_template "success"; |
24 local recaptcha_tpl = get_template "recaptcha"; | |
25 | 24 |
26 function generate_captcha(display_options) | 25 if next(captcha_options) ~= nil then |
27 return recaptcha_tpl.apply(setmetatable({ | 26 local recaptcha_tpl = get_template "recaptcha"; |
28 recaptcha_display_error = display_options and display_options.recaptcha_error | 27 |
29 and ("&error="..display_options.recaptcha_error) or ""; | 28 function generate_captcha(display_options) |
30 }, { | 29 return recaptcha_tpl.apply(setmetatable({ |
31 __index = function (t, k) | 30 recaptcha_display_error = display_options and display_options.recaptcha_error |
32 if captcha_options[k] then return captcha_options[k]; end | 31 and ("&error="..display_options.recaptcha_error) or ""; |
33 module:log("error", "Missing parameter from captcha_options: %s", k); | 32 }, { |
33 __index = function (t, k) | |
34 if captcha_options[k] then return captcha_options[k]; end | |
35 module:log("error", "Missing parameter from captcha_options: %s", k); | |
36 end | |
37 })); | |
38 end | |
39 function verify_captcha(form, callback) | |
40 http.request("https://www.google.com/recaptcha/api/verify", { | |
41 body = http.formencode { | |
42 privatekey = captcha_options.recaptcha_private_key; | |
43 remoteip = request.conn:ip(); | |
44 challenge = form.recaptcha_challenge_field; | |
45 response = form.recaptcha_response_field; | |
46 }; | |
47 }, function (verify_result, code) | |
48 local verify_ok, verify_err = verify_result:match("^([^\n]+)\n([^\n]+)"); | |
49 if verify_ok == "true" then | |
50 callback(true); | |
51 else | |
52 callback(false, verify_err) | |
53 end | |
54 end); | |
55 end | |
56 else | |
57 module:log("debug", "No Recaptcha options set, using fallback captcha") | |
58 local hmac_sha1 = require "util.hashes".hmac_sha1; | |
59 local secret = require "util.uuid".generate() | |
60 local ops = { '+', '-' }; | |
61 local captcha_tpl = get_template "simplecaptcha"; | |
62 function generate_captcha() | |
63 local op = ops[math.random(1, #ops)]; | |
64 local x, y = math.random(1, 9) | |
65 repeat | |
66 y = math.random(1, 9); | |
67 until x ~= y; | |
68 local answer; | |
69 if op == '+' then | |
70 answer = x + y; | |
71 elseif op == '-' then | |
72 if x < y then | |
73 -- Avoid negative numbers | |
74 x, y = y, x; | |
75 end | |
76 answer = x - y; | |
34 end | 77 end |
35 })); | 78 local challenge = hmac_sha1(secret, answer, true); |
36 end | 79 return captcha_tpl.apply { |
37 function verify_captcha(form, callback) | 80 op = op, x = x, y = y, challenge = challenge; |
38 http.request("https://www.google.com/recaptcha/api/verify", { | |
39 body = http.formencode { | |
40 privatekey = captcha_options.recaptcha_private_key; | |
41 remoteip = request.conn:ip(); | |
42 challenge = form.recaptcha_challenge_field; | |
43 response = form.recaptcha_response_field; | |
44 }; | 81 }; |
45 }, function (verify_result, code) | 82 end |
46 local verify_ok, verify_err = verify_result:match("^([^\n]+)\n([^\n]+)"); | 83 function verify_captcha(form, callback) |
47 if verify_ok == "true" then | 84 if hmac_sha1(secret, form.captcha_reply, true) == form.captcha_challenge then |
48 callback(true); | 85 callback(true); |
49 else | 86 else |
50 callback(false, verify_err) | 87 callback(false, "Captcha verification failed"); |
51 end | 88 end |
52 end); | 89 end |
53 end | 90 end |
54 | 91 |
55 function generate_page(event, display_options) | 92 function generate_page(event, display_options) |
56 local request = event.request; | 93 local request = event.request; |
57 | 94 |