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 |
