Skip to content
This repository
Browse code

Added some ReCAPTCHA files

  • Loading branch information...
commit e2de9b8e2b94cd5d56b7e18882940958f26f6062 1 parent 9336013
Jonathan McAllister authored
BIN  Mnesia.nitrogen@localhost/DECISION_TAB.LOG
Binary file not shown
BIN  Mnesia.nitrogen@localhost/LATEST.LOG
Binary file not shown
BIN  Mnesia.nitrogen@localhost/users.DCD
Binary file not shown
BIN  ebin/db_users.beam
Binary file not shown
BIN  ebin/web_users_dashboard.beam
Binary file not shown
BIN  ebin/web_users_register.beam
Binary file not shown
10 src/db_users.erl
@@ -20,7 +20,7 @@
20 20 -module(db_users).
21 21 -include("wf.inc").
22 22 -include("config.inc").
23   --export([init/0, add_user/3, validate_user/2, delete_user/1, is_username_used/1, is_email_used/1, get_email_address/1, verify_email/1, invalidate_email/1, delete_email_verification_code/1, new_email_verification_code/1]).
  23 +-export([init/0, add_user/3, validate_user/2, delete_user/1, is_username_used/1, is_email_used/1, get_email_address/1, update_email_address/2, verify_email/1, invalidate_email/1, delete_email_verification_code/1, new_email_verification_code/1]).
