diff options
Diffstat (limited to 'src/mod_privacy_mnesia.erl')
-rw-r--r-- | src/mod_privacy_mnesia.erl | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/src/mod_privacy_mnesia.erl b/src/mod_privacy_mnesia.erl new file mode 100644 index 000000000..4026b7f64 --- /dev/null +++ b/src/mod_privacy_mnesia.erl @@ -0,0 +1,198 @@ +%%%------------------------------------------------------------------- +%%% @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_privacy_mnesia). + +-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/2]). + +-include("jlib.hrl"). +-include("mod_privacy.hrl"). +-include("logger.hrl"). + +%%%=================================================================== +%%% API +%%%=================================================================== +init(_Host, _Opts) -> + mnesia:create_table(privacy, + [{disc_copies, [node()]}, + {attributes, record_info(fields, privacy)}]), + update_table(). + +process_lists_get(LUser, LServer) -> + case catch mnesia:dirty_read(privacy, {LUser, LServer}) of + {'EXIT', _Reason} -> error; + [] -> {none, []}; + [#privacy{default = Default, lists = Lists}] -> + LItems = lists:map(fun ({N, _}) -> + #xmlel{name = <<"list">>, + attrs = [{<<"name">>, N}], + children = []} + end, Lists), + {Default, LItems} + end. + +process_list_get(LUser, LServer, Name) -> + case catch mnesia:dirty_read(privacy, {LUser, LServer}) of + {'EXIT', _Reason} -> error; + [] -> not_found; + [#privacy{lists = Lists}] -> + case lists:keysearch(Name, 1, Lists) of + {value, {_, List}} -> List; + _ -> not_found + end + end. + +process_default_set(LUser, LServer, {value, Name}) -> + F = fun () -> + case mnesia:read({privacy, {LUser, LServer}}) of + [] -> not_found; + [#privacy{lists = Lists} = P] -> + case lists:keymember(Name, 1, Lists) of + true -> + mnesia:write(P#privacy{default = Name, + lists = Lists}), + ok; + false -> not_found + end + end + end, + mnesia:transaction(F); +process_default_set(LUser, LServer, false) -> + F = fun () -> + case mnesia:read({privacy, {LUser, LServer}}) of + [] -> ok; + [R] -> mnesia:write(R#privacy{default = none}) + end + end, + mnesia:transaction(F). + +process_active_set(LUser, LServer, Name) -> + case catch mnesia:dirty_read(privacy, {LUser, LServer}) of + [] -> error; + [#privacy{lists = Lists}] -> + case lists:keysearch(Name, 1, Lists) of + {value, {_, List}} -> List; + false -> error + end + end. + +remove_privacy_list(LUser, LServer, Name) -> + F = fun () -> + case mnesia:read({privacy, {LUser, LServer}}) of + [] -> ok; + [#privacy{default = Default, lists = Lists} = P] -> + if Name == Default -> conflict; + true -> + NewLists = lists:keydelete(Name, 1, Lists), + mnesia:write(P#privacy{lists = NewLists}) + end + end + end, + mnesia:transaction(F). + +set_privacy_list(Privacy) -> + mnesia:dirty_write(Privacy). + +set_privacy_list(LUser, LServer, Name, List) -> + F = fun () -> + case mnesia:wread({privacy, {LUser, LServer}}) of + [] -> + NewLists = [{Name, List}], + mnesia:write(#privacy{us = {LUser, LServer}, + lists = NewLists}); + [#privacy{lists = Lists} = P] -> + NewLists1 = lists:keydelete(Name, 1, Lists), + NewLists = [{Name, List} | NewLists1], + mnesia:write(P#privacy{lists = NewLists}) + end + end, + mnesia:transaction(F). + +get_user_list(LUser, LServer) -> + case catch mnesia:dirty_read(privacy, {LUser, LServer}) + of + [] -> {none, []}; + [#privacy{default = Default, lists = Lists}] -> + case Default of + none -> {none, []}; + _ -> + case lists:keysearch(Default, 1, Lists) of + {value, {_, List}} -> {Default, List}; + _ -> {none, []} + end + end; + _ -> {none, []} + end. + +get_user_lists(LUser, LServer) -> + case catch mnesia:dirty_read(privacy, {LUser, LServer}) of + [#privacy{} = P] -> + {ok, P}; + _ -> + error + end. + +remove_user(LUser, LServer) -> + F = fun () -> mnesia:delete({privacy, {LUser, LServer}}) end, + mnesia:transaction(F). + +import(_LServer, #privacy{} = P) -> + mnesia:dirty_write(P). + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== +update_table() -> + Fields = record_info(fields, privacy), + case mnesia:table_info(privacy, attributes) of + Fields -> + ejabberd_config:convert_table_to_binary( + privacy, Fields, set, + fun(#privacy{us = {U, _}}) -> U end, + fun(#privacy{us = {U, S}, default = Def, lists = Lists} = R) -> + NewLists = + lists:map( + fun({Name, Ls}) -> + NewLs = + lists:map( + fun(#listitem{value = Val} = L) -> + NewVal = + case Val of + {LU, LS, LR} -> + {iolist_to_binary(LU), + iolist_to_binary(LS), + iolist_to_binary(LR)}; + none -> none; + both -> both; + from -> from; + to -> to; + _ -> iolist_to_binary(Val) + end, + L#listitem{value = NewVal} + end, Ls), + {iolist_to_binary(Name), NewLs} + end, Lists), + NewDef = case Def of + none -> none; + _ -> iolist_to_binary(Def) + end, + NewUS = {iolist_to_binary(U), iolist_to_binary(S)}, + R#privacy{us = NewUS, default = NewDef, + lists = NewLists} + end); + _ -> + ?INFO_MSG("Recreating privacy table", []), + mnesia:transform_table(privacy, ignore, Fields) + end. |