|
| 1 | +defmodule Recaptcha do |
| 2 | + require Elixir.EEx |
| 3 | + |
| 4 | + @secret_key_errors ~w(missing-input-secret invalid-input-secret) |
| 5 | + |
| 6 | + EEx.function_from_file :defp, :render_template, "lib/template.html.eex", [:assigns] |
| 7 | + |
| 8 | + def display(options \\ []) do |
| 9 | + public_key = options[:public_key] || config.public_key |
| 10 | + render_template(public_key: public_key, options: options) |
| 11 | + end |
| 12 | + |
| 13 | + def verify(remote_ip, response, options \\ []) |
| 14 | + |
| 15 | + def verify(remote_ip, response, options) when is_tuple(remote_ip) do |
| 16 | + verify(:inet_parse.ntoa(remote_ip), response, options) |
| 17 | + end |
| 18 | + |
| 19 | + def verify(remote_ip, response, options) do |
| 20 | + case api_response(remote_ip, response, options) do |
| 21 | + %{"success" => true} -> |
| 22 | + :ok |
| 23 | + %{"success" => false, "error-codes" => error_codes} -> |
| 24 | + handle_error_codes(error_codes) |
| 25 | + %{"success" => false} -> |
| 26 | + :error |
| 27 | + end |
| 28 | + end |
| 29 | + |
| 30 | + defp api_response(remote_ip, response, options) do |
| 31 | + private_key = options[:private_key] || config.private_key |
| 32 | + timeout = options[:timeout] || 3000 |
| 33 | + body_content = URI.encode_query(%{"remoteip" => to_string(remote_ip), |
| 34 | + "response" => response, |
| 35 | + "secret" => private_key}) |
| 36 | + headers = ["Content-type": "application/x-www-form-urlencoded"] |
| 37 | + options = [body: body_content, headers: headers, timeout: timeout] |
| 38 | + HTTPotion.post(config.verify_url, options).body |> Poison.decode! |
| 39 | + end |
| 40 | + |
| 41 | + defp config do |
| 42 | + Application.get_env(:recaptcha, :api_config) |
| 43 | + end |
| 44 | + |
| 45 | + defp handle_error_codes(error_codes) do |
| 46 | + if Enum.any?(error_codes, fn(code) -> Enum.member?(@secret_key_errors, code) end) do |
| 47 | + raise RuntimeError, |
| 48 | + message: "reCaptcha API has declined the private key. Please make sure you've set the correct private key" |
| 49 | + else |
| 50 | + :error |
| 51 | + end |
| 52 | + end |
| 53 | + |
| 54 | +end |
0 commit comments