aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlexey Shchepin <alexey@process-one.net>2006-11-03 15:42:21 +0000
committerAlexey Shchepin <alexey@process-one.net>2006-11-03 15:42:21 +0000
commit85cbbeae23176eba4151afe2ad898d5f6863c785 (patch)
tree8ca52346a713b36fe65c385cef731247d63dfef7 /src
parentNow really added (diff)
Now really committed
SVN Revision: 670
Diffstat (limited to 'src')
-rw-r--r--src/mod_privacy_odbc.erl876
1 files changed, 876 insertions, 0 deletions
diff --git a/src/mod_privacy_odbc.erl b/src/mod_privacy_odbc.erl
new file mode 100644
index 000000000..271fc4506
--- /dev/null
+++ b/src/mod_privacy_odbc.erl
@@ -0,0 +1,876 @@
+%%%----------------------------------------------------------------------
+%%% File : mod_privacy_odbc.erl
+%%% Author : Alexey Shchepin <alexey@sevcom.net>
+%%% Purpose : jabber:iq:privacy support
+%%% Created : 5 Oct 2006 by Alexey Shchepin <alexey@sevcom.net>
+%%% Id : $Id$
+%%%----------------------------------------------------------------------
+
+-module(mod_privacy_odbc).
+-author('alexey@sevcom.net').
+-vsn('$Revision$ ').
+
+-behaviour(gen_mod).
+
+-export([start/2, stop/1,
+ process_iq/3,
+ process_iq_set/4,
+ process_iq_get/5,
+ get_user_list/3,
+ check_packet/6,
+ updated_list/3]).
+
+-include("ejabberd.hrl").
+-include("jlib.hrl").
+
+-record(privacy, {us,
+ default = none,
+ lists = []}).
+
+-record(listitem, {type = none,
+ value = none,
+ action,
+ order,
+ match_all = false,
+ match_iq = false,
+ match_message = false,
+ match_presence_in = false,
+ match_presence_out = false
+ }).
+
+-record(userlist, {name = none, list = []}).
+
+
+start(Host, Opts) ->
+ IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
+ ejabberd_hooks:add(privacy_iq_get, Host,
+ ?MODULE, process_iq_get, 50),
+ ejabberd_hooks:add(privacy_iq_set, Host,
+ ?MODULE, process_iq_set, 50),
+ ejabberd_hooks:add(privacy_get_user_list, Host,
+ ?MODULE, get_user_list, 50),
+ ejabberd_hooks:add(privacy_check_packet, Host,
+ ?MODULE, check_packet, 50),
+ ejabberd_hooks:add(privacy_updated_list, Host,
+ ?MODULE, updated_list, 50),
+ gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVACY,
+ ?MODULE, process_iq, IQDisc).
+
+stop(Host) ->
+ ejabberd_hooks:delete(privacy_iq_get, Host,
+ ?MODULE, process_iq_get, 50),
+ ejabberd_hooks:delete(privacy_iq_set, Host,
+ ?MODULE, process_iq_set, 50),
+ ejabberd_hooks:delete(privacy_get_user_list, Host,
+ ?MODULE, get_user_list, 50),
+ ejabberd_hooks:delete(privacy_check_packet, Host,
+ ?MODULE, check_packet, 50),
+ ejabberd_hooks:delete(privacy_updated_list, Host,
+ ?MODULE, updated_list, 50),
+ gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PRIVACY).
+
+process_iq(_From, _To, IQ) ->
+ SubEl = IQ#iq.sub_el,
+ IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}.
+
+
+process_iq_get(_, From, _To, #iq{sub_el = SubEl},
+ #userlist{name = Active}) ->
+ #jid{luser = LUser, lserver = LServer} = From,
+ {xmlelement, _, _, Els} = SubEl,
+ case xml:remove_cdata(Els) of
+ [] ->
+ process_lists_get(LUser, LServer, Active);
+ [{xmlelement, Name, Attrs, _SubEls}] ->
+ case Name of
+ "list" ->
+ ListName = xml:get_attr("name", Attrs),
+ process_list_get(LUser, LServer, ListName);
+ _ ->
+ {error, ?ERR_BAD_REQUEST}
+ end;
+ _ ->
+ {error, ?ERR_BAD_REQUEST}
+ end.
+
+
+process_lists_get(LUser, LServer, Active) ->
+ Default = case catch sql_get_default_privacy_list(LUser, LServer) of
+ {'EXIT', _Reason} ->
+ none;
+ {selected, ["name"], []} ->
+ none;
+ {selected, ["name"], [{DefName}]} ->
+ DefName
+ end,
+ case catch sql_get_privacy_list_names(LUser, LServer) of
+ {'EXIT', _Reason2} ->
+ {error, ?ERR_INTERNAL_SERVER_ERROR};
+ {selected, ["name"], []} ->
+ {result, [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}], []}]};
+ {selected, ["name"], Names} ->
+ LItems = lists:map(
+ fun({N}) ->
+ {xmlelement, "list",
+ [{"name", N}], []}
+ end, Names),
+ DItems =
+ case Default of
+ none ->
+ LItems;
+ _ ->
+ [{xmlelement, "default",
+ [{"name", Default}], []} | LItems]
+ end,
+ ADItems =
+ case Active of
+ none ->
+ DItems;
+ _ ->
+ [{xmlelement, "active",
+ [{"name", Active}], []} | DItems]
+ end,
+ {result,
+ [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}],
+ ADItems}]}
+ end.
+
+process_list_get(LUser, LServer, {value, Name}) ->
+ case catch sql_get_privacy_list_id(LUser, LServer, Name) of
+ {'EXIT', _Reason} ->
+ {error, ?ERR_INTERNAL_SERVER_ERROR};
+ {selected, ["id"], []} ->
+ {error, ?ERR_ITEM_NOT_FOUND};
+ {selected, ["id"], [{ID}]} ->
+ case catch sql_get_privacy_list_data_by_id(ID, LServer) of
+ {'EXIT', _Reason} ->
+ {error, ?ERR_INTERNAL_SERVER_ERROR};
+ {selected, ["t", "value", "action", "ord", "match_all",
+ "match_iq", "match_message",
+ "match_presence_in", "match_presence_out"],
+ RItems} ->
+ Items = lists:map(fun raw_to_item/1, RItems),
+ LItems = lists:map(fun item_to_xml/1, Items),
+ {result,
+ [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}],
+ [{xmlelement, "list",
+ [{"name", Name}], LItems}]}]}
+ end
+ end;
+
+process_list_get(_LUser, _LServer, false) ->
+ {error, ?ERR_BAD_REQUEST}.
+
+item_to_xml(Item) ->
+ Attrs1 = [{"action", action_to_list(Item#listitem.action)},
+ {"order", order_to_list(Item#listitem.order)}],
+ Attrs2 = case Item#listitem.type of
+ none ->
+ Attrs1;
+ Type ->
+ [{"type", type_to_list(Item#listitem.type)},
+ {"value", value_to_list(Type, Item#listitem.value)} |
+ Attrs1]
+ end,
+ SubEls = case Item#listitem.match_all of
+ true ->
+ [];
+ false ->
+ SE1 = case Item#listitem.match_iq of
+ true ->
+ [{xmlelement, "iq", [], []}];
+ false ->
+ []
+ end,
+ SE2 = case Item#listitem.match_message of
+ true ->
+ [{xmlelement, "message", [], []} | SE1];
+ false ->
+ SE1
+ end,
+ SE3 = case Item#listitem.match_presence_in of
+ true ->
+ [{xmlelement, "presence-in", [], []} | SE2];
+ false ->
+ SE2
+ end,
+ SE4 = case Item#listitem.match_presence_out of
+ true ->
+ [{xmlelement, "presence-out", [], []} | SE3];
+ false ->
+ SE3
+ end,
+ SE4
+ end,
+ {xmlelement, "item", Attrs2, SubEls}.
+
+
+action_to_list(Action) ->
+ case Action of
+ allow -> "allow";
+ deny -> "deny"
+ end.
+
+order_to_list(Order) ->
+ integer_to_list(Order).
+
+type_to_list(Type) ->
+ case Type of
+ jid -> "jid";
+ group -> "group";
+ subscription -> "subscription"
+ end.
+
+value_to_list(Type, Val) ->
+ case Type of
+ jid -> jlib:jid_to_string(Val);
+ group -> Val;
+ subscription ->
+ case Val of
+ both -> "both";
+ to -> "to";
+ from -> "from";
+ none -> "none"
+ end
+ end.
+
+
+
+list_to_action(S) ->
+ case S of
+ "allow" -> allow;
+ "deny" -> deny
+ end.
+
+
+
+process_iq_set(_, From, _To, #iq{sub_el = SubEl}) ->
+ #jid{luser = LUser, lserver = LServer} = From,
+ {xmlelement, _, _, Els} = SubEl,
+ case xml:remove_cdata(Els) of
+ [{xmlelement, Name, Attrs, SubEls}] ->
+ ListName = xml:get_attr("name", Attrs),
+ case Name of
+ "list" ->
+ process_list_set(LUser, LServer, ListName,
+ xml:remove_cdata(SubEls));
+ "active" ->
+ process_active_set(LUser, LServer, ListName);
+ "default" ->
+ process_default_set(LUser, LServer, ListName);
+ _ ->
+ {error, ?ERR_BAD_REQUEST}
+ end;
+ _ ->
+ {error, ?ERR_BAD_REQUEST}
+ end.
+
+
+process_default_set(LUser, LServer, {value, Name}) ->
+ F = fun() ->
+ case sql_get_privacy_list_names_t(LUser) of
+ {selected, ["name"], []} ->
+ {error, ?ERR_ITEM_NOT_FOUND};
+ {selected, ["name"], Names} ->
+ case lists:member({Name}, Names) of
+ true ->
+ sql_set_default_privacy_list(LUser, Name),
+ {result, []};
+ false ->
+ {error, ?ERR_ITEM_NOT_FOUND}
+ end
+ end
+ end,
+ case odbc_queries:sql_transaction(LServer, F) of
+ {atomic, {error, _} = Error} ->
+ Error;
+ {atomic, {result, _} = Res} ->
+ Res;
+ _ ->
+ {error, ?ERR_INTERNAL_SERVER_ERROR}
+ end;
+
+process_default_set(LUser, LServer, false) ->
+ case catch sql_unset_default_privacy_list(LUser, LServer) of
+ {'EXIT', _Reason} ->
+ {error, ?ERR_INTERNAL_SERVER_ERROR};
+ _ ->
+ {result, []}
+ end.
+
+
+process_active_set(LUser, LServer, {value, Name}) ->
+ case catch sql_get_privacy_list_id(LUser, LServer, Name) of
+ {'EXIT', _Reason} ->
+ {error, ?ERR_INTERNAL_SERVER_ERROR};
+ {selected, ["id"], []} ->
+ {error, ?ERR_ITEM_NOT_FOUND};
+ {selected, ["id"], [{ID}]} ->
+ case catch sql_get_privacy_list_data_by_id(ID, LServer) of
+ {'EXIT', _Reason} ->
+ {error, ?ERR_INTERNAL_SERVER_ERROR};
+ {selected, ["t", "value", "action", "ord", "match_all",
+ "match_iq", "match_message",
+ "match_presence_in", "match_presence_out"],
+ RItems} ->
+ Items = lists:map(fun raw_to_item/1, RItems),
+ {result, [], #userlist{name = Name, list = Items}}
+ end
+ end;
+
+process_active_set(_LUser, _LServer, false) ->
+ {result, [], #userlist{}}.
+
+
+
+
+
+
+process_list_set(LUser, LServer, {value, Name}, Els) ->
+ case parse_items(Els) of
+ false ->
+ {error, ?ERR_BAD_REQUEST};
+ remove ->
+ F =
+ fun() ->
+ case sql_get_default_privacy_list_t(LUser) of
+ {selected, ["name"], []} ->
+ sql_remove_privacy_list(LUser, Name),
+ {result, []};
+ {selected, ["name"], [{Default}]} ->
+ %% TODO: check active
+ if
+ Name == Default ->
+ {error, ?ERR_CONFLICT};
+ true ->
+ sql_remove_privacy_list(LUser, Name),
+ {result, []}
+ end
+ end
+ end,
+ case odbc_queries:sql_transaction(LServer, F) of
+ {atomic, {error, _} = Error} ->
+ Error;
+ {atomic, {result, _} = Res} ->
+ ejabberd_router:route(
+ jlib:make_jid(LUser, LServer, ""),
+ jlib:make_jid(LUser, LServer, ""),
+ {xmlelement, "broadcast", [],
+ [{privacy_list,
+ #userlist{name = Name, list = []},
+ Name}]}),
+ Res;
+ _ ->
+ {error, ?ERR_INTERNAL_SERVER_ERROR}
+ end;
+ List ->
+ RItems = lists:map(fun item_to_raw/1, List),
+ F =
+ fun() ->
+ ID =
+ case sql_get_privacy_list_id_t(LUser, Name) of
+ {selected, ["id"], []} ->
+ sql_add_privacy_list(LUser, Name),
+ {selected, ["id"], [{I}]} =
+ sql_get_privacy_list_id_t(LUser, Name),
+ I;
+ {selected, ["id"], [{I}]} ->
+ I
+ end,
+ sql_set_privacy_list(ID, RItems),
+ {result, []}
+ end,
+ case odbc_queries:sql_transaction(LServer, F) of
+ {atomic, {error, _} = Error} ->
+ Error;
+ {atomic, {result, _} = Res} ->
+ ejabberd_router:route(
+ jlib:make_jid(LUser, LServer, ""),
+ jlib:make_jid(LUser, LServer, ""),
+ {xmlelement, "broadcast", [],
+ [{privacy_list,
+ #userlist{name = Name, list = List},
+ Name}]}),
+ Res;
+ _ ->
+ {error, ?ERR_INTERNAL_SERVER_ERROR}
+ end
+ end;
+
+process_list_set(_LUser, _LServer, false, _Els) ->
+ {error, ?ERR_BAD_REQUEST}.
+
+
+parse_items([]) ->
+ remove;
+parse_items(Els) ->
+ parse_items(Els, []).
+
+parse_items([], Res) ->
+ lists:reverse(Res);
+parse_items([{xmlelement, "item", Attrs, SubEls} | Els], Res) ->
+ Type = xml:get_attr("type", Attrs),
+ Value = xml:get_attr("value", Attrs),
+ SAction = xml:get_attr("action", Attrs),
+ SOrder = xml:get_attr("order", Attrs),
+ Action = case catch list_to_action(element(2, SAction)) of
+ {'EXIT', _} -> false;
+ Val -> Val
+ end,
+ Order = case catch list_to_integer(element(2, SOrder)) of
+ {'EXIT', _} ->
+ false;
+ IntVal ->
+ if
+ IntVal >= 0 ->
+ IntVal;
+ true ->
+ false
+ end
+ end,
+ if
+ (Action /= false) and (Order /= false) ->
+ I1 = #listitem{action = Action, order = Order},
+ I2 = case {Type, Value} of
+ {{value, T}, {value, V}} ->
+ case T of
+ "jid" ->
+ case jlib:string_to_jid(V) of
+ error ->
+ false;
+ JID ->
+ I1#listitem{
+ type = jid,
+ value = jlib:jid_tolower(JID)}
+ end;
+ "group" ->
+ I1#listitem{type = group,
+ value = V};
+ "subscription" ->
+ case V of
+ "none" ->
+ I1#listitem{type = subscription,
+ value = none};
+ "both" ->
+ I1#listitem{type = subscription,
+ value = both};
+ "from" ->
+ I1#listitem{type = subscription,
+ value = from};
+ "to" ->
+ I1#listitem{type = subscription,
+ value = to};
+ _ ->
+ false
+ end
+ end;
+ {{value, _}, false} ->
+ false;
+ _ ->
+ I1
+ end,
+ case I2 of
+ false ->
+ false;
+ _ ->
+ case parse_matches(I2, xml:remove_cdata(SubEls)) of
+ false ->
+ false;
+ I3 ->
+ parse_items(Els, [I3 | Res])
+ end
+ end;
+ true ->
+ false
+ end;
+
+parse_items(_, _Res) ->
+ false.
+
+
+parse_matches(Item, []) ->
+ Item#listitem{match_all = true};
+parse_matches(Item, Els) ->
+ parse_matches1(Item, Els).
+
+parse_matches1(Item, []) ->
+ Item;
+parse_matches1(Item, [{xmlelement, "message", _, _} | Els]) ->
+ parse_matches1(Item#listitem{match_message = true}, Els);
+parse_matches1(Item, [{xmlelement, "iq", _, _} | Els]) ->
+ parse_matches1(Item#listitem{match_iq = true}, Els);
+parse_matches1(Item, [{xmlelement, "presence-in", _, _} | Els]) ->
+ parse_matches1(Item#listitem{match_presence_in = true}, Els);
+parse_matches1(Item, [{xmlelement, "presence-out", _, _} | Els]) ->
+ parse_matches1(Item#listitem{match_presence_out = true}, Els);
+parse_matches1(_Item, [{xmlelement, _, _, _} | _Els]) ->
+ false.
+
+
+
+
+
+
+
+get_user_list(_, User, Server) ->
+ LUser = jlib:nodeprep(User),
+ LServer = jlib:nameprep(Server),
+
+ case catch sql_get_default_privacy_list(LUser, LServer) of
+ {'EXIT', _Reason} ->
+ #userlist{};
+ {selected, ["name"], []} ->
+ #userlist{};
+ {selected, ["name"], [{Default}]} ->
+ case catch sql_get_privacy_list_data(LUser, LServer, Default) of
+ {'EXIT', _Reason} ->
+ #userlist{};
+ {selected, ["t", "value", "action", "ord", "match_all",
+ "match_iq", "match_message",
+ "match_presence_in", "match_presence_out"],
+ RItems} ->
+ Items = lists:map(fun raw_to_item/1, RItems),
+ #userlist{name = Default, list = Items}
+ end
+ end.
+
+
+check_packet(_, User, Server,
+ #userlist{list = List},
+ {From, To, {xmlelement, PName, _, _}},
+ Dir) ->
+ case List of
+ [] ->
+ allow;
+ _ ->
+ PType = case PName of
+ "message" -> message;
+ "iq" -> iq;
+ "presence" -> presence
+ end,
+ case {PType, Dir} of
+ {message, in} ->
+ LJID = jlib:jid_tolower(From),
+ {Subscription, Groups} =
+ ejabberd_hooks:run_fold(
+ roster_get_jid_info, jlib:nameprep(Server),
+ {none, []}, [User, Server, LJID]),
+ check_packet_aux(List, message,
+ LJID, Subscription, Groups);
+ {iq, in} ->
+ LJID = jlib:jid_tolower(From),
+ {Subscription, Groups} =
+ ejabberd_hooks:run_fold(
+ roster_get_jid_info, jlib:nameprep(Server),
+ {none, []}, [User, Server, LJID]),
+ check_packet_aux(List, iq,
+ LJID, Subscription, Groups);
+ {presence, in} ->
+ LJID = jlib:jid_tolower(From),
+ {Subscription, Groups} =
+ ejabberd_hooks:run_fold(
+ roster_get_jid_info, jlib:nameprep(Server),
+ {none, []}, [User, Server, LJID]),
+ check_packet_aux(List, presence_in,
+ LJID, Subscription, Groups);
+ {presence, out} ->
+ LJID = jlib:jid_tolower(To),
+ {Subscription, Groups} =
+ ejabberd_hooks:run_fold(
+ roster_get_jid_info, jlib:nameprep(Server),
+ {none, []}, [User, Server, LJID]),
+ check_packet_aux(List, presence_out,
+ LJID, Subscription, Groups);
+ _ ->
+ allow
+ end
+ end.
+
+check_packet_aux([], _PType, _JID, _Subscription, _Groups) ->
+ allow;
+check_packet_aux([Item | List], PType, JID, Subscription, Groups) ->
+ #listitem{type = Type, value = Value, action = Action} = Item,
+ case is_ptype_match(Item, PType) of
+ true ->
+ case Type of
+ none ->
+ Action;
+ _ ->
+ case is_type_match(Type, Value,
+ JID, Subscription, Groups) of
+ true ->
+ Action;
+ false ->
+ check_packet_aux(List, PType,
+ JID, Subscription, Groups)
+ end
+ end;
+ false ->
+ check_packet_aux(List, PType, JID, Subscription, Groups)
+ end.
+
+
+is_ptype_match(Item, PType) ->
+ case Item#listitem.match_all of
+ true ->
+ true;
+ false ->
+ case PType of
+ message ->
+ Item#listitem.match_message;
+ iq ->
+ Item#listitem.match_iq;
+ presence_in ->
+ Item#listitem.match_presence_in;
+ presence_out ->
+ Item#listitem.match_presence_out
+ end
+ end.
+
+
+is_type_match(Type, Value, JID, Subscription, Groups) ->
+ case Type of
+ jid ->
+ case Value of
+ {"", Server, ""} ->
+ case JID of
+ {_, Server, _} ->
+ true;
+ _ ->
+ false
+ end;
+ {User, Server, ""} ->
+ case JID of
+ {User, Server, _} ->
+ true;
+ _ ->
+ false
+ end;
+ _ ->
+ Value == JID
+ end;
+ subscription ->
+ Value == Subscription;
+ group ->
+ lists:member(Value, Groups)
+ end.
+
+
+updated_list(_,
+ #userlist{name = OldName} = Old,
+ #userlist{name = NewName} = New) ->
+ if
+ OldName == NewName ->
+ New;
+ true ->
+ Old
+ end.
+
+
+raw_to_item({SType, SValue, SAction, SOrder, SMatchAll, SMatchIQ,
+ SMatchMessage, SMatchPresenceIn, SMatchPresenceOut}) ->
+ {Type, Value} =
+ case SType of
+ "n" ->
+ {none, none};
+ "j" ->
+ case jlib:string_to_jid(SValue) of
+ #jid{} = JID ->
+ {jid, jlib:jid_tolower(JID)}
+ end;
+ "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,
+ Order = list_to_integer(SOrder),
+ MatchAll = SMatchAll == "t",
+ MatchIQ = SMatchIQ == "t",
+ MatchMessage = SMatchMessage == "t",
+ MatchPresenceIn = SMatchPresenceIn == "t",
+ MatchPresenceOut = SMatchPresenceOut == "t",
+ #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
+ }.
+
+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", jlib:jid_to_string(Value)};
+ 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,
+ SOrder = integer_to_list(Order),
+ SMatchAll = if MatchAll -> "t"; true -> "f" end,
+ SMatchIQ = if MatchIQ -> "t"; true -> "f" end,
+ SMatchMessage = if MatchMessage -> "t"; true -> "f" end,
+ SMatchPresenceIn = if MatchPresenceIn -> "t"; true -> "f" end,
+ SMatchPresenceOut = if MatchPresenceOut -> "t"; true -> "f" end,
+ ["'", SType, "', "
+ "'", SValue, "', "
+ "'", SAction, "', "
+ "'", SOrder, "', "
+ "'", SMatchAll, "', "
+ "'", SMatchIQ, "', "
+ "'", SMatchMessage, "', "
+ "'", SMatchPresenceIn, "', "
+ "'", SMatchPresenceOut, "'"].
+
+
+sql_get_default_privacy_list(LUser, LServer) ->
+ Username = ejabberd_odbc:escape(LUser),
+ ejabberd_odbc:sql_query(
+ LServer,
+ ["select name from privacy_default_list "
+ "where username='", Username, "';"]).
+
+sql_get_default_privacy_list_t(LUser) ->
+ Username = ejabberd_odbc:escape(LUser),
+ ejabberd_odbc:sql_query_t(
+ ["select name from privacy_default_list "
+ "where username='", Username, "';"]).
+
+sql_get_privacy_list_names(LUser, LServer) ->
+ Username = ejabberd_odbc:escape(LUser),
+ ejabberd_odbc:sql_query(
+ LServer,
+ ["select name from privacy_list "
+ "where username='", Username, "';"]).
+
+sql_get_privacy_list_names_t(LUser) ->
+ Username = ejabberd_odbc:escape(LUser),
+ ejabberd_odbc:sql_query_t(
+ ["select name from privacy_list "
+ "where username='", Username, "';"]).
+
+sql_get_privacy_list_id(LUser, LServer, Name) ->
+ Username = ejabberd_odbc:escape(LUser),
+ SName = ejabberd_odbc:escape(Name),
+ ejabberd_odbc:sql_query(
+ LServer,
+ ["select id from privacy_list "
+ "where username='", Username, "' and name='", SName, "';"]).
+
+sql_get_privacy_list_id_t(LUser, Name) ->
+ Username = ejabberd_odbc:escape(LUser),
+ SName = ejabberd_odbc:escape(Name),
+ ejabberd_odbc:sql_query_t(
+ ["select id from privacy_list "
+ "where username='", Username, "' and name='", SName, "';"]).
+
+sql_get_privacy_list_data(LUser, LServer, Name) ->
+ Username = ejabberd_odbc:escape(LUser),
+ SName = ejabberd_odbc:escape(Name),
+ ejabberd_odbc:sql_query(
+ LServer,
+ ["select t, value, action, ord, match_all, match_iq, "
+ "match_message, match_presence_in, match_presence_out "
+ "from privacy_list_data "
+ "where id = (select id from privacy_list where "
+ " username='", Username, "' and name='", SName, "') "
+ "order by ord;"]).
+
+sql_get_privacy_list_data_by_id(ID, LServer) ->
+ ejabberd_odbc:sql_query(
+ LServer,
+ ["select t, value, action, ord, match_all, match_iq, "
+ "match_message, match_presence_in, match_presence_out "
+ "from privacy_list_data "
+ "where id='", ID, "' order by ord;"]).
+
+sql_set_default_privacy_list(LUser, Name) ->
+ Username = ejabberd_odbc:escape(LUser),
+ SName = ejabberd_odbc:escape(Name),
+ ejabberd_odbc:sql_query_t(
+ ["delete from privacy_default_list "
+ " where username='", Username, "';"]),
+ ejabberd_odbc:sql_query_t(
+ ["insert into privacy_default_list(username, name) "
+ "values ('", Username, "', '", SName, "');"]).
+
+sql_unset_default_privacy_list(LUser, LServer) ->
+ Username = ejabberd_odbc:escape(LUser),
+ ejabberd_odbc:sql_query(
+ LServer,
+ ["delete from privacy_default_list "
+ " where username='", Username, "';"]).
+
+sql_remove_privacy_list(LUser, Name) ->
+ Username = ejabberd_odbc:escape(LUser),
+ SName = ejabberd_odbc:escape(Name),
+ ejabberd_odbc:sql_query_t(
+ ["delete from privacy_list "
+ "where username='", Username, "' and name='", SName, "';"]).
+
+sql_add_privacy_list(LUser, Name) ->
+ Username = ejabberd_odbc:escape(LUser),
+ SName = ejabberd_odbc:escape(Name),
+ ejabberd_odbc:sql_query_t(
+ ["insert into privacy_list(username, name) "
+ "values ('", Username, "', '", SName, "');"]).
+
+sql_set_privacy_list(ID, RItems) ->
+ ejabberd_odbc:sql_query_t(
+ ["delete from privacy_list_data "
+ "where id='", ID, "';"]),
+ lists:foreach(fun(Items) ->
+ ejabberd_odbc:sql_query_t(
+ ["insert into privacy_list_data("
+ "id, t, value, action, ord, match_all, match_iq, "
+ "match_message, match_presence_in, "
+ "match_presence_out "
+ ") "
+ "values ('", ID, "', ", Items, ");"])
+ end, RItems).
+
+
+