mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-26 17:38:45 +01:00
Added mod_register_web: web page for account registration (EJAB-471)
This commit is contained in:
parent
60b36beda8
commit
f672fd0824
@ -88,6 +88,7 @@
|
|||||||
\newcommand{\modpubsub}{\module{mod\_pubsub}}
|
\newcommand{\modpubsub}{\module{mod\_pubsub}}
|
||||||
\newcommand{\modpubsubodbc}{\module{mod\_pubsub\_odbc}}
|
\newcommand{\modpubsubodbc}{\module{mod\_pubsub\_odbc}}
|
||||||
\newcommand{\modregister}{\module{mod\_register}}
|
\newcommand{\modregister}{\module{mod\_register}}
|
||||||
|
\newcommand{\modregisterweb}{\module{mod\_register\_web}}
|
||||||
\newcommand{\modroster}{\module{mod\_roster}}
|
\newcommand{\modroster}{\module{mod\_roster}}
|
||||||
\newcommand{\modrosterodbc}{\module{mod\_roster\_odbc}}
|
\newcommand{\modrosterodbc}{\module{mod\_roster\_odbc}}
|
||||||
\newcommand{\modservicelog}{\module{mod\_service\_log}}
|
\newcommand{\modservicelog}{\module{mod\_service\_log}}
|
||||||
@ -2530,6 +2531,7 @@ The following table lists all modules included in \ejabberd{}.
|
|||||||
\hline \ahrefloc{modpubsub}{\modpubsub{}} & Pub-Sub (\xepref{0060}), PEP (\xepref{0163}) & \modcaps{} \\
|
\hline \ahrefloc{modpubsub}{\modpubsub{}} & Pub-Sub (\xepref{0060}), PEP (\xepref{0163}) & \modcaps{} \\
|
||||||
\hline \ahrefloc{modpubsub}{\modpubsubodbc{}} & Pub-Sub (\xepref{0060}), PEP (\xepref{0163}) & supported DB (*) and \modcaps{} \\
|
\hline \ahrefloc{modpubsub}{\modpubsubodbc{}} & Pub-Sub (\xepref{0060}), PEP (\xepref{0163}) & supported DB (*) and \modcaps{} \\
|
||||||
\hline \ahrefloc{modregister}{\modregister{}} & In-Band Registration (\xepref{0077}) & \\
|
\hline \ahrefloc{modregister}{\modregister{}} & In-Band Registration (\xepref{0077}) & \\
|
||||||
|
\hline \ahrefloc{modregisterweb}{\modregisterweb{}} & Web for Account Registrations & \\
|
||||||
\hline \ahrefloc{modroster}{\modroster{}} & Roster management (XMPP IM) & \\
|
\hline \ahrefloc{modroster}{\modroster{}} & Roster management (XMPP IM) & \\
|
||||||
\hline \ahrefloc{modroster}{\modrosterodbc{}} & Roster management (XMPP IM) & supported DB (*) \\
|
\hline \ahrefloc{modroster}{\modrosterodbc{}} & Roster management (XMPP IM) & supported DB (*) \\
|
||||||
\hline \ahrefloc{modservicelog}{\modservicelog{}} & Copy user messages to logger service & \\
|
\hline \ahrefloc{modservicelog}{\modservicelog{}} & Copy user messages to logger service & \\
|
||||||
@ -3862,6 +3864,49 @@ Also define a registration timeout of one hour:
|
|||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
|
\makesubsection{modregisterweb}{\modregisterweb{}}
|
||||||
|
\ind{modules!\modregisterweb{}}
|
||||||
|
|
||||||
|
This module provides a web page where people can:
|
||||||
|
\begin{itemize}
|
||||||
|
\item Register a new account on the server.
|
||||||
|
\item Change the password from an existing account on the server.
|
||||||
|
\item Delete an existing account on the server.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
This module supports CAPTCHA image to register a new account.
|
||||||
|
To enable this feature, configure the options captcha\_cmd and captcha\_host.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
\begin{description}
|
||||||
|
\titem{\{registration\_watchers, [ JID, ...]\}} \ind{options!rwatchers}This option defines a
|
||||||
|
list of JIDs which will be notified each time a new account is registered.
|
||||||
|
\end{description}
|
||||||
|
|
||||||
|
This example configuration shows how to enable the module and the web handler:
|
||||||
|
\begin{verbatim}
|
||||||
|
{listen, [
|
||||||
|
...
|
||||||
|
{5281, ejabberd_http, [
|
||||||
|
tls,
|
||||||
|
{certfile, "/etc/ejabberd/certificate.pem"},
|
||||||
|
register
|
||||||
|
]},
|
||||||
|
...
|
||||||
|
]}.
|
||||||
|
|
||||||
|
{modules,
|
||||||
|
[
|
||||||
|
...
|
||||||
|
{mod_register_web, []},
|
||||||
|
...
|
||||||
|
]}.
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
The users can visit this page: https://localhost:5281/register/
|
||||||
|
It is important to include the last / character in the URL,
|
||||||
|
otherwise the subpages URL will be incorrect.
|
||||||
|
|
||||||
\makesubsection{modroster}{\modroster{}}
|
\makesubsection{modroster}{\modroster{}}
|
||||||
\ind{modules!\modroster{}}\ind{roster management}\ind{protocols!RFC 3921: XMPP IM}
|
\ind{modules!\modroster{}}\ind{roster management}\ind{protocols!RFC 3921: XMPP IM}
|
||||||
|
|
||||||
|
@ -162,6 +162,7 @@
|
|||||||
captcha,
|
captcha,
|
||||||
http_bind,
|
http_bind,
|
||||||
http_poll,
|
http_poll,
|
||||||
|
register,
|
||||||
web_admin
|
web_admin
|
||||||
]}
|
]}
|
||||||
|
|
||||||
@ -546,6 +547,13 @@
|
|||||||
|
|
||||||
{access, register}
|
{access, register}
|
||||||
]},
|
]},
|
||||||
|
{mod_register_web, [
|
||||||
|
%%
|
||||||
|
%% When a user registers, send a notification to
|
||||||
|
%% these XMPP accounts.
|
||||||
|
%%
|
||||||
|
%%{registration_watchers, ["admin1@example.org"]}
|
||||||
|
]},
|
||||||
{mod_roster, []},
|
{mod_roster, []},
|
||||||
%%{mod_service_log,[]},
|
%%{mod_service_log,[]},
|
||||||
{mod_shared_roster,[]},
|
{mod_shared_roster,[]},
|
||||||
|
@ -111,6 +111,7 @@ init({SockMod, Socket}, Opts) ->
|
|||||||
%% web_admin -> {["admin"], ejabberd_web_admin}
|
%% web_admin -> {["admin"], ejabberd_web_admin}
|
||||||
%% http_bind -> {["http-bind"], mod_http_bind}
|
%% http_bind -> {["http-bind"], mod_http_bind}
|
||||||
%% http_poll -> {["http-poll"], ejabberd_http_poll}
|
%% http_poll -> {["http-poll"], ejabberd_http_poll}
|
||||||
|
%% register -> {["register"], mod_register_web}
|
||||||
|
|
||||||
RequestHandlers =
|
RequestHandlers =
|
||||||
case lists:keysearch(request_handlers, 1, Opts) of
|
case lists:keysearch(request_handlers, 1, Opts) of
|
||||||
@ -121,6 +122,10 @@ init({SockMod, Socket}, Opts) ->
|
|||||||
true -> [{["captcha"], ejabberd_captcha}];
|
true -> [{["captcha"], ejabberd_captcha}];
|
||||||
false -> []
|
false -> []
|
||||||
end ++
|
end ++
|
||||||
|
case lists:member(register, Opts) of
|
||||||
|
true -> [{["register"], mod_register_web}];
|
||||||
|
false -> []
|
||||||
|
end ++
|
||||||
case lists:member(web_admin, Opts) of
|
case lists:member(web_admin, Opts) of
|
||||||
true -> [{["admin"], ejabberd_web_admin}];
|
true -> [{["admin"], ejabberd_web_admin}];
|
||||||
false -> []
|
false -> []
|
||||||
|
613
src/web/mod_register_web.erl
Normal file
613
src/web/mod_register_web.erl
Normal file
@ -0,0 +1,613 @@
|
|||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
%%% File : mod_register_web.erl
|
||||||
|
%%% Author : Badlop <badlop@process-one.net>
|
||||||
|
%%% Purpose : Web page to register account and related tasks
|
||||||
|
%%% Created : 4 May 2008 by Badlop <badlop@process-one.net>
|
||||||
|
%%%
|
||||||
|
%%%
|
||||||
|
%%% ejabberd, Copyright (C) 2002-2010 ProcessOne
|
||||||
|
%%%
|
||||||
|
%%% This program is free software; you can redistribute it and/or
|
||||||
|
%%% modify it under the terms of the GNU General Public License as
|
||||||
|
%%% published by the Free Software Foundation; either version 2 of the
|
||||||
|
%%% License, or (at your option) any later version.
|
||||||
|
%%%
|
||||||
|
%%% This program is distributed in the hope that it will be useful,
|
||||||
|
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
%%% General Public License for more details.
|
||||||
|
%%%
|
||||||
|
%%% You should have received a copy of the GNU General Public License
|
||||||
|
%%% along with this program; if not, write to the Free Software
|
||||||
|
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
%%% 02111-1307 USA
|
||||||
|
%%%
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
%%% IDEAS:
|
||||||
|
%%%
|
||||||
|
%%% * Implement those options, already present in mod_register:
|
||||||
|
%%% + access
|
||||||
|
%%% + captcha_protected
|
||||||
|
%%% + password_strength
|
||||||
|
%%% + welcome_message
|
||||||
|
%%% + registration_timeout
|
||||||
|
%%%
|
||||||
|
%%% * Improve this module to allow each virtual host to have different
|
||||||
|
%%% options. See http://support.process-one.net/browse/EJAB-561
|
||||||
|
%%%
|
||||||
|
%%% * Check that all the text is translatable.
|
||||||
|
%%%
|
||||||
|
%%% * Add option to use a custom CSS file, or custom CSS lines.
|
||||||
|
%%%
|
||||||
|
%%% * Don't hardcode the "register" path in URL.
|
||||||
|
%%%
|
||||||
|
%%% * Allow private email during register, and store in custom table.
|
||||||
|
%%% * Optionally require private email to register.
|
||||||
|
%%% * Optionally require email confirmation to register.
|
||||||
|
%%% * Allow to set a private email address anytime.
|
||||||
|
%%% * Allow to recover password using private email to confirm (mod_passrecover)
|
||||||
|
%%% * Optionally require invitation
|
||||||
|
%%% * Optionally register request is forwarded to admin, no account created.
|
||||||
|
|
||||||
|
-module(mod_register_web).
|
||||||
|
-author('badlop@process-one.net').
|
||||||
|
|
||||||
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
|
-export([start/2,
|
||||||
|
stop/1,
|
||||||
|
process/2
|
||||||
|
]).
|
||||||
|
|
||||||
|
-include("ejabberd.hrl").
|
||||||
|
-include("jlib.hrl").
|
||||||
|
-include("ejabberd_http.hrl").
|
||||||
|
-include("ejabberd_web_admin.hrl").
|
||||||
|
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% gen_mod callbacks
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
start(_Host, _Opts) ->
|
||||||
|
%% case gen_mod:get_opt(docroot, Opts, undefined) of
|
||||||
|
ok.
|
||||||
|
|
||||||
|
stop(_Host) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% HTTP handlers
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
process([], #request{method = 'GET', lang = Lang}) ->
|
||||||
|
index_page(Lang);
|
||||||
|
|
||||||
|
process(["register.css"], #request{method = 'GET'}) ->
|
||||||
|
serve_css();
|
||||||
|
|
||||||
|
process(["new"], #request{method = 'GET', lang = Lang, host = Host}) ->
|
||||||
|
form_new_get(Host, Lang);
|
||||||
|
|
||||||
|
process(["delete"], #request{method = 'GET', lang = Lang, host = Host}) ->
|
||||||
|
form_del_get(Host, Lang);
|
||||||
|
|
||||||
|
process(["change_password"], #request{method = 'GET', lang = Lang, host = Host}) ->
|
||||||
|
form_changepass_get(Host, Lang);
|
||||||
|
|
||||||
|
process(["new"], #request{method = 'POST', q = Q, ip = {Ip,_Port}, lang = Lang, host = Host}) ->
|
||||||
|
case form_new_post(Q, Host) of
|
||||||
|
{success, ok, {Username, Host, _Password}} ->
|
||||||
|
Jid = jlib:make_jid(Username, Host, ""),
|
||||||
|
send_registration_notifications(Jid, Ip),
|
||||||
|
Text = ?T("Your Jabber account was succesfully created."),
|
||||||
|
{200, [], Text};
|
||||||
|
Error ->
|
||||||
|
ErrorText = ?T("There was an error creating the account: ") ++
|
||||||
|
?T(get_error_text(Error)),
|
||||||
|
{404, [], ErrorText}
|
||||||
|
end;
|
||||||
|
|
||||||
|
process(["delete"], #request{method = 'POST', q = Q, lang = Lang, host = Host}) ->
|
||||||
|
case form_del_post(Q, Host) of
|
||||||
|
{atomic, ok} ->
|
||||||
|
Text = ?T("Your Jabber account was succesfully deleted."),
|
||||||
|
{200, [], Text};
|
||||||
|
Error ->
|
||||||
|
ErrorText = ?T("There was an error deleting the account: ") ++
|
||||||
|
?T(get_error_text(Error)),
|
||||||
|
{404, [], ErrorText}
|
||||||
|
end;
|
||||||
|
|
||||||
|
%% TODO: Currently only the first vhost is usable. The web request record
|
||||||
|
%% should include the host where the POST was sent.
|
||||||
|
process(["change_password"], #request{method = 'POST', q = Q, lang = Lang, host = Host}) ->
|
||||||
|
case form_changepass_post(Q, Host) of
|
||||||
|
{atomic, ok} ->
|
||||||
|
Text = ?T("The password of your Jabber account was succesfully changed."),
|
||||||
|
{200, [], Text};
|
||||||
|
Error ->
|
||||||
|
ErrorText = ?T("There was an error changing the password: ") ++
|
||||||
|
?T(get_error_text(Error)),
|
||||||
|
{404, [], ErrorText}
|
||||||
|
end.
|
||||||
|
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% CSS
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
serve_css() ->
|
||||||
|
{200, [{"Content-Type", "text/css"},
|
||||||
|
last_modified(), cache_control_public()], css()}.
|
||||||
|
|
||||||
|
last_modified() ->
|
||||||
|
{"Last-Modified", "Mon, 25 Feb 2008 13:23:30 GMT"}.
|
||||||
|
cache_control_public() ->
|
||||||
|
{"Cache-Control", "public"}.
|
||||||
|
|
||||||
|
css() ->
|
||||||
|
"html,body {
|
||||||
|
background: white;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 100%;
|
||||||
|
}".
|
||||||
|
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% Index page
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
index_page(Lang) ->
|
||||||
|
HeadEls = [
|
||||||
|
?XCT("title", "Jabber Account Registration"),
|
||||||
|
?XA("link",
|
||||||
|
[{"href", "/register/register.css"},
|
||||||
|
{"type", "text/css"},
|
||||||
|
{"rel", "stylesheet"}])
|
||||||
|
],
|
||||||
|
Els=[
|
||||||
|
?XACT("h1",
|
||||||
|
[{"class", "title"}, {"style", "text-align:center;"}],
|
||||||
|
"Jabber Account Registration"),
|
||||||
|
?XE("ul", [
|
||||||
|
?XE("li", [?ACT("new", "Register a Jabber account")]),
|
||||||
|
?XE("li", [?ACT("change_password", "Change Password")]),
|
||||||
|
?XE("li", [?ACT("delete", "Unregister a Jabber account")])
|
||||||
|
]
|
||||||
|
)
|
||||||
|
],
|
||||||
|
{200,
|
||||||
|
[{"Server", "ejabberd"},
|
||||||
|
{"Content-Type", "text/html"}],
|
||||||
|
ejabberd_web:make_xhtml(HeadEls, Els)}.
|
||||||
|
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% Formulary new account GET
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
form_new_get(Host, Lang) ->
|
||||||
|
CaptchaEls = build_captcha_li_list(Lang),
|
||||||
|
HeadEls = [
|
||||||
|
?XCT("title", "Register a Jabber account"),
|
||||||
|
?XA("link",
|
||||||
|
[{"href", "/register/register.css"},
|
||||||
|
{"type", "text/css"},
|
||||||
|
{"rel", "stylesheet"}])
|
||||||
|
],
|
||||||
|
Els=[
|
||||||
|
?XACT("h1",
|
||||||
|
[{"class", "title"}, {"style", "text-align:center;"}],
|
||||||
|
"Register a Jabber account"),
|
||||||
|
?XCT("p",
|
||||||
|
"This page allows to create a Jabber account in this Jabber server. "
|
||||||
|
"Your JID (Jabber IDentifier) will be of the form: username@server. "
|
||||||
|
"Please read carefully the instructions to fill correctly the fields."),
|
||||||
|
%% <!-- JID's take the form of 'username@server.com'. For example, my JID is 'kirjava@jabber.org'.
|
||||||
|
%% The maximum length for a JID is 255 characters. -->
|
||||||
|
?XAE("form", [{"action", ""}, {"method", "post"}],
|
||||||
|
[
|
||||||
|
?XE("ol", [
|
||||||
|
?XE("li", [
|
||||||
|
?CT("Username:"),
|
||||||
|
?C(" "),
|
||||||
|
?INPUTS("text", "username", "", "20"),
|
||||||
|
?BR,
|
||||||
|
?XE("ul", [
|
||||||
|
?XCT("li", "This is case insensitive: macbeth is the same that MacBeth and Macbeth."),
|
||||||
|
?XCT("li", "Characters not allowed: @ : ' \" < > &")
|
||||||
|
])
|
||||||
|
]),
|
||||||
|
?XE("li", [
|
||||||
|
?CT("Server:"),
|
||||||
|
?C(" "),
|
||||||
|
?C(Host)
|
||||||
|
]),
|
||||||
|
?XE("li", [
|
||||||
|
?CT("Password:"),
|
||||||
|
?C(" "),
|
||||||
|
?INPUTS("password", "password", "", "20"),
|
||||||
|
?BR,
|
||||||
|
?XE("ul", [
|
||||||
|
?XCT("li", "Don't tell your password to anybody, "
|
||||||
|
"not even the administrators of the Jabber server."),
|
||||||
|
?XCT("li", "You can later change your password using a Jabber client."),
|
||||||
|
?XCT("li", "Some Jabber clients can store your password in your computer. "
|
||||||
|
"Use that feature only if you trust your computer is safe."),
|
||||||
|
?XCT("li", "Memorize your password, or write it in a paper placed in a safe place. "
|
||||||
|
"In Jabber there isn't an automated way to recover your password if you forget it.")
|
||||||
|
])
|
||||||
|
]),
|
||||||
|
?XE("li", [
|
||||||
|
?CT("Password Verification:"),
|
||||||
|
?C(" "),
|
||||||
|
?INPUTS("password", "password2", "", "20")
|
||||||
|
])] ++ CaptchaEls ++ [
|
||||||
|
%% Nombre</b> (opcional)<b>:</b> <input type="text" size="20" name="name" maxlength="255"> <br /> <br /> -->
|
||||||
|
%%
|
||||||
|
%% Dirección de correo</b> (opcional)<b>:</b> <input type="text" size="20" name="email" maxlength="255"> <br /> <br /> -->
|
||||||
|
?XE("li", [
|
||||||
|
?INPUTT("submit", "register", "Register")
|
||||||
|
])
|
||||||
|
])
|
||||||
|
])
|
||||||
|
],
|
||||||
|
{200,
|
||||||
|
[{"Server", "ejabberd"},
|
||||||
|
{"Content-Type", "text/html"}],
|
||||||
|
ejabberd_web:make_xhtml(HeadEls, Els)}.
|
||||||
|
|
||||||
|
%% Copied from mod_register.erl
|
||||||
|
send_registration_notifications(UJID, Source) ->
|
||||||
|
Host = UJID#jid.lserver,
|
||||||
|
case gen_mod:get_module_opt(Host, ?MODULE, registration_watchers, []) of
|
||||||
|
[] -> ok;
|
||||||
|
JIDs when is_list(JIDs) ->
|
||||||
|
Body = lists:flatten(
|
||||||
|
io_lib:format(
|
||||||
|
"[~s] The account ~s was registered from IP address ~s "
|
||||||
|
"on node ~w using ~p.",
|
||||||
|
[get_time_string(), jlib:jid_to_string(UJID),
|
||||||
|
ip_to_string(Source), node(), ?MODULE])),
|
||||||
|
lists:foreach(
|
||||||
|
fun(S) ->
|
||||||
|
case jlib:string_to_jid(S) of
|
||||||
|
error -> ok;
|
||||||
|
JID ->
|
||||||
|
ejabberd_router:route(
|
||||||
|
jlib:make_jid("", Host, ""),
|
||||||
|
JID,
|
||||||
|
{xmlelement, "message", [{"type", "chat"}],
|
||||||
|
[{xmlelement, "body", [],
|
||||||
|
[{xmlcdata, Body}]}]})
|
||||||
|
end
|
||||||
|
end, JIDs);
|
||||||
|
_ ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
ip_to_string(Source) when is_tuple(Source) -> inet_parse:ntoa(Source);
|
||||||
|
ip_to_string(undefined) -> "undefined";
|
||||||
|
ip_to_string(_) -> "unknown".
|
||||||
|
get_time_string() -> write_time(erlang:localtime()).
|
||||||
|
%% Function copied from ejabberd_logger_h.erl and customized
|
||||||
|
write_time({{Y,Mo,D},{H,Mi,S}}) ->
|
||||||
|
io_lib:format("~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w",
|
||||||
|
[Y, Mo, D, H, Mi, S]).
|
||||||
|
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% Formulary new POST
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
form_new_post(Q, Host) ->
|
||||||
|
case catch get_register_parameters(Q) of
|
||||||
|
[Username, Password, Password, Id, Key] ->
|
||||||
|
form_new_post(Username, Host, Password, {Id, Key});
|
||||||
|
[_Username, _Password, _Password2, false, false] ->
|
||||||
|
{error, passwords_not_identical};
|
||||||
|
[_Username, _Password, _Password2, Id, Key] ->
|
||||||
|
ejabberd_captcha:check_captcha(Id, Key), %% This deletes the captcha
|
||||||
|
{error, passwords_not_identical};
|
||||||
|
_ ->
|
||||||
|
{error, wrong_parameters}
|
||||||
|
end.
|
||||||
|
|
||||||
|
get_register_parameters(Q) ->
|
||||||
|
lists:map(
|
||||||
|
fun(Key) ->
|
||||||
|
case lists:keysearch(Key, 1, Q) of
|
||||||
|
{value, {_Key, Value}} -> Value;
|
||||||
|
false -> false
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
["username", "password", "password2", "id", "key"]).
|
||||||
|
|
||||||
|
form_new_post(Username, Host, Password, {false, false}) ->
|
||||||
|
register_account(Username, Host, Password);
|
||||||
|
form_new_post(Username, Host, Password, {Id, Key}) ->
|
||||||
|
case ejabberd_captcha:check_captcha(Id, Key) of
|
||||||
|
captcha_valid ->
|
||||||
|
register_account(Username, Host, Password);
|
||||||
|
captcha_non_valid ->
|
||||||
|
{error, captcha_non_valid};
|
||||||
|
captcha_not_found ->
|
||||||
|
{error, captcha_non_valid}
|
||||||
|
end.
|
||||||
|
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% Formulary Captcha support for new GET/POST
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
build_captcha_li_list(Lang) ->
|
||||||
|
case ejabberd_captcha:is_feature_available() of
|
||||||
|
true -> build_captcha_li_list2(Lang);
|
||||||
|
false -> []
|
||||||
|
end.
|
||||||
|
|
||||||
|
build_captcha_li_list2(Lang) ->
|
||||||
|
Id = randoms:get_string(),
|
||||||
|
SID = "",
|
||||||
|
From = #jid{user = "", server = "test", resource = ""},
|
||||||
|
To = #jid{user = "", server = "test", resource = ""},
|
||||||
|
Args = [],
|
||||||
|
ejabberd_captcha:create_captcha(Id, SID, From, To, Lang, Args),
|
||||||
|
{_, {CImg,CText,CId,CKey}} = ejabberd_captcha:build_captcha_html(Id, Lang),
|
||||||
|
[?XE("li", [CText,
|
||||||
|
?C(" "),
|
||||||
|
CId,
|
||||||
|
CKey,
|
||||||
|
?BR,
|
||||||
|
CImg]
|
||||||
|
)].
|
||||||
|
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% Formulary change password GET
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
form_changepass_get(Host, Lang) ->
|
||||||
|
HeadEls = [
|
||||||
|
?XCT("title", "Change Password"),
|
||||||
|
?XA("link",
|
||||||
|
[{"href", "/register/register.css"},
|
||||||
|
{"type", "text/css"},
|
||||||
|
{"rel", "stylesheet"}])
|
||||||
|
],
|
||||||
|
Els=[
|
||||||
|
?XACT("h1",
|
||||||
|
[{"class", "title"}, {"style", "text-align:center;"}],
|
||||||
|
"Change Password"),
|
||||||
|
?XAE("form", [{"action", ""}, {"method", "post"}],
|
||||||
|
[
|
||||||
|
?XE("ol", [
|
||||||
|
?XE("li", [
|
||||||
|
?CT("Username:"),
|
||||||
|
?C(" "),
|
||||||
|
?INPUTS("text", "username", "", "20")
|
||||||
|
]),
|
||||||
|
?XE("li", [
|
||||||
|
?CT("Server:"),
|
||||||
|
?C(" "),
|
||||||
|
?C(Host)
|
||||||
|
]),
|
||||||
|
?XE("li", [
|
||||||
|
?CT("Old Password:"),
|
||||||
|
?C(" "),
|
||||||
|
?INPUTS("password", "passwordold", "", "20")
|
||||||
|
]),
|
||||||
|
?XE("li", [
|
||||||
|
?CT("New Password:"),
|
||||||
|
?C(" "),
|
||||||
|
?INPUTS("password", "password", "", "20")
|
||||||
|
]),
|
||||||
|
?XE("li", [
|
||||||
|
?CT("Password Verification:"),
|
||||||
|
?C(" "),
|
||||||
|
?INPUTS("password", "password2", "", "20")
|
||||||
|
]),
|
||||||
|
?XE("li", [
|
||||||
|
?INPUTT("submit", "changepass", "Change Password")
|
||||||
|
])
|
||||||
|
])
|
||||||
|
])
|
||||||
|
],
|
||||||
|
{200,
|
||||||
|
[{"Server", "ejabberd"},
|
||||||
|
{"Content-Type", "text/html"}],
|
||||||
|
ejabberd_web:make_xhtml(HeadEls, Els)}.
|
||||||
|
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% Formulary change password POST
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
form_changepass_post(Q, Host) ->
|
||||||
|
case catch get_changepass_parameters(Q) of
|
||||||
|
[Username, PasswordOld, Password, Password] ->
|
||||||
|
try_change_password(Username, Host, PasswordOld, Password);
|
||||||
|
[_Username, _PasswordOld, _Password, _Password2] ->
|
||||||
|
{error, passwords_not_identical};
|
||||||
|
_ ->
|
||||||
|
{error, wrong_parameters}
|
||||||
|
end.
|
||||||
|
|
||||||
|
get_changepass_parameters(Q) ->
|
||||||
|
lists:map(
|
||||||
|
fun(Key) ->
|
||||||
|
{value, {_Key, Value}} = lists:keysearch(Key, 1, Q),
|
||||||
|
Value
|
||||||
|
end,
|
||||||
|
["username", "passwordold", "password", "password2"]).
|
||||||
|
|
||||||
|
%% @spec(Username,Host,PasswordOld,Password) -> {atomic, ok} |
|
||||||
|
%% {error, account_doesnt_exist} |
|
||||||
|
%% {error, password_not_changed} |
|
||||||
|
%% {error, password_incorrect}
|
||||||
|
try_change_password(Username, Host, PasswordOld, Password) ->
|
||||||
|
try change_password(Username, Host, PasswordOld, Password) of
|
||||||
|
{atomic, ok} ->
|
||||||
|
{atomic, ok}
|
||||||
|
catch
|
||||||
|
error:{badmatch, Error} ->
|
||||||
|
{error, Error}
|
||||||
|
end.
|
||||||
|
|
||||||
|
change_password(Username, Host, PasswordOld, Password) ->
|
||||||
|
%% Check the account exists
|
||||||
|
account_exists = check_account_exists(Username, Host),
|
||||||
|
|
||||||
|
%% Check the old password is correct
|
||||||
|
password_correct = check_password(Username, Host, PasswordOld),
|
||||||
|
|
||||||
|
%% This function always returns: ok
|
||||||
|
%% Change the password
|
||||||
|
ok = ejabberd_auth:set_password(Username, Host, Password),
|
||||||
|
|
||||||
|
%% Check the new password is correct
|
||||||
|
case check_password(Username, Host, Password) of
|
||||||
|
password_correct ->
|
||||||
|
{atomic, ok};
|
||||||
|
password_incorrect ->
|
||||||
|
{error, password_not_changed}
|
||||||
|
end.
|
||||||
|
|
||||||
|
check_account_exists(Username, Host) ->
|
||||||
|
case ejabberd_auth:is_user_exists(Username, Host) of
|
||||||
|
true -> account_exists;
|
||||||
|
false -> account_doesnt_exist
|
||||||
|
end.
|
||||||
|
|
||||||
|
check_password(Username, Host, Password) ->
|
||||||
|
case ejabberd_auth:check_password(Username, Host, Password) of
|
||||||
|
true -> password_correct;
|
||||||
|
false -> password_incorrect
|
||||||
|
end.
|
||||||
|
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% Formulary delete account GET
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
form_del_get(Host, Lang) ->
|
||||||
|
HeadEls = [
|
||||||
|
?XCT("title", "Unregister a Jabber account"),
|
||||||
|
?XA("link",
|
||||||
|
[{"href", "/register/register.css"},
|
||||||
|
{"type", "text/css"},
|
||||||
|
{"rel", "stylesheet"}])
|
||||||
|
],
|
||||||
|
Els=[
|
||||||
|
?XACT("h1",
|
||||||
|
[{"class", "title"}, {"style", "text-align:center;"}],
|
||||||
|
"Unregister a Jabber account"),
|
||||||
|
?XCT("p",
|
||||||
|
"This page allows to unregister a Jabber account in this Jabber server."),
|
||||||
|
?XAE("form", [{"action", ""}, {"method", "post"}],
|
||||||
|
[
|
||||||
|
?XE("ol", [
|
||||||
|
?XE("li", [
|
||||||
|
?CT("Username:"),
|
||||||
|
?C(" "),
|
||||||
|
?INPUTS("text", "username", "", "20")
|
||||||
|
]),
|
||||||
|
?XE("li", [
|
||||||
|
?CT("Server:"),
|
||||||
|
?C(" "),
|
||||||
|
?C(Host)
|
||||||
|
]),
|
||||||
|
?XE("li", [
|
||||||
|
?CT("Password:"),
|
||||||
|
?C(" "),
|
||||||
|
?INPUTS("password", "password", "", "20")
|
||||||
|
]),
|
||||||
|
?XE("li", [
|
||||||
|
?INPUTT("submit", "unregister", "Unregister")
|
||||||
|
])
|
||||||
|
])
|
||||||
|
])
|
||||||
|
],
|
||||||
|
{200,
|
||||||
|
[{"Server", "ejabberd"},
|
||||||
|
{"Content-Type", "text/html"}],
|
||||||
|
ejabberd_web:make_xhtml(HeadEls, Els)}.
|
||||||
|
|
||||||
|
%% @spec(Username, Host, Password) -> {success, ok, {Username, Host, Password} |
|
||||||
|
%% {success, exists, {Username, Host, Password}} |
|
||||||
|
%% {error, not_allowed} |
|
||||||
|
%% {error, invalid_jid}
|
||||||
|
register_account(Username, Host, Password) ->
|
||||||
|
case ejabberd_auth:try_register(Username, Host, Password) of
|
||||||
|
{atomic, Res} ->
|
||||||
|
{success, Res, {Username, Host, Password}};
|
||||||
|
Other ->
|
||||||
|
Other
|
||||||
|
end.
|
||||||
|
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% Formulary delete POST
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
form_del_post(Q, Host) ->
|
||||||
|
case catch get_unregister_parameters(Q) of
|
||||||
|
[Username, Password] ->
|
||||||
|
try_unregister_account(Username, Host, Password);
|
||||||
|
_ ->
|
||||||
|
{error, wrong_parameters}
|
||||||
|
end.
|
||||||
|
|
||||||
|
get_unregister_parameters(Q) ->
|
||||||
|
lists:map(
|
||||||
|
fun(Key) ->
|
||||||
|
{value, {_Key, Value}} = lists:keysearch(Key, 1, Q),
|
||||||
|
Value
|
||||||
|
end,
|
||||||
|
["username", "password"]).
|
||||||
|
|
||||||
|
%% @spec(Username, Host, Password) -> {atomic, ok} |
|
||||||
|
%% {error, account_doesnt_exist} |
|
||||||
|
%% {error, account_exists} |
|
||||||
|
%% {error, password_incorrect}
|
||||||
|
try_unregister_account(Username, Host, Password) ->
|
||||||
|
try unregister_account(Username, Host, Password) of
|
||||||
|
{atomic, ok} ->
|
||||||
|
{atomic, ok}
|
||||||
|
catch
|
||||||
|
error:{badmatch, Error} ->
|
||||||
|
{error, Error}
|
||||||
|
end.
|
||||||
|
|
||||||
|
unregister_account(Username, Host, Password) ->
|
||||||
|
%% Check the account exists
|
||||||
|
account_exists = check_account_exists(Username, Host),
|
||||||
|
|
||||||
|
%% Check the password is correct
|
||||||
|
password_correct = check_password(Username, Host, Password),
|
||||||
|
|
||||||
|
%% This function always returns: ok
|
||||||
|
ok = ejabberd_auth:remove_user(Username, Host, Password),
|
||||||
|
|
||||||
|
%% Check the account does not exist anymore
|
||||||
|
account_doesnt_exist = check_account_exists(Username, Host),
|
||||||
|
|
||||||
|
%% If we reached this point, return success
|
||||||
|
{atomic, ok}.
|
||||||
|
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% Error texts
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
get_error_text({error, captcha_non_valid}) ->
|
||||||
|
"The captcha you entered is wrong";
|
||||||
|
get_error_text({atomic, exists}) ->
|
||||||
|
"The account already exists";
|
||||||
|
get_error_text({error, password_incorrect}) ->
|
||||||
|
"Incorrect password";
|
||||||
|
get_error_text({error, invalid_jid}) ->
|
||||||
|
"The username is not valid";
|
||||||
|
get_error_text({error, not_allowed}) ->
|
||||||
|
"Not allowed";
|
||||||
|
get_error_text({error, account_doesnt_exist}) ->
|
||||||
|
"Account doesn't exist";
|
||||||
|
get_error_text({error, account_exists}) ->
|
||||||
|
"The account was not deleted";
|
||||||
|
get_error_text({error, password_not_changed}) ->
|
||||||
|
"The password was not changed";
|
||||||
|
get_error_text({error, passwords_not_identical}) ->
|
||||||
|
"The passwords are different";
|
||||||
|
get_error_text({error, wrong_parameters}) ->
|
||||||
|
"Wrong parameters in the web formulary".
|
Loading…
Reference in New Issue
Block a user