113 lines
No EOL
2.6 KiB
Lua
113 lines
No EOL
2.6 KiB
Lua
local http = require "resty.http"
|
|
local cjson = require "cjson"
|
|
local template = require "plugins.crowdsec.template"
|
|
local utils = require "plugins.crowdsec.utils"
|
|
|
|
|
|
local M = {_TYPE='module', _NAME='recaptcha.funcs', _VERSION='1.0-0'}
|
|
|
|
local recaptcha_verify_url = "https://www.google.com/recaptcha/api/siteverify"
|
|
|
|
M._VERIFY_STATE = "to_verify"
|
|
M._VALIDATED_STATE = "validated"
|
|
|
|
|
|
M.State = {}
|
|
M.State["1"] = M._VERIFY_STATE
|
|
M.State["2"] = M._VALIDATED_STATE
|
|
|
|
M.SecretKey = ""
|
|
M.SiteKey = ""
|
|
M.Template = ""
|
|
|
|
|
|
function M.GetStateID(state)
|
|
for k, v in pairs(M.State) do
|
|
if v == state then
|
|
return tonumber(k)
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
|
|
|
|
function M.New(siteKey, secretKey, TemplateFilePath)
|
|
|
|
if siteKey == nil or siteKey == "" then
|
|
return "no recaptcha site key provided, can't use recaptcha"
|
|
end
|
|
M.SiteKey = siteKey
|
|
|
|
if secretKey == nil or secretKey == "" then
|
|
return "no recaptcha secret key provided, can't use recaptcha"
|
|
end
|
|
|
|
M.SecretKey = secretKey
|
|
|
|
if utils.file_exist(TemplateFilePath) == false then
|
|
return "captcha template file doesn't exist, can't use recaptcha"
|
|
end
|
|
|
|
local captcha_template = utils.read_file(TemplateFilePath)
|
|
if captcha_template == nil then
|
|
return "Template file " .. TemplateFilePath .. "not found."
|
|
end
|
|
|
|
local template_data = {}
|
|
template_data["recaptcha_site_key"] = M.SiteKey
|
|
local view = template.compile(captcha_template, template_data)
|
|
M.Template = view
|
|
|
|
return nil
|
|
end
|
|
|
|
|
|
function M.GetTemplate()
|
|
return M.Template
|
|
end
|
|
|
|
|
|
function table_to_encoded_url(args)
|
|
local params = {}
|
|
for k, v in pairs(args) do table.insert(params, k .. '=' .. v) end
|
|
return table.concat(params, "&")
|
|
end
|
|
|
|
function M.Validate(g_captcha_res, remote_ip)
|
|
local body = {
|
|
secret = M.SecretKey,
|
|
response = g_captcha_res,
|
|
remoteip = remote_ip
|
|
}
|
|
|
|
local data = table_to_encoded_url(body)
|
|
local httpc = http.new()
|
|
httpc:set_timeout(1000)
|
|
local res, err = httpc:request_uri(recaptcha_verify_url, {
|
|
method = "POST",
|
|
body = data,
|
|
headers = {
|
|
["Content-Type"] = "application/x-www-form-urlencoded",
|
|
},
|
|
})
|
|
if err ~= nil then
|
|
return true, err
|
|
end
|
|
|
|
local result = cjson.decode(res.body)
|
|
|
|
if result.success == false then
|
|
for k, v in pairs(result["error-codes"]) do
|
|
if v == "invalid-input-secret" then
|
|
ngx.log(ngx.ERR, "reCaptcha secret key is invalid")
|
|
return true, nil
|
|
end
|
|
end
|
|
end
|
|
|
|
return result.success, nil
|
|
end
|
|
|
|
|
|
return M |