mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-30 16:36:29 +01:00
Clean mod_shared_roster.erl from DB specific code
This commit is contained in:
parent
398f1de5ae
commit
f8e3560ad2
5
include/mod_shared_roster.hrl
Normal file
5
include/mod_shared_roster.hrl
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
-record(sr_group, {group_host = {<<"">>, <<"">>} :: {'$1' | binary(), '$2' | binary()},
|
||||||
|
opts = [] :: list() | '_' | '$2'}).
|
||||||
|
|
||||||
|
-record(sr_user, {us = {<<"">>, <<"">>} :: {binary(), binary()},
|
||||||
|
group_host = {<<"">>, <<"">>} :: {binary(), binary()}}).
|
@ -38,7 +38,7 @@
|
|||||||
list_groups/1, create_group/2, create_group/3,
|
list_groups/1, create_group/2, create_group/3,
|
||||||
delete_group/2, get_group_opts/2, set_group_opts/3,
|
delete_group/2, get_group_opts/2, set_group_opts/3,
|
||||||
get_group_users/2, get_group_explicit_users/2,
|
get_group_users/2, get_group_explicit_users/2,
|
||||||
is_user_in_group/3, add_user_to_group/3,
|
is_user_in_group/3, add_user_to_group/3, opts_to_binary/1,
|
||||||
remove_user_from_group/3, mod_opt_type/1]).
|
remove_user_from_group/3, mod_opt_type/1]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
@ -52,25 +52,28 @@
|
|||||||
|
|
||||||
-include("ejabberd_web_admin.hrl").
|
-include("ejabberd_web_admin.hrl").
|
||||||
|
|
||||||
-record(sr_group, {group_host = {<<"">>, <<"">>} :: {'$1' | binary(), '$2' | binary()},
|
-include("mod_shared_roster.hrl").
|
||||||
opts = [] :: list() | '_' | '$2'}).
|
|
||||||
|
|
||||||
-record(sr_user, {us = {<<"">>, <<"">>} :: {binary(), binary()},
|
-type group_options() :: [{atom(), any()}].
|
||||||
group_host = {<<"">>, <<"">>} :: {binary(), binary()}}).
|
-callback init(binary(), gen_mod:opts()) -> any().
|
||||||
|
-callback import(binary(), #sr_user{} | #sr_group{}) -> ok | pass.
|
||||||
|
-callback list_groups(binary()) -> [binary()].
|
||||||
|
-callback groups_with_opts(binary()) -> [{binary(), group_options()}].
|
||||||
|
-callback create_group(binary(), binary(), group_options()) -> {atomic, any()}.
|
||||||
|
-callback delete_group(binary(), binary()) -> {atomic, any()}.
|
||||||
|
-callback get_group_opts(binary(), binary()) -> group_options() | error.
|
||||||
|
-callback set_group_opts(binary(), binary(), group_options()) -> {atomic, any()}.
|
||||||
|
-callback get_user_groups({binary(), binary()}, binary()) -> [binary()].
|
||||||
|
-callback get_group_explicit_users(binary(), binary()) -> [{binary(), binary()}].
|
||||||
|
-callback get_user_displayed_groups(binary(), binary(), group_options()) ->
|
||||||
|
[{binary(), group_options()}].
|
||||||
|
-callback is_user_in_group({binary(), binary()}, binary(), binary()) -> boolean().
|
||||||
|
-callback add_user_to_group(binary(), {binary(), binary()}, binary()) -> {atomic, any()}.
|
||||||
|
-callback remove_user_from_group(binary(), {binary(), binary()}, binary()) -> {atomic, any()}.
|
||||||
|
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
case gen_mod:db_type(Host, Opts) of
|
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
||||||
mnesia ->
|
Mod:init(Host, Opts),
|
||||||
mnesia:create_table(sr_group,
|
|
||||||
[{disc_copies, [node()]},
|
|
||||||
{attributes, record_info(fields, sr_group)}]),
|
|
||||||
mnesia:create_table(sr_user,
|
|
||||||
[{disc_copies, [node()]}, {type, bag},
|
|
||||||
{attributes, record_info(fields, sr_user)}]),
|
|
||||||
update_tables(),
|
|
||||||
mnesia:add_table_index(sr_user, group_host);
|
|
||||||
_ -> ok
|
|
||||||
end,
|
|
||||||
ejabberd_hooks:add(webadmin_menu_host, Host, ?MODULE,
|
ejabberd_hooks:add(webadmin_menu_host, Host, ?MODULE,
|
||||||
webadmin_menu, 70),
|
webadmin_menu, 70),
|
||||||
ejabberd_hooks:add(webadmin_page_host, Host, ?MODULE,
|
ejabberd_hooks:add(webadmin_page_host, Host, ?MODULE,
|
||||||
@ -391,195 +394,36 @@ process_subscription(Direction, User, Server, JID,
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
list_groups(Host) ->
|
list_groups(Host) ->
|
||||||
list_groups(Host, gen_mod:db_type(Host, ?MODULE)).
|
Mod = gen_mod:db_mod(Host, ?MODULE),
|
||||||
|
Mod:list_groups(Host).
|
||||||
list_groups(Host, mnesia) ->
|
|
||||||
mnesia:dirty_select(sr_group,
|
|
||||||
[{#sr_group{group_host = {'$1', '$2'}, _ = '_'},
|
|
||||||
[{'==', '$2', Host}], ['$1']}]);
|
|
||||||
list_groups(Host, riak) ->
|
|
||||||
case ejabberd_riak:get_keys_by_index(sr_group, <<"host">>, Host) of
|
|
||||||
{ok, Gs} ->
|
|
||||||
[G || {G, _} <- Gs];
|
|
||||||
_ ->
|
|
||||||
[]
|
|
||||||
end;
|
|
||||||
list_groups(Host, odbc) ->
|
|
||||||
case ejabberd_odbc:sql_query(Host,
|
|
||||||
[<<"select name from sr_group;">>])
|
|
||||||
of
|
|
||||||
{selected, [<<"name">>], Rs} -> [G || [G] <- Rs];
|
|
||||||
_ -> []
|
|
||||||
end.
|
|
||||||
|
|
||||||
groups_with_opts(Host) ->
|
groups_with_opts(Host) ->
|
||||||
groups_with_opts(Host, gen_mod:db_type(Host, ?MODULE)).
|
Mod = gen_mod:db_mod(Host, ?MODULE),
|
||||||
|
Mod:groups_with_opts(Host).
|
||||||
groups_with_opts(Host, mnesia) ->
|
|
||||||
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);
|
|
||||||
groups_with_opts(Host, riak) ->
|
|
||||||
case ejabberd_riak:get_by_index(sr_group, sr_group_schema(),
|
|
||||||
<<"host">>, Host) of
|
|
||||||
{ok, Rs} ->
|
|
||||||
[{G, O} || #sr_group{group_host = {G, _}, opts = O} <- Rs];
|
|
||||||
_ ->
|
|
||||||
[]
|
|
||||||
end;
|
|
||||||
groups_with_opts(Host, odbc) ->
|
|
||||||
case ejabberd_odbc:sql_query(Host,
|
|
||||||
[<<"select name, opts from sr_group;">>])
|
|
||||||
of
|
|
||||||
{selected, [<<"name">>, <<"opts">>], Rs} ->
|
|
||||||
[{G, opts_to_binary(ejabberd_odbc:decode_term(Opts))}
|
|
||||||
|| [G, Opts] <- Rs];
|
|
||||||
_ -> []
|
|
||||||
end.
|
|
||||||
|
|
||||||
create_group(Host, Group) ->
|
create_group(Host, Group) ->
|
||||||
create_group(Host, Group, []).
|
create_group(Host, Group, []).
|
||||||
|
|
||||||
create_group(Host, Group, Opts) ->
|
create_group(Host, Group, Opts) ->
|
||||||
create_group(Host, Group, Opts,
|
Mod = gen_mod:db_mod(Host, ?MODULE),
|
||||||
gen_mod:db_type(Host, ?MODULE)).
|
Mod:create_group(Host, Group, Opts).
|
||||||
|
|
||||||
create_group(Host, Group, Opts, mnesia) ->
|
|
||||||
R = #sr_group{group_host = {Group, Host}, opts = Opts},
|
|
||||||
F = fun () -> mnesia:write(R) end,
|
|
||||||
mnesia:transaction(F);
|
|
||||||
create_group(Host, Group, Opts, riak) ->
|
|
||||||
{atomic, ejabberd_riak:put(#sr_group{group_host = {Group, Host},
|
|
||||||
opts = Opts},
|
|
||||||
sr_group_schema(),
|
|
||||||
[{'2i', [{<<"host">>, Host}]}])};
|
|
||||||
create_group(Host, Group, Opts, odbc) ->
|
|
||||||
SGroup = ejabberd_odbc:escape(Group),
|
|
||||||
SOpts = ejabberd_odbc:encode_term(Opts),
|
|
||||||
F = fun () ->
|
|
||||||
odbc_queries:update_t(<<"sr_group">>,
|
|
||||||
[<<"name">>, <<"opts">>], [SGroup, SOpts],
|
|
||||||
[<<"name='">>, SGroup, <<"'">>])
|
|
||||||
end,
|
|
||||||
ejabberd_odbc:sql_transaction(Host, F).
|
|
||||||
|
|
||||||
delete_group(Host, Group) ->
|
delete_group(Host, Group) ->
|
||||||
delete_group(Host, Group,
|
Mod = gen_mod:db_mod(Host, ?MODULE),
|
||||||
gen_mod:db_type(Host, ?MODULE)).
|
Mod:delete_group(Host, Group).
|
||||||
|
|
||||||
delete_group(Host, Group, mnesia) ->
|
|
||||||
GroupHost = {Group, Host},
|
|
||||||
F = fun () ->
|
|
||||||
mnesia:delete({sr_group, GroupHost}),
|
|
||||||
Users = mnesia:index_read(sr_user, GroupHost,
|
|
||||||
#sr_user.group_host),
|
|
||||||
lists:foreach(fun (UserEntry) ->
|
|
||||||
mnesia:delete_object(UserEntry)
|
|
||||||
end,
|
|
||||||
Users)
|
|
||||||
end,
|
|
||||||
mnesia:transaction(F);
|
|
||||||
delete_group(Host, Group, riak) ->
|
|
||||||
try
|
|
||||||
ok = ejabberd_riak:delete(sr_group, {Group, Host}),
|
|
||||||
ok = ejabberd_riak:delete_by_index(sr_user, <<"group_host">>,
|
|
||||||
{Group, Host}),
|
|
||||||
{atomic, ok}
|
|
||||||
catch _:{badmatch, Err} ->
|
|
||||||
{atomic, Err}
|
|
||||||
end;
|
|
||||||
delete_group(Host, Group, odbc) ->
|
|
||||||
SGroup = ejabberd_odbc:escape(Group),
|
|
||||||
F = fun () ->
|
|
||||||
ejabberd_odbc:sql_query_t([<<"delete from sr_group where name='">>,
|
|
||||||
SGroup, <<"';">>]),
|
|
||||||
ejabberd_odbc:sql_query_t([<<"delete from sr_user where grp='">>,
|
|
||||||
SGroup, <<"';">>])
|
|
||||||
end,
|
|
||||||
case ejabberd_odbc:sql_transaction(Host, F) of
|
|
||||||
{atomic,{updated,_}} -> {atomic, ok};
|
|
||||||
Res -> Res
|
|
||||||
end.
|
|
||||||
|
|
||||||
get_group_opts(Host, Group) ->
|
get_group_opts(Host, Group) ->
|
||||||
get_group_opts(Host, Group,
|
Mod = gen_mod:db_mod(Host, ?MODULE),
|
||||||
gen_mod:db_type(Host, ?MODULE)).
|
Mod:get_group_opts(Host, Group).
|
||||||
|
|
||||||
get_group_opts(Host, Group, mnesia) ->
|
|
||||||
case catch mnesia:dirty_read(sr_group, {Group, Host}) of
|
|
||||||
[#sr_group{opts = Opts}] -> Opts;
|
|
||||||
_ -> error
|
|
||||||
end;
|
|
||||||
get_group_opts(Host, Group, riak) ->
|
|
||||||
case ejabberd_riak:get(sr_group, sr_group_schema(), {Group, Host}) of
|
|
||||||
{ok, #sr_group{opts = Opts}} -> Opts;
|
|
||||||
_ -> error
|
|
||||||
end;
|
|
||||||
get_group_opts(Host, Group, odbc) ->
|
|
||||||
SGroup = ejabberd_odbc:escape(Group),
|
|
||||||
case catch ejabberd_odbc:sql_query(Host,
|
|
||||||
[<<"select opts from sr_group where name='">>,
|
|
||||||
SGroup, <<"';">>])
|
|
||||||
of
|
|
||||||
{selected, [<<"opts">>], [[SOpts]]} ->
|
|
||||||
opts_to_binary(ejabberd_odbc:decode_term(SOpts));
|
|
||||||
_ -> error
|
|
||||||
end.
|
|
||||||
|
|
||||||
set_group_opts(Host, Group, Opts) ->
|
set_group_opts(Host, Group, Opts) ->
|
||||||
set_group_opts(Host, Group, Opts,
|
Mod = gen_mod:db_mod(Host, ?MODULE),
|
||||||
gen_mod:db_type(Host, ?MODULE)).
|
Mod:set_group_opts(Host, Group, Opts).
|
||||||
|
|
||||||
set_group_opts(Host, Group, Opts, mnesia) ->
|
|
||||||
R = #sr_group{group_host = {Group, Host}, opts = Opts},
|
|
||||||
F = fun () -> mnesia:write(R) end,
|
|
||||||
mnesia:transaction(F);
|
|
||||||
set_group_opts(Host, Group, Opts, riak) ->
|
|
||||||
{atomic, ejabberd_riak:put(#sr_group{group_host = {Group, Host},
|
|
||||||
opts = Opts},
|
|
||||||
sr_group_schema(),
|
|
||||||
[{'2i', [{<<"host">>, Host}]}])};
|
|
||||||
set_group_opts(Host, Group, Opts, odbc) ->
|
|
||||||
SGroup = ejabberd_odbc:escape(Group),
|
|
||||||
SOpts = ejabberd_odbc:encode_term(Opts),
|
|
||||||
F = fun () ->
|
|
||||||
odbc_queries:update_t(<<"sr_group">>,
|
|
||||||
[<<"name">>, <<"opts">>], [SGroup, SOpts],
|
|
||||||
[<<"name='">>, SGroup, <<"'">>])
|
|
||||||
end,
|
|
||||||
ejabberd_odbc:sql_transaction(Host, F).
|
|
||||||
|
|
||||||
get_user_groups(US) ->
|
get_user_groups(US) ->
|
||||||
Host = element(2, US),
|
Host = element(2, US),
|
||||||
DBType = gen_mod:db_type(Host, ?MODULE),
|
Mod = gen_mod:db_mod(Host, ?MODULE),
|
||||||
get_user_groups(US, Host, DBType) ++
|
Mod:get_user_groups(US, Host) ++ get_special_users_groups(Host).
|
||||||
get_special_users_groups(Host).
|
|
||||||
|
|
||||||
get_user_groups(US, Host, mnesia) ->
|
|
||||||
case catch mnesia:dirty_read(sr_user, US) of
|
|
||||||
Rs when is_list(Rs) ->
|
|
||||||
[Group
|
|
||||||
|| #sr_user{group_host = {Group, H}} <- Rs, H == Host];
|
|
||||||
_ -> []
|
|
||||||
end;
|
|
||||||
get_user_groups(US, Host, riak) ->
|
|
||||||
case ejabberd_riak:get_by_index(sr_user, sr_user_schema(), <<"us">>, US) of
|
|
||||||
{ok, Rs} ->
|
|
||||||
[Group || #sr_user{group_host = {Group, H}} <- Rs, H == Host];
|
|
||||||
_ ->
|
|
||||||
[]
|
|
||||||
end;
|
|
||||||
get_user_groups(US, Host, odbc) ->
|
|
||||||
SJID = make_jid_s(US),
|
|
||||||
case catch ejabberd_odbc:sql_query(Host,
|
|
||||||
[<<"select grp from sr_user where jid='">>,
|
|
||||||
SJID, <<"';">>])
|
|
||||||
of
|
|
||||||
{selected, [<<"grp">>], Rs} -> [G || [G] <- Rs];
|
|
||||||
_ -> []
|
|
||||||
end.
|
|
||||||
|
|
||||||
is_group_enabled(Host1, Group1) ->
|
is_group_enabled(Host1, Group1) ->
|
||||||
{Host, Group} = split_grouphost(Host1, Group1),
|
{Host, Group} = split_grouphost(Host1, Group1),
|
||||||
@ -630,39 +474,8 @@ get_group_users(Host, Group, GroupOpts) ->
|
|||||||
++ get_group_explicit_users(Host, Group).
|
++ get_group_explicit_users(Host, Group).
|
||||||
|
|
||||||
get_group_explicit_users(Host, Group) ->
|
get_group_explicit_users(Host, Group) ->
|
||||||
get_group_explicit_users(Host, Group,
|
Mod = gen_mod:db_mod(Host, ?MODULE),
|
||||||
gen_mod:db_type(Host, ?MODULE)).
|
Mod:get_group_explicit_users(Host, Group).
|
||||||
|
|
||||||
get_group_explicit_users(Host, Group, mnesia) ->
|
|
||||||
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_explicit_users(Host, Group, riak) ->
|
|
||||||
case ejabberd_riak:get_by_index(sr_user, sr_user_schema(),
|
|
||||||
<<"group_host">>, {Group, Host}) of
|
|
||||||
{ok, Rs} ->
|
|
||||||
[R#sr_user.us || R <- Rs];
|
|
||||||
_ ->
|
|
||||||
[]
|
|
||||||
end;
|
|
||||||
get_group_explicit_users(Host, Group, odbc) ->
|
|
||||||
SGroup = ejabberd_odbc:escape(Group),
|
|
||||||
case catch ejabberd_odbc:sql_query(Host,
|
|
||||||
[<<"select jid from sr_user where grp='">>,
|
|
||||||
SGroup, <<"';">>])
|
|
||||||
of
|
|
||||||
{selected, [<<"jid">>], Rs} ->
|
|
||||||
lists:map(fun ([JID]) ->
|
|
||||||
{U, S, _} =
|
|
||||||
jid:tolower(jid:from_string(JID)),
|
|
||||||
{U, S}
|
|
||||||
end,
|
|
||||||
Rs);
|
|
||||||
_ -> []
|
|
||||||
end.
|
|
||||||
|
|
||||||
get_group_name(Host1, Group1) ->
|
get_group_name(Host1, Group1) ->
|
||||||
{Host, Group} = split_grouphost(Host1, Group1),
|
{Host, Group} = split_grouphost(Host1, Group1),
|
||||||
@ -718,44 +531,10 @@ get_special_displayed_groups(GroupsOpts) ->
|
|||||||
%% for the list of groups of that server that user is member
|
%% for the list of groups of that server that user is member
|
||||||
%% get the list of groups displayed
|
%% get the list of groups displayed
|
||||||
get_user_displayed_groups(LUser, LServer, GroupsOpts) ->
|
get_user_displayed_groups(LUser, LServer, GroupsOpts) ->
|
||||||
Groups = get_user_displayed_groups(LUser, LServer,
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
GroupsOpts,
|
Groups = Mod:get_user_displayed_groups(LUser, LServer, GroupsOpts),
|
||||||
gen_mod:db_type(LServer, ?MODULE)),
|
|
||||||
displayed_groups(GroupsOpts, Groups).
|
displayed_groups(GroupsOpts, Groups).
|
||||||
|
|
||||||
get_user_displayed_groups(LUser, LServer, GroupsOpts,
|
|
||||||
mnesia) ->
|
|
||||||
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;
|
|
||||||
get_user_displayed_groups(LUser, LServer, GroupsOpts,
|
|
||||||
riak) ->
|
|
||||||
case ejabberd_riak:get_by_index(sr_user, sr_user_schema(),
|
|
||||||
<<"us">>, {LUser, LServer}) of
|
|
||||||
{ok, Rs} ->
|
|
||||||
[{Group, proplists:get_value(Group, GroupsOpts, [])}
|
|
||||||
|| #sr_user{group_host = {Group, _}} <- Rs];
|
|
||||||
_ ->
|
|
||||||
[]
|
|
||||||
end;
|
|
||||||
get_user_displayed_groups(LUser, LServer, GroupsOpts,
|
|
||||||
odbc) ->
|
|
||||||
SJID = make_jid_s(LUser, LServer),
|
|
||||||
case catch ejabberd_odbc:sql_query(LServer,
|
|
||||||
[<<"select grp from sr_user where jid='">>,
|
|
||||||
SJID, <<"';">>])
|
|
||||||
of
|
|
||||||
{selected, [<<"grp">>], Rs} ->
|
|
||||||
[{Group, proplists:get_value(Group, GroupsOpts, [])}
|
|
||||||
|| [Group] <- Rs];
|
|
||||||
_ -> []
|
|
||||||
end.
|
|
||||||
|
|
||||||
%% @doc Get the list of groups that are displayed to this user
|
%% @doc Get the list of groups that are displayed to this user
|
||||||
get_user_displayed_groups(US) ->
|
get_user_displayed_groups(US) ->
|
||||||
Host = element(2, US),
|
Host = element(2, US),
|
||||||
@ -779,42 +558,12 @@ get_user_displayed_groups(US) ->
|
|||||||
is_group_enabled(Host, Group)].
|
is_group_enabled(Host, Group)].
|
||||||
|
|
||||||
is_user_in_group(US, Group, Host) ->
|
is_user_in_group(US, Group, Host) ->
|
||||||
is_user_in_group(US, Group, Host,
|
Mod = gen_mod:db_mod(Host, ?MODULE),
|
||||||
gen_mod:db_type(Host, ?MODULE)).
|
case Mod:is_user_in_group(US, Group, Host) of
|
||||||
|
|
||||||
is_user_in_group(US, Group, Host, mnesia) ->
|
|
||||||
case catch mnesia:dirty_match_object(#sr_user{us = US,
|
|
||||||
group_host = {Group, Host}})
|
|
||||||
of
|
|
||||||
[] -> lists:member(US, get_group_users(Host, Group));
|
|
||||||
_ -> true
|
|
||||||
end;
|
|
||||||
is_user_in_group(US, Group, Host, riak) ->
|
|
||||||
case ejabberd_riak:get_by_index(sr_user, sr_user_schema(), <<"us">>, US) of
|
|
||||||
{ok, Rs} ->
|
|
||||||
case lists:any(
|
|
||||||
fun(#sr_user{group_host = {G, H}}) ->
|
|
||||||
(Group == G) and (Host == H)
|
|
||||||
end, Rs) of
|
|
||||||
false ->
|
false ->
|
||||||
lists:member(US, get_group_users(Host, Group));
|
lists:member(US, get_group_users(Host, Group));
|
||||||
true ->
|
true ->
|
||||||
true
|
true
|
||||||
end;
|
|
||||||
_Err ->
|
|
||||||
false
|
|
||||||
end;
|
|
||||||
is_user_in_group(US, Group, Host, odbc) ->
|
|
||||||
SJID = make_jid_s(US),
|
|
||||||
SGroup = ejabberd_odbc:escape(Group),
|
|
||||||
case catch ejabberd_odbc:sql_query(Host,
|
|
||||||
[<<"select * from sr_user where jid='">>,
|
|
||||||
SJID, <<"' and grp='">>, SGroup,
|
|
||||||
<<"';">>])
|
|
||||||
of
|
|
||||||
{selected, _, []} ->
|
|
||||||
lists:member(US, get_group_users(Host, Group));
|
|
||||||
_ -> true
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%% @spec (Host::string(), {User::string(), Server::string()}, Group::string()) -> {atomic, ok}
|
%% @spec (Host::string(), {User::string(), Server::string()}, Group::string()) -> {atomic, ok}
|
||||||
@ -837,31 +586,10 @@ add_user_to_group(Host, US, Group) ->
|
|||||||
push_displayed_to_user(LUser, LServer, Host, both, DisplayedGroups),
|
push_displayed_to_user(LUser, LServer, Host, both, DisplayedGroups),
|
||||||
broadcast_user_to_displayed(LUser, LServer, Host, both, DisplayedToGroups),
|
broadcast_user_to_displayed(LUser, LServer, Host, both, DisplayedToGroups),
|
||||||
broadcast_displayed_to_user(LUser, LServer, Host, both, DisplayedGroups),
|
broadcast_displayed_to_user(LUser, LServer, Host, both, DisplayedGroups),
|
||||||
add_user_to_group(Host, US, Group, gen_mod:db_type(Host, ?MODULE))
|
Mod = gen_mod:db_mod(Host, ?MODULE),
|
||||||
|
Mod:add_user_to_group(Host, US, Group)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
add_user_to_group(Host, US, Group, mnesia) ->
|
|
||||||
R = #sr_user{us = US, group_host = {Group, Host}},
|
|
||||||
F = fun () -> mnesia:write(R) end,
|
|
||||||
mnesia:transaction(F);
|
|
||||||
add_user_to_group(Host, US, Group, riak) ->
|
|
||||||
{atomic, ejabberd_riak:put(
|
|
||||||
#sr_user{us = US, group_host = {Group, Host}},
|
|
||||||
sr_user_schema(),
|
|
||||||
[{i, {US, {Group, Host}}},
|
|
||||||
{'2i', [{<<"us">>, US},
|
|
||||||
{<<"group_host">>, {Group, Host}}]}])};
|
|
||||||
add_user_to_group(Host, US, Group, odbc) ->
|
|
||||||
SJID = make_jid_s(US),
|
|
||||||
SGroup = ejabberd_odbc:escape(Group),
|
|
||||||
F = fun () ->
|
|
||||||
odbc_queries:update_t(<<"sr_user">>,
|
|
||||||
[<<"jid">>, <<"grp">>], [SJID, SGroup],
|
|
||||||
[<<"jid='">>, SJID, <<"' and grp='">>,
|
|
||||||
SGroup, <<"'">>])
|
|
||||||
end,
|
|
||||||
ejabberd_odbc:sql_transaction(Host, F).
|
|
||||||
|
|
||||||
get_displayed_groups(Group, LServer) ->
|
get_displayed_groups(Group, LServer) ->
|
||||||
GroupsOpts = groups_with_opts(LServer),
|
GroupsOpts = groups_with_opts(LServer),
|
||||||
GroupOpts = proplists:get_value(Group, GroupsOpts, []),
|
GroupOpts = proplists:get_value(Group, GroupsOpts, []),
|
||||||
@ -894,8 +622,8 @@ remove_user_from_group(Host, US, Group) ->
|
|||||||
end,
|
end,
|
||||||
(?MODULE):set_group_opts(Host, Group, NewGroupOpts);
|
(?MODULE):set_group_opts(Host, Group, NewGroupOpts);
|
||||||
nomatch ->
|
nomatch ->
|
||||||
Result = remove_user_from_group(Host, US, Group,
|
Mod = gen_mod:db_mod(Host, ?MODULE),
|
||||||
gen_mod:db_type(Host, ?MODULE)),
|
Result = Mod:remove_user_from_group(Host, US, Group),
|
||||||
DisplayedToGroups = displayed_to_groups(Group, Host),
|
DisplayedToGroups = displayed_to_groups(Group, Host),
|
||||||
DisplayedGroups = get_displayed_groups(Group, LServer),
|
DisplayedGroups = get_displayed_groups(Group, LServer),
|
||||||
push_user_to_displayed(LUser, LServer, Group, Host, remove, DisplayedToGroups),
|
push_user_to_displayed(LUser, LServer, Group, Host, remove, DisplayedToGroups),
|
||||||
@ -903,23 +631,6 @@ remove_user_from_group(Host, US, Group) ->
|
|||||||
Result
|
Result
|
||||||
end.
|
end.
|
||||||
|
|
||||||
remove_user_from_group(Host, US, Group, mnesia) ->
|
|
||||||
R = #sr_user{us = US, group_host = {Group, Host}},
|
|
||||||
F = fun () -> mnesia:delete_object(R) end,
|
|
||||||
mnesia:transaction(F);
|
|
||||||
remove_user_from_group(Host, US, Group, riak) ->
|
|
||||||
{atomic, ejabberd_riak:delete(sr_group, {US, {Group, Host}})};
|
|
||||||
remove_user_from_group(Host, US, Group, odbc) ->
|
|
||||||
SJID = make_jid_s(US),
|
|
||||||
SGroup = ejabberd_odbc:escape(Group),
|
|
||||||
F = fun () ->
|
|
||||||
ejabberd_odbc:sql_query_t([<<"delete from sr_user where jid='">>,
|
|
||||||
SJID, <<"' and grp='">>, SGroup,
|
|
||||||
<<"';">>]),
|
|
||||||
ok
|
|
||||||
end,
|
|
||||||
ejabberd_odbc:sql_transaction(Host, F).
|
|
||||||
|
|
||||||
push_members_to_user(LUser, LServer, Group, Host,
|
push_members_to_user(LUser, LServer, Group, Host,
|
||||||
Subscription) ->
|
Subscription) ->
|
||||||
GroupsOpts = groups_with_opts(LServer),
|
GroupsOpts = groups_with_opts(LServer),
|
||||||
@ -1385,13 +1096,6 @@ displayed_groups_update(Members, DisplayedGroups, Subscription) ->
|
|||||||
end
|
end
|
||||||
end, Members).
|
end, Members).
|
||||||
|
|
||||||
make_jid_s(U, S) ->
|
|
||||||
ejabberd_odbc:escape(jid:to_string(jid:tolower(jid:make(U,
|
|
||||||
S,
|
|
||||||
<<"">>)))).
|
|
||||||
|
|
||||||
make_jid_s({U, S}) -> make_jid_s(U, S).
|
|
||||||
|
|
||||||
opts_to_binary(Opts) ->
|
opts_to_binary(Opts) ->
|
||||||
lists:map(
|
lists:map(
|
||||||
fun({name, Name}) ->
|
fun({name, Name}) ->
|
||||||
@ -1404,105 +1108,17 @@ opts_to_binary(Opts) ->
|
|||||||
Opt
|
Opt
|
||||||
end, Opts).
|
end, Opts).
|
||||||
|
|
||||||
sr_group_schema() ->
|
export(LServer) ->
|
||||||
{record_info(fields, sr_group), #sr_group{}}.
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
|
Mod:export(LServer).
|
||||||
sr_user_schema() ->
|
|
||||||
{record_info(fields, sr_user), #sr_user{}}.
|
|
||||||
|
|
||||||
update_tables() ->
|
|
||||||
update_sr_group_table(),
|
|
||||||
update_sr_user_table().
|
|
||||||
|
|
||||||
update_sr_group_table() ->
|
|
||||||
Fields = record_info(fields, sr_group),
|
|
||||||
case mnesia:table_info(sr_group, attributes) of
|
|
||||||
Fields ->
|
|
||||||
ejabberd_config:convert_table_to_binary(
|
|
||||||
sr_group, Fields, set,
|
|
||||||
fun(#sr_group{group_host = {G, _}}) -> G end,
|
|
||||||
fun(#sr_group{group_host = {G, H},
|
|
||||||
opts = Opts} = R) ->
|
|
||||||
R#sr_group{group_host = {iolist_to_binary(G),
|
|
||||||
iolist_to_binary(H)},
|
|
||||||
opts = opts_to_binary(Opts)}
|
|
||||||
end);
|
|
||||||
_ ->
|
|
||||||
?INFO_MSG("Recreating sr_group table", []),
|
|
||||||
mnesia:transform_table(sr_group, ignore, Fields)
|
|
||||||
end.
|
|
||||||
|
|
||||||
update_sr_user_table() ->
|
|
||||||
Fields = record_info(fields, sr_user),
|
|
||||||
case mnesia:table_info(sr_user, attributes) of
|
|
||||||
Fields ->
|
|
||||||
ejabberd_config:convert_table_to_binary(
|
|
||||||
sr_user, Fields, bag,
|
|
||||||
fun(#sr_user{us = {U, _}}) -> U end,
|
|
||||||
fun(#sr_user{us = {U, S}, group_host = {G, H}} = R) ->
|
|
||||||
R#sr_user{us = {iolist_to_binary(U), iolist_to_binary(S)},
|
|
||||||
group_host = {iolist_to_binary(G),
|
|
||||||
iolist_to_binary(H)}}
|
|
||||||
end);
|
|
||||||
_ ->
|
|
||||||
?INFO_MSG("Recreating sr_user table", []),
|
|
||||||
mnesia:transform_table(sr_user, ignore, Fields)
|
|
||||||
end.
|
|
||||||
|
|
||||||
export(_Server) ->
|
|
||||||
[{sr_group,
|
|
||||||
fun(Host, #sr_group{group_host = {Group, LServer}, opts = Opts})
|
|
||||||
when LServer == Host ->
|
|
||||||
SGroup = ejabberd_odbc:escape(Group),
|
|
||||||
SOpts = ejabberd_odbc:encode_term(Opts),
|
|
||||||
[[<<"delete from sr_group where name='">>, Group, <<"';">>],
|
|
||||||
[<<"insert into sr_group(name, opts) values ('">>,
|
|
||||||
SGroup, <<"', '">>, SOpts, <<"');">>]];
|
|
||||||
(_Host, _R) ->
|
|
||||||
[]
|
|
||||||
end},
|
|
||||||
{sr_user,
|
|
||||||
fun(Host, #sr_user{us = {U, S}, group_host = {Group, LServer}})
|
|
||||||
when LServer == Host ->
|
|
||||||
SGroup = ejabberd_odbc:escape(Group),
|
|
||||||
SJID = ejabberd_odbc:escape(
|
|
||||||
jid:to_string(
|
|
||||||
jid:tolower(
|
|
||||||
jid:make(U, S, <<"">>)))),
|
|
||||||
[[<<"delete from sr_user where jid='">>, SJID,
|
|
||||||
<<"'and grp='">>, Group, <<"';">>],
|
|
||||||
[<<"insert into sr_user(jid, grp) values ('">>,
|
|
||||||
SJID, <<"', '">>, SGroup, <<"');">>]];
|
|
||||||
(_Host, _R) ->
|
|
||||||
[]
|
|
||||||
end}].
|
|
||||||
|
|
||||||
import(LServer) ->
|
import(LServer) ->
|
||||||
[{<<"select name, opts from sr_group;">>,
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
fun([Group, SOpts]) ->
|
Mod:import(LServer).
|
||||||
#sr_group{group_host = {Group, LServer},
|
|
||||||
opts = ejabberd_odbc:decode_term(SOpts)}
|
|
||||||
end},
|
|
||||||
{<<"select jid, grp from sr_user;">>,
|
|
||||||
fun([SJID, Group]) ->
|
|
||||||
#jid{luser = U, lserver = S} = jid:from_string(SJID),
|
|
||||||
#sr_user{us = {U, S}, group_host = {Group, LServer}}
|
|
||||||
end}].
|
|
||||||
|
|
||||||
import(_LServer, mnesia, #sr_group{} = G) ->
|
import(LServer, DBType, Data) ->
|
||||||
mnesia:dirty_write(G);
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
|
Mod:import(LServer, Data).
|
||||||
import(_LServer, mnesia, #sr_user{} = U) ->
|
|
||||||
mnesia:dirty_write(U);
|
|
||||||
import(_LServer, riak, #sr_group{group_host = {_, Host}} = G) ->
|
|
||||||
ejabberd_riak:put(G, sr_group_schema(), [{'2i', [{<<"host">>, Host}]}]);
|
|
||||||
import(_LServer, riak, #sr_user{us = US, group_host = {Group, Host}} = User) ->
|
|
||||||
ejabberd_riak:put(User, sr_user_schema(),
|
|
||||||
[{i, {US, {Group, Host}}},
|
|
||||||
{'2i', [{<<"us">>, US},
|
|
||||||
{<<"group_host">>, {Group, Host}}]}]);
|
|
||||||
import(_, _, _) ->
|
|
||||||
pass.
|
|
||||||
|
|
||||||
mod_opt_type(db_type) -> fun gen_mod:v_db/1;
|
mod_opt_type(db_type) -> fun gen_mod:v_db/1;
|
||||||
mod_opt_type(_) -> [db_type].
|
mod_opt_type(_) -> [db_type].
|
||||||
|
167
src/mod_shared_roster_mnesia.erl
Normal file
167
src/mod_shared_roster_mnesia.erl
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||||
|
%%% @copyright (C) 2016, Evgeny Khramtsov
|
||||||
|
%%% @doc
|
||||||
|
%%%
|
||||||
|
%%% @end
|
||||||
|
%%% Created : 14 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
-module(mod_shared_roster_mnesia).
|
||||||
|
|
||||||
|
-behaviour(mod_shared_roster).
|
||||||
|
|
||||||
|
%% API
|
||||||
|
-export([init/2, list_groups/1, groups_with_opts/1, create_group/3,
|
||||||
|
delete_group/2, get_group_opts/2, set_group_opts/3,
|
||||||
|
get_user_groups/2, get_group_explicit_users/2,
|
||||||
|
get_user_displayed_groups/3, is_user_in_group/3,
|
||||||
|
add_user_to_group/3, remove_user_from_group/3, import/2]).
|
||||||
|
|
||||||
|
-include("jlib.hrl").
|
||||||
|
-include("mod_roster.hrl").
|
||||||
|
-include("mod_shared_roster.hrl").
|
||||||
|
-include("logger.hrl").
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% API
|
||||||
|
%%%===================================================================
|
||||||
|
init(_Host, _Opts) ->
|
||||||
|
mnesia:create_table(sr_group,
|
||||||
|
[{disc_copies, [node()]},
|
||||||
|
{attributes, record_info(fields, sr_group)}]),
|
||||||
|
mnesia:create_table(sr_user,
|
||||||
|
[{disc_copies, [node()]}, {type, bag},
|
||||||
|
{attributes, record_info(fields, sr_user)}]),
|
||||||
|
update_tables(),
|
||||||
|
mnesia:add_table_index(sr_user, group_host).
|
||||||
|
|
||||||
|
list_groups(Host) ->
|
||||||
|
mnesia:dirty_select(sr_group,
|
||||||
|
[{#sr_group{group_host = {'$1', '$2'}, _ = '_'},
|
||||||
|
[{'==', '$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, Opts) ->
|
||||||
|
R = #sr_group{group_host = {Group, Host}, opts = Opts},
|
||||||
|
F = fun () -> mnesia:write(R) end,
|
||||||
|
mnesia:transaction(F).
|
||||||
|
|
||||||
|
delete_group(Host, Group) ->
|
||||||
|
GroupHost = {Group, Host},
|
||||||
|
F = fun () ->
|
||||||
|
mnesia:delete({sr_group, GroupHost}),
|
||||||
|
Users = mnesia:index_read(sr_user, GroupHost,
|
||||||
|
#sr_user.group_host),
|
||||||
|
lists:foreach(fun (UserEntry) ->
|
||||||
|
mnesia:delete_object(UserEntry)
|
||||||
|
end,
|
||||||
|
Users)
|
||||||
|
end,
|
||||||
|
mnesia:transaction(F).
|
||||||
|
|
||||||
|
get_group_opts(Host, Group) ->
|
||||||
|
case catch mnesia:dirty_read(sr_group, {Group, Host}) of
|
||||||
|
[#sr_group{opts = Opts}] -> Opts;
|
||||||
|
_ -> error
|
||||||
|
end.
|
||||||
|
|
||||||
|
set_group_opts(Host, Group, Opts) ->
|
||||||
|
R = #sr_group{group_host = {Group, Host}, opts = Opts},
|
||||||
|
F = fun () -> mnesia:write(R) end,
|
||||||
|
mnesia:transaction(F).
|
||||||
|
|
||||||
|
get_user_groups(US, Host) ->
|
||||||
|
case catch mnesia:dirty_read(sr_user, US) of
|
||||||
|
Rs when is_list(Rs) ->
|
||||||
|
[Group || #sr_user{group_host = {Group, H}} <- Rs, H == Host];
|
||||||
|
_ ->
|
||||||
|
[]
|
||||||
|
end.
|
||||||
|
|
||||||
|
get_group_explicit_users(Host, Group) ->
|
||||||
|
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_user_displayed_groups(LUser, LServer, GroupsOpts) ->
|
||||||
|
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.
|
||||||
|
|
||||||
|
is_user_in_group(US, Group, Host) ->
|
||||||
|
case mnesia:dirty_match_object(
|
||||||
|
#sr_user{us = US, group_host = {Group, Host}}) of
|
||||||
|
[] -> false;
|
||||||
|
_ -> true
|
||||||
|
end.
|
||||||
|
|
||||||
|
add_user_to_group(Host, US, Group) ->
|
||||||
|
R = #sr_user{us = US, group_host = {Group, Host}},
|
||||||
|
F = fun () -> mnesia:write(R) end,
|
||||||
|
mnesia:transaction(F).
|
||||||
|
|
||||||
|
remove_user_from_group(Host, US, Group) ->
|
||||||
|
R = #sr_user{us = US, group_host = {Group, Host}},
|
||||||
|
F = fun () -> mnesia:delete_object(R) end,
|
||||||
|
mnesia:transaction(F).
|
||||||
|
|
||||||
|
import(_LServer, #sr_group{} = G) ->
|
||||||
|
mnesia:dirty_write(G);
|
||||||
|
import(_LServer, #sr_user{} = U) ->
|
||||||
|
mnesia:dirty_write(U).
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% Internal functions
|
||||||
|
%%%===================================================================
|
||||||
|
update_tables() ->
|
||||||
|
update_sr_group_table(),
|
||||||
|
update_sr_user_table().
|
||||||
|
|
||||||
|
update_sr_group_table() ->
|
||||||
|
Fields = record_info(fields, sr_group),
|
||||||
|
case mnesia:table_info(sr_group, attributes) of
|
||||||
|
Fields ->
|
||||||
|
ejabberd_config:convert_table_to_binary(
|
||||||
|
sr_group, Fields, set,
|
||||||
|
fun(#sr_group{group_host = {G, _}}) -> G end,
|
||||||
|
fun(#sr_group{group_host = {G, H},
|
||||||
|
opts = Opts} = R) ->
|
||||||
|
R#sr_group{group_host = {iolist_to_binary(G),
|
||||||
|
iolist_to_binary(H)},
|
||||||
|
opts = mod_shared_roster:opts_to_binary(Opts)}
|
||||||
|
end);
|
||||||
|
_ ->
|
||||||
|
?INFO_MSG("Recreating sr_group table", []),
|
||||||
|
mnesia:transform_table(sr_group, ignore, Fields)
|
||||||
|
end.
|
||||||
|
|
||||||
|
update_sr_user_table() ->
|
||||||
|
Fields = record_info(fields, sr_user),
|
||||||
|
case mnesia:table_info(sr_user, attributes) of
|
||||||
|
Fields ->
|
||||||
|
ejabberd_config:convert_table_to_binary(
|
||||||
|
sr_user, Fields, bag,
|
||||||
|
fun(#sr_user{us = {U, _}}) -> U end,
|
||||||
|
fun(#sr_user{us = {U, S}, group_host = {G, H}} = R) ->
|
||||||
|
R#sr_user{us = {iolist_to_binary(U), iolist_to_binary(S)},
|
||||||
|
group_host = {iolist_to_binary(G),
|
||||||
|
iolist_to_binary(H)}}
|
||||||
|
end);
|
||||||
|
_ ->
|
||||||
|
?INFO_MSG("Recreating sr_user table", []),
|
||||||
|
mnesia:transform_table(sr_user, ignore, Fields)
|
||||||
|
end.
|
139
src/mod_shared_roster_riak.erl
Normal file
139
src/mod_shared_roster_riak.erl
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||||
|
%%% @copyright (C) 2016, Evgeny Khramtsov
|
||||||
|
%%% @doc
|
||||||
|
%%%
|
||||||
|
%%% @end
|
||||||
|
%%% Created : 14 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
-module(mod_shared_roster_riak).
|
||||||
|
|
||||||
|
-behaviour(mod_shared_roster).
|
||||||
|
|
||||||
|
%% API
|
||||||
|
-export([init/2, list_groups/1, groups_with_opts/1, create_group/3,
|
||||||
|
delete_group/2, get_group_opts/2, set_group_opts/3,
|
||||||
|
get_user_groups/2, get_group_explicit_users/2,
|
||||||
|
get_user_displayed_groups/3, is_user_in_group/3,
|
||||||
|
add_user_to_group/3, remove_user_from_group/3, import/2]).
|
||||||
|
|
||||||
|
-include("jlib.hrl").
|
||||||
|
-include("mod_roster.hrl").
|
||||||
|
-include("mod_shared_roster.hrl").
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% API
|
||||||
|
%%%===================================================================
|
||||||
|
init(_Host, _Opts) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
list_groups(Host) ->
|
||||||
|
case ejabberd_riak:get_keys_by_index(sr_group, <<"host">>, Host) of
|
||||||
|
{ok, Gs} ->
|
||||||
|
[G || {G, _} <- Gs];
|
||||||
|
_ ->
|
||||||
|
[]
|
||||||
|
end.
|
||||||
|
|
||||||
|
groups_with_opts(Host) ->
|
||||||
|
case ejabberd_riak:get_by_index(sr_group, sr_group_schema(),
|
||||||
|
<<"host">>, Host) of
|
||||||
|
{ok, Rs} ->
|
||||||
|
[{G, O} || #sr_group{group_host = {G, _}, opts = O} <- Rs];
|
||||||
|
_ ->
|
||||||
|
[]
|
||||||
|
end.
|
||||||
|
|
||||||
|
create_group(Host, Group, Opts) ->
|
||||||
|
{atomic, ejabberd_riak:put(#sr_group{group_host = {Group, Host},
|
||||||
|
opts = Opts},
|
||||||
|
sr_group_schema(),
|
||||||
|
[{'2i', [{<<"host">>, Host}]}])}.
|
||||||
|
|
||||||
|
delete_group(Host, Group) ->
|
||||||
|
try
|
||||||
|
ok = ejabberd_riak:delete(sr_group, {Group, Host}),
|
||||||
|
ok = ejabberd_riak:delete_by_index(sr_user, <<"group_host">>,
|
||||||
|
{Group, Host}),
|
||||||
|
{atomic, ok}
|
||||||
|
catch _:{badmatch, Err} ->
|
||||||
|
{atomic, Err}
|
||||||
|
end.
|
||||||
|
|
||||||
|
get_group_opts(Host, Group) ->
|
||||||
|
case ejabberd_riak:get(sr_group, sr_group_schema(), {Group, Host}) of
|
||||||
|
{ok, #sr_group{opts = Opts}} -> Opts;
|
||||||
|
_ -> error
|
||||||
|
end.
|
||||||
|
|
||||||
|
set_group_opts(Host, Group, Opts) ->
|
||||||
|
{atomic, ejabberd_riak:put(#sr_group{group_host = {Group, Host},
|
||||||
|
opts = Opts},
|
||||||
|
sr_group_schema(),
|
||||||
|
[{'2i', [{<<"host">>, Host}]}])}.
|
||||||
|
|
||||||
|
get_user_groups(US, Host) ->
|
||||||
|
case ejabberd_riak:get_by_index(sr_user, sr_user_schema(), <<"us">>, US) of
|
||||||
|
{ok, Rs} ->
|
||||||
|
[Group || #sr_user{group_host = {Group, H}} <- Rs, H == Host];
|
||||||
|
_ ->
|
||||||
|
[]
|
||||||
|
end.
|
||||||
|
|
||||||
|
get_group_explicit_users(Host, Group) ->
|
||||||
|
case ejabberd_riak:get_by_index(sr_user, sr_user_schema(),
|
||||||
|
<<"group_host">>, {Group, Host}) of
|
||||||
|
{ok, Rs} ->
|
||||||
|
[R#sr_user.us || R <- Rs];
|
||||||
|
_ ->
|
||||||
|
[]
|
||||||
|
end.
|
||||||
|
|
||||||
|
get_user_displayed_groups(LUser, LServer, GroupsOpts) ->
|
||||||
|
case ejabberd_riak:get_by_index(sr_user, sr_user_schema(),
|
||||||
|
<<"us">>, {LUser, LServer}) of
|
||||||
|
{ok, Rs} ->
|
||||||
|
[{Group, proplists:get_value(Group, GroupsOpts, [])}
|
||||||
|
|| #sr_user{group_host = {Group, _}} <- Rs];
|
||||||
|
_ ->
|
||||||
|
[]
|
||||||
|
end.
|
||||||
|
|
||||||
|
is_user_in_group(US, Group, Host) ->
|
||||||
|
case ejabberd_riak:get_by_index(sr_user, sr_user_schema(), <<"us">>, US) of
|
||||||
|
{ok, Rs} ->
|
||||||
|
lists:any(
|
||||||
|
fun(#sr_user{group_host = {G, H}}) ->
|
||||||
|
(Group == G) and (Host == H)
|
||||||
|
end, Rs);
|
||||||
|
_Err ->
|
||||||
|
false
|
||||||
|
end.
|
||||||
|
|
||||||
|
add_user_to_group(Host, US, Group) ->
|
||||||
|
{atomic, ejabberd_riak:put(
|
||||||
|
#sr_user{us = US, group_host = {Group, Host}},
|
||||||
|
sr_user_schema(),
|
||||||
|
[{i, {US, {Group, Host}}},
|
||||||
|
{'2i', [{<<"us">>, US},
|
||||||
|
{<<"group_host">>, {Group, Host}}]}])}.
|
||||||
|
|
||||||
|
remove_user_from_group(Host, US, Group) ->
|
||||||
|
{atomic, ejabberd_riak:delete(sr_group, {US, {Group, Host}})}.
|
||||||
|
|
||||||
|
import(_LServer, #sr_group{group_host = {_, Host}} = G) ->
|
||||||
|
ejabberd_riak:put(G, sr_group_schema(), [{'2i', [{<<"host">>, Host}]}]);
|
||||||
|
import(_LServer, #sr_user{us = US, group_host = {Group, Host}} = User) ->
|
||||||
|
ejabberd_riak:put(User, sr_user_schema(),
|
||||||
|
[{i, {US, {Group, Host}}},
|
||||||
|
{'2i', [{<<"us">>, US},
|
||||||
|
{<<"group_host">>, {Group, Host}}]}]).
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% Internal functions
|
||||||
|
%%%===================================================================
|
||||||
|
sr_group_schema() ->
|
||||||
|
{record_info(fields, sr_group), #sr_group{}}.
|
||||||
|
|
||||||
|
sr_user_schema() ->
|
||||||
|
{record_info(fields, sr_user), #sr_user{}}.
|
212
src/mod_shared_roster_sql.erl
Normal file
212
src/mod_shared_roster_sql.erl
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||||
|
%%% @copyright (C) 2016, Evgeny Khramtsov
|
||||||
|
%%% @doc
|
||||||
|
%%%
|
||||||
|
%%% @end
|
||||||
|
%%% Created : 14 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
-module(mod_shared_roster_sql).
|
||||||
|
|
||||||
|
-behaviour(mod_shared_roster).
|
||||||
|
|
||||||
|
%% API
|
||||||
|
-export([init/2, list_groups/1, groups_with_opts/1, create_group/3,
|
||||||
|
delete_group/2, get_group_opts/2, set_group_opts/3,
|
||||||
|
get_user_groups/2, get_group_explicit_users/2,
|
||||||
|
get_user_displayed_groups/3, is_user_in_group/3,
|
||||||
|
add_user_to_group/3, remove_user_from_group/3, import/1,
|
||||||
|
import/2, export/1]).
|
||||||
|
|
||||||
|
-include("jlib.hrl").
|
||||||
|
-include("mod_roster.hrl").
|
||||||
|
-include("mod_shared_roster.hrl").
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% API
|
||||||
|
%%%===================================================================
|
||||||
|
init(_Host, _Opts) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
list_groups(Host) ->
|
||||||
|
case ejabberd_odbc:sql_query(
|
||||||
|
Host, [<<"select name from sr_group;">>]) of
|
||||||
|
{selected, [<<"name">>], Rs} -> [G || [G] <- Rs];
|
||||||
|
_ -> []
|
||||||
|
end.
|
||||||
|
|
||||||
|
groups_with_opts(Host) ->
|
||||||
|
case ejabberd_odbc:sql_query(Host,
|
||||||
|
[<<"select name, opts from sr_group;">>])
|
||||||
|
of
|
||||||
|
{selected, [<<"name">>, <<"opts">>], Rs} ->
|
||||||
|
[{G, mod_shared_roster:opts_to_binary(ejabberd_odbc:decode_term(Opts))}
|
||||||
|
|| [G, Opts] <- Rs];
|
||||||
|
_ -> []
|
||||||
|
end.
|
||||||
|
|
||||||
|
create_group(Host, Group, Opts) ->
|
||||||
|
SGroup = ejabberd_odbc:escape(Group),
|
||||||
|
SOpts = ejabberd_odbc:encode_term(Opts),
|
||||||
|
F = fun () ->
|
||||||
|
odbc_queries:update_t(<<"sr_group">>,
|
||||||
|
[<<"name">>, <<"opts">>], [SGroup, SOpts],
|
||||||
|
[<<"name='">>, SGroup, <<"'">>])
|
||||||
|
end,
|
||||||
|
ejabberd_odbc:sql_transaction(Host, F).
|
||||||
|
|
||||||
|
delete_group(Host, Group) ->
|
||||||
|
SGroup = ejabberd_odbc:escape(Group),
|
||||||
|
F = fun () ->
|
||||||
|
ejabberd_odbc:sql_query_t([<<"delete from sr_group where name='">>,
|
||||||
|
SGroup, <<"';">>]),
|
||||||
|
ejabberd_odbc:sql_query_t([<<"delete from sr_user where grp='">>,
|
||||||
|
SGroup, <<"';">>])
|
||||||
|
end,
|
||||||
|
case ejabberd_odbc:sql_transaction(Host, F) of
|
||||||
|
{atomic,{updated,_}} -> {atomic, ok};
|
||||||
|
Res -> Res
|
||||||
|
end.
|
||||||
|
|
||||||
|
get_group_opts(Host, Group) ->
|
||||||
|
SGroup = ejabberd_odbc:escape(Group),
|
||||||
|
case catch ejabberd_odbc:sql_query(
|
||||||
|
Host,
|
||||||
|
[<<"select opts from sr_group where name='">>,
|
||||||
|
SGroup, <<"';">>]) of
|
||||||
|
{selected, [<<"opts">>], [[SOpts]]} ->
|
||||||
|
mod_shared_roster:opts_to_binary(ejabberd_odbc:decode_term(SOpts));
|
||||||
|
_ -> error
|
||||||
|
end.
|
||||||
|
|
||||||
|
set_group_opts(Host, Group, Opts) ->
|
||||||
|
SGroup = ejabberd_odbc:escape(Group),
|
||||||
|
SOpts = ejabberd_odbc:encode_term(Opts),
|
||||||
|
F = fun () ->
|
||||||
|
odbc_queries:update_t(<<"sr_group">>,
|
||||||
|
[<<"name">>, <<"opts">>], [SGroup, SOpts],
|
||||||
|
[<<"name='">>, SGroup, <<"'">>])
|
||||||
|
end,
|
||||||
|
ejabberd_odbc:sql_transaction(Host, F).
|
||||||
|
|
||||||
|
get_user_groups(US, Host) ->
|
||||||
|
SJID = make_jid_s(US),
|
||||||
|
case catch ejabberd_odbc:sql_query(
|
||||||
|
Host,
|
||||||
|
[<<"select grp from sr_user where jid='">>,
|
||||||
|
SJID, <<"';">>]) of
|
||||||
|
{selected, [<<"grp">>], Rs} -> [G || [G] <- Rs];
|
||||||
|
_ -> []
|
||||||
|
end.
|
||||||
|
|
||||||
|
get_group_explicit_users(Host, Group) ->
|
||||||
|
SGroup = ejabberd_odbc:escape(Group),
|
||||||
|
case catch ejabberd_odbc:sql_query(
|
||||||
|
Host,
|
||||||
|
[<<"select jid from sr_user where grp='">>,
|
||||||
|
SGroup, <<"';">>]) of
|
||||||
|
{selected, [<<"jid">>], Rs} ->
|
||||||
|
lists:map(
|
||||||
|
fun([JID]) ->
|
||||||
|
{U, S, _} = jid:tolower(jid:from_string(JID)),
|
||||||
|
{U, S}
|
||||||
|
end, Rs);
|
||||||
|
_ ->
|
||||||
|
[]
|
||||||
|
end.
|
||||||
|
|
||||||
|
get_user_displayed_groups(LUser, LServer, GroupsOpts) ->
|
||||||
|
SJID = make_jid_s(LUser, LServer),
|
||||||
|
case catch ejabberd_odbc:sql_query(
|
||||||
|
LServer,
|
||||||
|
[<<"select grp from sr_user where jid='">>,
|
||||||
|
SJID, <<"';">>]) of
|
||||||
|
{selected, [<<"grp">>], Rs} ->
|
||||||
|
[{Group, proplists:get_value(Group, GroupsOpts, [])}
|
||||||
|
|| [Group] <- Rs];
|
||||||
|
_ -> []
|
||||||
|
end.
|
||||||
|
|
||||||
|
is_user_in_group(US, Group, Host) ->
|
||||||
|
SJID = make_jid_s(US),
|
||||||
|
SGroup = ejabberd_odbc:escape(Group),
|
||||||
|
case catch ejabberd_odbc:sql_query(Host,
|
||||||
|
[<<"select * from sr_user where jid='">>,
|
||||||
|
SJID, <<"' and grp='">>, SGroup,
|
||||||
|
<<"';">>]) of
|
||||||
|
{selected, _, []} -> false;
|
||||||
|
_ -> true
|
||||||
|
end.
|
||||||
|
|
||||||
|
add_user_to_group(Host, US, Group) ->
|
||||||
|
SJID = make_jid_s(US),
|
||||||
|
SGroup = ejabberd_odbc:escape(Group),
|
||||||
|
F = fun () ->
|
||||||
|
odbc_queries:update_t(<<"sr_user">>,
|
||||||
|
[<<"jid">>, <<"grp">>], [SJID, SGroup],
|
||||||
|
[<<"jid='">>, SJID, <<"' and grp='">>,
|
||||||
|
SGroup, <<"'">>])
|
||||||
|
end,
|
||||||
|
ejabberd_odbc:sql_transaction(Host, F).
|
||||||
|
|
||||||
|
remove_user_from_group(Host, US, Group) ->
|
||||||
|
SJID = make_jid_s(US),
|
||||||
|
SGroup = ejabberd_odbc:escape(Group),
|
||||||
|
F = fun () ->
|
||||||
|
ejabberd_odbc:sql_query_t([<<"delete from sr_user where jid='">>,
|
||||||
|
SJID, <<"' and grp='">>, SGroup,
|
||||||
|
<<"';">>]),
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
ejabberd_odbc:sql_transaction(Host, F).
|
||||||
|
|
||||||
|
export(_Server) ->
|
||||||
|
[{sr_group,
|
||||||
|
fun(Host, #sr_group{group_host = {Group, LServer}, opts = Opts})
|
||||||
|
when LServer == Host ->
|
||||||
|
SGroup = ejabberd_odbc:escape(Group),
|
||||||
|
SOpts = ejabberd_odbc:encode_term(Opts),
|
||||||
|
[[<<"delete from sr_group where name='">>, Group, <<"';">>],
|
||||||
|
[<<"insert into sr_group(name, opts) values ('">>,
|
||||||
|
SGroup, <<"', '">>, SOpts, <<"');">>]];
|
||||||
|
(_Host, _R) ->
|
||||||
|
[]
|
||||||
|
end},
|
||||||
|
{sr_user,
|
||||||
|
fun(Host, #sr_user{us = {U, S}, group_host = {Group, LServer}})
|
||||||
|
when LServer == Host ->
|
||||||
|
SGroup = ejabberd_odbc:escape(Group),
|
||||||
|
SJID = ejabberd_odbc:escape(
|
||||||
|
jid:to_string(
|
||||||
|
jid:tolower(
|
||||||
|
jid:make(U, S, <<"">>)))),
|
||||||
|
[[<<"delete from sr_user where jid='">>, SJID,
|
||||||
|
<<"'and grp='">>, Group, <<"';">>],
|
||||||
|
[<<"insert into sr_user(jid, grp) values ('">>,
|
||||||
|
SJID, <<"', '">>, SGroup, <<"');">>]];
|
||||||
|
(_Host, _R) ->
|
||||||
|
[]
|
||||||
|
end}].
|
||||||
|
|
||||||
|
import(LServer) ->
|
||||||
|
[{<<"select name, opts from sr_group;">>,
|
||||||
|
fun([Group, SOpts]) ->
|
||||||
|
#sr_group{group_host = {Group, LServer},
|
||||||
|
opts = ejabberd_odbc:decode_term(SOpts)}
|
||||||
|
end},
|
||||||
|
{<<"select jid, grp from sr_user;">>,
|
||||||
|
fun([SJID, Group]) ->
|
||||||
|
#jid{luser = U, lserver = S} = jid:from_string(SJID),
|
||||||
|
#sr_user{us = {U, S}, group_host = {Group, LServer}}
|
||||||
|
end}].
|
||||||
|
|
||||||
|
import(_, _) ->
|
||||||
|
pass.
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% Internal functions
|
||||||
|
%%%===================================================================
|
||||||
|
make_jid_s(U, S) ->
|
||||||
|
ejabberd_odbc:escape(jid:to_string(jid:tolower(jid:make(U, S, <<"">>)))).
|
||||||
|
|
||||||
|
make_jid_s({U, S}) -> make_jid_s(U, S).
|
Loading…
Reference in New Issue
Block a user