diff options
Diffstat (limited to 'src/mod_roster.erl')
-rw-r--r-- | src/mod_roster.erl | 89 |
1 files changed, 39 insertions, 50 deletions
diff --git a/src/mod_roster.erl b/src/mod_roster.erl index 27fac3131..fdf9de9f4 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -41,7 +41,7 @@ -behaviour(gen_mod). -export([start/2, stop/1, reload/3, process_iq/1, export/1, - import_info/0, process_local_iq/1, get_user_roster/2, + import_info/0, process_local_iq/1, get_user_roster_items/2, import/5, get_roster/2, push_item/3, import_start/2, import_stop/2, is_subscribed/2, c2s_self_presence/1, in_subscription/2, @@ -92,7 +92,7 @@ start(Host, Opts) -> Mod:init(Host, Opts), init_cache(Mod, Host, Opts), ejabberd_hooks:add(roster_get, Host, ?MODULE, - get_user_roster, 50), + get_user_roster_items, 50), ejabberd_hooks:add(roster_in_subscription, Host, ?MODULE, in_subscription, 50), ejabberd_hooks:add(roster_out_subscription, Host, @@ -114,7 +114,7 @@ start(Host, Opts) -> stop(Host) -> ejabberd_hooks:delete(roster_get, Host, ?MODULE, - get_user_roster, 50), + get_user_roster_items, 50), ejabberd_hooks:delete(roster_in_subscription, Host, ?MODULE, in_subscription, 50), ejabberd_hooks:delete(roster_out_subscription, Host, @@ -205,9 +205,8 @@ process_local_iq(#iq{lang = Lang} = IQ) -> -spec roster_hash([#roster{}]) -> binary(). roster_hash(Items) -> - str:sha(term_to_binary(lists:sort([R#roster{groups = - lists:sort(Grs)} - || R = #roster{groups = Grs} + str:sha(term_to_binary(lists:sort([R#roster_item{groups = lists:sort(Grs)} + || R = #roster_item{groups = Grs} <- Items]))). %% Returns a list that may contain an xmlelement with the XEP-237 feature if it's enabled. @@ -227,7 +226,6 @@ get_versioning_feature(Acc, Host) -> -spec roster_version(binary(), binary()) -> undefined | binary(). roster_version(LServer, LUser) -> - US = {LUser, LServer}, case mod_roster_opt:store_current_id(LServer) of true -> case read_roster_version(LUser, LServer) of @@ -235,8 +233,7 @@ roster_version(LServer, LUser) -> {ok, V} -> V end; false -> - roster_hash(ejabberd_hooks:run_fold(roster_get, LServer, - [], [US])) + roster_hash(run_roster_get_hook(LUser, LServer)) end. -spec read_roster_version(binary(), binary()) -> {ok, binary()} | error. @@ -279,7 +276,6 @@ process_iq_get(#iq{to = To, from = From, sub_els = [#roster_query{ver = RequestedVersion, mix_annotate = MixAnnotate}]} = IQ) -> LUser = To#jid.luser, LServer = To#jid.lserver, - US = {LUser, LServer}, MixEnabled = MixAnnotate == #mix_roster_annotate{}, {ItemsToSend, VersionToSend} = case {mod_roster_opt:versioning(LServer), @@ -288,32 +284,22 @@ process_iq_get(#iq{to = To, from = From, case read_roster_version(LUser, LServer) of error -> RosterVersion = write_roster_version(LUser, LServer), - {lists:map(fun encode_item/1, - ejabberd_hooks:run_fold( - roster_get, To#jid.lserver, [], [US])), - RosterVersion}; + {run_roster_get_hook(LUser, LServer), RosterVersion}; {ok, RequestedVersion} -> {false, false}; {ok, NewVersion} -> - {lists:map(fun encode_item/1, - ejabberd_hooks:run_fold( - roster_get, To#jid.lserver, [], [US])), - NewVersion} + {run_roster_get_hook(LUser, LServer), NewVersion} end; {true, false} when RequestedVersion /= undefined -> - RosterItems = ejabberd_hooks:run_fold( - roster_get, To#jid.lserver, [], [US]), + RosterItems = run_roster_get_hook(LUser, LServer), case roster_hash(RosterItems) of RequestedVersion -> {false, false}; New -> - {lists:map(fun encode_item/1, RosterItems), New} + {RosterItems, New} end; _ -> - {lists:map(fun encode_item/1, - ejabberd_hooks:run_fold( - roster_get, To#jid.lserver, [], [US])), - false} + {run_roster_get_hook(LUser, LServer), false} end, % Store that MIX annotation is enabled (for roster pushes) set_mix_annotation_enabled(From, MixEnabled), @@ -334,16 +320,21 @@ process_iq_get(#iq{to = To, from = From, ver = Version} end). --spec get_user_roster([#roster{}], {binary(), binary()}) -> [#roster{}]. -get_user_roster(Acc, {LUser, LServer}) -> - Items = get_roster(LUser, LServer), - lists:filter(fun (#roster{subscription = none, - ask = in}) -> - false; - (_) -> true - end, - Items) - ++ Acc. +-spec run_roster_get_hook(binary(), binary()) -> [#roster_item{}]. +run_roster_get_hook(LUser, LServer) -> + ejabberd_hooks:run_fold(roster_get, LServer, [], [{LUser, LServer}]). + +-spec get_filtered_roster(binary(), binary()) -> [#roster{}]. +get_filtered_roster(LUser, LServer) -> + lists:filter( + fun (#roster{subscription = none, ask = in}) -> false; + (_) -> true + end, + get_roster(LUser, LServer)). + +-spec get_user_roster_items([#roster_item{}], {binary(), binary()}) -> [#roster_item{}]. +get_user_roster_items(Acc, {LUser, LServer}) -> + lists:map(fun encode_item/1, get_filtered_roster(LUser, LServer)) ++ Acc. -spec get_roster(binary(), binary()) -> [#roster{}]. get_roster(LUser, LServer) -> @@ -435,11 +426,7 @@ encode_item(Item) -> both -> subscribe; _ -> undefined end, - groups = Item#roster.groups, - mix_channel = case Item#roster.mix_participant_id of - <<>> -> undefined; - _ -> #mix_roster_channel{'participant-id' = Item#roster.mix_participant_id} - end}. + groups = Item#roster.groups}. -spec decode_item(roster_item(), #roster{}, boolean()) -> #roster{}. decode_item(#roster_item{subscription = remove} = Item, R, _) -> @@ -494,7 +481,7 @@ set_item_and_notify_clients(To, #roster_item{jid = PeerJID} = RosterItem, end, case transaction(LUser, LServer, [PeerLJID], F) of {atomic, {OldItem, NewItem}} -> - push_item(To, OldItem, NewItem), + push_item(To, encode_item(OldItem), encode_item(NewItem)), case NewItem#roster.subscription of remove -> send_unsubscribing_presence(To, OldItem); @@ -505,7 +492,7 @@ set_item_and_notify_clients(To, #roster_item{jid = PeerJID} = RosterItem, {error, Reason} end. --spec push_item(jid(), #roster{}, #roster{}) -> ok. +-spec push_item(jid(), #roster_item{}, #roster_item{}) -> ok. push_item(To, OldItem, NewItem) -> #jid{luser = LUser, lserver = LServer} = To, Ver = case mod_roster_opt:versioning(LServer) of @@ -518,10 +505,10 @@ push_item(To, OldItem, NewItem) -> push_item(To1, OldItem, NewItem, Ver) end, ejabberd_sm:get_user_resources(LUser, LServer)). --spec push_item(jid(), #roster{}, #roster{}, undefined | binary()) -> ok. +-spec push_item(jid(), #roster_item{}, #roster_item{}, undefined | binary()) -> ok. push_item(To, OldItem, NewItem, Ver) -> route_presence_change(To, OldItem, NewItem), - [Item] = process_items_mix([encode_item(NewItem)], To), + [Item] = process_items_mix([NewItem], To), IQ = #iq{type = set, to = To, from = jid:remove_resource(To), id = <<"push", (p1_rand:get_string())/binary>>, @@ -529,11 +516,11 @@ push_item(To, OldItem, NewItem, Ver) -> items = [Item]}]}, ejabberd_router:route(IQ). --spec route_presence_change(jid(), #roster{}, #roster{}) -> ok. +-spec route_presence_change(jid(), #roster_item{}, #roster_item{}) -> ok. route_presence_change(From, OldItem, NewItem) -> - OldSub = OldItem#roster.subscription, - NewSub = NewItem#roster.subscription, - To = jid:make(NewItem#roster.jid), + OldSub = OldItem#roster_item.subscription, + NewSub = NewItem#roster_item.subscription, + To = NewItem#roster_item.jid, NewIsFrom = NewSub == both orelse NewSub == from, OldIsFrom = OldSub == both orelse OldSub == from, if NewIsFrom andalso not OldIsFrom -> @@ -657,7 +644,9 @@ process_subscription(Direction, User, Server, JID1, NewItem#roster.ask == in -> ok; true -> - push_item(jid:make(User, Server), OldItem, NewItem) + push_item(jid:make(User, Server), + encode_item(OldItem), + encode_item(NewItem)) end, true; none -> @@ -835,7 +824,7 @@ in_auto_reply(_, _, _) -> none. remove_user(User, Server) -> LUser = jid:nodeprep(User), LServer = jid:nameprep(Server), - Items = get_user_roster([], {LUser, LServer}), + Items = get_filtered_roster(LUser, LServer), send_unsubscription_to_rosteritems(LUser, LServer, Items), Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:remove_user(LUser, LServer), |