25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-24 16:23:40 +01:00

* src/web/ejabberd_web_admin.erl: Moved roster stuff to mod_roster*

* src/mod_roster.erl: Likewise
* src/mod_roster_odbc.erl: Likewise

SVN Revision: 886
This commit is contained in:
Alexey Shchepin 2007-08-24 16:15:05 +00:00
parent 38ad132ba2
commit a8bc3a46af
4 changed files with 371 additions and 177 deletions

View File

@ -1,3 +1,9 @@
2007-08-24 Alexey Shchepin <alexey@process-one.net>
* src/web/ejabberd_web_admin.erl: Moved roster stuff to mod_roster*
* src/mod_roster.erl: Likewise
* src/mod_roster_odbc.erl: Likewise
2007-08-23 Alexey Shchepin <alexey@process-one.net> 2007-08-23 Alexey Shchepin <alexey@process-one.net>
* src/ejabberd_sm.erl: Removed check which denies resource to * src/ejabberd_sm.erl: Removed check which denies resource to

View File

@ -7,7 +7,10 @@
-module(mod_roster). -module(mod_roster).
-author('alexey@sevcom.net'). -author('alexey@sevcom.net').
v v v v v v v
*************
-vsn('$Revision$ '). -vsn('$Revision$ ').
^ ^ ^ ^ ^ ^ ^
-behaviour(gen_mod). -behaviour(gen_mod).
@ -21,11 +24,15 @@
out_subscription/4, out_subscription/4,
set_items/3, set_items/3,
remove_user/2, remove_user/2,
get_jid_info/4]). get_jid_info/4,
webadmin_page/3,
webadmin_user/4]).
-include("ejabberd.hrl"). -include("ejabberd.hrl").
-include("jlib.hrl"). -include("jlib.hrl").
-include("mod_roster.hrl"). -include("mod_roster.hrl").
-include("web/ejabberd_http.hrl").
-include("web/ejabberd_web_admin.hrl").
start(Host, Opts) -> start(Host, Opts) ->
@ -50,6 +57,10 @@ start(Host, Opts) ->
?MODULE, remove_user, 50), ?MODULE, remove_user, 50),
ejabberd_hooks:add(resend_subscription_requests_hook, Host, ejabberd_hooks:add(resend_subscription_requests_hook, Host,
?MODULE, get_in_pending_subscriptions, 50), ?MODULE, get_in_pending_subscriptions, 50),
ejabberd_hooks:add(webadmin_page_host, Host,
?MODULE, webadmin_page, 50),
ejabberd_hooks:add(webadmin_user, Host,
?MODULE, webadmin_user, 50),
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ROSTER, gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ROSTER,
?MODULE, process_iq, IQDisc). ?MODULE, process_iq, IQDisc).
@ -69,7 +80,11 @@ stop(Host) ->
ejabberd_hooks:delete(anonymous_purge_hook, Host, ejabberd_hooks:delete(anonymous_purge_hook, Host,
?MODULE, remove_user, 50), ?MODULE, remove_user, 50),
ejabberd_hooks:delete(resend_subscription_requests_hook, Host, ejabberd_hooks:delete(resend_subscription_requests_hook, Host,
?MODULE, get_in_pending_subscriptions, 50), ?MODULE, get_in_pending_subscriptions, 50),
ejabberd_hooks:delete(webadmin_page_host, Host,
?MODULE, webadmin_page, 50),
ejabberd_hooks:delete(webadmin_user, Host,
?MODULE, webadmin_user, 50),
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_ROSTER). gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_ROSTER).
@ -781,3 +796,164 @@ convert_table2(Fields) ->
?INFO_MSG("Converting roster table from " ?INFO_MSG("Converting roster table from "
"{usj, us, jid, name, subscription, ask, groups, xattrs, xs} format", []), "{usj, us, jid, name, subscription, ask, groups, xattrs, xs} format", []),
mnesia:transform_table(roster, ignore, Fields). mnesia:transform_table(roster, ignore, Fields).
webadmin_page(_, Host,
#request{us = _US,
path = ["user", U, "roster"],
q = Query,
lang = Lang} = _Request) ->
Res = user_roster(U, Host, Query, Lang),
{stop, Res};
webadmin_page(Acc, _, _) -> Acc.
user_roster(User, Server, Query, Lang) ->
US = {jlib:nodeprep(User), jlib:nameprep(Server)},
Items1 = mnesia:dirty_index_read(roster, US, #roster.us),
Res = user_roster_parse_query(User, Server, Items1, Query),
Items = mnesia:dirty_index_read(roster, US, #roster.us),
SItems = lists:sort(Items),
FItems =
case SItems of
[] ->
[?CT("None")];
_ ->
[?XE("table",
[?XE("thead",
[?XE("tr",
[?XCT("td", "Jabber ID"),
?XCT("td", "Nickname"),
?XCT("td", "Subscription"),
?XCT("td", "Pending"),
?XCT("td", "Groups")
])]),
?XE("tbody",
lists:map(
fun(R) ->
Groups =
lists:flatmap(
fun(Group) ->
[?C(Group), ?BR]
end, R#roster.groups),
Pending = ask_to_pending(R#roster.ask),
?XE("tr",
[?XAC("td", [{"class", "valign"}],
jlib:jid_to_string(R#roster.jid)),
?XAC("td", [{"class", "valign"}],
R#roster.name),
?XAC("td", [{"class", "valign"}],
atom_to_list(R#roster.subscription)),
?XAC("td", [{"class", "valign"}],
atom_to_list(Pending)),
?XAE("td", [{"class", "valign"}], Groups),
if
Pending == in ->
?XAE("td", [{"class", "valign"}],
[?INPUTT("submit",
"validate" ++
ejabberd_web_admin:term_to_id(R#roster.jid),
"Validate")]);
true ->
?X("td")
end,
?XAE("td", [{"class", "valign"}],
[?INPUTT("submit",
"remove" ++
ejabberd_web_admin:term_to_id(R#roster.jid),
"Remove")])])
end, SItems))])]
end,
[?XC("h1", ?T("Roster of ") ++ us_to_list(US))] ++
case Res of
ok -> [?CT("Submitted"), ?P];
error -> [?CT("Bad format"), ?P];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
FItems ++
[?P,
?INPUT("text", "newjid", ""), ?C(" "),
?INPUTT("submit", "addjid", "Add Jabber ID")
])].
user_roster_parse_query(User, Server, Items, Query) ->
case lists:keysearch("addjid", 1, Query) of
{value, _} ->
case lists:keysearch("newjid", 1, Query) of
{value, {_, undefined}} ->
error;
{value, {_, SJID}} ->
case jlib:string_to_jid(SJID) of
JID when is_record(JID, jid) ->
user_roster_subscribe_jid(User, Server, JID),
ok;
error ->
error
end;
false ->
error
end;
false ->
case catch user_roster_item_parse_query(
User, Server, Items, Query) of
submitted ->
ok;
{'EXIT', _Reason} ->
error;
_ ->
nothing
end
end.
user_roster_subscribe_jid(User, Server, JID) ->
out_subscription(User, Server, JID, subscribe),
UJID = jlib:make_jid(User, Server, ""),
ejabberd_router:route(
UJID, JID, {xmlelement, "presence", [{"type", "subscribe"}], []}).
user_roster_item_parse_query(User, Server, Items, Query) ->
lists:foreach(
fun(R) ->
JID = R#roster.jid,
case lists:keysearch(
"validate" ++ ejabberd_web_admin:term_to_id(JID), 1, Query) of
{value, _} ->
JID1 = jlib:make_jid(JID),
out_subscription(
User, Server, JID1, subscribed),
UJID = jlib:make_jid(User, Server, ""),
ejabberd_router:route(
UJID, JID1, {xmlelement, "presence",
[{"type", "subscribed"}], []}),
throw(submitted);
false ->
case lists:keysearch(
"remove" ++ ejabberd_web_admin:term_to_id(JID), 1, Query) of
{value, _} ->
UJID = jlib:make_jid(User, Server, ""),
process_iq(
UJID, UJID,
#iq{type = set,
sub_el = {xmlelement, "query",
[{"xmlns", ?NS_ROSTER}],
[{xmlelement, "item",
[{"jid", jlib:jid_to_string(JID)},
{"subscription", "remove"}],
[]}]}}),
throw(submitted);
false ->
ok
end
end
end, Items),
nothing.
us_to_list({User, Server}) ->
jlib:jid_to_string({User, Server, ""}).
webadmin_user(Acc, _User, _Server, Lang) ->
Acc ++ [?XE("h3", [?ACT("roster/", "Roster")])].

View File

@ -20,11 +20,16 @@
out_subscription/4, out_subscription/4,
set_items/3, set_items/3,
remove_user/2, remove_user/2,
get_jid_info/4]). get_jid_info/4,
webadmin_page/3,
webadmin_user/4]).
-include("ejabberd.hrl"). -include("ejabberd.hrl").
-include("jlib.hrl"). -include("jlib.hrl").
-include("mod_roster.hrl"). -include("mod_roster.hrl").
-include("web/ejabberd_http.hrl").
-include("web/ejabberd_web_admin.hrl").
start(Host, Opts) -> start(Host, Opts) ->
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
@ -44,6 +49,10 @@ start(Host, Opts) ->
?MODULE, remove_user, 50), ?MODULE, remove_user, 50),
ejabberd_hooks:add(resend_subscription_requests_hook, Host, ejabberd_hooks:add(resend_subscription_requests_hook, Host,
?MODULE, get_in_pending_subscriptions, 50), ?MODULE, get_in_pending_subscriptions, 50),
ejabberd_hooks:add(webadmin_page_host, Host,
?MODULE, webadmin_page, 50),
ejabberd_hooks:add(webadmin_user, Host,
?MODULE, webadmin_user, 50),
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ROSTER, gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ROSTER,
?MODULE, process_iq, IQDisc). ?MODULE, process_iq, IQDisc).
@ -64,6 +73,10 @@ stop(Host) ->
?MODULE, remove_user, 50), ?MODULE, remove_user, 50),
ejabberd_hooks:delete(resend_subscription_requests_hook, Host, ejabberd_hooks:delete(resend_subscription_requests_hook, Host,
?MODULE, get_in_pending_subscriptions, 50), ?MODULE, get_in_pending_subscriptions, 50),
ejabberd_hooks:delete(webadmin_page_host, Host,
?MODULE, webadmin_page, 50),
ejabberd_hooks:delete(webadmin_user, Host,
?MODULE, webadmin_user, 50),
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_ROSTER). gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_ROSTER).
@ -124,6 +137,14 @@ process_iq_get(From, To, #iq{sub_el = SubEl} = IQ) ->
end. end.
get_user_roster(Acc, {LUser, LServer}) -> get_user_roster(Acc, {LUser, LServer}) ->
Items = get_roster(LUser, LServer),
lists:filter(fun(#roster{subscription = none, ask = in}) ->
false;
(_) ->
true
end, Items) ++ Acc.
get_roster(LUser, LServer) ->
Username = ejabberd_odbc:escape(LUser), Username = ejabberd_odbc:escape(LUser),
case catch odbc_queries:get_roster(LServer, Username) of case catch odbc_queries:get_roster(LServer, Username) of
{selected, ["username", "jid", "nick", "subscription", "ask", {selected, ["username", "jid", "nick", "subscription", "ask",
@ -142,9 +163,6 @@ get_user_roster(Acc, {LUser, LServer}) ->
%% Bad JID in database: %% Bad JID in database:
error -> error ->
[]; [];
#roster{subscription = none,
ask = in} ->
[];
R -> R ->
SJID = jlib:jid_to_string(R#roster.jid), SJID = jlib:jid_to_string(R#roster.jid),
Groups = lists:flatmap( Groups = lists:flatmap(
@ -156,9 +174,9 @@ get_user_roster(Acc, {LUser, LServer}) ->
[R#roster{groups = Groups}] [R#roster{groups = Groups}]
end end
end, Items), end, Items),
RItems ++ Acc; RItems;
_ -> _ ->
Acc []
end. end.
@ -882,3 +900,164 @@ groups_to_string(#roster{us = {User, _Server},
"'", ejabberd_odbc:escape(Group), "'"], "'", ejabberd_odbc:escape(Group), "'"],
[String|Acc] end, [], Groups). [String|Acc] end, [], Groups).
webadmin_page(_, Host,
#request{us = _US,
path = ["user", U, "roster"],
q = Query,
lang = Lang} = _Request) ->
Res = user_roster(U, Host, Query, Lang),
{stop, Res};
webadmin_page(Acc, _, _) -> Acc.
user_roster(User, Server, Query, Lang) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
US = {LUser, LServer},
Items1 = get_roster(LUser, LServer),
Res = user_roster_parse_query(User, Server, Items1, Query),
Items = get_roster(LUser, LServer),
SItems = lists:sort(Items),
FItems =
case SItems of
[] ->
[?CT("None")];
_ ->
[?XE("table",
[?XE("thead",
[?XE("tr",
[?XCT("td", "Jabber ID"),
?XCT("td", "Nickname"),
?XCT("td", "Subscription"),
?XCT("td", "Pending"),
?XCT("td", "Groups")
])]),
?XE("tbody",
lists:map(
fun(R) ->
Groups =
lists:flatmap(
fun(Group) ->
[?C(Group), ?BR]
end, R#roster.groups),
Pending = ask_to_pending(R#roster.ask),
?XE("tr",
[?XAC("td", [{"class", "valign"}],
jlib:jid_to_string(R#roster.jid)),
?XAC("td", [{"class", "valign"}],
R#roster.name),
?XAC("td", [{"class", "valign"}],
atom_to_list(R#roster.subscription)),
?XAC("td", [{"class", "valign"}],
atom_to_list(Pending)),
?XAE("td", [{"class", "valign"}], Groups),
if
Pending == in ->
?XAE("td", [{"class", "valign"}],
[?INPUTT("submit",
"validate" ++
ejabberd_web_admin:term_to_id(R#roster.jid),
"Validate")]);
true ->
?X("td")
end,
?XAE("td", [{"class", "valign"}],
[?INPUTT("submit",
"remove" ++
ejabberd_web_admin:term_to_id(R#roster.jid),
"Remove")])])
end, SItems))])]
end,
[?XC("h1", ?T("Roster of ") ++ us_to_list(US))] ++
case Res of
ok -> [?CT("Submitted"), ?P];
error -> [?CT("Bad format"), ?P];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
FItems ++
[?P,
?INPUT("text", "newjid", ""), ?C(" "),
?INPUTT("submit", "addjid", "Add Jabber ID")
])].
user_roster_parse_query(User, Server, Items, Query) ->
case lists:keysearch("addjid", 1, Query) of
{value, _} ->
case lists:keysearch("newjid", 1, Query) of
{value, {_, undefined}} ->
error;
{value, {_, SJID}} ->
case jlib:string_to_jid(SJID) of
JID when is_record(JID, jid) ->
user_roster_subscribe_jid(User, Server, JID),
ok;
error ->
error
end;
false ->
error
end;
false ->
case catch user_roster_item_parse_query(
User, Server, Items, Query) of
submitted ->
ok;
{'EXIT', _Reason} ->
error;
_ ->
nothing
end
end.
user_roster_subscribe_jid(User, Server, JID) ->
out_subscription(User, Server, JID, subscribe),
UJID = jlib:make_jid(User, Server, ""),
ejabberd_router:route(
UJID, JID, {xmlelement, "presence", [{"type", "subscribe"}], []}).
user_roster_item_parse_query(User, Server, Items, Query) ->
lists:foreach(
fun(R) ->
JID = R#roster.jid,
case lists:keysearch(
"validate" ++ ejabberd_web_admin:term_to_id(JID), 1, Query) of
{value, _} ->
JID1 = jlib:make_jid(JID),
out_subscription(
User, Server, JID1, subscribed),
UJID = jlib:make_jid(User, Server, ""),
ejabberd_router:route(
UJID, JID1, {xmlelement, "presence",
[{"type", "subscribed"}], []}),
throw(submitted);
false ->
case lists:keysearch(
"remove" ++ ejabberd_web_admin:term_to_id(JID), 1, Query) of
{value, _} ->
UJID = jlib:make_jid(User, Server, ""),
process_iq(
UJID, UJID,
#iq{type = set,
sub_el = {xmlelement, "query",
[{"xmlns", ?NS_ROSTER}],
[{xmlelement, "item",
[{"jid", jlib:jid_to_string(JID)},
{"subscription", "remove"}],
[]}]}}),
throw(submitted);
false ->
ok
end
end
end, Items),
nothing.
us_to_list({User, Server}) ->
jlib:jid_to_string({User, Server, ""}).
webadmin_user(Acc, _User, _Server, Lang) ->
Acc ++ [?XE("h3", [?ACT("roster/", "Roster")])].

View File

@ -16,7 +16,8 @@
-export([process/2, -export([process/2,
list_users/4, list_users/4,
list_users_in_diapason/4, list_users_in_diapason/4,
pretty_print_xml/1]). pretty_print_xml/1,
term_to_id/1]).
-include("ejabberd.hrl"). -include("ejabberd.hrl").
-include("jlib.hrl"). -include("jlib.hrl").
@ -957,14 +958,6 @@ process_admin(Host,
Res = user_info(U, Host, Query, Lang), Res = user_info(U, Host, Query, Lang),
make_xhtml(Res, Host, Lang); make_xhtml(Res, Host, Lang);
process_admin(Host,
#request{us = US,
path = ["user", U, "roster"],
q = Query,
lang = Lang} = Request) ->
Res = user_roster(U, Host, Query, Lang, true),
make_xhtml(Res, Host, Lang);
process_admin(Host, process_admin(Host,
#request{us = US, #request{us = US,
path = ["nodes"], path = ["nodes"],
@ -1469,7 +1462,6 @@ user_info(User, Server, Query, Lang) ->
[?XAE("form", [{"action", ""}, {"method", "post"}], [?XAE("form", [{"action", ""}, {"method", "post"}],
[?XCT("h3", "Connected Resources:")] ++ FResources ++ [?XCT("h3", "Connected Resources:")] ++ FResources ++
[?XCT("h3", "Password:")] ++ FPassword ++ [?XCT("h3", "Password:")] ++ FPassword ++
[?XE("h3", [?ACT("roster/", "Roster")])] ++
UserItems ++ UserItems ++
[?P, ?INPUTT("submit", "removeuser", "Remove User")])]. [?P, ?INPUTT("submit", "removeuser", "Remove User")])].
@ -1498,165 +1490,6 @@ user_parse_query(User, Server, Query) ->
-record(roster, {usj,
us,
jid,
name = "",
subscription = none,
ask = none,
groups = [],
xattrs = [],
xs = []}).
ask_to_pending(subscribe) -> out;
ask_to_pending(unsubscribe) -> none;
ask_to_pending(Ask) -> Ask.
user_roster(User, Server, Query, Lang, Admin) ->
US = {jlib:nodeprep(User), jlib:nameprep(Server)},
Items1 = mnesia:dirty_index_read(roster, US, #roster.us),
Res = user_roster_parse_query(User, Server, Items1, Query, Admin),
Items = mnesia:dirty_index_read(roster, US, #roster.us),
SItems = lists:sort(Items),
FItems =
case SItems of
[] ->
[?CT("None")];
_ ->
[?XE("table",
[?XE("thead",
[?XE("tr",
[?XCT("td", "Jabber ID"),
?XCT("td", "Nickname"),
?XCT("td", "Subscription"),
?XCT("td", "Pending"),
?XCT("td", "Groups")
])]),
?XE("tbody",
lists:map(
fun(R) ->
Groups =
lists:flatmap(
fun(Group) ->
[?C(Group), ?BR]
end, R#roster.groups),
Pending = ask_to_pending(R#roster.ask),
?XE("tr",
[?XAC("td", [{"class", "valign"}],
jlib:jid_to_string(R#roster.jid)),
?XAC("td", [{"class", "valign"}],
R#roster.name),
?XAC("td", [{"class", "valign"}],
atom_to_list(R#roster.subscription)),
?XAC("td", [{"class", "valign"}],
atom_to_list(Pending)),
?XAE("td", [{"class", "valign"}], Groups),
if
Pending == in ->
?XAE("td", [{"class", "valign"}],
[?INPUTT("submit",
"validate" ++
term_to_id(R#roster.jid),
"Validate")]);
true ->
?X("td")
end,
?XAE("td", [{"class", "valign"}],
[?INPUTT("submit",
"remove" ++
term_to_id(R#roster.jid),
"Remove")])])
end, SItems))])]
end,
[?XC("h1", ?T("Roster of ") ++ us_to_list(US))] ++
case Res of
ok -> [?CT("Submitted"), ?P];
error -> [?CT("Bad format"), ?P];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
FItems ++
[?P,
?INPUT("text", "newjid", ""), ?C(" "),
?INPUTT("submit", "addjid", "Add Jabber ID")
])].
user_roster_parse_query(User, Server, Items, Query, Admin) ->
case lists:keysearch("addjid", 1, Query) of
{value, _} ->
case lists:keysearch("newjid", 1, Query) of
{value, {_, undefined}} ->
error;
{value, {_, SJID}} ->
case jlib:string_to_jid(SJID) of
JID when is_record(JID, jid) ->
user_roster_subscribe_jid(User, Server, JID),
ok;
error ->
error
end;
false ->
error
end;
false ->
case catch user_roster_item_parse_query(
User, Server, Items, Query) of
submitted ->
ok;
{'EXIT', _Reason} ->
error;
_ ->
nothing
end
end.
user_roster_subscribe_jid(User, Server, JID) ->
mod_roster:out_subscription(User, Server, JID, subscribe),
UJID = jlib:make_jid(User, Server, ""),
ejabberd_router:route(
UJID, JID, {xmlelement, "presence", [{"type", "subscribe"}], []}).
user_roster_item_parse_query(User, Server, Items, Query) ->
lists:foreach(
fun(R) ->
JID = R#roster.jid,
case lists:keysearch(
"validate" ++ term_to_id(JID), 1, Query) of
{value, _} ->
JID1 = jlib:make_jid(JID),
mod_roster:out_subscription(
User, Server, JID1, subscribed),
UJID = jlib:make_jid(User, Server, ""),
ejabberd_router:route(
UJID, JID1, {xmlelement, "presence",
[{"type", "subscribed"}], []}),
throw(submitted);
false ->
case lists:keysearch(
"remove" ++ term_to_id(JID), 1, Query) of
{value, _} ->
UJID = jlib:make_jid(User, Server, ""),
mod_roster:process_iq(
UJID, UJID,
#iq{type = set,
sub_el = {xmlelement, "query",
[{"xmlns", ?NS_ROSTER}],
[{xmlelement, "item",
[{"jid", jlib:jid_to_string(JID)},
{"subscription", "remove"}],
[]}]}}),
throw(submitted);
false ->
ok
end
end
end, Items),
nothing.
list_last_activity(Host, Lang, Integral, Period) -> list_last_activity(Host, Lang, Integral, Period) ->
{MegaSecs, Secs, _MicroSecs} = now(), {MegaSecs, Secs, _MicroSecs} = now(),
TimeStamp = MegaSecs * 1000000 + Secs, TimeStamp = MegaSecs * 1000000 + Secs,