]> granicus.if.org Git - ejabberd/commitdiff
* src/mod_shared_roster.erl: Fix for new registered accounts not
authorBadlop <badlop@process-one.net>
Sat, 26 Apr 2008 17:54:57 +0000 (17:54 +0000)
committerBadlop <badlop@process-one.net>
Sat, 26 Apr 2008 17:54:57 +0000 (17:54 +0000)
being immediately shown in an 'all' special shared roster
group (thanks to Alexey Shchepin) (EJAB-71)
* src/mod_register.erl: New vhost event user_registered

SVN Revision: 1304

ChangeLog
src/mod_register.erl
src/mod_shared_roster.erl

index 4d14067497ff2ca38c37924becbf26717d10dd16..b6699865ff1f3c8f700757edb0d084261d25b18a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2008-04-26  Badlop  <badlop@process-one.net>
+
+       * src/mod_shared_roster.erl: Fix for new registered accounts not
+       being immediately shown in an 'all' special shared roster
+       group (thanks to Alexey Shchepin) (EJAB-71)
+       * src/mod_register.erl: New vhost event user_registered
+
 2008-04-22  Badlop  <badlop@process-one.net>
 
        * src/ejabberd_auth.erl: Improve anonymous authentication to not
index fc5dbc17e63be25d9aec9dfcc2eb94d97de92106..a1f9c0ef302777b023e60475b733260b1be57f00 100644 (file)
@@ -192,6 +192,8 @@ try_register(User, Server, Password) ->
                allow ->
                    case ejabberd_auth:try_register(User, Server, Password) of
                        {atomic, ok} ->
+                           ejabberd_hooks:run(user_registered, Server,
+                                              [User, Server]),
                            send_welcome_message(JID),
                            send_registration_notifications(JID),
                            ok;
index 89c4777cb877de24f0c7207258107b2125769eb0..7b8558cf54c0c5d118314ebcc52f01590a9c41f5 100644 (file)
@@ -37,6 +37,7 @@
         process_item/2,
         in_subscription/6,
         out_subscription/4,
+        user_registered/2,
         list_groups/1,
         create_group/2,
         create_group/3,
@@ -81,7 +82,9 @@ start(Host, _Opts) ->
     ejabberd_hooks:add(roster_get_jid_info, Host,
                       ?MODULE, get_jid_info, 70),
     ejabberd_hooks:add(roster_process_item, Host,
-                      ?MODULE, process_item, 50).
+                      ?MODULE, process_item, 50),
+    ejabberd_hooks:add(user_registered, Host,
+                      ?MODULE, user_registered, 50).
 %%ejabberd_hooks:add(remove_user, Host,
 %%            ?MODULE, remove_user, 50),
 
@@ -101,7 +104,9 @@ stop(Host) ->
     ejabberd_hooks:delete(roster_get_jid_info, Host,
                          ?MODULE, get_jid_info, 70),
     ejabberd_hooks:delete(roster_process_item, Host,
-                         ?MODULE, process_item, 50).
+                         ?MODULE, process_item, 50),
+    ejabberd_hooks:delete(user_registered, Host,
+                         ?MODULE, user_registered, 50).
 %%ejabberd_hooks:delete(remove_user, Host,
 %%               ?MODULE, remove_user, 50),
 
@@ -252,6 +257,14 @@ list_groups(Host) ->
        [{'==', '$2', Host}],
        ['$1']}]).
 
+groups_with_opts(Host) ->
+    Gs = mnesia:dirty_select(
+          sr_group,
+          [{#sr_group{group_host={'$1', Host}, opts='$2', _='_'},
+            [],
+            [['$1','$2']] }]),
+    lists:map(fun([G,O]) -> {G, O} end, Gs).
+
 create_group(Host, Group) ->
     create_group(Host, Group, []).
 
