From a2bed6709c0088057178d41bc09dd0919bd4238e Mon Sep 17 00:00:00 2001 From: Badlop Date: Wed, 9 Jul 2008 19:06:44 +0000 Subject: [PATCH] * src/mod_shared_roster.erl: Allow to get subscribed to a contact that is already in the roster by means of a shared roster group: add it to another roster group and it gets subscribed automatically (EJAB-407) * src/mod_roster.erl: Likewise SVN Revision: 1427 --- ChangeLog | 6 +++ src/mod_roster.erl | 1 + src/mod_shared_roster.erl | 88 +++++++++++++++++++++++++++++++++++---- 3 files changed, 88 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index eb0074ae1..958e6935a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2008-07-09 Badlop + * src/mod_shared_roster.erl: Allow to get subscribed to a contact + that is already in the roster by means of a shared roster group: + add it to another roster group and it gets subscribed + automatically (EJAB-407) + * src/mod_roster.erl: Likewise + * src/mod_muc/mod_muc_log.erl: Fix XHTML compliance: ensure some language is set, include ID attribute in each message, add microseconds to ensure unique value (EJAB-497) diff --git a/src/mod_roster.erl b/src/mod_roster.erl index f1f59665a..038de586a 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -40,6 +40,7 @@ set_items/3, remove_user/2, get_jid_info/4, + item_to_xml/1, webadmin_page/3, webadmin_user/4]). diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl index 7b8558cf5..548b3072a 100644 --- a/src/mod_shared_roster.erl +++ b/src/mod_shared_roster.erl @@ -155,12 +155,12 @@ get_user_roster(Items, US) -> {{U1, S1}, GroupNames} <- dict:to_list(SRUsersRest)], SRItems ++ NewItems1. -%% This function in use to rewrite the roster entries when moving or renaming +%% This function rewrites the roster entries when moving or renaming %% them in the user contact list. process_item(RosterItem, Host) -> - USFrom = RosterItem#roster.us, - {User,Server,_Resource} = RosterItem#roster.jid, - USTo = {User,Server}, + USFrom = {UserFrom, ServerFrom} = RosterItem#roster.us, + {UserTo, ServerTo, ResourceTo} = RosterItem#roster.jid, + USTo = {UserTo, ServerTo}, DisplayedGroups = get_user_displayed_groups(USFrom), CommonGroups = lists:filter(fun(Group) -> is_user_in_group(USTo, Group, Host) @@ -174,9 +174,83 @@ process_item(RosterItem, Host) -> end, CommonGroups), RosterItem#roster{subscription = both, ask = none, groups=[GroupNames]}; - _ -> RosterItem#roster{subscription = both, ask = none} + %% Both users have at least a common shared group, + %% So each user can see the other + _ -> + %% Check if the list of groups of the new roster item + %% include at least a new one + case lists:subtract(RosterItem#roster.groups, CommonGroups) of + [] -> + RosterItem#roster{subscription = both, ask = none}; + %% If so, it means the user wants to add that contact + %% to his personal roster + PersonalGroups -> + %% Store roster items in From and To rosters + set_new_rosteritems(UserFrom, ServerFrom, + UserTo, ServerTo, ResourceTo, + PersonalGroups) + end end. +build_roster_record(User1, Server1, User2, Server2, Groups) -> + USR2 = {User2, Server2, ""}, + #roster{usj = {User1, Server1, USR2}, + us = {User1, Server1}, + jid = USR2, + name = User2, + subscription = both, + ask = none, + groups = Groups + }. + +set_new_rosteritems(UserFrom, ServerFrom, + UserTo, ServerTo, ResourceTo, GroupsFrom) -> + Mod = case lists:member(mod_roster_odbc, + gen_mod:loaded_modules(ServerFrom)) of + true -> mod_roster_odbc; + false -> mod_roster + end, + + RIFrom = build_roster_record(UserFrom, ServerFrom, + UserTo, ServerTo, GroupsFrom), + set_item(UserFrom, ServerFrom, ResourceTo, RIFrom), + JIDTo = jlib:make_jid(UserTo, ServerTo, ""), + + JIDFrom = jlib:make_jid(UserFrom, ServerFrom, ""), + RITo = build_roster_record(UserTo, ServerTo, + UserFrom, ServerFrom, []), + set_item(UserTo, ServerTo, "", RITo), + + %% From requests + Mod:out_subscription(UserFrom, ServerFrom, JIDTo, subscribe), + Mod:in_subscription(aaa, UserTo, ServerTo, JIDFrom, subscribe, ""), + + %% To accepts + Mod:out_subscription(UserTo, ServerTo, JIDFrom, subscribed), + Mod:in_subscription(aaa, UserFrom, ServerFrom, JIDTo, subscribed, ""), + + %% To requests + Mod:out_subscription(UserTo, ServerTo, JIDFrom, subscribe), + Mod:in_subscription(aaa, UserFrom, ServerFrom, JIDTo, subscribe, ""), + + %% From accepts + Mod:out_subscription(UserFrom, ServerFrom, JIDTo, subscribed), + Mod:in_subscription(aaa, UserTo, ServerTo, JIDFrom, subscribed, ""), + + RIFrom. + +set_item(User, Server, Resource, Item) -> + ResIQ = #iq{type = set, xmlns = ?NS_ROSTER, + id = "push", + sub_el = [{xmlelement, "query", + [{"xmlns", ?NS_ROSTER}], + [mod_roster:item_to_xml(Item)]}]}, + ejabberd_router:route( + jlib:make_jid(User, Server, Resource), + jlib:make_jid("", Server, ""), + jlib:iq_to_xml(ResIQ)). + + get_subscription_lists({F, T}, User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), @@ -414,10 +488,10 @@ get_user_displayed_groups(US) -> end, get_user_groups(US))), [Group || Group <- DisplayedGroups1, is_group_enabled(Host, Group)]. -is_user_in_group(US, Group, Host) -> +is_user_in_group({U, S} = US, Group, Host) -> case catch mnesia:dirty_match_object( #sr_user{us=US, group_host={Group, Host}}) of - [] -> false; + [] -> lists:member(US, get_group_users(S, Group)); _ -> true end.