]> granicus.if.org Git - ejabberd/commitdiff
* src/mod_shared_roster.erl: Allow to get subscribed to a contact
authorBadlop <badlop@process-one.net>
Wed, 9 Jul 2008 19:06:44 +0000 (19:06 +0000)
committerBadlop <badlop@process-one.net>
Wed, 9 Jul 2008 19:06:44 +0000 (19:06 +0000)
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
src/mod_roster.erl
src/mod_shared_roster.erl

index eb0074ae12e32572ccc043508b73cb57fca008ae..958e6935a96590a5f6b7646b1ccd35a471bc1a88 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2008-07-09  Badlop  <badlop@process-one.net>
 
+       * 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)
index f1f59665a048823c1a16d24e4d6404f1fbb0283d..038de586a81b822a88c4eb48ee0495b551b1794d 100644 (file)
@@ -40,6 +40,7 @@
         set_items/3,
         remove_user/2,
         get_jid_info/4,
+        item_to_xml/1,
         webadmin_page/3,
         webadmin_user/4]).
 
index 7b8558cf54c0c5d118314ebcc52f01590a9c41f5..548b3072ae5c1ce11814509c87e2847af89840b1 100644 (file)
@@ -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.