diff options
Diffstat (limited to 'src/mod_shared_roster.erl')
-rw-r--r-- | src/mod_shared_roster.erl | 176 |
1 files changed, 68 insertions, 108 deletions
diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl index b472e1aab..8ef0f41b5 100644 --- a/src/mod_shared_roster.erl +++ b/src/mod_shared_roster.erl @@ -29,10 +29,10 @@ -behaviour(gen_mod). --export([start/2, stop/1, item_to_xml/1, export/1, - import/1, webadmin_menu/3, webadmin_page/3, +-export([start/2, stop/1, export/1, + import_info/0, webadmin_menu/3, webadmin_page/3, get_user_roster/2, get_subscription_lists/3, - get_jid_info/4, import/3, process_item/2, + get_jid_info/4, import/5, process_item/2, import_start/2, in_subscription/6, out_subscription/4, user_available/1, unset_presence/4, register_user/2, remove_user/2, list_groups/1, create_group/2, create_group/3, @@ -44,7 +44,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_roster.hrl"). @@ -56,7 +56,7 @@ -type group_options() :: [{atom(), any()}]. -callback init(binary(), gen_mod:opts()) -> any(). --callback import(binary(), #sr_user{} | #sr_group{}) -> ok | pass. +-callback import(binary(), binary(), [binary()]) -> ok. -callback list_groups(binary()) -> [binary()]. -callback groups_with_opts(binary()) -> [{binary(), group_options()}]. -callback create_group(binary(), binary(), group_options()) -> {atomic, any()}. @@ -135,6 +135,7 @@ stop(Host) -> depends(_Host, _Opts) -> []. +-spec get_user_roster([#roster{}], {binary(), binary()}) -> [#roster{}]. get_user_roster(Items, US) -> {U, S} = US, DisplayedGroups = get_user_displayed_groups(US), @@ -172,56 +173,37 @@ get_user_roster(Items, US) -> end end, SRUsers, Items), - ModVcard = get_vcard_module(S), SRItems = [#roster{usj = {U, S, {U1, S1, <<"">>}}, us = US, jid = {U1, S1, <<"">>}, - name = get_rosteritem_name(ModVcard, U1, S1), + name = get_rosteritem_name(U1, S1), subscription = both, ask = none, groups = GroupNames} || {{U1, S1}, GroupNames} <- dict:to_list(SRUsersRest)], SRItems ++ NewItems1. -get_vcard_module(Server) -> - Modules = gen_mod:loaded_modules(Server), - [M - || M <- Modules, - (M == mod_vcard) or (M == mod_vcard_ldap)]. - -get_rosteritem_name([], _, _) -> <<"">>; -get_rosteritem_name([ModVcard], U, S) -> - From = jid:make(<<"">>, S, jlib:atom_to_binary(?MODULE)), - To = jid:make(U, S, <<"">>), - case lists:member(To#jid.lserver, ?MYHOSTS) of +get_rosteritem_name(U, S) -> + case gen_mod:is_loaded(S, mod_vcard) of true -> - IQ = {iq, <<"">>, get, <<"vcard-temp">>, <<"">>, - #xmlel{name = <<"vCard">>, - attrs = [{<<"xmlns">>, <<"vcard-temp">>}], - children = []}}, - IQ_Vcard = ModVcard:process_sm_iq(From, To, IQ), - case catch get_rosteritem_name_vcard(IQ_Vcard#iq.sub_el) of - {'EXIT', Err} -> - ?ERROR_MSG("Error found when trying to get the " - "vCard of ~s@~s in ~p:~n ~p", - [U, S, ModVcard, Err]), - <<"">>; - NickName -> - NickName - end; + SubEls = mod_vcard:get_vcard(U, S), + get_rosteritem_name_vcard(SubEls); false -> <<"">> end. -get_rosteritem_name_vcard([]) -> <<"">>; -get_rosteritem_name_vcard([Vcard]) -> +-spec get_rosteritem_name_vcard([xmlel()]) -> binary(). +get_rosteritem_name_vcard([Vcard|_]) -> case fxml:get_path_s(Vcard, [{elem, <<"NICKNAME">>}, cdata]) of <<"">> -> fxml:get_path_s(Vcard, [{elem, <<"FN">>}, cdata]); Nickname -> Nickname - end. + end; +get_rosteritem_name_vcard(_) -> + <<"">>. %% This function rewrites the roster entries when moving or renaming %% them in the user contact list. +-spec process_item(#roster{}, binary()) -> #roster{}. process_item(RosterItem, Host) -> USFrom = {UserFrom, ServerFrom} = RosterItem#roster.us, {UserTo, ServerTo, ResourceTo} = RosterItem#roster.jid, @@ -305,17 +287,15 @@ set_new_rosteritems(UserFrom, ServerFrom, UserTo, RIFrom. set_item(User, Server, Resource, Item) -> - ResIQ = #iq{type = set, xmlns = ?NS_ROSTER, - id = <<"push", (randoms:get_string())/binary>>, - sub_el = - [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, ?NS_ROSTER}], - children = [mod_roster:item_to_xml(Item)]}]}, - ejabberd_router:route(jid:make(User, Server, - Resource), - jid:make(<<"">>, Server, <<"">>), - jlib:iq_to_xml(ResIQ)). - + ResIQ = #iq{type = set, id = <<"push", (randoms:get_string())/binary>>, + sub_els = [#roster_query{ + items = [mod_roster:encode_item(Item)]}]}, + ejabberd_router:route(jid:make(User, Server, Resource), + jid:make(Server), + ResIQ). + +-spec get_subscription_lists({[ljid()], [ljid()]}, binary(), binary()) + -> {[ljid()], [ljid()]}. get_subscription_lists({F, T}, User, Server) -> LUser = jid:nodeprep(User), LServer = jid:nameprep(Server), @@ -328,6 +308,8 @@ get_subscription_lists({F, T}, User, Server) -> SRJIDs = [{U1, S1, <<"">>} || {U1, S1} <- SRUsers], {lists:usort(SRJIDs ++ F), lists:usort(SRJIDs ++ T)}. +-spec get_jid_info({subscription(), [binary()]}, binary(), binary(), jid()) + -> {subscription(), [binary()]}. get_jid_info({Subscription, Groups}, User, Server, JID) -> LUser = jid:nodeprep(User), @@ -356,10 +338,16 @@ get_jid_info({Subscription, Groups}, User, Server, error -> {Subscription, Groups} end. +-spec in_subscription(boolean(), binary(), binary(), jid(), + subscribe | subscribed | unsubscribe | unsubscribed, + binary()) -> boolean(). in_subscription(Acc, User, Server, JID, Type, _Reason) -> process_subscription(in, User, Server, JID, Type, Acc). +-spec out_subscription( + binary(), binary(), jid(), + subscribed | unsubscribed | subscribe | unsubscribe) -> boolean(). out_subscription(UserFrom, ServerFrom, JIDTo, unsubscribed) -> #jid{luser = UserTo, lserver = ServerTo} = JIDTo, @@ -574,13 +562,13 @@ add_user_to_group(Host, US, Group) -> {LUser, LServer} = US, case ejabberd_regexp:run(LUser, <<"^@.+@\$">>) of match -> - GroupOpts = (?MODULE):get_group_opts(Host, Group), + GroupOpts = mod_shared_roster:get_group_opts(Host, Group), MoreGroupOpts = case LUser of <<"@all@">> -> [{all_users, true}]; <<"@online@">> -> [{online_users, true}]; _ -> [] end, - (?MODULE):set_group_opts(Host, Group, + mod_shared_roster:set_group_opts(Host, Group, GroupOpts ++ MoreGroupOpts); nomatch -> DisplayedToGroups = displayed_to_groups(Group, Host), @@ -612,7 +600,7 @@ remove_user_from_group(Host, US, Group) -> {LUser, LServer} = US, case ejabberd_regexp:run(LUser, <<"^@.+@\$">>) of match -> - GroupOpts = (?MODULE):get_group_opts(Host, Group), + GroupOpts = mod_shared_roster:get_group_opts(Host, Group), NewGroupOpts = case LUser of <<"@all@">> -> lists:filter(fun (X) -> X /= {all_users, true} @@ -623,7 +611,7 @@ remove_user_from_group(Host, US, Group) -> end, GroupOpts) end, - (?MODULE):set_group_opts(Host, Group, NewGroupOpts); + mod_shared_roster:set_group_opts(Host, Group, NewGroupOpts); nomatch -> Mod = gen_mod:db_mod(Host, ?MODULE), Result = Mod:remove_user_from_group(Host, US, Group), @@ -653,12 +641,15 @@ broadcast_members_to_user(LUser, LServer, Group, Host, Subscription) -> broadcast_subscription(U, S, {LUser, LServer, <<"">>}, Subscription) end, Members). +-spec register_user(binary(), binary()) -> ok. register_user(User, Server) -> Groups = get_user_groups({User, Server}), [push_user_to_displayed(User, Server, Group, Server, both, displayed_to_groups(Group, Server)) - || Group <- Groups]. + || Group <- Groups], + ok. +-spec remove_user(binary(), binary()) -> ok. remove_user(User, Server) -> push_user_to_members(User, Server, remove). @@ -730,13 +721,9 @@ displayed_to_groups(GroupName, LServer) -> [Name || {Name, _} <- Gs]. push_item(User, Server, Item) -> - Stanza = jlib:iq_to_xml(#iq{type = set, - xmlns = ?NS_ROSTER, - id = <<"push", (randoms:get_string())/binary>>, - sub_el = - [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, ?NS_ROSTER}], - children = [item_to_xml(Item)]}]}), + Stanza = #iq{type = set, id = <<"push", (randoms:get_string())/binary>>, + sub_els = [#roster_query{ + items = [mod_roster:encode_item(Item)]}]}, lists:foreach(fun (Resource) -> JID = jid:make(User, Server, Resource), ejabberd_router:route(jid:remove_resource(JID), JID, Stanza) @@ -752,38 +739,7 @@ push_roster_item(User, Server, ContactU, ContactS, groups = [GroupName]}, push_item(User, Server, Item). -item_to_xml(Item) -> - Attrs1 = [{<<"jid">>, - jid:to_string(Item#roster.jid)}], - Attrs2 = case Item#roster.name of - <<"">> -> Attrs1; - Name -> [{<<"name">>, Name} | Attrs1] - end, - Attrs3 = case Item#roster.subscription of - none -> [{<<"subscription">>, <<"none">>} | Attrs2]; - from -> [{<<"subscription">>, <<"from">>} | Attrs2]; - to -> [{<<"subscription">>, <<"to">>} | Attrs2]; - both -> [{<<"subscription">>, <<"both">>} | Attrs2]; - remove -> [{<<"subscription">>, <<"remove">>} | Attrs2] - end, - Attrs4 = case ask_to_pending(Item#roster.ask) of - out -> [{<<"ask">>, <<"subscribe">>} | Attrs3]; - both -> [{<<"ask">>, <<"subscribe">>} | Attrs3]; - _ -> Attrs3 - end, - SubEls1 = lists:map(fun (G) -> - #xmlel{name = <<"group">>, attrs = [], - children = [{xmlcdata, G}]} - end, - Item#roster.groups), - SubEls = SubEls1 ++ Item#roster.xs, - #xmlel{name = <<"item">>, attrs = Attrs4, - children = SubEls}. - -ask_to_pending(subscribe) -> out; -ask_to_pending(unsubscribe) -> none; -ask_to_pending(Ask) -> Ask. - +-spec user_available(jid()) -> ok. user_available(New) -> LUser = New#jid.luser, LServer = New#jid.lserver, @@ -807,6 +763,7 @@ user_available(New) -> _ -> ok end. +-spec unset_presence(binary(), binary(), binary(), binary()) -> ok. unset_presence(LUser, LServer, Resource, Status) -> Resources = ejabberd_sm:get_user_resources(LUser, LServer), @@ -850,7 +807,7 @@ webadmin_page(Acc, _, _) -> Acc. list_shared_roster_groups(Host, Query, Lang) -> Res = list_sr_groups_parse_query(Host, Query), - SRGroups = (?MODULE):list_groups(Host), + SRGroups = mod_shared_roster:list_groups(Host), FGroups = (?XAE(<<"table">>, [], [?XE(<<"tbody">>, (lists:map(fun (Group) -> @@ -901,15 +858,15 @@ list_sr_groups_parse_query(Host, Query) -> list_sr_groups_parse_addnew(Host, Query) -> case lists:keysearch(<<"namenew">>, 1, Query) of {value, {_, Group}} when Group /= <<"">> -> - (?MODULE):create_group(Host, Group), ok; + mod_shared_roster:create_group(Host, Group), ok; _ -> error end. list_sr_groups_parse_delete(Host, Query) -> - SRGroups = (?MODULE):list_groups(Host), + SRGroups = mod_shared_roster:list_groups(Host), lists:foreach(fun (Group) -> case lists:member({<<"selected">>, Group}, Query) of - true -> (?MODULE):delete_group(Host, Group); + true -> mod_shared_roster:delete_group(Host, Group); _ -> ok end end, @@ -919,14 +876,14 @@ list_sr_groups_parse_delete(Host, Query) -> shared_roster_group(Host, Group, Query, Lang) -> Res = shared_roster_group_parse_query(Host, Group, Query), - GroupOpts = (?MODULE):get_group_opts(Host, Group), + GroupOpts = mod_shared_roster:get_group_opts(Host, Group), Name = get_opt(GroupOpts, name, <<"">>), Description = get_opt(GroupOpts, description, <<"">>), AllUsers = get_opt(GroupOpts, all_users, false), OnlineUsers = get_opt(GroupOpts, online_users, false), DisplayedGroups = get_opt(GroupOpts, displayed_groups, []), - Members = (?MODULE):get_group_explicit_users(Host, + Members = mod_shared_roster:get_group_explicit_users(Host, Group), FMembers = iolist_to_binary( [if AllUsers -> <<"@all@\n">>; @@ -950,21 +907,21 @@ shared_roster_group(Host, Group, Query, Lang) -> [?XCT(<<"td">>, <<"Description:">>), ?XE(<<"td">>, [?TEXTAREA(<<"description">>, - jlib:integer_to_binary(lists:max([3, + integer_to_binary(lists:max([3, DescNL])), <<"20">>, Description)])]), ?XE(<<"tr">>, [?XCT(<<"td">>, <<"Members:">>), ?XE(<<"td">>, [?TEXTAREA(<<"members">>, - jlib:integer_to_binary(lists:max([3, + integer_to_binary(lists:max([3, byte_size(FMembers)])), <<"20">>, FMembers)])]), ?XE(<<"tr">>, [?XCT(<<"td">>, <<"Displayed Groups:">>), ?XE(<<"td">>, [?TEXTAREA(<<"dispgroups">>, - jlib:integer_to_binary(lists:max([3, length(FDisplayedGroups)])), + integer_to_binary(lists:max([3, length(FDisplayedGroups)])), <<"20">>, list_to_binary(FDisplayedGroups))])])])])), (?H1GL((?T(<<"Shared Roster Groups">>)), @@ -1003,7 +960,7 @@ shared_roster_group_parse_query(Host, Group, Query) -> DispGroupsOpt = if DispGroups == [] -> []; true -> [{displayed_groups, DispGroups}] end, - OldMembers = (?MODULE):get_group_explicit_users(Host, + OldMembers = mod_shared_roster:get_group_explicit_users(Host, Group), SJIDs = str:tokens(SMembers, <<", \r\n">>), NewMembers = lists:foldl(fun (_SJID, error) -> error; @@ -1040,7 +997,7 @@ shared_roster_group_parse_query(Host, Group, Query) -> RemovedDisplayedGroups = CurrentDisplayedGroups -- DispGroups, displayed_groups_update(OldMembers, RemovedDisplayedGroups, remove), displayed_groups_update(OldMembers, AddedDisplayedGroups, both), - (?MODULE):set_group_opts(Host, Group, + mod_shared_roster:set_group_opts(Host, Group, NameOpt ++ DispGroupsOpt ++ DescriptionOpt ++ @@ -1050,13 +1007,13 @@ shared_roster_group_parse_query(Host, Group, Query) -> AddedMembers = NewMembers -- OldMembers, RemovedMembers = OldMembers -- NewMembers, lists:foreach(fun (US) -> - (?MODULE):remove_user_from_group(Host, + mod_shared_roster:remove_user_from_group(Host, US, Group) end, RemovedMembers), lists:foreach(fun (US) -> - (?MODULE):add_user_to_group(Host, US, + mod_shared_roster:add_user_to_group(Host, US, Group) end, AddedMembers), @@ -1115,13 +1072,16 @@ export(LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:export(LServer). -import(LServer) -> - Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:import(LServer). +import_info() -> + [{<<"sr_group">>, 3}, {<<"sr_user">>, 3}]. + +import_start(LServer, DBType) -> + Mod = gen_mod:db_mod(DBType, ?MODULE), + Mod:init(LServer, []). -import(LServer, DBType, Data) -> +import(LServer, {sql, _}, DBType, Tab, L) -> Mod = gen_mod:db_mod(DBType, ?MODULE), - Mod:import(LServer, Data). + Mod:import(LServer, Tab, L). mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; mod_opt_type(_) -> [db_type]. |