aboutsummaryrefslogtreecommitdiff
path: root/src/mod_roster.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/mod_roster.erl')
-rw-r--r--src/mod_roster.erl180
1 files changed, 178 insertions, 2 deletions
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")])].
+