diff --git a/ChangeLog b/ChangeLog index 6309edf2c..fef505885 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2006-10-05 Alexey Shchepin + + * src/mod_privacy.erl: Use hooks instead of direct function calls + * src/ejabberd_c2s.erl: Updated + 2006-10-01 Alexey Shchepin * src/shaper.erl: Bugfix diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 5c05d863a..db0755c54 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -390,11 +390,10 @@ wait_for_auth({xmlstreamelement, El}, StateData) -> Fs1 = [LJID | Fs], Ts1 = [LJID | Ts], PrivList = - case catch mod_privacy:get_user_list( - U, StateData#state.server) of - {'EXIT', _} -> none; - PL -> PL - end, + ejabberd_hooks:run_fold( + privacy_get_user_list, StateData#state.server, + none, + [U, StateData#state.server]), {next_state, session_established, StateData#state{user = U, resource = R, @@ -700,11 +699,10 @@ wait_for_session({xmlstreamelement, El}, StateData) -> Fs1 = [LJID | Fs], Ts1 = [LJID | Ts], PrivList = - case catch mod_privacy:get_user_list( - U, StateData#state.server) of - {'EXIT', _} -> none; - PL -> PL - end, + ejabberd_hooks:run_fold( + privacy_get_user_list, StateData#state.server, + none, + [U, StateData#state.server]), {next_state, session_established, StateData#state{sid = SID, pres_f = ?SETS:from_list(Fs1), @@ -950,15 +948,14 @@ handle_info({route, From, To, Packet}, StateName, StateData) -> "unsubscribed" -> {true, Attrs, StateData}; _ -> -%-ifdef(PRIVACY_SUPPORT). - case catch mod_privacy:check_packet( - StateData#state.user, - StateData#state.server, - StateData#state.privacy_list, - {From, To, Packet}, - in) of - {'EXIT', _Reason} -> - {true, Attrs, StateData}; + case ejabberd_hooks:run_fold( + privacy_check_packet, StateData#state.server, + allow, + [StateData#state.user, + StateData#state.server, + StateData#state.privacy_list, + {From, To, Packet}, + in]) of allow -> LFrom = jlib:jid_tolower(From), LBFrom = jlib:jid_remove_resource(LFrom), @@ -994,9 +991,6 @@ handle_info({route, From, To, Packet}, StateName, StateData) -> deny -> {false, Attrs, StateData} end -%-elseif. -% {true, Attrs, StateData} -%-endif. end; "broadcast" -> ?DEBUG("broadcast~n~p~n", [Els]), @@ -1008,28 +1002,30 @@ handle_info({route, From, To, Packet}, StateName, StateData) -> [{exit, Reason}] -> {exit, Attrs, Reason}; [{privacy_list, PrivList, PrivListName}] -> - case catch mod_privacy:updated_list( - StateData#state.privacy_list, - PrivList) of - {'EXIT', _} -> - {false, Attrs, StateData}; - NewPL -> - PrivPushIQ = - #iq{type = set, xmlns = ?NS_PRIVACY, - id = "push", - sub_el = [{xmlelement, "query", - [{"xmlns", ?NS_PRIVACY}], - [{xmlelement, "list", - [{"name", PrivListName}], - []}]}]}, - PrivPushEl = - jlib:replace_from_to( - jlib:jid_remove_resource( - StateData#state.jid), - StateData#state.jid, - jlib:iq_to_xml(PrivPushIQ)), - send_element(StateData, PrivPushEl), - {false, Attrs, StateData#state{privacy_list = NewPL}} + case ejabberd_hooks:run_fold( + privacy_updated_list, StateData#state.server, + false, + [StateData#state.privacy_list, + PrivList]) of + false -> + {false, Attrs, StateData}; + NewPL -> + PrivPushIQ = + #iq{type = set, xmlns = ?NS_PRIVACY, + id = "push", + sub_el = [{xmlelement, "query", + [{"xmlns", ?NS_PRIVACY}], + [{xmlelement, "list", + [{"name", PrivListName}], + []}]}]}, + PrivPushEl = + jlib:replace_from_to( + jlib:jid_remove_resource( + StateData#state.jid), + StateData#state.jid, + jlib:iq_to_xml(PrivPushIQ)), + send_element(StateData, PrivPushEl), + {false, Attrs, StateData#state{privacy_list = NewPL}} end; _ -> {false, Attrs, StateData} @@ -1049,16 +1045,15 @@ handle_info({route, From, To, Packet}, StateName, StateData) -> ejabberd_router:route(To, From, Err) end, {false, Attrs, StateData}; -%-ifdef(PRIVACY_SUPPORT). #iq{} -> - case catch mod_privacy:check_packet( - StateData#state.user, - StateData#state.server, - StateData#state.privacy_list, - {From, To, Packet}, - in) of - {'EXIT', _Reason} -> - {true, Attrs, StateData}; + case ejabberd_hooks:run_fold( + privacy_check_packet, StateData#state.server, + allow, + [StateData#state.user, + StateData#state.server, + StateData#state.privacy_list, + {From, To, Packet}, + in]) of allow -> {true, Attrs, StateData}; deny -> @@ -1067,26 +1062,23 @@ handle_info({route, From, To, Packet}, StateName, StateData) -> ejabberd_router:route(To, From, Err), {false, Attrs, StateData} end; -%-endif. _ -> {true, Attrs, StateData} end; -%-ifdef(PRIVACY_SUPPORT). "message" -> - case catch mod_privacy:check_packet( - StateData#state.user, - StateData#state.server, - StateData#state.privacy_list, - {From, To, Packet}, - in) of - {'EXIT', _Reason} -> - {true, Attrs, StateData}; + case ejabberd_hooks:run_fold( + privacy_check_packet, StateData#state.server, + allow, + [StateData#state.user, + StateData#state.server, + StateData#state.privacy_list, + {From, To, Packet}, + in]) of allow -> {true, Attrs, StateData}; deny -> {false, Attrs, StateData} end; -%-endif. _ -> {true, Attrs, StateData} end, @@ -1252,21 +1244,19 @@ process_presence_probe(From, To, StateData) -> if Cond1 -> Packet = StateData#state.pres_last, -%-ifdef(PRIVACY_SUPPORT). - case catch mod_privacy:check_packet( - StateData#state.user, - StateData#state.server, - StateData#state.privacy_list, - {To, From, Packet}, - out) of + case ejabberd_hooks:run_fold( + privacy_check_packet, StateData#state.server, + allow, + [StateData#state.user, + StateData#state.server, + StateData#state.privacy_list, + {To, From, Packet}, + out]) of deny -> ok; - _ -> -%-endif. + allow -> ejabberd_router:route(To, From, Packet) -%-ifdef(PRIVACY_SUPPORT). end; -%-endif. Cond2 -> ejabberd_router:route(To, From, {xmlelement, "presence", @@ -1420,21 +1410,19 @@ presence_track(From, To, Packet, StateData) -> ejabberd_router:route(From, To, Packet), StateData; _ -> -%-ifdef(PRIVACY_SUPPORT). - case catch mod_privacy:check_packet( - StateData#state.user, - StateData#state.server, - StateData#state.privacy_list, - {From, To, Packet}, - out) of + case ejabberd_hooks:run_fold( + privacy_check_packet, StateData#state.server, + allow, + [StateData#state.user, + StateData#state.server, + StateData#state.privacy_list, + {From, To, Packet}, + out]) of deny -> ok; - _ -> -%-endif. + allow -> ejabberd_router:route(From, To, Packet) -%-ifdef(PRIVACY_SUPPORT). end, -%-endif. I = remove_element(LTo, StateData#state.pres_i), A = ?SETS:add_element(LTo, StateData#state.pres_a), StateData#state{pres_i = I, @@ -1444,21 +1432,19 @@ presence_track(From, To, Packet, StateData) -> presence_broadcast(StateData, From, JIDSet, Packet) -> lists:foreach(fun(JID) -> FJID = jlib:make_jid(JID), -%-ifdef(PRIVACY_SUPPORT). - case catch mod_privacy:check_packet( - StateData#state.user, - StateData#state.server, - StateData#state.privacy_list, - {From, FJID, Packet}, - out) of + case ejabberd_hooks:run_fold( + privacy_check_packet, StateData#state.server, + allow, + [StateData#state.user, + StateData#state.server, + StateData#state.privacy_list, + {From, FJID, Packet}, + out]) of deny -> ok; - _ -> -%-endif. + allow -> ejabberd_router:route(From, FJID, Packet) -%-ifdef(PRIVACY_SUPPORT). end -%-endif. end, ?SETS:to_list(JIDSet)). presence_broadcast_to_trusted(StateData, From, T, A, Packet) -> @@ -1467,21 +1453,19 @@ presence_broadcast_to_trusted(StateData, From, T, A, Packet) -> case ?SETS:is_element(JID, T) of true -> FJID = jlib:make_jid(JID), -%-ifdef(PRIVACY_SUPPORT). - case catch mod_privacy:check_packet( - StateData#state.user, - StateData#state.server, - StateData#state.privacy_list, - {From, FJID, Packet}, - out) of + case ejabberd_hooks:run_fold( + privacy_check_packet, StateData#state.server, + allow, + [StateData#state.user, + StateData#state.server, + StateData#state.privacy_list, + {From, FJID, Packet}, + out]) of deny -> ok; - _ -> -%-endif. + allow -> ejabberd_router:route(From, FJID, Packet) -%-ifdef(PRIVACY_SUPPORT). end; -%-endif. _ -> ok end @@ -1507,21 +1491,19 @@ presence_broadcast_first(From, StateData, Packet) -> As = ?SETS:fold( fun(JID, A) -> FJID = jlib:make_jid(JID), -%-ifdef(PRIVACY_SUPPORT). - case catch mod_privacy:check_packet( - StateData#state.user, - StateData#state.server, - StateData#state.privacy_list, - {From, FJID, Packet}, - out) of + case ejabberd_hooks:run_fold( + privacy_check_packet, StateData#state.server, + allow, + [StateData#state.user, + StateData#state.server, + StateData#state.privacy_list, + {From, FJID, Packet}, + out]) of deny -> ok; - _ -> -%-endif. + allow -> ejabberd_router:route(From, FJID, Packet) -%-ifdef(PRIVACY_SUPPORT). end, -%-endif. ?SETS:add_element(JID, A) end, StateData#state.pres_a, @@ -1571,15 +1553,17 @@ roster_change(IJID, ISubscription, StateData) -> if Cond1 -> ?DEBUG("C1: ~p~n", [LIJID]), - case catch mod_privacy:check_packet( - StateData#state.user, - StateData#state.server, - StateData#state.privacy_list, - {From, To, P}, - out) of + case ejabberd_hooks:run_fold( + privacy_check_packet, StateData#state.server, + allow, + [StateData#state.user, + StateData#state.server, + StateData#state.privacy_list, + {From, To, P}, + out]) of deny -> ok; - _ -> + allow -> ejabberd_router:route(From, To, P) end, A = ?SETS:add_element(LIJID, @@ -1591,15 +1575,17 @@ roster_change(IJID, ISubscription, StateData) -> ?DEBUG("C2: ~p~n", [LIJID]), PU = {xmlelement, "presence", [{"type", "unavailable"}], []}, - case catch mod_privacy:check_packet( - StateData#state.user, - StateData#state.server, - StateData#state.privacy_list, - {From, To, PU}, - out) of + case ejabberd_hooks:run_fold( + privacy_check_packet, StateData#state.server, + allow, + [StateData#state.user, + StateData#state.server, + StateData#state.privacy_list, + {From, To, PU}, + out]) of deny -> ok; - _ -> + allow -> ejabberd_router:route(From, To, PU) end, I = remove_element(LIJID, @@ -1642,20 +1628,16 @@ process_privacy_iq(From, To, {Res, NewStateData} = case Type of get -> - case catch - mod_privacy:process_iq_get( - From, To, IQ, - StateData#state.privacy_list) of - {'EXIT', _} -> - {{error, ?ERR_FEATURE_NOT_IMPLEMENTED}, StateData}; - R -> {R, StateData} - end; + R = ejabberd_hooks:run_fold( + privacy_iq_get, StateData#state.server, + {error, ?ERR_FEATURE_NOT_IMPLEMENTED}, + [From, To, IQ, StateData#state.privacy_list]), + {R, StateData}; set -> - case catch - mod_privacy:process_iq_set( - From, To, IQ) of - {'EXIT', _} -> - {{error, ?ERR_FEATURE_NOT_IMPLEMENTED}, StateData}; + case ejabberd_hooks:run_fold( + privacy_iq_set, StateData#state.server, + {error, ?ERR_FEATURE_NOT_IMPLEMENTED}, + [From, To, IQ]) of {result, R, NewPrivList} -> {{result, R}, StateData#state{privacy_list = NewPrivList}}; @@ -1685,14 +1667,14 @@ resend_offline_messages(#state{user = User, lists:foreach( fun({route, From, To, {xmlelement, Name, Attrs, Els} = Packet}) -> - Pass = case catch mod_privacy:check_packet( - User, - Server, - PrivList, - {From, To, Packet}, - in) of - {'EXIT', _Reason} -> - true; + Pass = case ejabberd_hooks:run_fold( + privacy_check_packet, Server, + allow, + [User, + Server, + PrivList, + {From, To, Packet}, + in]) of allow -> true; deny -> diff --git a/src/mod_privacy.erl b/src/mod_privacy.erl index db2a78693..b201df1e7 100644 --- a/src/mod_privacy.erl +++ b/src/mod_privacy.erl @@ -14,13 +14,12 @@ -export([start/2, stop/1, process_iq/3, - process_iq_set/3, - process_iq_get/4, - get_user_list/2, - check_packet/5, - updated_list/2]). + process_iq_set/4, + process_iq_get/5, + get_user_list/3, + check_packet/6, + updated_list/3]). -%-include_lib("mnemosyne/include/mnemosyne.hrl"). -include("ejabberd.hrl"). -include("jlib.hrl"). @@ -47,37 +46,38 @@ start(Host, Opts) -> mnesia:create_table(privacy, [{disc_copies, [node()]}, {attributes, record_info(fields, privacy)}]), update_table(), + 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) -> - #iq{type = Type, sub_el = SubEl} = IQ, - #jid{lserver = Server} = From, - Res = - case ?MYNAME of - Server -> - case Type of - set -> - %process_iq_set(From, To, IQ); - {error, ?ERR_NOT_ALLOWED}; - get -> - {error, ?ERR_NOT_ALLOWED} - end; - _ -> - {error, ?ERR_NOT_ALLOWED} - end, - case Res of - {result, IQRes} -> - IQ#iq{type = result, sub_el = IQRes}; - {error, Error} -> - IQ#iq{type = error, sub_el = [SubEl, Error]} - end. +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}, +process_iq_get(_, From, _To, #iq{sub_el = SubEl}, #userlist{name = Active}) -> #jid{luser = LUser, lserver = LServer} = From, {xmlelement, _, _, Els} = SubEl, @@ -242,7 +242,7 @@ list_to_action(S) -> -process_iq_set(From, _To, #iq{sub_el = SubEl}) -> +process_iq_set(_, From, _To, #iq{sub_el = SubEl}) -> #jid{luser = LUser, lserver = LServer} = From, {xmlelement, _, _, Els} = SubEl, case xml:remove_cdata(Els) of @@ -517,7 +517,7 @@ parse_matches1(_Item, [{xmlelement, _, _, _} | _Els]) -> -get_user_list(User, Server) -> +get_user_list(_, User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), case catch mnesia:dirty_read(privacy, {LUser, LServer}) of @@ -541,7 +541,7 @@ get_user_list(User, Server) -> end. -check_packet(User, Server, +check_packet(_, User, Server, #userlist{list = List}, {From, To, {xmlelement, PName, _, _}}, Dir) -> @@ -662,7 +662,8 @@ is_type_match(Type, Value, JID, Subscription, Groups) -> end. -updated_list(#userlist{name = OldName} = Old, +updated_list(_, + #userlist{name = OldName} = Old, #userlist{name = NewName} = New) -> if OldName == NewName -> diff --git a/src/odbc/pg.sql b/src/odbc/pg.sql index 32f20fdd0..9246c591b 100644 --- a/src/odbc/pg.sql +++ b/src/odbc/pg.sql @@ -91,6 +91,28 @@ CREATE INDEX i_vcard_search_lemail ON vcard_search(lemail); CREATE INDEX i_vcard_search_lorgname ON vcard_search(lorgname); CREATE INDEX i_vcard_search_lorgunit ON vcard_search(lorgunit); +CREATE TABLE privacy_default_list ( + username text PRIMARY KEY, + name text NOT NULL +); + +CREATE TABLE privacy_list ( + username text NOT NULL, + name text NOT NULL, + type character(1) NOT NULL, + value text NOT NULL, + action character(1) NOT NULL, + ord NUMERIC NOT NULL, + match_all boolean NOT NULL, + match_iq boolean NOT NULL, + match_message boolean NOT NULL, + match_presence_in boolean NOT NULL, + match_presence_out boolean NOT NULL +); + +CREATE INDEX i_privacy_list_username ON privacy_list USING btree (username); + + --- To update from 0.9.8: -- CREATE SEQUENCE spool_seq_seq; -- ALTER TABLE spool ADD COLUMN seq integer;