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