From a8bc3a46afe8d1437440b5b03381812c87abbf55 Mon Sep 17 00:00:00 2001 From: Alexey Shchepin Date: Fri, 24 Aug 2007 16:15:05 +0000 Subject: [PATCH] * 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 --- ChangeLog | 6 ++ src/mod_roster.erl | 180 ++++++++++++++++++++++++++++++- src/mod_roster_odbc.erl | 191 +++++++++++++++++++++++++++++++-- src/web/ejabberd_web_admin.erl | 171 +---------------------------- 4 files changed, 371 insertions(+), 177 deletions(-) diff --git a/ChangeLog b/ChangeLog index 97c7ebe0f..905658876 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2007-08-24 Alexey Shchepin + + * 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 * src/ejabberd_sm.erl: Removed check which denies resource to diff --git a/src/mod_roster.erl b/src/mod_roster.erl index 785f30c76..3955fad00 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -7,7 +7,10 @@ -module(mod_roster). -author('alexey@sevcom.net'). +v v v v v v v +************* -vsn('$Revision$ '). +^ ^ ^ ^ ^ ^ ^ -behaviour(gen_mod). @@ -21,11 +24,15 @@ out_subscription/4, set_items/3, remove_user/2, - get_jid_info/4]). + get_jid_info/4, + webadmin_page/3, + webadmin_user/4]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("mod_roster.hrl"). +-include("web/ejabberd_http.hrl"). +-include("web/ejabberd_web_admin.hrl"). start(Host, Opts) -> @@ -50,6 +57,10 @@ start(Host, Opts) -> ?MODULE, remove_user, 50), ejabberd_hooks:add(resend_subscription_requests_hook, Host, ?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, ?MODULE, process_iq, IQDisc). @@ -69,7 +80,11 @@ stop(Host) -> ejabberd_hooks:delete(anonymous_purge_hook, Host, ?MODULE, remove_user, 50), 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). @@ -781,3 +796,164 @@ convert_table2(Fields) -> ?INFO_MSG("Converting roster table from " "{usj, us, jid, name, subscription, ask, groups, xattrs, xs} format", []), 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")])]. + diff --git a/src/mod_roster_odbc.erl b/src/mod_roster_odbc.erl index 2cf327cef..27cab420d 100644 --- a/src/mod_roster_odbc.erl +++ b/src/mod_roster_odbc.erl @@ -20,11 +20,16 @@ out_subscription/4, set_items/3, remove_user/2, - get_jid_info/4]). + get_jid_info/4, + webadmin_page/3, + webadmin_user/4]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("mod_roster.hrl"). +-include("web/ejabberd_http.hrl"). +-include("web/ejabberd_web_admin.hrl"). + start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), @@ -44,6 +49,10 @@ start(Host, Opts) -> ?MODULE, remove_user, 50), ejabberd_hooks:add(resend_subscription_requests_hook, Host, ?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, ?MODULE, process_iq, IQDisc). @@ -64,6 +73,10 @@ stop(Host) -> ?MODULE, remove_user, 50), ejabberd_hooks:delete(resend_subscription_requests_hook, Host, ?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). @@ -124,6 +137,14 @@ process_iq_get(From, To, #iq{sub_el = SubEl} = IQ) -> end. 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), case catch odbc_queries:get_roster(LServer, Username) of {selected, ["username", "jid", "nick", "subscription", "ask", @@ -142,9 +163,6 @@ get_user_roster(Acc, {LUser, LServer}) -> %% Bad JID in database: error -> []; - #roster{subscription = none, - ask = in} -> - []; R -> SJID = jlib:jid_to_string(R#roster.jid), Groups = lists:flatmap( @@ -156,9 +174,9 @@ get_user_roster(Acc, {LUser, LServer}) -> [R#roster{groups = Groups}] end end, Items), - RItems ++ Acc; + RItems; _ -> - Acc + [] end. @@ -882,3 +900,164 @@ groups_to_string(#roster{us = {User, _Server}, "'", ejabberd_odbc:escape(Group), "'"], [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")])]. + diff --git a/src/web/ejabberd_web_admin.erl b/src/web/ejabberd_web_admin.erl index c760a8233..8d5fff382 100644 --- a/src/web/ejabberd_web_admin.erl +++ b/src/web/ejabberd_web_admin.erl @@ -16,7 +16,8 @@ -export([process/2, list_users/4, list_users_in_diapason/4, - pretty_print_xml/1]). + pretty_print_xml/1, + term_to_id/1]). -include("ejabberd.hrl"). -include("jlib.hrl"). @@ -957,14 +958,6 @@ process_admin(Host, Res = user_info(U, Host, Query, 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, #request{us = US, path = ["nodes"], @@ -1469,7 +1462,6 @@ user_info(User, Server, Query, Lang) -> [?XAE("form", [{"action", ""}, {"method", "post"}], [?XCT("h3", "Connected Resources:")] ++ FResources ++ [?XCT("h3", "Password:")] ++ FPassword ++ - [?XE("h3", [?ACT("roster/", "Roster")])] ++ UserItems ++ [?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) -> {MegaSecs, Secs, _MicroSecs} = now(), TimeStamp = MegaSecs * 1000000 + Secs, -- 2.49.0