mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-24 16:23:40 +01:00
250 lines
8.1 KiB
Erlang
250 lines
8.1 KiB
Erlang
%%%-------------------------------------------------------------------
|
|
%%% File : mod_shared_roster_sql.erl
|
|
%%% Author : Evgeny Khramtsov <ekhramtsov@process-one.net>
|
|
%%% Created : 14 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
|
%%%
|
|
%%%
|
|
%%% ejabberd, Copyright (C) 2002-2024 ProcessOne
|
|
%%%
|
|
%%% This program is free software; you can redistribute it and/or
|
|
%%% modify it under the terms of the GNU General Public License as
|
|
%%% published by the Free Software Foundation; either version 2 of the
|
|
%%% License, or (at your option) any later version.
|
|
%%%
|
|
%%% This program is distributed in the hope that it will be useful,
|
|
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
%%% General Public License for more details.
|
|
%%%
|
|
%%% You should have received a copy of the GNU General Public License along
|
|
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
|
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
%%%
|
|
%%%----------------------------------------------------------------------
|
|
|
|
-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/3,
|
|
export/1]).
|
|
-export([sql_schemas/0]).
|
|
|
|
-include_lib("xmpp/include/jid.hrl").
|
|
-include("mod_roster.hrl").
|
|
-include("mod_shared_roster.hrl").
|
|
-include("ejabberd_sql_pt.hrl").
|
|
|
|
%%%===================================================================
|
|
%%% API
|
|
%%%===================================================================
|
|
init(Host, _Opts) ->
|
|
ejabberd_sql_schema:update_schema(Host, ?MODULE, sql_schemas()),
|
|
ok.
|
|
|
|
sql_schemas() ->
|
|
[#sql_schema{
|
|
version = 1,
|
|
tables =
|
|
[#sql_table{
|
|
name = <<"sr_group">>,
|
|
columns =
|
|
[#sql_column{name = <<"name">>, type = text},
|
|
#sql_column{name = <<"server_host">>, type = text},
|
|
#sql_column{name = <<"opts">>, type = text},
|
|
#sql_column{name = <<"created_at">>, type = timestamp,
|
|
default = true}],
|
|
indices = [#sql_index{
|
|
columns = [<<"server_host">>, <<"name">>],
|
|
unique = true}]},
|
|
#sql_table{
|
|
name = <<"sr_user">>,
|
|
columns =
|
|
[#sql_column{name = <<"jid">>, type = text},
|
|
#sql_column{name = <<"server_host">>, type = text},
|
|
#sql_column{name = <<"grp">>, type = text},
|
|
#sql_column{name = <<"created_at">>, type = timestamp,
|
|
default = true}],
|
|
indices = [#sql_index{
|
|
columns = [<<"server_host">>,
|
|
<<"jid">>, <<"grp">>],
|
|
unique = true},
|
|
#sql_index{
|
|
columns = [<<"server_host">>, <<"grp">>]}]}]}].
|
|
|
|
list_groups(Host) ->
|
|
case ejabberd_sql:sql_query(
|
|
Host,
|
|
?SQL("select @(name)s from sr_group where %(Host)H")) of
|
|
{selected, Rs} -> [G || {G} <- Rs];
|
|
_ -> []
|
|
end.
|
|
|
|
groups_with_opts(Host) ->
|
|
case ejabberd_sql:sql_query(
|
|
Host,
|
|
?SQL("select @(name)s, @(opts)s from sr_group where %(Host)H"))
|
|
of
|
|
{selected, Rs} ->
|
|
[{G, mod_shared_roster:opts_to_binary(ejabberd_sql:decode_term(Opts))}
|
|
|| {G, Opts} <- Rs];
|
|
_ -> []
|
|
end.
|
|
|
|
create_group(Host, Group, Opts) ->
|
|
SOpts = misc:term_to_expr(Opts),
|
|
F = fun () ->
|
|
?SQL_UPSERT_T(
|
|
"sr_group",
|
|
["!name=%(Group)s",
|
|
"!server_host=%(Host)s",
|
|
"opts=%(SOpts)s"])
|
|
end,
|
|
ejabberd_sql:sql_transaction(Host, F).
|
|
|
|
delete_group(Host, Group) ->
|
|
F = fun () ->
|
|
ejabberd_sql:sql_query_t(
|
|
?SQL("delete from sr_group where name=%(Group)s and %(Host)H")),
|
|
ejabberd_sql:sql_query_t(
|
|
?SQL("delete from sr_user where grp=%(Group)s and %(Host)H"))
|
|
end,
|
|
case ejabberd_sql:sql_transaction(Host, F) of
|
|
{atomic,{updated,_}} -> {atomic, ok};
|
|
Res -> Res
|
|
end.
|
|
|
|
get_group_opts(Host, Group) ->
|
|
case catch ejabberd_sql:sql_query(
|
|
Host,
|
|
?SQL("select @(opts)s from sr_group"
|
|
" where name=%(Group)s and %(Host)H")) of
|
|
{selected, [{SOpts}]} ->
|
|
{ok, mod_shared_roster:opts_to_binary(ejabberd_sql:decode_term(SOpts))};
|
|
_ -> error
|
|
end.
|
|
|
|
set_group_opts(Host, Group, Opts) ->
|
|
SOpts = misc:term_to_expr(Opts),
|
|
F = fun () ->
|
|
?SQL_UPSERT_T(
|
|
"sr_group",
|
|
["!name=%(Group)s",
|
|
"!server_host=%(Host)s",
|
|
"opts=%(SOpts)s"])
|
|
end,
|
|
ejabberd_sql:sql_transaction(Host, F).
|
|
|
|
get_user_groups(US, Host) ->
|
|
SJID = make_jid_s(US),
|
|
case catch ejabberd_sql:sql_query(
|
|
Host,
|
|
?SQL("select @(grp)s from sr_user"
|
|
" where jid=%(SJID)s and %(Host)H")) of
|
|
{selected, Rs} -> [G || {G} <- Rs];
|
|
_ -> []
|
|
end.
|
|
|
|
get_group_explicit_users(Host, Group) ->
|
|
case catch ejabberd_sql:sql_query(
|
|
Host,
|
|
?SQL("select @(jid)s from sr_user"
|
|
" where grp=%(Group)s and %(Host)H")) of
|
|
{selected, Rs} ->
|
|
lists:map(
|
|
fun({JID}) ->
|
|
{U, S, _} = jid:tolower(jid:decode(JID)),
|
|
{U, S}
|
|
end, Rs);
|
|
_ ->
|
|
[]
|
|
end.
|
|
|
|
get_user_displayed_groups(LUser, LServer, GroupsOpts) ->
|
|
SJID = make_jid_s(LUser, LServer),
|
|
case catch ejabberd_sql:sql_query(
|
|
LServer,
|
|
?SQL("select @(grp)s from sr_user"
|
|
" where jid=%(SJID)s and %(LServer)H")) of
|
|
{selected, Rs} ->
|
|
[{Group, proplists:get_value(Group, GroupsOpts, [])}
|
|
|| {Group} <- Rs];
|
|
_ -> []
|
|
end.
|
|
|
|
is_user_in_group(US, Group, Host) ->
|
|
SJID = make_jid_s(US),
|
|
case catch ejabberd_sql:sql_query(
|
|
Host,
|
|
?SQL("select @(jid)s from sr_user where jid=%(SJID)s"
|
|
" and %(Host)H and grp=%(Group)s")) of
|
|
{selected, []} -> false;
|
|
_ -> true
|
|
end.
|
|
|
|
add_user_to_group(Host, US, Group) ->
|
|
SJID = make_jid_s(US),
|
|
ejabberd_sql:sql_query(
|
|
Host,
|
|
?SQL_INSERT(
|
|
"sr_user",
|
|
["jid=%(SJID)s",
|
|
"server_host=%(Host)s",
|
|
"grp=%(Group)s"])).
|
|
|
|
remove_user_from_group(Host, US, Group) ->
|
|
SJID = make_jid_s(US),
|
|
F = fun () ->
|
|
ejabberd_sql:sql_query_t(
|
|
?SQL("delete from sr_user where jid=%(SJID)s and %(Host)H"
|
|
" and grp=%(Group)s")),
|
|
ok
|
|
end,
|
|
ejabberd_sql:sql_transaction(Host, F).
|
|
|
|
export(_Server) ->
|
|
[{sr_group,
|
|
fun(Host, #sr_group{group_host = {Group, LServer}, opts = Opts})
|
|
when LServer == Host ->
|
|
SOpts = misc:term_to_expr(Opts),
|
|
[?SQL("delete from sr_group where name=%(Group)s and %(Host)H;"),
|
|
?SQL_INSERT(
|
|
"sr_group",
|
|
["name=%(Group)s",
|
|
"server_host=%(Host)s",
|
|
"opts=%(SOpts)s"])];
|
|
(_Host, _R) ->
|
|
[]
|
|
end},
|
|
{sr_user,
|
|
fun(Host, #sr_user{us = {U, S}, group_host = {Group, LServer}})
|
|
when LServer == Host ->
|
|
SJID = make_jid_s(U, S),
|
|
[?SQL("select @(jid)s from sr_user where jid=%(SJID)s"
|
|
" and %(Host)H and grp=%(Group)s;"),
|
|
?SQL_INSERT(
|
|
"sr_user",
|
|
["jid=%(SJID)s",
|
|
"server_host=%(Host)s",
|
|
"grp=%(Group)s"])];
|
|
(_Host, _R) ->
|
|
[]
|
|
end}].
|
|
|
|
import(_, _, _) ->
|
|
ok.
|
|
|
|
%%%===================================================================
|
|
%%% Internal functions
|
|
%%%===================================================================
|
|
make_jid_s(U, S) ->
|
|
jid:encode(jid:tolower(jid:make(U, S))).
|
|
|
|
make_jid_s({U, S}) -> make_jid_s(U, S).
|