aboutsummaryrefslogtreecommitdiff
path: root/src/ejabberd_web_admin.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/ejabberd_web_admin.erl')
-rw-r--r--src/ejabberd_web_admin.erl927
1 files changed, 44 insertions, 883 deletions
diff --git a/src/ejabberd_web_admin.erl b/src/ejabberd_web_admin.erl
index a112eac35..5eaef7582 100644
--- a/src/ejabberd_web_admin.erl
+++ b/src/ejabberd_web_admin.erl
@@ -27,13 +27,11 @@
-module(ejabberd_web_admin).
--behaviour(ejabberd_config).
-
-author('alexey@process-one.net').
-export([process/2, list_users/4,
list_users_in_diapason/4, pretty_print_xml/1,
- term_to_id/1, opt_type/1]).
+ term_to_id/1]).
-include("logger.hrl").
@@ -132,7 +130,7 @@ is_allowed_path([<<"admin">> | Path], JID) ->
is_allowed_path(Path, JID);
is_allowed_path(Path, JID) ->
{HostOfRule, AccessRule} = get_acl_rule(Path, 'GET'),
- acl:any_rules_allowed(HostOfRule, AccessRule, JID).
+ any_rules_allowed(HostOfRule, AccessRule, JID).
%% @spec(Path) -> URL
%% where Path = [string()]
@@ -186,8 +184,8 @@ process([<<"server">>, SHost | RPath] = Path,
AJID = get_jid(Auth, HostHTTP, Method),
process_admin(Host,
Request#request{path = RPath,
- auth = {auth_jid, Auth, AJID},
- us = {User, Server}});
+ us = {User, Server}},
+ AJID);
{unauthorized, <<"no-auth-provided">>} ->
{401,
[{<<"WWW-Authenticate">>,
@@ -218,8 +216,8 @@ process(RPath,
AJID = get_jid(Auth, HostHTTP, Method),
process_admin(global,
Request#request{path = RPath,
- auth = {auth_jid, Auth, AJID},
- us = {User, Server}});
+ us = {User, Server}},
+ AJID);
{unauthorized, <<"no-auth-provided">>} ->
{401,
[{<<"WWW-Authenticate">>,
@@ -262,8 +260,8 @@ get_auth_account(HostOfRule, AccessRule, User, Server,
Pass) ->
case ejabberd_auth:check_password(User, <<"">>, Server, Pass) of
true ->
- case acl:any_rules_allowed(HostOfRule, AccessRule,
- jid:make(User, Server))
+ case any_rules_allowed(HostOfRule, AccessRule,
+ jid:make(User, Server))
of
false -> {unauthorized, <<"unprivileged-account">>};
true -> {ok, {User, Server}}
@@ -342,7 +340,6 @@ make_xhtml(Els, Host, Node, Lang, JID) ->
?AC(<<"https://www.process-one.net/">>, <<"ProcessOne, leader in messaging and push solutions">>)]
)])])])]}}.
-direction(ltr) -> [{<<"dir">>, <<"ltr">>}];
direction(<<"he">>) -> [{<<"dir">>, <<"rtl">>}];
direction(_) -> [].
@@ -395,9 +392,7 @@ logo_fill() ->
%%%==================================
%%%% process_admin
-process_admin(global,
- #request{path = [], auth = {_, _, AJID},
- lang = Lang}) ->
+process_admin(global, #request{path = [], lang = Lang}, AJID) ->
make_xhtml((?H1GL((?T(<<"Administration">>)), <<"">>,
<<"Contents">>))
++
@@ -406,290 +401,65 @@ process_admin(global,
|| {MIU, MIN}
<- get_menu_items(global, cluster, Lang, AJID)])],
global, Lang, AJID);
-process_admin(Host,
- #request{path = [], auth = {_, _Auth, AJID},
- lang = Lang}) ->
+process_admin(Host, #request{path = [], lang = Lang}, AJID) ->
make_xhtml([?XCT(<<"h1">>, <<"Administration">>),
?XE(<<"ul">>,
[?LI([?ACT(MIU, MIN)])
|| {MIU, MIN}
<- get_menu_items(Host, cluster, Lang, AJID)])],
Host, Lang, AJID);
-process_admin(Host,
- #request{path = [<<"style.css">>]}) ->
+process_admin(Host, #request{path = [<<"style.css">>]}, _) ->
{200,
[{<<"Content-Type">>, <<"text/css">>}, last_modified(),
cache_control_public()],
css(Host)};
-process_admin(_Host,
- #request{path = [<<"favicon.ico">>]}) ->
+process_admin(_Host, #request{path = [<<"favicon.ico">>]}, _) ->
{200,
[{<<"Content-Type">>, <<"image/x-icon">>},
last_modified(), cache_control_public()],
favicon()};
-process_admin(_Host,
- #request{path = [<<"logo.png">>]}) ->
+process_admin(_Host, #request{path = [<<"logo.png">>]}, _) ->
{200,
[{<<"Content-Type">>, <<"image/png">>}, last_modified(),
cache_control_public()],
logo()};
-process_admin(_Host,
- #request{path = [<<"logo-fill.png">>]}) ->
+process_admin(_Host, #request{path = [<<"logo-fill.png">>]}, _) ->
{200,
[{<<"Content-Type">>, <<"image/png">>}, last_modified(),
cache_control_public()],
logo_fill()};
-process_admin(_Host,
- #request{path = [<<"additions.js">>]}) ->
+process_admin(_Host, #request{path = [<<"additions.js">>]}, _) ->
{200,
[{<<"Content-Type">>, <<"text/javascript">>},
last_modified(), cache_control_public()],
additions_js()};
-process_admin(Host,
- #request{path = [<<"acls-raw">>], q = Query,
- auth = {_, _Auth, AJID}, lang = Lang}) ->
- Res = case lists:keysearch(<<"acls">>, 1, Query) of
- {value, {_, String}} ->
- case erl_scan:string(binary_to_list(String)) of
- {ok, Tokens, _} ->
- case erl_parse:parse_term(Tokens) of
- {ok, NewACLs} ->
- case catch acl:add_list(Host, NewACLs, true) of
- ok -> ok;
- _ -> error
- end;
- _ -> error
- end;
- _ -> error
- end;
- _ -> nothing
- end,
- ACLs = lists:keysort(2,
- mnesia:dirty_select(acl,
- [{{acl, {'$1', Host}, '$2'}, [],
- [{{acl, '$1', '$2'}}]}])),
- {NumLines, ACLsP} = term_to_paragraph(ACLs, 80),
- make_xhtml((?H1GL((?T(<<"Access Control Lists">>)),
- <<"acldefinition">>, <<"ACL Definition">>))
- ++
- case Res of
- ok -> [?XREST(<<"Submitted">>)];
- error -> [?XREST(<<"Bad format">>)];
- nothing -> []
- end
- ++
- [?XAE(<<"form">>,
- [{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}]++direction(ltr),
- [?TEXTAREA(<<"acls">>,
- (integer_to_binary(lists:max([16,
- NumLines]))),
- <<"80">>, <<(iolist_to_binary(ACLsP))/binary, ".">>),
- ?BR,
- ?INPUTT(<<"submit">>, <<"submit">>, <<"Submit">>)])],
- Host, Lang, AJID);
-process_admin(Host,
- #request{method = Method, path = [<<"acls">>],
- auth = {_, _Auth, AJID}, q = Query, lang = Lang}) ->
- ?DEBUG("query: ~p", [Query]),
- Res = case Method of
- 'POST' ->
- case catch acl_parse_query(Host, Query) of
- {'EXIT', _} -> error;
- NewACLs ->
- ?INFO_MSG("NewACLs at ~s: ~p", [Host, NewACLs]),
- case catch acl:add_list(Host, NewACLs, true) of
- ok -> ok;
- _ -> error
- end
- end;
- _ -> nothing
- end,
- ACLs = lists:keysort(2,
- mnesia:dirty_select(acl,
- [{{acl, {'$1', Host}, '$2'}, [],
- [{{acl, '$1', '$2'}}]}])),
- make_xhtml((?H1GL((?T(<<"Access Control Lists">>)),
- <<"acldefinition">>, <<"ACL Definition">>))
- ++
- case Res of
- ok -> [?XREST(<<"Submitted">>)];
- error -> [?XREST(<<"Bad format">>)];
- nothing -> []
- end
- ++
- [?XAE(<<"p">>, direction(ltr), [?ACT(<<"../acls-raw/">>, <<"Raw">>)])] ++
- [?XAE(<<"form">>,
- [{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}]++direction(ltr),
- [acls_to_xhtml(ACLs), ?BR,
- ?INPUTT(<<"submit">>, <<"delete">>,
- <<"Delete Selected">>),
- ?C(<<" ">>),
- ?INPUTT(<<"submit">>, <<"submit">>,
- <<"Submit">>)])],
- Host, Lang, AJID);
-process_admin(Host,
- #request{path = [<<"access-raw">>],
- auth = {_, _Auth, AJID}, q = Query, lang = Lang}) ->
- SetAccess = fun (Rs) ->
- mnesia:transaction(fun () ->
- Os = mnesia:select(access,
- [{{access,
- {'$1',
- Host},
- '$2'},
- [],
- ['$_']}]),
- lists:foreach(fun (O) ->
- mnesia:delete_object(O)
- end,
- Os),
- lists:foreach(fun ({access,
- Name,
- Rules}) ->
- mnesia:write({access,
- {Name,
- Host},
- Rules})
- end,
- Rs)
- end)
- end,
- Res = case lists:keysearch(<<"access">>, 1, Query) of
- {value, {_, String}} ->
- case erl_scan:string(binary_to_list(String)) of
- {ok, Tokens, _} ->
- case erl_parse:parse_term(Tokens) of
- {ok, Rs} ->
- case SetAccess(Rs) of
- {atomic, _} -> ok;
- _ -> error
- end;
- _ -> error
- end;
- _ -> error
- end;
- _ -> nothing
- end,
- Access = mnesia:dirty_select(access,
- [{{access, {'$1', Host}, '$2'}, [],
- [{{access, '$1', '$2'}}]}]),
- {NumLines, AccessP} = term_to_paragraph(lists:keysort(2,Access), 80),
- make_xhtml((?H1GL((?T(<<"Access Rules">>)),
- <<"accessrights">>, <<"Access Rights">>))
- ++
- case Res of
- ok -> [?XREST(<<"Submitted">>)];
- error -> [?XREST(<<"Bad format">>)];
- nothing -> []
- end
- ++
- [?XAE(<<"form">>,
- [{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}]++direction(ltr),
- [?TEXTAREA(<<"access">>,
- (integer_to_binary(lists:max([16,
- NumLines]))),
- <<"80">>, <<(iolist_to_binary(AccessP))/binary, ".">>),
- ?BR,
- ?INPUTT(<<"submit">>, <<"submit">>, <<"Submit">>)])],
- Host, Lang, AJID);
-process_admin(Host,
- #request{method = Method, path = [<<"access">>],
- q = Query, auth = {_, _Auth, AJID}, lang = Lang}) ->
- ?DEBUG("query: ~p", [Query]),
- Res = case Method of
- 'POST' ->
- case catch access_parse_query(Host, Query) of
- {'EXIT', _} -> error;
- ok -> ok
- end;
- _ -> nothing
- end,
- AccessRules = mnesia:dirty_select(access,
- [{{access, {'$1', Host}, '$2'}, [],
- [{{access, '$1', '$2'}}]}]),
- make_xhtml((?H1GL((?T(<<"Access Rules">>)),
- <<"accessrights">>, <<"Access Rights">>))
- ++
- case Res of
- ok -> [?XREST(<<"Submitted">>)];
- error -> [?XREST(<<"Bad format">>)];
- nothing -> []
- end
- ++
- [?XAE(<<"p">>, direction(ltr), [?ACT(<<"../access-raw/">>, <<"Raw">>)])]
- ++
- [?XAE(<<"form">>,
- [{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}]++direction(ltr),
- [access_rules_to_xhtml(AccessRules, Lang), ?BR,
- ?INPUTT(<<"submit">>, <<"delete">>,
- <<"Delete Selected">>)])],
- Host, Lang, AJID);
-process_admin(Host,
- #request{path = [<<"access">>, SName], q = Query,
- auth = {_, _Auth, AJID}, lang = Lang}) ->
- ?DEBUG("query: ~p", [Query]),
- Name = misc:binary_to_atom(SName),
- Res = case lists:keysearch(<<"rules">>, 1, Query) of
- {value, {_, String}} ->
- case parse_access_rule(String) of
- {ok, Rs} ->
- ejabberd_config:add_option({access, Name, Host},
- Rs),
- ok;
- _ -> error
- end;
- _ -> nothing
- end,
- Rules = ejabberd_config:get_option({access, Name, Host}, []),
- make_xhtml([?XC(<<"h1">>,
- (str:format(
- ?T(<<"~s access rule configuration">>),
- [SName])))]
- ++
- case Res of
- ok -> [?XREST(<<"Submitted">>)];
- error -> [?XREST(<<"Bad format">>)];
- nothing -> []
- end
- ++
- [?XAE(<<"form">>,
- [{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}],
- [access_rule_to_xhtml(Rules), ?BR,
- ?INPUTT(<<"submit">>, <<"submit">>, <<"Submit">>)])],
- Host, Lang, AJID);
-process_admin(global,
- #request{path = [<<"vhosts">>], auth = {_, _Auth, AJID},
- lang = Lang}) ->
+process_admin(global, #request{path = [<<"vhosts">>], lang = Lang}, AJID) ->
Res = list_vhosts(Lang, AJID),
make_xhtml((?H1GL((?T(<<"Virtual Hosts">>)),
<<"virtualhosting">>, <<"Virtual Hosting">>))
++ Res,
global, Lang, AJID);
-process_admin(Host,
- #request{path = [<<"users">>], q = Query,
- auth = {_, _Auth, AJID}, lang = Lang})
+process_admin(Host, #request{path = [<<"users">>], q = Query,
+ lang = Lang}, AJID)
when is_binary(Host) ->
Res = list_users(Host, Query, Lang, fun url_func/1),
make_xhtml([?XCT(<<"h1">>, <<"Users">>)] ++ Res, Host,
Lang, AJID);
-process_admin(Host,
- #request{path = [<<"users">>, Diap],
- auth = {_, _Auth, AJID}, lang = Lang})
+process_admin(Host, #request{path = [<<"users">>, Diap],
+ lang = Lang}, AJID)
when is_binary(Host) ->
Res = list_users_in_diapason(Host, Diap, Lang,
fun url_func/1),
make_xhtml([?XCT(<<"h1">>, <<"Users">>)] ++ Res, Host,
Lang, AJID);
-process_admin(Host,
- #request{path = [<<"online-users">>],
- auth = {_, _Auth, AJID}, lang = Lang})
+process_admin(Host, #request{path = [<<"online-users">>],
+ lang = Lang}, AJID)
when is_binary(Host) ->
Res = list_online_users(Host, Lang),
make_xhtml([?XCT(<<"h1">>, <<"Online Users">>)] ++ Res,
Host, Lang, AJID);
-process_admin(Host,
- #request{path = [<<"last-activity">>],
- auth = {_, _Auth, AJID}, q = Query, lang = Lang})
+process_admin(Host, #request{path = [<<"last-activity">>],
+ q = Query, lang = Lang}, AJID)
when is_binary(Host) ->
?DEBUG("query: ~p", [Query]),
Month = case lists:keysearch(<<"period">>, 1, Query) of
@@ -730,15 +500,12 @@ process_admin(Host,
<<"Show Integral Table">>)])]
++ Res,
Host, Lang, AJID);
-process_admin(Host,
- #request{path = [<<"stats">>], auth = {_, _Auth, AJID},
- lang = Lang}) ->
+process_admin(Host, #request{path = [<<"stats">>], lang = Lang}, AJID) ->
Res = get_stats(Host, Lang),
make_xhtml([?XCT(<<"h1">>, <<"Statistics">>)] ++ Res,
Host, Lang, AJID);
-process_admin(Host,
- #request{path = [<<"user">>, U],
- auth = {_, _Auth, AJID}, q = Query, lang = Lang}) ->
+process_admin(Host, #request{path = [<<"user">>, U],
+ q = Query, lang = Lang}, AJID) ->
case ejabberd_auth:user_exists(U, Host) of
true ->
Res = user_info(U, Host, Query, Lang),
@@ -747,14 +514,11 @@ process_admin(Host,
make_xhtml([?XCT(<<"h1">>, <<"Not Found">>)], Host,
Lang, AJID)
end;
-process_admin(Host,
- #request{path = [<<"nodes">>], auth = {_, _Auth, AJID},
- lang = Lang}) ->
+process_admin(Host, #request{path = [<<"nodes">>], lang = Lang}, AJID) ->
Res = get_nodes(Lang),
make_xhtml(Res, Host, Lang, AJID);
-process_admin(Host,
- #request{path = [<<"node">>, SNode | NPath],
- auth = {_, _Auth, AJID}, q = Query, lang = Lang}) ->
+process_admin(Host, #request{path = [<<"node">>, SNode | NPath],
+ q = Query, lang = Lang}, AJID) ->
case search_running_node(SNode) of
false ->
make_xhtml([?XCT(<<"h1">>, <<"Node not found">>)], Host,
@@ -765,9 +529,7 @@ process_admin(Host,
end;
%%%==================================
%%%% process_admin default case
-process_admin(Host,
- #request{lang = Lang, auth = {_, _Auth, AJID}} =
- Request) ->
+process_admin(Host, #request{lang = Lang} = Request, AJID) ->
Res = case Host of
global ->
ejabberd_hooks:run_fold(
@@ -785,286 +547,15 @@ process_admin(Host,
_ -> make_xhtml(Res, Host, Lang, AJID)
end.
-%%%==================================
-%%%% acl
-
-acls_to_xhtml(ACLs) ->
- ?XAE(<<"table">>, [],
- [?XE(<<"tbody">>,
- (lists:map(fun ({acl, Name, Spec} = ACL) ->
- SName = iolist_to_binary(atom_to_list(Name)),
- ID = term_to_id(ACL),
- ?XE(<<"tr">>,
- ([?XE(<<"td">>,
- [?INPUT(<<"checkbox">>,
- <<"selected">>, ID)]),
- ?XC(<<"td">>, SName)]
- ++ acl_spec_to_xhtml(ID, Spec)))
- end,
- ACLs)
- ++
- [?XE(<<"tr">>,
- ([?X(<<"td">>),
- ?XE(<<"td">>,
- [?INPUT(<<"text">>, <<"namenew">>, <<"">>)])]
- ++ acl_spec_to_xhtml(<<"new">>, {user, <<"">>})))]))]).
-
-acl_spec_to_text({user, {U, S}}) ->
- {user, <<U/binary, "@", S/binary>>};
-acl_spec_to_text({user, U}) -> {user, U};
-acl_spec_to_text({server, S}) -> {server, S};
-acl_spec_to_text({user_regexp, {RU, S}}) ->
- {user_regexp, <<RU/binary, "@", S/binary>>};
-acl_spec_to_text({user_regexp, RU}) ->
- {user_regexp, RU};
-acl_spec_to_text({server_regexp, RS}) ->
- {server_regexp, RS};
-acl_spec_to_text({node_regexp, {RU, RS}}) ->
- {node_regexp, <<RU/binary, "@", RS/binary>>};
-acl_spec_to_text({user_glob, {RU, S}}) ->
- {user_glob, <<RU/binary, "@", S/binary>>};
-acl_spec_to_text({user_glob, RU}) -> {user_glob, RU};
-acl_spec_to_text({server_glob, RS}) ->
- {server_glob, RS};
-acl_spec_to_text({node_glob, {RU, RS}}) ->
- {node_glob, <<RU/binary, "@", RS/binary>>};
-acl_spec_to_text(all) -> {all, <<"">>};
-acl_spec_to_text({ip, {IP, L}}) -> {ip, <<(misc:ip_to_list(IP))/binary, "/",
- (integer_to_binary(L))/binary>>};
-acl_spec_to_text(Spec) -> {raw, term_to_string(Spec)}.
-
-acl_spec_to_xhtml(ID, Spec) ->
- {Type, Str} = acl_spec_to_text(Spec),
- [acl_spec_select(ID, Type), ?ACLINPUT(Str)].
-
-acl_spec_select(ID, Opt) ->
- ?XE(<<"td">>,
- [?XAE(<<"select">>,
- [{<<"name">>, <<"type", ID/binary>>}],
- (lists:map(fun (O) ->
- Sel = if O == Opt ->
- [{<<"selected">>,
- <<"selected">>}];
- true -> []
- end,
- ?XAC(<<"option">>,
- (Sel ++
- [{<<"value">>,
- iolist_to_binary(atom_to_list(O))}]),
- (iolist_to_binary(atom_to_list(O))))
- end,
- [user, server, user_regexp, server_regexp, node_regexp,
- user_glob, server_glob, node_glob, all, ip, raw])))]).
-
-%% @spec (T::any()) -> StringLine::string()
-term_to_string(T) ->
- StringParagraph =
- (str:format("~1000000p", [T])),
- ejabberd_regexp:greplace(StringParagraph, <<"\\n ">>,
- <<"">>).
-
-%% @spec (T::any(), Cols::integer()) -> {NumLines::integer(), Paragraph::string()}
-term_to_paragraph(T, Cols) ->
- Paragraph = iolist_to_binary(io_lib:print(T, 1, Cols, -1)),
- FieldList = ejabberd_regexp:split(Paragraph, <<"\n">>),
- NumLines = length(FieldList),
- {NumLines, Paragraph}.
-
term_to_id(T) -> base64:encode((term_to_binary(T))).
-acl_parse_query(Host, Query) ->
- ACLs = mnesia:dirty_select(acl,
- [{{acl, {'$1', Host}, '$2'}, [],
- [{{acl, '$1', '$2'}}]}]),
- case lists:keysearch(<<"submit">>, 1, Query) of
- {value, _} -> acl_parse_submit(ACLs, Query);
- _ ->
- case lists:keysearch(<<"delete">>, 1, Query) of
- {value, _} -> acl_parse_delete(ACLs, Query)
- end
- end.
-
-acl_parse_submit(ACLs, Query) ->
- NewACLs = lists:map(fun ({acl, Name, Spec} = ACL) ->
- ID = term_to_id(ACL),
- case {lists:keysearch(<<"type", ID/binary>>, 1,
- Query),
- lists:keysearch(<<"value", ID/binary>>, 1,
- Query)}
- of
- {{value, {_, T}}, {value, {_, V}}} ->
- {Type, Str} = acl_spec_to_text(Spec),
- case
- {iolist_to_binary(atom_to_list(Type)),
- Str}
- of
- {T, V} -> ACL;
- _ ->
- NewSpec = string_to_spec(T, V),
- {acl, Name, NewSpec}
- end;
- _ -> ACL
- end
- end,
- ACLs),
- NewACL = case {lists:keysearch(<<"namenew">>, 1, Query),
- lists:keysearch(<<"typenew">>, 1, Query),
- lists:keysearch(<<"valuenew">>, 1, Query)}
- of
- {{value, {_, <<"">>}}, _, _} -> [];
- {{value, {_, N}}, {value, {_, T}}, {value, {_, V}}} ->
- NewName = misc:binary_to_atom(N),
- NewSpec = string_to_spec(T, V),
- [{acl, NewName, NewSpec}];
- _ -> []
- end,
- NewACLs ++ NewACL.
-
-string_to_spec(<<"user">>, Val) ->
- string_to_spec2(user, Val);
-string_to_spec(<<"server">>, Val) -> {server, Val};
-string_to_spec(<<"user_regexp">>, Val) ->
- string_to_spec2(user_regexp, Val);
-string_to_spec(<<"server_regexp">>, Val) ->
- {server_regexp, Val};
-string_to_spec(<<"node_regexp">>, Val) ->
- #jid{luser = U, lserver = S, resource = <<"">>} =
- jid:decode(Val),
- {node_regexp, U, S};
-string_to_spec(<<"user_glob">>, Val) ->
- string_to_spec2(user_glob, Val);
-string_to_spec(<<"server_glob">>, Val) ->
- {server_glob, Val};
-string_to_spec(<<"node_glob">>, Val) ->
- #jid{luser = U, lserver = S, resource = <<"">>} =
- jid:decode(Val),
- {node_glob, U, S};
-string_to_spec(<<"ip">>, Val) ->
- [IPs, Ms] = str:tokens(Val, <<"/">>),
- {ok, IP} = inet_parse:address(binary_to_list(IPs)),
- {ip, {IP, binary_to_integer(Ms)}};
-string_to_spec(<<"all">>, _) -> all;
-string_to_spec(<<"raw">>, Val) ->
- {ok, Tokens, _} = erl_scan:string(binary_to_list(<<Val/binary, ".">>)),
- {ok, NewSpec} = erl_parse:parse_term(Tokens),
- NewSpec.
-
-string_to_spec2(ACLName, Val) ->
- #jid{luser = U, lserver = S, resource = <<"">>} =
- jid:decode(Val),
- case U of
- <<"">> -> {ACLName, S};
- _ -> {ACLName, {U, S}}
- end.
-
-acl_parse_delete(ACLs, Query) ->
- NewACLs = lists:filter(fun ({acl, _Name, _Spec} =
- ACL) ->
- ID = term_to_id(ACL),
- not lists:member({<<"selected">>, ID}, Query)
- end,
- ACLs),
- NewACLs.
-
-access_rules_to_xhtml(AccessRules, Lang) ->
- ?XAE(<<"table">>, [],
- [?XE(<<"tbody">>,
- (lists:map(fun ({access, Name, Rules} = Access) ->
- SName = iolist_to_binary(atom_to_list(Name)),
- ID = term_to_id(Access),
- ?XE(<<"tr">>,
- [?XE(<<"td">>,
- [?INPUT(<<"checkbox">>,
- <<"selected">>, ID)]),
- ?XE(<<"td">>,
- [?AC(<<SName/binary, "/">>, SName)]),
- ?XC(<<"td">>, (term_to_string(Rules)))])
- end,
- lists:keysort(2,AccessRules))
- ++
- [?XE(<<"tr">>,
- [?X(<<"td">>),
- ?XE(<<"td">>,
- [?INPUT(<<"text">>, <<"namenew">>, <<"">>)]),
- ?XE(<<"td">>,
- [?INPUTT(<<"submit">>, <<"addnew">>,
- <<"Add New">>)])])]))]).
-
-access_parse_query(Host, Query) ->
- AccessRules = mnesia:dirty_select(access,
- [{{access, {'$1', Host}, '$2'}, [],
- [{{access, '$1', '$2'}}]}]),
- case lists:keysearch(<<"addnew">>, 1, Query) of
- {value, _} ->
- access_parse_addnew(AccessRules, Host, Query);
- _ ->
- case lists:keysearch(<<"delete">>, 1, Query) of
- {value, _} ->
- access_parse_delete(AccessRules, Host, Query)
- end
- end.
-
-access_parse_addnew(_AccessRules, Host, Query) ->
- case lists:keysearch(<<"namenew">>, 1, Query) of
- {value, {_, String}} when String /= <<"">> ->
- Name = misc:binary_to_atom(String),
- ejabberd_config:add_option({access, Name, Host},
- []),
- ok
- end.
-
-access_parse_delete(AccessRules, Host, Query) ->
- lists:foreach(fun ({access, Name, _Rules} =
- AccessRule) ->
- ID = term_to_id(AccessRule),
- case lists:member({<<"selected">>, ID}, Query) of
- true ->
- mnesia:transaction(fun () ->
- mnesia:delete({access,
- {Name,
- Host}})
- end);
- _ -> ok
- end
- end,
- AccessRules),
- ok.
-
-access_rule_to_xhtml(Rules) ->
- Text = lists:flatmap(fun ({Access, ACL} = _Rule) ->
- SAccess = element_to_list(Access),
- SACL = atom_to_list(ACL),
- [SAccess, " \t", SACL, "\n"]
- end,
- Rules),
- ?XAC(<<"textarea">>,
- [{<<"name">>, <<"rules">>}, {<<"rows">>, <<"16">>},
- {<<"cols">>, <<"80">>}],
- list_to_binary(Text)).
-
-parse_access_rule(Text) ->
- Strings = str:tokens(Text, <<"\r\n">>),
- case catch lists:flatmap(fun (String) ->
- case str:tokens(String, <<" \t">>) of
- [Access, ACL] ->
- [{list_to_element(Access),
- misc:binary_to_atom(ACL)}];
- [] -> []
- end
- end,
- Strings)
- of
- {'EXIT', _Reason} -> error;
- Rs -> {ok, Rs}
- end.
-
%%%==================================
%%%% list_vhosts
list_vhosts(Lang, JID) ->
- Hosts = ejabberd_config:get_myhosts(),
+ Hosts = ejabberd_option:hosts(),
HostsAllowed = lists:filter(fun (Host) ->
- acl:any_rules_allowed(Host,
+ any_rules_allowed(Host,
[configure, webadmin_view],
JID)
end,
@@ -1262,7 +753,7 @@ get_offlinemsg_module(Server) ->
end.
get_lastactivity_menuitem_list(Server) ->
- case gen_mod:get_module_opt(Server, mod_last, db_type) of
+ case mod_last_opt:db_type(Server) of
mnesia -> [{<<"last-activity">>, <<"Last Activity">>}];
_ -> []
end.
@@ -1282,7 +773,7 @@ get_stats(global, Lang) ->
ejabberd_auth:count_users(Host)
+ Total
end,
- 0, ejabberd_config:get_myhosts()),
+ 0, ejabberd_option:hosts()),
OutS2SNumber = ejabberd_s2s:outgoing_s2s_number(),
InS2SNumber = ejabberd_s2s:incoming_s2s_number(),
[?XAE(<<"table">>, [],
@@ -1579,8 +1070,6 @@ get_node(global, Node, [], Query, Lang) ->
[?XE(<<"ul">>,
([?LI([?ACT(<<Base/binary, "db/">>, <<"Database">>)]),
?LI([?ACT(<<Base/binary, "backup/">>, <<"Backup">>)]),
- ?LI([?ACT(<<Base/binary, "ports/">>,
- <<"Listened Ports">>)]),
?LI([?ACT(<<Base/binary, "stats/">>,
<<"Statistics">>)]),
?LI([?ACT(<<Base/binary, "update/">>, <<"Update">>)])]
@@ -1594,10 +1083,7 @@ get_node(Host, Node, [], _Query, Lang) ->
Base = get_base_path(Host, Node),
MenuItems2 = make_menu_items(Host, Node, Base, Lang),
[?XC(<<"h1">>, (str:format(?T(<<"Node ~p">>), [Node]))),
- ?XE(<<"ul">>,
- ([?LI([?ACT(<<Base/binary, "modules/">>,
- <<"Modules">>)])]
- ++ MenuItems2))];
+ ?XE(<<"ul">>, MenuItems2)];
get_node(global, Node, [<<"db">>], Query, Lang) ->
case ejabberd_cluster:call(Node, mnesia, system_info, [tables]) of
{badrpc, _Reason} ->
@@ -1830,68 +1316,6 @@ get_node(global, Node, [<<"backup">>], Query, Lang) ->
?XE(<<"td">>,
[?INPUTT(<<"submit">>, <<"import_dir">>,
<<"OK">>)])])])])])];
-get_node(global, Node, [<<"ports">>], Query, Lang) ->
- Ports = ejabberd_cluster:call(Node, ejabberd_config,
- get_local_option, [listen,
- {ejabberd_listener, validate_cfg},
- []]),
- Res = case catch node_ports_parse_query(Node, Ports,
- Query)
- of
- submitted -> ok;
- {'EXIT', _Reason} -> error;
- {is_added, ok} -> ok;
- {is_added, {error, Reason}} ->
- {error, (str:format("~p", [Reason]))};
- _ -> nothing
- end,
- NewPorts = lists:sort(ejabberd_cluster:call(Node, ejabberd_config,
- get_local_option,
- [listen,
- {ejabberd_listener, validate_cfg},
- []])),
- H1String = <<(?T(<<"Listened Ports at ">>))/binary,
- (iolist_to_binary(atom_to_list(Node)))/binary>>,
- (?H1GL(H1String, <<"listeningports">>, <<"Listening Ports">>))
- ++
- case Res of
- ok -> [?XREST(<<"Submitted">>)];
- error -> [?XREST(<<"Bad format">>)];
- {error, ReasonT} ->
- [?XRES(<<(?T(<<"Error">>))/binary, ": ",
- ReasonT/binary>>)];
- nothing -> []
- end
- ++
- [?XAE(<<"form">>,
- [{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}],
- [node_ports_to_xhtml(NewPorts, Lang)])];
-get_node(Host, Node, [<<"modules">>], Query, Lang)
- when is_binary(Host) ->
- Modules = ejabberd_cluster:call(Node, gen_mod,
- loaded_modules_with_opts, [Host]),
- Res = case catch node_modules_parse_query(Host, Node,
- Modules, Query)
- of
- submitted -> ok;
- {'EXIT', Reason} -> ?ERROR_MSG("~p~n", [Reason]), error;
- _ -> nothing
- end,
- NewModules = lists:sort(ejabberd_cluster:call(Node, gen_mod,
- loaded_modules_with_opts, [Host])),
- H1String = (str:format(?T(<<"Modules at ~p">>), [Node])),
- (?H1GL(H1String, <<"modulesoverview">>,
- <<"Modules Overview">>))
- ++
- case Res of
- ok -> [?XREST(<<"Submitted">>)];
- error -> [?XREST(<<"Bad format">>)];
- nothing -> []
- end
- ++
- [?XAE(<<"form">>,
- [{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}],
- [node_modules_to_xhtml(NewModules, Lang)])];
get_node(global, Node, [<<"stats">>], _Query, Lang) ->
UpTime = ejabberd_cluster:call(Node, erlang, statistics,
[wall_clock]),
@@ -2170,252 +1594,6 @@ node_backup_parse_query(Node, Query) ->
<<"import_piefxis_file">>, <<"export_piefxis_dir">>,
<<"export_piefxis_host_dir">>, <<"export_sql_file">>]).
-node_ports_to_xhtml(Ports, Lang) ->
- ?XAE(<<"table">>, [{<<"class">>, <<"withtextareas">>}],
- [?XE(<<"thead">>,
- [?XE(<<"tr">>,
- [?XCT(<<"td">>, <<"Port">>), ?XCT(<<"td">>, <<"IP">>),
- ?XCT(<<"td">>, <<"Protocol">>),
- ?XCT(<<"td">>, <<"Module">>),
- ?XCT(<<"td">>, <<"Options">>)])]),
- ?XE(<<"tbody">>,
- (lists:map(fun ({PortIP, Module, Opts} = _E) ->
- {_Port, SPort, _TIP, SIP, SSPort, NetProt,
- OptsClean} =
- get_port_data(PortIP, Opts),
- SModule =
- iolist_to_binary(atom_to_list(Module)),
- {NumLines, SOptsClean} =
- term_to_paragraph(OptsClean, 40),
- ?XE(<<"tr">>,
- [?XAE(<<"td">>, [{<<"size">>, <<"6">>}],
- [?C(SPort)]),
- ?XAE(<<"td">>, [{<<"size">>, <<"15">>}],
- [?C(SIP)]),
- ?XAE(<<"td">>, [{<<"size">>, <<"4">>}],
- [?C((iolist_to_binary(atom_to_list(NetProt))))]),
- ?XE(<<"td">>,
- [?INPUTS(<<"text">>,
- <<"module", SSPort/binary>>,
- SModule, <<"15">>)]),
- ?XAE(<<"td">>, direction(ltr),
- [?TEXTAREA(<<"opts", SSPort/binary>>,
- (integer_to_binary(NumLines)),
- <<"35">>, SOptsClean)]),
- ?XE(<<"td">>,
- [?INPUTT(<<"submit">>,
- <<"add", SSPort/binary>>,
- <<"Restart">>)]),
- ?XE(<<"td">>,
- [?INPUTT(<<"submit">>,
- <<"delete", SSPort/binary>>,
- <<"Stop">>)])])
- end,
- Ports)
- ++
- [?XE(<<"tr">>,
- [?XE(<<"td">>,
- [?INPUTS(<<"text">>, <<"portnew">>, <<"">>,
- <<"6">>)]),
- ?XE(<<"td">>,
- [?INPUTS(<<"text">>, <<"ipnew">>, <<"0.0.0.0">>,
- <<"15">>)]),
- ?XE(<<"td">>, [make_netprot_html(<<"tcp">>)]),
- ?XE(<<"td">>,
- [?INPUTS(<<"text">>, <<"modulenew">>, <<"">>,
- <<"15">>)]),
- ?XAE(<<"td">>, direction(ltr),
- [?TEXTAREA(<<"optsnew">>, <<"2">>, <<"35">>,
- <<"[]">>)]),
- ?XAE(<<"td">>, [{<<"colspan">>, <<"2">>}],
- [?INPUTT(<<"submit">>, <<"addnew">>,
- <<"Start">>)])])]))]).
-
-make_netprot_html(NetProt) ->
- ?XAE(<<"select">>, [{<<"name">>, <<"netprotnew">>}],
- (lists:map(fun (O) ->
- Sel = if O == NetProt ->
- [{<<"selected">>, <<"selected">>}];
- true -> []
- end,
- ?XAC(<<"option">>, (Sel ++ [{<<"value">>, O}]), O)
- end,
- [<<"tcp">>, <<"udp">>]))).
-
-get_port_data(PortIP, Opts) ->
- {Port, IPT, _IPV, NetProt, OptsClean} =
- ejabberd_listener:parse_listener_portip(PortIP, Opts),
- IPS = misc:ip_to_list(IPT),
- SPort = integer_to_binary(Port),
- SSPort = list_to_binary(
- lists:map(fun (N) ->
- io_lib:format("~.16b", [N])
- end,
- binary_to_list(
- erlang:md5(
- [SPort, IPS, atom_to_list(NetProt)])))),
- {Port, SPort, IPT, IPS, SSPort, NetProt, OptsClean}.
-
-node_ports_parse_query(Node, Ports, Query) ->
- lists:foreach(fun ({PortIpNetp, Module1, Opts1}) ->
- {Port, _SPort, TIP, _SIP, SSPort, NetProt,
- _OptsClean} =
- get_port_data(PortIpNetp, Opts1),
- case lists:keysearch(<<"add", SSPort/binary>>, 1,
- Query)
- of
- {value, _} ->
- PortIpNetp2 = {Port, TIP, NetProt},
- {{value, {_, SModule}}, {value, {_, SOpts}}} =
- {lists:keysearch(<<"module",
- SSPort/binary>>,
- 1, Query),
- lists:keysearch(<<"opts", SSPort/binary>>,
- 1, Query)},
- Module = misc:binary_to_atom(SModule),
- {ok, Tokens, _} =
- erl_scan:string(binary_to_list(SOpts) ++ "."),
- {ok, Opts} = erl_parse:parse_term(Tokens),
- ejabberd_cluster:call(Node, ejabberd_listener,
- delete_listener,
- [PortIpNetp2, Module1]),
- R = ejabberd_cluster:call(Node, ejabberd_listener,
- add_listener,
- [PortIpNetp2, Module, Opts]),
- throw({is_added, R});
- _ ->
- case lists:keysearch(<<"delete",
- SSPort/binary>>,
- 1, Query)
- of
- {value, _} ->
- ejabberd_cluster:call(Node, ejabberd_listener,
- delete_listener,
- [PortIpNetp, Module1]),
- throw(submitted);
- _ -> ok
- end
- end
- end,
- Ports),
- case lists:keysearch(<<"addnew">>, 1, Query) of
- {value, _} ->
- {{value, {_, SPort}}, {value, {_, STIP}},
- {value, {_, SNetProt}}, {value, {_, SModule}},
- {value, {_, SOpts}}} =
- {lists:keysearch(<<"portnew">>, 1, Query),
- lists:keysearch(<<"ipnew">>, 1, Query),
- lists:keysearch(<<"netprotnew">>, 1, Query),
- lists:keysearch(<<"modulenew">>, 1, Query),
- lists:keysearch(<<"optsnew">>, 1, Query)},
- {ok, Toks, _} = erl_scan:string(binary_to_list(<<SPort/binary, ".">>)),
- {ok, Port2} = erl_parse:parse_term(Toks),
- {ok, ToksIP, _} = erl_scan:string(binary_to_list(<<STIP/binary, ".">>)),
- STIP2 = case erl_parse:parse_term(ToksIP) of
- {ok, IPTParsed} -> IPTParsed;
- {error, _} -> STIP
- end,
- Module = misc:binary_to_atom(SModule),
- NetProt2 = misc:binary_to_atom(SNetProt),
- {ok, Tokens, _} = erl_scan:string(binary_to_list(<<SOpts/binary, ".">>)),
- {ok, Opts} = erl_parse:parse_term(Tokens),
- {Port2, _SPort, IP2, _SIP, _SSPort, NetProt2,
- OptsClean} =
- get_port_data({Port2, STIP2, NetProt2}, Opts),
- R = ejabberd_cluster:call(Node, ejabberd_listener, add_listener,
- [{Port2, IP2, NetProt2}, Module, OptsClean]),
- throw({is_added, R});
- _ -> ok
- end.
-
-node_modules_to_xhtml(Modules, Lang) ->
- ?XAE(<<"table">>, [{<<"class">>, <<"withtextareas">>}],
- [?XE(<<"thead">>,
- [?XE(<<"tr">>,
- [?XCT(<<"td">>, <<"Module">>),
- ?XCT(<<"td">>, <<"Options">>)])]),
- ?XE(<<"tbody">>,
- (lists:map(fun ({Module, Opts} = _E) ->
- SModule =
- iolist_to_binary(atom_to_list(Module)),
- {NumLines, SOpts} = term_to_paragraph(Opts,
- 40),
- ?XE(<<"tr">>,
- [?XC(<<"td">>, SModule),
- ?XAE(<<"td">>, direction(ltr),
- [?TEXTAREA(<<"opts", SModule/binary>>,
- (integer_to_binary(NumLines)),
- <<"40">>, SOpts)]),
- ?XE(<<"td">>,
- [?INPUTT(<<"submit">>,
- <<"restart",
- SModule/binary>>,
- <<"Restart">>)]),
- ?XE(<<"td">>,
- [?INPUTT(<<"submit">>,
- <<"stop", SModule/binary>>,
- <<"Stop">>)])])
- end,
- Modules)
- ++
- [?XE(<<"tr">>,
- [?XE(<<"td">>,
- [?INPUT(<<"text">>, <<"modulenew">>, <<"">>)]),
- ?XAE(<<"td">>, direction(ltr),
- [?TEXTAREA(<<"optsnew">>, <<"2">>, <<"40">>,
- <<"[]">>)]),
- ?XAE(<<"td">>, [{<<"colspan">>, <<"2">>}],
- [?INPUTT(<<"submit">>, <<"start">>,
- <<"Start">>)])])]))]).
-
-node_modules_parse_query(Host, Node, Modules, Query) ->
- lists:foreach(fun ({Module, _Opts1}) ->
- SModule = iolist_to_binary(atom_to_list(Module)),
- case lists:keysearch(<<"restart", SModule/binary>>, 1,
- Query)
- of
- {value, _} ->
- {value, {_, SOpts}} = lists:keysearch(<<"opts",
- SModule/binary>>,
- 1, Query),
- {ok, Tokens, _} =
- erl_scan:string(binary_to_list(<<SOpts/binary, ".">>)),
- {ok, Opts} = erl_parse:parse_term(Tokens),
- NewMods = lists:keystore(Module, 1, ejabberd_config:get_option(modules), {Module, Opts}),
- ejabberd_cluster:call(Node, gen_mod, stop_module,
- [Host, Module]),
- ejabberd_cluster:call(Node, ejabberd_config, add_option,
- [modules, NewMods]),
- ejabberd_cluster:call(Node, gen_mod, start_module,
- [Host, Module]),
- throw(submitted);
- _ ->
- case lists:keysearch(<<"stop", SModule/binary>>,
- 1, Query)
- of
- {value, _} ->
- ejabberd_cluster:call(Node, gen_mod, stop_module,
- [Host, Module]),
- throw(submitted);
- _ -> ok
- end
- end
- end,
- Modules),
- case lists:keysearch(<<"start">>, 1, Query) of
- {value, _} ->
- {{value, {_, SModule}}, {value, {_, SOpts}}} =
- {lists:keysearch(<<"modulenew">>, 1, Query),
- lists:keysearch(<<"optsnew">>, 1, Query)},
- Module = misc:binary_to_atom(SModule),
- {ok, Tokens, _} = erl_scan:string(binary_to_list(<<SOpts/binary, ".">>)),
- {ok, Opts} = erl_parse:parse_term(Tokens),
- ejabberd_cluster:call(Node, gen_mod, start_module,
- [Host, Module, Opts]),
- throw(submitted);
- _ -> ok
- end.
-
node_update_parse_query(Node, Query) ->
case lists:keysearch(<<"update">>, 1, Query) of
{value, _} ->
@@ -2495,16 +1673,6 @@ pretty_print_xml(#xmlel{name = Name, attrs = Attrs,
end
end].
-element_to_list(X) when is_atom(X) ->
- iolist_to_binary(atom_to_list(X));
-element_to_list(X) when is_integer(X) ->
- integer_to_binary(X).
-
-list_to_element(Bin) ->
- {ok, Tokens, _} = erl_scan:string(binary_to_list(Bin)),
- [{_, _, Element}] = Tokens,
- Element.
-
url_func({user_diapason, From, To}) ->
<<(integer_to_binary(From))/binary, "-",
(integer_to_binary(To))/binary, "/">>;
@@ -2576,8 +1744,7 @@ make_host_node_menu(_, cluster, _Lang, _JID) ->
{<<"">>, <<"">>, []};
make_host_node_menu(Host, Node, Lang, JID) ->
HostNodeBase = get_base_path(Host, Node),
- HostNodeFixed = [{<<"modules/">>, <<"Modules">>}] ++
- get_menu_items_hook({hostnode, Host, Node}, Lang),
+ HostNodeFixed = get_menu_items_hook({hostnode, Host, Node}, Lang),
HostNodeBasePath = url_to_path(HostNodeBase),
HostNodeFixed2 = [Tuple
|| Tuple <- HostNodeFixed,
@@ -2589,9 +1756,7 @@ make_host_menu(global, _HostNodeMenu, _Lang, _JID) ->
{<<"">>, <<"">>, []};
make_host_menu(Host, HostNodeMenu, Lang, JID) ->
HostBase = get_base_path(Host, cluster),
- HostFixed = [{<<"acls">>, <<"Access Control Lists">>},
- {<<"access">>, <<"Access Rules">>},
- {<<"users">>, <<"Users">>},
+ HostFixed = [{<<"users">>, <<"Users">>},
{<<"online-users">>, <<"Online Users">>}]
++
get_lastactivity_menuitem_list(Host) ++
@@ -2610,7 +1775,6 @@ make_node_menu(global, Node, Lang) ->
NodeBase = get_base_path(global, Node),
NodeFixed = [{<<"db/">>, <<"Database">>},
{<<"backup/">>, <<"Backup">>},
- {<<"ports/">>, <<"Listened Ports">>},
{<<"stats/">>, <<"Statistics">>},
{<<"update/">>, <<"Update">>}]
++ get_menu_items_hook({node, Node}, Lang),
@@ -2621,9 +1785,7 @@ make_node_menu(_Host, _Node, _Lang) ->
make_server_menu(HostMenu, NodeMenu, Lang, JID) ->
Base = get_base_path(global, cluster),
- Fixed = [{<<"acls">>, <<"Access Control Lists">>},
- {<<"access">>, <<"Access Rules">>},
- {<<"vhosts">>, <<"Virtual Hosts">>, HostMenu},
+ Fixed = [{<<"vhosts">>, <<"Virtual Hosts">>, HostMenu},
{<<"nodes">>, <<"Nodes">>, NodeMenu},
{<<"stats">>, <<"Statistics">>}]
++ get_menu_items_hook(server, Lang),
@@ -2696,11 +1858,10 @@ make_menu_item(item, 3, URI, Name, Lang) ->
?LI([?XAE(<<"div">>, [{<<"id">>, <<"navitemsubsub">>}],
[?ACT(URI, Name)])]).
-%%%==================================
-
-
--spec opt_type(atom()) -> fun((any()) -> any()) | [atom()].
-opt_type(access_readonly) -> fun acl:access_rules_validator/1;
-opt_type(_) -> [access_readonly].
+any_rules_allowed(Host, Access, Entity) ->
+ lists:any(
+ fun(Rule) ->
+ allow == acl:match_rule(Host, Rule, Entity)
+ end, Access).
%%% vim: set foldmethod=marker foldmarker=%%%%,%%%=: