aboutsummaryrefslogtreecommitdiff
path: root/src/mod_privacy_sql.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/mod_privacy_sql.erl')
-rw-r--r--src/mod_privacy_sql.erl507
1 files changed, 265 insertions, 242 deletions
diff --git a/src/mod_privacy_sql.erl b/src/mod_privacy_sql.erl
index 6da917e9d..673787328 100644
--- a/src/mod_privacy_sql.erl
+++ b/src/mod_privacy_sql.erl
@@ -1,34 +1,40 @@
%%%-------------------------------------------------------------------
-%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
-%%% @copyright (C) 2016, Evgeny Khramtsov
-%%% @doc
-%%%
-%%% @end
+%%% File : mod_privacy_sql.erl
+%%% Author : Evgeny Khramtsov <ekhramtsov@process-one.net>
%%% Created : 14 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
-%%%-------------------------------------------------------------------
+%%%
+%%%
+%%% ejabberd, Copyright (C) 2002-2019 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_privacy_sql).
--compile([{parse_transform, ejabberd_sql_pt}]).
-behaviour(mod_privacy).
%% API
--export([init/2, process_lists_get/2, process_list_get/3,
- process_default_set/3, process_active_set/3,
- remove_privacy_list/3, set_privacy_list/1,
- set_privacy_list/4, get_user_list/2, get_user_lists/2,
- remove_user/2, import/1, import/2, export/1]).
-
--export([item_to_raw/1, raw_to_item/1,
- sql_add_privacy_list/2,
- sql_get_default_privacy_list/2,
- sql_get_default_privacy_list_t/1,
- sql_get_privacy_list_data/3,
- sql_get_privacy_list_data_by_id_t/1,
- sql_get_privacy_list_id_t/2,
- sql_set_default_privacy_list/2, sql_set_privacy_list/2]).
-
--include("jlib.hrl").
+-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").
-include("ejabberd_sql_pt.hrl").
@@ -39,171 +45,151 @@
init(_Host, _Opts) ->
ok.
-process_lists_get(LUser, LServer) ->
- Default = case catch sql_get_default_privacy_list(LUser, LServer) of
- {selected, []} -> none;
- {selected, [{DefName}]} -> DefName;
- _ -> none
- end,
- case catch sql_get_privacy_list_names(LUser, LServer) of
- {selected, Names} ->
- LItems = lists:map(fun ({N}) ->
- #xmlel{name = <<"list">>,
- attrs = [{<<"name">>, N}],
- children = []}
- end,
- Names),
- {Default, LItems};
- _ -> error
- end.
-
-process_list_get(LUser, LServer, Name) ->
- case catch sql_get_privacy_list_id(LUser, LServer, Name) of
- {selected, []} -> not_found;
- {selected, [{ID}]} ->
- case catch sql_get_privacy_list_data_by_id(ID, LServer) of
- {selected, RItems} ->
- lists:flatmap(fun raw_to_item/1, RItems);
- _ -> error
- end;
- _ -> error
+unset_default(LUser, LServer) ->
+ case unset_default_privacy_list(LUser, LServer) of
+ ok ->
+ ok;
+ _Err ->
+ {error, db_failure}
end.
-process_default_set(LUser, LServer, {value, Name}) ->
+set_default(LUser, LServer, Name) ->
F = fun () ->
- case sql_get_privacy_list_names_t(LUser) of
- {selected, []} -> not_found;
- {selected, Names} ->
- case lists:member({Name}, Names) of
- true -> sql_set_default_privacy_list(LUser, Name), ok;
- false -> not_found
- end
+ case get_privacy_list_names_t(LUser, LServer) of
+ {selected, []} ->
+ {error, notfound};
+ {selected, Names} ->
+ case lists:member({Name}, Names) of
+ true ->
+ set_default_privacy_list(LUser, LServer, Name);
+ false ->
+ {error, notfound}
+ end
end
end,
- sql_queries:sql_transaction(LServer, F);
-process_default_set(LUser, LServer, false) ->
- case catch sql_unset_default_privacy_list(LUser,
- LServer)
- of
- {'EXIT', _Reason} -> {atomic, error};
- {error, _Reason} -> {atomic, error};
- _ -> {atomic, ok}
- end.
-
-process_active_set(LUser, LServer, Name) ->
- case catch sql_get_privacy_list_id(LUser, LServer, Name) of
- {selected, []} -> error;
- {selected, [{ID}]} ->
- case catch sql_get_privacy_list_data_by_id(ID, LServer) of
- {selected, RItems} ->
- lists:flatmap(fun raw_to_item/1, RItems);
- _ -> error
- end;
- _ -> error
- end.
+ transaction(LServer, F).
-remove_privacy_list(LUser, LServer, Name) ->
+remove_list(LUser, LServer, Name) ->
F = fun () ->
- case sql_get_default_privacy_list_t(LUser) of
- {selected, []} ->
- sql_remove_privacy_list(LUser, Name), ok;
- {selected, [{Default}]} ->
- if Name == Default -> conflict;
- true -> sql_remove_privacy_list(LUser, Name), ok
- end
+ case get_default_privacy_list_t(LUser, LServer) of
+ {selected, []} ->
+ remove_privacy_list_t(LUser, LServer, Name);
+ {selected, [{Default}]} ->
+ if Name == Default ->
+ {error, conflict};
+ true ->
+ remove_privacy_list_t(LUser, LServer, Name)
+ end
end
end,
- sql_queries:sql_transaction(LServer, F).
+ transaction(LServer, F).
-set_privacy_list(#privacy{us = {LUser, LServer},
- default = Default,
- lists = Lists}) ->
+set_lists(#privacy{us = {LUser, LServer},
+ default = Default,
+ lists = Lists}) ->
F = fun() ->
lists:foreach(
fun({Name, List}) ->
- sql_add_privacy_list(LUser, Name),
- {selected, [<<"id">>], [[I]]} =
- sql_get_privacy_list_id_t(LUser, Name),
+ add_privacy_list(LUser, LServer, Name),
+ {selected, [{I}]} =
+ get_privacy_list_id_t(LUser, LServer, Name),
RItems = lists:map(fun item_to_raw/1, List),
- sql_set_privacy_list(I, RItems),
+ set_privacy_list(I, RItems),
if is_binary(Default) ->
- sql_set_default_privacy_list(LUser, Default),
- ok;
+ set_default_privacy_list(
+ LUser, LServer, Default);
true ->
ok
end
end, Lists)
end,
- sql_queries:sql_transaction(LServer, F).
+ transaction(LServer, F).
-set_privacy_list(LUser, LServer, Name, List) ->
+set_list(LUser, LServer, Name, List) ->
RItems = lists:map(fun item_to_raw/1, List),
F = fun () ->
- ID = case sql_get_privacy_list_id_t(LUser, Name) of
+ ID = case get_privacy_list_id_t(LUser, LServer, Name) of
{selected, []} ->
- sql_add_privacy_list(LUser, Name),
- {selected, [{I}]} =
- sql_get_privacy_list_id_t(LUser, Name),
- I;
- {selected, [{I}]} -> I
+ add_privacy_list(LUser, LServer, Name),
+ {selected, [{I}]} =
+ get_privacy_list_id_t(LUser, LServer, Name),
+ I;
+ {selected, [{I}]} -> I
end,
- sql_set_privacy_list(ID, RItems),
- ok
+ set_privacy_list(ID, RItems)
end,
- sql_queries:sql_transaction(LServer, F).
-
-get_user_list(LUser, LServer) ->
- case catch sql_get_default_privacy_list(LUser, LServer)
- of
- {selected, []} -> {none, []};
- {selected, [{Default}]} ->
- case catch sql_get_privacy_list_data(LUser, LServer,
- Default) of
- {selected, RItems} ->
- {Default, lists:flatmap(fun raw_to_item/1, RItems)};
- _ -> {none, []}
- end;
- _ -> {none, []}
+ 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_user_lists(LUser, LServer) ->
- Default = case catch sql_get_default_privacy_list(LUser, LServer) of
- {selected, []} ->
- none;
- {selected, [{DefName}]} ->
- DefName;
- _ ->
- none
- end,
- case catch sql_get_privacy_list_names(LUser, LServer) of
- {selected, Names} ->
- Lists =
- lists:flatmap(
- fun({Name}) ->
- case catch sql_get_privacy_list_data(
- LUser, LServer, Name) of
- {selected, RItems} ->
- [{Name, lists:flatmap(fun raw_to_item/1, RItems)}];
- _ ->
- []
- end
- end, Names),
- {ok, #privacy{default = Default,
- us = {LUser, LServer},
- lists = Lists}};
- _ ->
- error
+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_user(LUser, LServer) ->
- sql_del_privacy_lists(LUser, LServer).
+remove_lists(LUser, LServer) ->
+ case del_privacy_lists(LUser, LServer) of
+ ok ->
+ ok;
+ _Err ->
+ {error, db_failure}
+ end.
export(Server) ->
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, jlib:binary_to_integer(I));
+ put(id, binary_to_integer(I));
_ ->
put(id, 0)
end,
@@ -213,9 +199,12 @@ export(Server) ->
when LServer == Host ->
if Default /= none ->
[?SQL("delete from privacy_default_list where"
- " username=%(LUser)s;"),
- ?SQL("insert into privacy_default_list(username, name) "
- "values (%(LUser)s, %(Default)s);")];
+ " username=%(LUser)s and %(LServer)H;"),
+ ?SQL_INSERT(
+ "privacy_default_list",
+ ["username=%(LUser)s",
+ "server_host=%(LServer)s",
+ "name=%(Default)s"])];
true ->
[]
end ++
@@ -224,11 +213,14 @@ export(Server) ->
RItems = lists:map(fun item_to_raw/1, List),
ID = get_id(),
[?SQL("delete from privacy_list where"
- " username=%(LUser)s and"
+ " username=%(LUser)s and %(LServer)H and"
" name=%(Name)s;"),
- ?SQL("insert into privacy_list(username, "
- "name, id) values ("
- "%(LUser)s, %(Name)s, %(ID)d);"),
+ ?SQL_INSERT(
+ "privacy_list",
+ ["username=%(LUser)s",
+ "server_host=%(LServer)s",
+ "name=%(Name)s",
+ "id=%(ID)d"]),
?SQL("delete from privacy_list_data where"
" id=%(ID)d;")] ++
[?SQL("insert into privacy_list_data(id, t, "
@@ -238,7 +230,7 @@ export(Server) ->
"values (%(ID)d, %(SType)s, %(SValue)s, %(SAction)s,"
" %(Order)d, %(MatchAll)b, %(MatchIQ)b,"
" %(MatchMessage)b, %(MatchPresenceIn)b,"
- " %(MatchPresenceOut)b)")
+ " %(MatchPresenceOut)b);")
|| {SType, SValue, SAction, Order,
MatchAll, MatchIQ,
MatchMessage, MatchPresenceIn,
@@ -254,41 +246,18 @@ get_id() ->
put(id, ID + 1),
ID + 1.
-import(LServer) ->
- [{<<"select username from privacy_list;">>,
- fun([LUser]) ->
- Default = case sql_get_default_privacy_list_t(LUser) of
- {selected, [<<"name">>], []} ->
- none;
- {selected, [<<"name">>], [[DefName]]} ->
- DefName;
- _ ->
- none
- end,
- {selected, [<<"name">>], Names} =
- sql_get_privacy_list_names_t(LUser),
- Lists = lists:flatmap(
- fun([Name]) ->
- case sql_get_privacy_list_data_t(LUser, Name) of
- {selected, _, RItems} ->
- [{Name,
- lists:map(fun raw_to_item/1,
- RItems)}];
- _ ->
- []
- end
- end, Names),
- #privacy{default = Default,
- us = {LUser, LServer},
- lists = Lists}
- end}].
-
-import(_, _) ->
- pass.
+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) ->
@@ -296,10 +265,8 @@ raw_to_item({SType, SValue, SAction, Order, MatchAll,
{Type, Value} = case SType of
<<"n">> -> {none, none};
<<"j">> ->
- case jid:from_string(SValue) of
- #jid{} = JID ->
- {jid, jid:tolower(JID)}
- end;
+ JID = jid:decode(SValue),
+ {jid, jid:tolower(JID)};
<<"g">> -> {group, SValue};
<<"s">> ->
case SValue of
@@ -319,7 +286,7 @@ raw_to_item({SType, SValue, SAction, Order, MatchAll,
match_presence_in = MatchPresenceIn,
match_presence_out = MatchPresenceOut}]
catch _:_ ->
- ?WARNING_MSG("failed to parse row: ~p", [Row]),
+ ?WARNING_MSG("Failed to parse row: ~p", [Row]),
[]
end.
@@ -330,7 +297,7 @@ item_to_raw(#listitem{type = Type, value = Value,
match_presence_out = MatchPresenceOut}) ->
{SType, SValue} = case Type of
none -> {<<"n">>, <<"">>};
- jid -> {<<"j">>, jid:to_string(Value)};
+ jid -> {<<"j">>, jid:encode(Value)};
group -> {<<"g">>, Value};
subscription ->
case Value of
@@ -347,50 +314,106 @@ item_to_raw(#listitem{type = Type, value = Value,
{SType, SValue, SAction, Order, MatchAll, MatchIQ,
MatchMessage, MatchPresenceIn, MatchPresenceOut}.
-sql_get_default_privacy_list(LUser, LServer) ->
- sql_queries:get_default_privacy_list(LServer, LUser).
-
-sql_get_default_privacy_list_t(LUser) ->
- sql_queries:get_default_privacy_list_t(LUser).
-
-sql_get_privacy_list_names(LUser, LServer) ->
- sql_queries:get_privacy_list_names(LServer, LUser).
-
-sql_get_privacy_list_names_t(LUser) ->
- sql_queries:get_privacy_list_names_t(LUser).
-
-sql_get_privacy_list_id(LUser, LServer, Name) ->
- sql_queries:get_privacy_list_id(LServer, LUser, Name).
-
-sql_get_privacy_list_id_t(LUser, Name) ->
- sql_queries:get_privacy_list_id_t(LUser, Name).
-
-sql_get_privacy_list_data(LUser, LServer, Name) ->
- sql_queries:get_privacy_list_data(LServer, LUser, Name).
-
-sql_get_privacy_list_data_t(LUser, Name) ->
- sql_queries:get_privacy_list_data_t(LUser, Name).
-
-sql_get_privacy_list_data_by_id(ID, LServer) ->
- sql_queries:get_privacy_list_data_by_id(LServer, ID).
-
-sql_get_privacy_list_data_by_id_t(ID) ->
- sql_queries:get_privacy_list_data_by_id_t(ID).
-
-sql_set_default_privacy_list(LUser, Name) ->
- sql_queries:set_default_privacy_list(LUser, Name).
-
-sql_unset_default_privacy_list(LUser, LServer) ->
- sql_queries:unset_default_privacy_list(LServer, LUser).
-
-sql_remove_privacy_list(LUser, Name) ->
- sql_queries:remove_privacy_list(LUser, Name).
-
-sql_add_privacy_list(LUser, Name) ->
- sql_queries:add_privacy_list(LUser, Name).
+get_default_privacy_list(LUser, LServer) ->
+ ejabberd_sql:sql_query(
+ LServer,
+ ?SQL("select @(name)s from privacy_default_list "
+ "where username=%(LUser)s and %(LServer)H")).
+
+get_default_privacy_list_t(LUser, LServer) ->
+ ejabberd_sql:sql_query_t(
+ ?SQL("select @(name)s from privacy_default_list "
+ "where username=%(LUser)s and %(LServer)H")).
+
+get_privacy_list_names(LUser, LServer) ->
+ ejabberd_sql:sql_query(
+ LServer,
+ ?SQL("select @(name)s from privacy_list"
+ " where username=%(LUser)s and %(LServer)H")).
+
+get_privacy_list_names_t(LUser, LServer) ->
+ ejabberd_sql:sql_query_t(
+ ?SQL("select @(name)s from privacy_list"
+ " where username=%(LUser)s and %(LServer)H")).
+
+get_privacy_list_id_t(LUser, LServer, Name) ->
+ ejabberd_sql:sql_query_t(
+ ?SQL("select @(id)d from privacy_list"
+ " where username=%(LUser)s and %(LServer)H and name=%(Name)s")).
+
+get_privacy_list_data(LUser, LServer, Name) ->
+ ejabberd_sql:sql_query(
+ LServer,
+ ?SQL("select @(t)s, @(value)s, @(action)s, @(ord)d, @(match_all)b, "
+ "@(match_iq)b, @(match_message)b, @(match_presence_in)b, "
+ "@(match_presence_out)b from privacy_list_data "
+ "where id ="
+ " (select id from privacy_list"
+ " where username=%(LUser)s and %(LServer)H and name=%(Name)s) "
+ "order by ord")).
+
+set_default_privacy_list(LUser, LServer, Name) ->
+ ?SQL_UPSERT_T(
+ "privacy_default_list",
+ ["!username=%(LUser)s",
+ "!server_host=%(LServer)s",
+ "name=%(Name)s"]).
+
+unset_default_privacy_list(LUser, LServer) ->
+ case ejabberd_sql:sql_query(
+ LServer,
+ ?SQL("delete from privacy_default_list"
+ " where username=%(LUser)s and %(LServer)H")) of
+ {updated, _} -> ok;
+ Err -> Err
+ end.
-sql_set_privacy_list(ID, RItems) ->
- sql_queries:set_privacy_list(ID, RItems).
+remove_privacy_list_t(LUser, LServer, Name) ->
+ case ejabberd_sql:sql_query_t(
+ ?SQL("delete from privacy_list where"
+ " username=%(LUser)s and %(LServer)H and name=%(Name)s")) of
+ {updated, 0} -> {error, notfound};
+ {updated, _} -> ok;
+ Err -> Err
+ end.
-sql_del_privacy_lists(LUser, LServer) ->
- sql_queries:del_privacy_lists(LServer, LUser).
+add_privacy_list(LUser, LServer, Name) ->
+ ejabberd_sql:sql_query_t(
+ ?SQL_INSERT(
+ "privacy_list",
+ ["username=%(LUser)s",
+ "server_host=%(LServer)s",
+ "name=%(Name)s"])).
+
+set_privacy_list(ID, RItems) ->
+ ejabberd_sql:sql_query_t(
+ ?SQL("delete from privacy_list_data where id=%(ID)d")),
+ lists:foreach(
+ fun({SType, SValue, SAction, Order, MatchAll, MatchIQ,
+ MatchMessage, MatchPresenceIn, MatchPresenceOut}) ->
+ ejabberd_sql:sql_query_t(
+ ?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)"))
+ end,
+ RItems).
+
+del_privacy_lists(LUser, LServer) ->
+ case ejabberd_sql:sql_query(
+ LServer,
+ ?SQL("delete from privacy_list where username=%(LUser)s and %(LServer)H")) of
+ {updated, _} ->
+ case ejabberd_sql:sql_query(
+ LServer,
+ ?SQL("delete from privacy_default_list "
+ "where username=%(LUser)s and %(LServer)H")) of
+ {updated, _} -> ok;
+ Err -> Err
+ end;
+ Err ->
+ Err
+ end.