25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-26 16:26:24 +01:00
xmpp.chapril.org-ejabberd/src/mod_privacy_sql.erl

356 lines
11 KiB
Erlang
Raw Normal View History

%%%-------------------------------------------------------------------
2016-12-27 10:44:07 +01:00
%%% File : mod_privacy_sql.erl
%%% Author : Evgeny Khramtsov <ekhramtsov@process-one.net>
%%% Created : 14 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
2016-12-27 10:44:07 +01:00
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
2016-12-27 10:44:07 +01:00
%%%
%%% 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_privacy_sql).
2016-05-04 20:01:05 +02:00
-compile([{parse_transform, ejabberd_sql_pt}]).
-behaviour(mod_privacy).
%% API
-export([init/2, set_default/3, unset_default/2, set_lists/1,
set_list/4, get_lists/2, get_list/3, remove_lists/2,
remove_list/3, import/1, export/1]).
-export([item_to_raw/1, raw_to_item/1]).
-include("xmpp.hrl").
-include("mod_privacy.hrl").
-include("logger.hrl").
2016-05-04 20:01:05 +02:00
-include("ejabberd_sql_pt.hrl").
%%%===================================================================
%%% API
%%%===================================================================
init(_Host, _Opts) ->
ok.
unset_default(LUser, LServer) ->
case unset_default_privacy_list(LUser, LServer) of
ok ->
ok;
_Err ->
{error, db_failure}
end.
set_default(LUser, LServer, Name) ->
F = fun () ->
case get_privacy_list_names_t(LUser) of
{selected, []} ->
{error, notfound};
{selected, Names} ->
case lists:member({Name}, Names) of
true ->
set_default_privacy_list(LUser, Name);
false ->
{error, notfound}
end
end
end,
transaction(LServer, F).
remove_list(LUser, LServer, Name) ->
F = fun () ->
case get_default_privacy_list_t(LUser) of
{selected, []} ->
remove_privacy_list(LUser, Name);
{selected, [{Default}]} ->
if Name == Default ->
{error, conflict};
true ->
remove_privacy_list(LUser, Name)
end
end
end,
transaction(LServer, F).
set_lists(#privacy{us = {LUser, LServer},
default = Default,
lists = Lists}) ->
F = fun() ->
lists:foreach(
fun({Name, List}) ->
add_privacy_list(LUser, Name),
{selected, [<<"id">>], [[I]]} =
get_privacy_list_id_t(LUser, Name),
RItems = lists:map(fun item_to_raw/1, List),
set_privacy_list(I, RItems),
if is_binary(Default) ->
set_default_privacy_list(LUser, Default);
true ->
ok
end
end, Lists)
end,
transaction(LServer, F).
set_list(LUser, LServer, Name, List) ->
RItems = lists:map(fun item_to_raw/1, List),
F = fun () ->
ID = case get_privacy_list_id_t(LUser, Name) of
{selected, []} ->
add_privacy_list(LUser, Name),
{selected, [{I}]} =
get_privacy_list_id_t(LUser, Name),
I;
{selected, [{I}]} -> I
end,
set_privacy_list(ID, RItems)
end,
transaction(LServer, F).
get_list(LUser, LServer, default) ->
case get_default_privacy_list(LUser, LServer) of
{selected, []} ->
error;
{selected, [{Default}]} ->
get_list(LUser, LServer, Default);
_Err ->
{error, db_failure}
end;
get_list(LUser, LServer, Name) ->
case get_privacy_list_data(LUser, LServer, Name) of
{selected, []} ->
error;
{selected, RItems} ->
{ok, {Name, lists:flatmap(fun raw_to_item/1, RItems)}};
_Err ->
{error, db_failure}
end.
get_lists(LUser, LServer) ->
case get_default_privacy_list(LUser, LServer) of
{selected, Selected} ->
Default = case Selected of
[] -> none;
[{DefName}] -> DefName
end,
case get_privacy_list_names(LUser, LServer) of
{selected, Names} ->
case lists:foldl(
fun(_, {error, _} = Err) ->
Err;
({Name}, Acc) ->
case get_privacy_list_data(LUser, LServer, Name) of
{selected, RItems} ->
Items = lists:flatmap(
fun raw_to_item/1,
RItems),
[{Name, Items}|Acc];
_Err ->
{error, db_failure}
end
end, [], Names) of
{error, Reason} ->
{error, Reason};
Lists ->
{ok, #privacy{default = Default,
us = {LUser, LServer},
lists = Lists}}
end;
_Err ->
{error, db_failure}
end;
_Err ->
{error, db_failure}
end.
remove_lists(LUser, LServer) ->
case del_privacy_lists(LUser, LServer) of
ok ->
ok;
_Err ->
{error, db_failure}
end.
export(Server) ->
2016-04-20 11:27:32 +02:00
case catch ejabberd_sql:sql_query(jid:nameprep(Server),
[<<"select id from privacy_list order by "
"id desc limit 1;">>]) of
{selected, [<<"id">>], [[I]]} ->
put(id, binary_to_integer(I));
_ ->
put(id, 0)
end,
[{privacy,
fun(Host, #privacy{us = {LUser, LServer}, lists = Lists,
default = Default})
when LServer == Host ->
if Default /= none ->
2016-05-04 20:01:05 +02:00
[?SQL("delete from privacy_default_list where"
" username=%(LUser)s;"),
?SQL("insert into privacy_default_list(username, name) "
"values (%(LUser)s, %(Default)s);")];
true ->
[]
end ++
lists:flatmap(
fun({Name, List}) ->
RItems = lists:map(fun item_to_raw/1, List),
2016-05-04 20:01:05 +02:00
ID = get_id(),
[?SQL("delete from privacy_list where"
" username=%(LUser)s and"
" name=%(Name)s;"),
?SQL("insert into privacy_list(username, "
"name, id) values ("
"%(LUser)s, %(Name)s, %(ID)d);"),
?SQL("delete from privacy_list_data where"
" id=%(ID)d;")] ++
[?SQL("insert into privacy_list_data(id, t, "
"value, action, ord, match_all, match_iq, "
"match_message, match_presence_in, "
"match_presence_out) "
"values (%(ID)d, %(SType)s, %(SValue)s, %(SAction)s,"
" %(Order)d, %(MatchAll)b, %(MatchIQ)b,"
" %(MatchMessage)b, %(MatchPresenceIn)b,"
" %(MatchPresenceOut)b);")
2016-05-04 20:01:05 +02:00
|| {SType, SValue, SAction, Order,
MatchAll, MatchIQ,
MatchMessage, MatchPresenceIn,
MatchPresenceOut} <- RItems]
end,
Lists);
(_Host, _R) ->
[]
end}].
get_id() ->
ID = get(id),
put(id, ID + 1),
ID + 1.
2016-11-22 14:48:01 +01:00
import(_) ->
ok.
%%%===================================================================
%%% Internal functions
%%%===================================================================
transaction(LServer, F) ->
case ejabberd_sql:sql_transaction(LServer, F) of
{atomic, Res} -> Res;
{aborted, _Reason} -> {error, db_failure}
end.
raw_to_item({SType, SValue, SAction, Order, MatchAll,
MatchIQ, MatchMessage, MatchPresenceIn,
MatchPresenceOut} = Row) ->
try
{Type, Value} = case SType of
<<"n">> -> {none, none};
<<"j">> ->
JID = jid:decode(SValue),
{jid, jid:tolower(JID)};
<<"g">> -> {group, SValue};
<<"s">> ->
case SValue of
<<"none">> -> {subscription, none};
<<"both">> -> {subscription, both};
<<"from">> -> {subscription, from};
<<"to">> -> {subscription, to}
end
end,
Action = case SAction of
<<"a">> -> allow;
<<"d">> -> deny
end,
[#listitem{type = Type, value = Value, action = Action,
order = Order, match_all = MatchAll, match_iq = MatchIQ,
match_message = MatchMessage,
match_presence_in = MatchPresenceIn,
match_presence_out = MatchPresenceOut}]
catch _:_ ->
?WARNING_MSG("failed to parse row: ~p", [Row]),
[]
end.
item_to_raw(#listitem{type = Type, value = Value,
action = Action, order = Order, match_all = MatchAll,
match_iq = MatchIQ, match_message = MatchMessage,
match_presence_in = MatchPresenceIn,
match_presence_out = MatchPresenceOut}) ->
{SType, SValue} = case Type of
none -> {<<"n">>, <<"">>};
jid -> {<<"j">>, jid:encode(Value)};
2016-05-04 20:01:05 +02:00
group -> {<<"g">>, Value};
subscription ->
case Value of
none -> {<<"s">>, <<"none">>};
both -> {<<"s">>, <<"both">>};
from -> {<<"s">>, <<"from">>};
to -> {<<"s">>, <<"to">>}
end
end,
SAction = case Action of
allow -> <<"a">>;
deny -> <<"d">>
end,
{SType, SValue, SAction, Order, MatchAll, MatchIQ,
MatchMessage, MatchPresenceIn, MatchPresenceOut}.
get_default_privacy_list(LUser, LServer) ->
2016-04-20 11:27:32 +02:00
sql_queries:get_default_privacy_list(LServer, LUser).
get_default_privacy_list_t(LUser) ->
2016-04-20 11:27:32 +02:00
sql_queries:get_default_privacy_list_t(LUser).
get_privacy_list_names(LUser, LServer) ->
2016-04-20 11:27:32 +02:00
sql_queries:get_privacy_list_names(LServer, LUser).
get_privacy_list_names_t(LUser) ->
2016-04-20 11:27:32 +02:00
sql_queries:get_privacy_list_names_t(LUser).
get_privacy_list_id_t(LUser, Name) ->
2016-04-20 11:27:32 +02:00
sql_queries:get_privacy_list_id_t(LUser, Name).
get_privacy_list_data(LUser, LServer, Name) ->
2016-04-20 11:27:32 +02:00
sql_queries:get_privacy_list_data(LServer, LUser, Name).
set_default_privacy_list(LUser, Name) ->
2016-04-20 11:27:32 +02:00
sql_queries:set_default_privacy_list(LUser, Name).
unset_default_privacy_list(LUser, LServer) ->
case sql_queries:unset_default_privacy_list(LServer, LUser) of
{updated, _} -> ok;
Err -> Err
end.
remove_privacy_list(LUser, Name) ->
case sql_queries:remove_privacy_list(LUser, Name) of
{updated, 0} -> {error, notfound};
{updated, _} -> ok;
Err -> Err
end.
add_privacy_list(LUser, Name) ->
2016-04-20 11:27:32 +02:00
sql_queries:add_privacy_list(LUser, Name).
set_privacy_list(ID, RItems) ->
2016-04-20 11:27:32 +02:00
sql_queries:set_privacy_list(ID, RItems).
del_privacy_lists(LUser, LServer) ->
case sql_queries:del_privacy_lists(LServer, LUser) of
{updated, _} -> ok;
Err -> Err
end.