From: Martin Langhoff <mar...@laptop.org>

With this patch, if the 'User' parameter is @all@, @online, @recent@ or
@nearby@, the add/removes change the group options to set/unset the
related modes.

This allows mod_ctlextra and other modules that tap call into these
functions to manipulate the mode of the SRG without explicit extensions.

---

Discussion points (not meant to be included in the commit msg)

This is coded and tested on top of 2.0.3, and applies cleanly to the tip
of 2.0.x .

This makes mod_ctrlextra able to control SRGs fully (sometihng I need for
the OLPC XS), and I suspect other modules (xmlrpc?) can take advantage of
this.

I am not aware of any security implications -- the onus is on the caller to
apply access control. If the user calling it has the rights to setup a SRG,
then they probably can do quite a bit of damage already.

One check that might be good to add is that the host is the local host.
It seems that this is as trivial as Host == LServer, but I am not completely
certain that Host is always local.

A trivial patch with the above check follows.

cheers,


martin 

---
 src/mod_shared_roster.erl |   87 +++++++++++++++++++++++++++++++++++----------
 1 files changed, 68 insertions(+), 19 deletions(-)

diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl
index d1b169d..1eb8e9a 100644
--- a/src/mod_shared_roster.erl
+++ b/src/mod_shared_roster.erl
@@ -620,15 +620,46 @@ is_user_in_group({_U, S} = US, Group, Host) ->
 %% @spec (Host::string(), {User::string(), Server::string()}, Group::string()) 
-> {atomic, ok}
 add_user_to_group(Host, US, Group) ->
     {LUser, LServer} = US,
-    %% Push this new user to members of groups where this group is displayed
-    push_user_to_displayed(LUser, LServer, Group, both),
-    %% Push members of groups that are displayed to this group
-    push_displayed_to_user(LUser, LServer, Group, Host, both),
-    R = #sr_user{us = US, group_host = {Group, Host}},
-    F = fun() ->
-               mnesia:write(R)
-       end,
-    mnesia:transaction(F).
+    
+    case regexp:match(LUser, "^...@.+@$") of
+       {match,_,_} ->
+           GroupOpts = mod_shared_roster:get_group_opts(Host, Group),
+           AllUsersOpt =
+               case LUser == "@all@" of
+                   true -> [{all_users, true}];
+                   false -> []
+               end,
+           %% FIXME: this should be specified by the user
+           RecentUsersOpt =
+               case LUser == "@recent@" of
+                   true -> [{recent_users_days, 7}];
+                   false -> []
+               end,
+           OnlineUsersOpt =
+               case LUser == "@online@" of
+                   true -> [{online_users, true}];
+                   false -> []
+               end,
+           NearbyUsersOpt =
+               case LUser == "@nearby@" of
+                   true -> [{nearby_users, true}];
+                   false -> []
+               end,
+            mod_shared_roster:set_group_opts(
+             Host, Group,
+             GroupOpts ++ AllUsersOpt
+             ++ RecentUsersOpt ++ OnlineUsersOpt ++ NearbyUsersOpt);
+       nomatch ->
+           %% Push this new user to members of groups where this group is 
displayed
+           push_user_to_displayed(LUser, LServer, Group, both),
+           %% Push members of groups that are displayed to this group
+           push_displayed_to_user(LUser, LServer, Group, Host, both),
+           R = #sr_user{us = US, group_host = {Group, Host}},
+           F = fun() ->
+                       mnesia:write(R)
+               end,
+           mnesia:transaction(F)
+    end.
 
 push_displayed_to_user(LUser, LServer, Group, Host, Subscription) ->
     GroupsOpts = groups_with_opts(LServer),
@@ -638,17 +669,35 @@ push_displayed_to_user(LUser, LServer, Group, Host, 
Subscription) ->
 
 remove_user_from_group(Host, US, Group) ->
     GroupHost = {Group, Host},
-    R = #sr_user{us = US, group_host = GroupHost},
-    F = fun() ->
-               mnesia:delete_object(R)
-       end,
-    Result = mnesia:transaction(F),
     {LUser, LServer} = US,
-    %% Push removal of the old user to members of groups where the group that 
this user was members was displayed
-    push_user_to_displayed(LUser, LServer, Group, remove),
-    %% Push removal of members of groups that where displayed to the group 
which this user has left
-    push_displayed_to_user(LUser, LServer, Group, Host, remove),
-    Result.
+
+    case regexp:match(LUser, "^...@.+@$") of
+       {match,_,_} ->
+           GroupOpts = mod_shared_roster:get_group_opts(Host, Group),
+           case LUser of
+               "@all@" ->
+                   NewGroupOpts = lists:filter(fun(X) -> X/={all_users,true} 
end, GroupOpts);
+               "@recent@" ->
+                   NewGroupOpts = lists:filter(fun(X) -> 
X/={recent_users_days,7} end, GroupOpts);
+               "@online@" ->
+                   NewGroupOpts = lists:filter(fun(X) -> 
X/={online_users,true} end, GroupOpts);
+               "@nearby@" ->
+                   NewGroupOpts = lists:filter(fun(X) -> 
X/={nearby_users,true} end, GroupOpts)
+           end,
+            mod_shared_roster:set_group_opts(Host, Group, NewGroupOpts);
+       nomatch ->
+           R = #sr_user{us = US, group_host = GroupHost},
+           F = fun() ->
+                       mnesia:delete_object(R)
+               end,
+           Result = mnesia:transaction(F),
+           %% Push removal of the old user to members of groups where the 
group that this user was members was displayed
+           push_user_to_displayed(LUser, LServer, Group, remove),
+           %% Push removal of members of groups that where displayed to the 
group which this user has left
+           push_displayed_to_user(LUser, LServer, Group, Host, remove),
+           Result
+    end.
+
 
 push_members_to_user(LUser, LServer, Group, Host, Subscription) ->
     GroupsOpts = groups_with_opts(LServer),
-- 
1.5.6.6

_______________________________________________
Server-devel mailing list
Server-devel@lists.laptop.org
http://lists.laptop.org/listinfo/server-devel

Reply via email to