[Server-devel] [PATCH] mod_shared_roster: Teach remove_user_from_group() and add_user_to_group() about special users
martin.langhoff at gmail.com
martin.langhoff at gmail.com
Fri Apr 17 14:42:03 EDT 2009
From: Martin Langhoff <martin at 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
More information about the Server-devel
mailing list