@@ -297,7 +310,7 @@ get_user_groups(US) ->
            [Group || #sr_user{group_host = {Group, H}} <- Rs, H == Host];
        _ ->
            []
-    end ++ get_all_users_groups(Host).
+    end ++ get_special_users_groups(Host).
 
 is_group_enabled(Host, Group) ->
     case catch mnesia:dirty_read(sr_group, {Group, Host}) of
@@ -328,23 +341,64 @@ get_group_users(Host, Group) ->
            []
     end ++ get_group_explicit_users(Host, Group).
 
+get_group_users(_User, Host, Group, GroupOpts) ->
+    case proplists:get_value(all_users, GroupOpts, false) of
+       true ->
+           ejabberd_auth:get_vh_registered_users(Host);
+       false ->
+           []
+    end ++ get_group_explicit_users(Host, Group).
+
 get_group_explicit_users(Host, Group) ->
-    case catch mnesia:dirty_index_read(
-                sr_user, {Group, Host}, #sr_user.group_host) of
-                                                                 Rs when is_list(Rs) ->
-                [R#sr_user.us || R <- Rs];
-              _ ->
-                []
-        end.
+    Read = (catch mnesia:dirty_index_read(
+                   sr_user,
+                   {Group, Host},
+                   #sr_user.group_host)),
+    case Read of
+       Rs when is_list(Rs) ->
+           [R#sr_user.us || R <- Rs];
+       _ ->
+           []
+    end.
 
 get_group_name(Host, Group) ->
     get_group_opt(Host, Group, name, Group).
 
-get_all_users_groups(Host) ->
+get_special_users_groups(Host) ->
     lists:filter(
-      fun(Group) -> get_group_opt(Host, Group, all_users, false) end,
+      fun(Group) ->
+             get_group_opt(Host, Group, all_users, false)
+      end,
       list_groups(Host)).
 
+displayed_groups(GroupsOpts, SelectedGroupsOpts) ->
+    DisplayedGroups =
+       lists:usort(
+         lists:flatmap(
+           fun({_Group, Opts}) ->
+                   [G || G <- proplists:get_value(displayed_groups, Opts, []),
+                         not lists:member(disabled, Opts)]
+           end, SelectedGroupsOpts)),
+    [G || G <- DisplayedGroups,
+         not lists:member(disabled, proplists:get_value(G, GroupsOpts, []))].
+
+get_special_displayed_groups(GroupsOpts) ->
+    Groups = lists:filter(
+              fun({_Group, Opts}) ->
+                      proplists:get_value(all_users, Opts, false)
+              end, GroupsOpts),
+    displayed_groups(GroupsOpts, Groups).
+
+get_user_displayed_groups(LUser, LServer, GroupsOpts) ->
+    Groups = case catch mnesia:dirty_read(sr_user, {LUser, LServer}) of
+                Rs when is_list(Rs) ->
+                    [{Group, proplists:get_value(Group, GroupsOpts, [])} ||
+                        #sr_user{group_host = {Group, H}} <- Rs, H == LServer];
+                _ ->
+                    []
+            end,
+    displayed_groups(GroupsOpts, Groups).
+
 get_user_displayed_groups(US) ->
     Host = element(2, US),
     DisplayedGroups1 =
@@ -382,6 +436,91 @@ remove_user_from_group(Host, US, Group) ->
        end,
     mnesia:transaction(F).
 
+user_registered(User, Server) ->
+    LUser = jlib:nodeprep(User),
+    LServer = jlib:nameprep(Server),
+    GroupsOpts = groups_with_opts(LServer),
+    SpecialGroups = get_special_displayed_groups(GroupsOpts),
+    UserGroups = get_user_displayed_groups(LUser, LServer, GroupsOpts),
+    lists:foreach(
+      fun(Group) ->
+             GroupOpts = proplists:get_value(Group, GroupsOpts, []),
+             GroupName = proplists:get_value(name, GroupOpts, Group),
+             lists:foreach(
+               fun({U, S}) ->
+                       Item = #roster{usj = {U, S, {LUser, LServer, ""}},
+                                      us = {U, S},
+                                      jid = {LUser, LServer, ""},
+                                      name = "",
+                                      subscription = both,
+                                      ask = none,
+                                      groups = [GroupName]},
+                       push_item(U, S, jlib:make_jid("", S, ""), Item)
+               end, get_group_users(LUser, LServer, Group, GroupOpts))
+      end, lists:usort(SpecialGroups++UserGroups)).
+
+push_item(_User, _Server, _From, none) ->
+    ok;
+push_item(User, Server, From, Item) ->
+    %% It was
+    %%  ejabberd_sm:route(jlib:make_jid("", "", ""),
+    %%                    jlib:make_jid(User, Server, "")
+    %% why?
+    ejabberd_sm:route(From, jlib:make_jid(User, Server, ""),
+                     {xmlelement, "broadcast", [],
+                      [{item,
+                        Item#roster.jid,
+                        Item#roster.subscription}]}),
+    Stanza = jlib:iq_to_xml(
+              #iq{type = set, xmlns = ?NS_ROSTER,
+                  id = "push",
+                  sub_el = [{xmlelement, "query",
+                             [{"xmlns", ?NS_ROSTER}],
+                             [item_to_xml(Item)]}]}),
+    lists:foreach(
+      fun(Resource) ->
+             JID = jlib:make_jid(User, Server, Resource),
+             ejabberd_router:route(JID, JID, Stanza)
+      end, ejabberd_sm:get_user_resources(User, Server)).
+
+item_to_xml(Item) ->
+    Attrs1 = [{"jid", jlib: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) ->
+                               {xmlelement, "group", [], [{xmlcdata, G}]}
+                       end, Item#roster.groups),
+    SubEls = SubEls1 ++ Item#roster.xs,
+    {xmlelement, "item", Attrs4, SubEls}.
+
+ask_to_pending(subscribe) -> out;
+ask_to_pending(unsubscribe) -> none;
+ask_to_pending(Ask) -> Ask.
+
 
 %%---------------------
 %% Web Admin