24 24
25 25 -include_lib("stdlib/include/qlc.hrl").
26 26
@@ -144,6 +144,14 @@ check(Username, EmailAddress, Input) ->
144 144 get_email_address(Username) ->
145 145 db_utils:do(qlc:q([X#users.email_address || X <- mnesia:table(users), X#users.username =:= Username])).
146 146
  147 +update_email_address(Username, NewEmailAddress) ->
  148 + FUpdateEmailAddress = fun() ->
  149 + [EmailAddress] = mnesia:read(users, Username, write),
  150 + EmailAddressUpdate = EmailAddress#users{email_address=NewEmailAddress},
  151 + mnesia:write(EmailAddressUpdate)
  152 + end,
  153 + mnesia:transaction(FUpdateEmailAddress).
  154 + % TODO: invalidate the email address
147 155
148 156 verify_email(Code) ->
149 157 FGetUsername = fun() ->
5 src/pages/web_users_dashboard.erl
@@ -21,8 +21,9 @@
21 21 -include_lib ("nitrogen/include/wf.inc").
22 22 -compile(export_all).
23 23
24   -main() ->
25   - case wf:user() of
  24 +main() ->
  25 + Username = wf:user(),
  26 + case Username of
26 27 undefined ->
27 28 wf:redirect("login");
28 29 _ ->
44 src/pages/web_users_register.erl
@@ -51,7 +51,7 @@ body() ->
51 51 #br {},
52 52 #password { id=password2 },
53 53 #br {},
54   - #recaptcha {},
  54 + #recaptcha { id=recaptcha, public_key="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" },
55 55 #br {},
56 56 #button { id=submit, text="Register", postback=register },
57 57 #flash { id=flash },
@@ -70,24 +70,28 @@ body() ->
70 70
71 71
72 72 event(register) ->
73   - io:format("response: ~s~n", [hd(wf:q(recaptcha_response_field))]),
74   - io:format("challenge ~s~n", [hd(wf:q(recaptcha_challenge_field))]),
75   -
76   -
77   -
78   - case db_users:add_user(hd(wf:q(username)), hd(wf:q(email_address)), hd(wf:q(password))) of
79   - ok ->
80   - io:format("New user: ~s has signed up~n", [wf:q(username)]),
81   - wf:user(hd(wf:q(username))),
82   - wf:redirect("dashboard");
83   - aborted ->
84   - wc:flash("Error: Registration failed, please try again.")
  73 + %io:format("response: ~s~n", [hd(wf:q(recaptcha_response_field))]),
  74 + %io:format("challenge: ~s~n", [hd(wf:q(recaptcha_challenge_field))]),
  75 + %io:format("ip: ~p~n", [inet_parse:ntoa(ip())]),
  76 + %io:format("answer: ~p~n", [util_recaptcha:recaptcha_check_answer(inet_parse:ntoa(ip()), hd(wf:q(recaptcha_challenge_field)), hd(wf:q(recaptcha_response_field)))]),
  77 + case util_recaptcha:check_answer(inet_parse:ntoa(util_ip:ip()), hd(wf:q(recaptcha_challenge_field)), hd(wf:q(recaptcha_response_field))) of
  78 + {"true", "success"} ->
  79 + case db_users:add_user(hd(wf:q(username)), hd(wf:q(email_address)), hd(wf:q(password))) of
  80 + ok ->
  81 + io:format("New user: ~s has signed up~n", [wf:q(username)]),
  82 + wf:user(hd(wf:q(username))),
  83 + wf:redirect("dashboard");
  84 + aborted ->
  85 + wf:flash("Error: Registration failed, please try again.")
  86 + end;
  87 + {"false", _} ->
  88 + %{_,{_,_,Error}} = util_recaptcha:get_error(ErrorCode),
  89 + %io:format("Error: ~p~n", [Error]),
  90 + %wf:update(recaptcha, #panel { id=recaptcha, body="<script type='text/javascript'>" ++ Error ++ "</script>" }),
  91 + wf:flash("Error: The CAPTCHA answer was incorrect, please try again.")
85 92 end;
86 93 event(_) -> ok.
87 94
88   -
89   -
90   -
91 95 is_username_used(_, _) ->
92 96 db_users:is_username_used(hd(wf:q(username))).
93 97
@@ -95,13 +99,7 @@ is_email_used(_, _) ->
95 99 db_users:is_email_used(hd(wf:q(email_address))).
96 100
97 101 check_username(_, _) ->
98   -% case string:chr(hd(wf:q(username)), $ ) of
99   -% 0 ->
100   -% true;
101   -% _ ->
102   -% false
103   -% end.
104   - case regexp:first_match(hd(wf:q(username)), "[^A-z0-9.]") of
  102 + case regexp:first_match(hd(wf:q(username)), "[^A-z0-9.]") of % not a letter, not a number, or not a period
105 103 nomatch ->
106 104 true;
107 105 _ ->
18 src/utils/util_ip.erl
... ... @@ -0,0 +1,18 @@
  1 +-module(util_ip).
  2 +-compile(export_all).
  3 +
  4 +ip() ->
  5 + %% Parts adapted from mochiweb_request.erl
  6 + Socket = wf_platform:get_socket(),
  7 + case inet:peername(Socket) of
  8 + {ok, {Addr = {X, _, _, _}, _Port}} when X == 10;
  9 + Addr == {127,0,0,1} ->
  10 + case wf_platform:get_header(x_forwarded_for) of
  11 + undefined -> Addr;
  12 + Hosts -> case inet_parse:address(string:strip(lists:last(string:tokens(Hosts, ",")))) of
  13 + {ok, AddrFwd} -> AddrFwd;
  14 + _ -> Addr
  15 + end
  16 + end;
  17 + {ok, {Addr, _Port}} -> Addr
  18 + end.
67 src/utils/util_recaptcha.erl
... ... @@ -0,0 +1,67 @@
  1 +% Copyright (c) 2009 Buddy Moore
  2 +%
  3 +% Permission is hereby granted, free of charge, to any person
  4 +% obtaining a copy of this software and associated documentation
  5 +% files (the "Software"), to deal in the Software without
  6 +% restriction, including without limitation the rights to use,
  7 +% copy, modify, merge, publish, distribute, sublicense, and/or sell
  8 +% copies of the Software, and to permit persons to whom the
  9 +% Software is furnished to do so, subject to the following
  10 +% conditions:
  11 +%
  12 +% The above copyright notice and this permission notice shall be
  13 +% included in all copies or substantial portions of the Software.
  14 +%
  15 +% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16 +% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  17 +% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18 +% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  19 +% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  20 +% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21 +% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  22 +% OTHER DEALINGS IN THE SOFTWARE.
  23 +
  24 +-module(util_recaptcha).
  25 +
  26 +-export([check_answer/3, get_error/1]).
  27 +
  28 +get_verify_url() ->
  29 + "http://api-verify.recaptcha.net/verify".
  30 +
  31 +get_challenge_url() ->
  32 + "http://api-secure.recaptcha.net/challenge".
  33 +
  34 +private_key() ->
  35 + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA".
  36 +
  37 +public_key() ->
  38 + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA".
  39 +
  40 +check_answer(RemoteIp, Challenge, Response) ->
  41 + %inets:start(),
  42 + Data = "privatekey=" ++ private_key() ++ "&remoteip=" ++ RemoteIp ++ "&challenge=" ++ Challenge ++ "&response=" ++ Response,
  43 +
  44 + BodyStr =
  45 + case make_http_request(get_verify_url(), Data) of
  46 + {ok, saved_to_file} ->
  47 + "saved";
  48 + {ok, Result} ->
  49 + case Result of
  50 + {_Status, _Headers, Body} -> Body;
  51 + {_Status, Body} -> Body
  52 + end;
  53 + {error, _Reason} -> "error"
  54 + end,
  55 + Lines = string:tokens(BodyStr, "\r\n"),
  56 + [Line1 | Rest] = Lines,
  57 + [Line2 | _Rest2] = Rest,
  58 + {Line1, Line2}.
  59 +
  60 +make_http_request(URL, Data) ->
  61 + http:request(post, {URL, [{"Host", URL}, {"User-Agent", "reCAPTCHA/PHP"}, {"Content-Length", integer_to_list(string:len(Data))} ], "application/x-www-form-urlencoded", Data }, [], []).
  62 +
  63 +get_error(ErrorCode) ->
  64 + Data = "?k=" ++ public_key() ++ "&error=" ++ ErrorCode,
  65 + http:request(get_challenge_url() ++ Data).
  66 +
  67 +
26 wwwroot/verification.html
... ... @@ -0,0 +1,26 @@
  1 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  2 +<html xmlns="http://www.w3.org/1999/xhtml">
  3 +<head>
  4 +<title>[[[page:title()]]]</title>
  5 +<script src='/nitrogen/jquery.js' type='text/javascript' charset='utf-8'></script>
  6 +<script src='/nitrogen/jquery-ui.js' type='text/javascript' charset='utf-8'></script>
  7 +<script src='/nitrogen/livevalidation.js' type='text/javascript' charset='utf-8'></script>
  8 +<script src='/nitrogen/nitrogen.js' type='text/javascript' charset='utf-8'></script>
  9 +<link rel="stylesheet" href="/nitrogen/jquery-ui/jquery-ui.css" type="text/css" media="screen" charset="utf-8">
  10 +<link rel="stylesheet" href="/nitrogen/elements.css" type="text/css" media="screen" charset="utf-8">
  11 +</head>
  12 +
  13 +<body>
  14 +
  15 +<h1>[[[page:title()]]]</h1>
  16 +
  17 +[[[element_flash:render()]]]
  18 +
  19 +[[[page:body(Verified)]]]
  20 +
  21 +
  22 +<script>
  23 +[[[script]]]
  24 +</script>
  25 +</body>
  26 +</html>

0 comments on commit e2de9b8

Please sign in to comment.
Something went wrong with that request. Please try again.