diff options
author | Alexey Shchepin <alexey@process-one.net> | 2004-08-12 22:34:19 +0000 |
---|---|---|
committer | Alexey Shchepin <alexey@process-one.net> | 2004-08-12 22:34:19 +0000 |
commit | d77a936b322220a67e703525ff585660ea8da670 (patch) | |
tree | 69c3cb1dfd199de6f78884f1e3db9a991958c42e /src | |
parent | * src/ejabberd_c2s.erl: Use resend_offline_messages_hook to fetch (diff) |
* src/ejabberd_c2s.erl: Bugfix in resend_offline_messages/1
* src/mod_announce.erl: New module to manage announce messages
(thanks to Sergei Golovan)
* src/ejabberd_local.erl: Moved processing of announce messages to
mod_announce (thanks to Sergei Golovan)
* src/ejabberd_c2s.erl: Added several hooks
* src/ejabberd_hooks.erl: Fixed run_fold (thanks to Sergei
Golovan)
* src/ejabberd.cfg.example: Updated (thanks to Sergei Golovan)
* doc/guide.tex: Updated (thanks to Sergei Golovan)
SVN Revision: 256
Diffstat (limited to 'src')
-rw-r--r-- | src/cyrsasl_digest.erl | 4 | ||||
-rw-r--r-- | src/ejabberd.cfg.example | 1 | ||||
-rw-r--r-- | src/ejabberd_c2s.erl | 48 | ||||
-rw-r--r-- | src/ejabberd_hooks.erl | 2 | ||||
-rw-r--r-- | src/ejabberd_local.erl | 33 | ||||
-rw-r--r-- | src/mod_announce.erl | 178 |
6 files changed, 231 insertions, 35 deletions
diff --git a/src/cyrsasl_digest.erl b/src/cyrsasl_digest.erl index ae94c181f..2e5e94e5a 100644 --- a/src/cyrsasl_digest.erl +++ b/src/cyrsasl_digest.erl @@ -51,7 +51,7 @@ mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) -> AuthzId = xml:get_attr_s("authzid", KeyVals), case ejabberd_auth:get_password(UserName) of false -> - {error, "no-user"}; + {error, "not-authorized"}; Passwd -> Response = response(KeyVals, UserName, Passwd, Nonce, AuthzId, "AUTHENTICATE"), @@ -66,7 +66,7 @@ mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) -> username = UserName, authzid = AuthzId}}; _ -> - {error, "bad-auth"} + {error, "not-authorized"} end end end; diff --git a/src/ejabberd.cfg.example b/src/ejabberd.cfg.example index 82e1cc43c..253752f53 100644 --- a/src/ejabberd.cfg.example +++ b/src/ejabberd.cfg.example @@ -121,6 +121,7 @@ {mod_stats, []}, {mod_vcard, []}, {mod_offline, []}, + {mod_announce, [{access, announce}]}, {mod_echo, [{host, "echo.localhost"}]}, {mod_private, []}, {mod_irc, []}, diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 844e7bcfb..d8021606f 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -673,12 +673,17 @@ session_established({xmlstreamelement, El}, StateData) -> process_privacy_iq( FromJID, ToJID, IQ, StateData); _ -> + ejabberd_hooks:run( + user_send_packet, + [FromJID, ToJID, NewEl]), ejabberd_router:route( FromJID, ToJID, NewEl), StateData end end; "message" -> + ejabberd_hooks:run(user_send_packet, + [FromJID, ToJID, NewEl]), ejabberd_router:route(FromJID, ToJID, NewEl), StateData; _ -> @@ -882,8 +887,11 @@ handle_info({route, From, To, Packet}, StateName, StateData) -> Attrs2 = jlib:replace_from_to_attrs(jlib:jid_to_string(From), jlib:jid_to_string(To), NewAttrs), - Text = xml:element_to_string({xmlelement, Name, Attrs2, Els}), + FixedPacket = {xmlelement, Name, Attrs2, Els}, + Text = xml:element_to_string(FixedPacket), send_text(StateData, Text), + ejabberd_hooks:run(user_receive_packet, + [StateData#state.jid, From, To, FixedPacket]), {next_state, StateName, NewState}; true -> {next_state, StateName, NewState} @@ -1102,6 +1110,8 @@ presence_update(From, Packet, StateData) -> NewState = if FromUnavail -> + ejabberd_hooks:run(user_available_hook, + [StateData#state.jid]), resend_offline_messages(StateData), presence_broadcast_first( From, StateData#state{pres_last = Packet, @@ -1385,17 +1395,37 @@ process_privacy_iq(From, To, NewStateData. -resend_offline_messages(StateData) -> +resend_offline_messages(#state{user = User, + privacy_list = PrivList} = StateData) -> case ejabberd_hooks:run_fold(resend_offline_messages_hook, [], - [StateData#state.user]) of + [User]) of Rs when list(Rs) -> lists:foreach( - fun({route, From, To, {xmlelement, Name, Attrs, Els}}) -> - Attrs2 = jlib:replace_from_to_attrs( - jlib:jid_to_string(From), - jlib:jid_to_string(To), - Attrs), - send_element(StateData, {xmlelement, Name, Attrs2, Els}) + fun({route, + From, To, {xmlelement, Name, Attrs, Els} = Packet}) -> + Pass = case catch mod_privacy:check_packet( + User, + PrivList, + {From, To, Packet}, + in) of + {'EXIT', _Reason} -> + true; + allow -> + true; + deny -> + false + end, + if + Pass -> + Attrs2 = jlib:replace_from_to_attrs( + jlib:jid_to_string(From), + jlib:jid_to_string(To), + Attrs), + send_element(StateData, + {xmlelement, Name, Attrs2, Els}); + true -> + ok + end end, Rs) end. diff --git a/src/ejabberd_hooks.erl b/src/ejabberd_hooks.erl index c00035b41..d316fae89 100644 --- a/src/ejabberd_hooks.erl +++ b/src/ejabberd_hooks.erl @@ -55,7 +55,7 @@ run_fold(Hook, Val, Args) -> [{_, Ls}] -> run_fold1(Ls, Hook, Val, Args); [] -> - ok + Val end. %%%---------------------------------------------------------------------- diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl index 446ec292b..5da4cfaa1 100644 --- a/src/ejabberd_local.erl +++ b/src/ejabberd_local.erl @@ -15,7 +15,8 @@ -export([register_iq_handler/3, register_iq_handler/4, unregister_iq_handler/1, - refresh_iq_handlers/0 + refresh_iq_handlers/0, + bounce_resource_packet/3 ]). -include("ejabberd.hrl"). @@ -32,6 +33,8 @@ init() -> MyDomain = ?MYNAME, ejabberd_router:register_route(MyDomain), catch ets:new(local_iqtable, [named_table, public]), + ejabberd_hooks:add(local_send_to_resource_hook, + ?MODULE, bounce_resource_packet, 100), loop(#state{mydomain = MyDomain, iqtable = local_iqtable}). @@ -104,14 +107,8 @@ do_route(State, From, To, Packet) -> "error" -> ok; "result" -> ok; _ -> - case {Res, Name} of - {"announce/online", "message"} -> - announce_online(From, To, Packet); - _ -> - Err = jlib:make_error_reply( - Packet, ?ERR_ITEM_NOT_FOUND), - ejabberd_router:route(To, From, Err) - end + ejabberd_hooks:run(local_send_to_resource_hook, + [From, To, Packet]) end; _ -> ejabberd_sm ! {route, From, To, Packet} @@ -159,17 +156,7 @@ unregister_iq_handler(XMLNS) -> refresh_iq_handlers() -> ejabberd_local ! refresh_iq_handlers. -announce_online(From, To, Packet) -> - case acl:match_rule(announce, From) of - deny -> - Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED), - ejabberd_router:route(To, From, Err); - allow -> - Local = jlib:make_jid("", ?MYNAME, ""), - lists:foreach( - fun({U, R}) -> - Dest = jlib:make_jid(U, ?MYNAME, R), - ejabberd_router:route(Local, Dest, Packet) - end, ejabberd_sm:dirty_get_sessions_list()) - end. - +bounce_resource_packet(From, To, Packet) -> + Err = jlib:make_error_reply(Packet, ?ERR_ITEM_NOT_FOUND), + ejabberd_router:route(To, From, Err), + stop. diff --git a/src/mod_announce.erl b/src/mod_announce.erl new file mode 100644 index 000000000..29ac65e87 --- /dev/null +++ b/src/mod_announce.erl @@ -0,0 +1,178 @@ +%%%---------------------------------------------------------------------- +%%% File : mod_announce.erl +%%% Author : Alexey Shchepin <alexey@sevcom.net> +%%% Purpose : Manage announce messages +%%% Created : 11 Aug 2003 by Alexey Shchepin <alexey@sevcom.net> +%%% Id : $Id$ +%%%---------------------------------------------------------------------- + +-module(mod_announce). +-author('alexey@sevcom.net'). + +-behaviour(gen_mod). + +-export([start/1, + init/0, + stop/0, + announce/3, + send_motd/1]). + +-include("ejabberd.hrl"). +-include("jlib.hrl"). + +-record(motd, {id, packet}). +-record(motd_users, {luser, dummy = []}). + +-define(PROCNAME, ejabberd_announce). + +start(_) -> + mnesia:create_table(motd, [{disc_copies, [node()]}, + {attributes, record_info(fields, motd)}]), + mnesia:create_table(motd_users, [{disc_copies, [node()]}, + {attributes, record_info(fields, motd_users)}]), + ejabberd_hooks:add(local_send_to_resource_hook, + ?MODULE, announce, 50), + ejabberd_hooks:add(user_available_hook, + ?MODULE, send_motd, 50), + register(?PROCNAME, proc_lib:spawn(?MODULE, init, [])). + +init() -> + loop(). + +loop() -> + receive + {announce_online, From, To, Packet} -> + announce_online(From, To, Packet), + loop(); + {announce_motd, From, To, Packet} -> + announce_motd(From, To, Packet), + loop(); + {announce_motd_update, From, To, Packet} -> + announce_motd_update(From, To, Packet), + loop(); + {announce_motd_delete, From, To, Packet} -> + announce_motd_delete(From, To, Packet), + loop(); + _ -> + loop() + end. + +stop() -> + ejabberd_hooks:delete(local_send_to_resource_hook, + ?MODULE, announce, 50), + ejabberd_hooks:delete(sm_register_connection_hook, + ?MODULE, send_motd, 50), + exit(whereis(?PROCNAME), stop), + ok. + +announce(From, To, Packet) -> + case To of + #jid{luser = "", lresource = Res} -> + {xmlelement, Name, _Attrs, _Els} = Packet, + case {Res, Name} of + {"announce/online", "message"} -> + ?PROCNAME ! {announce_online, From, To, Packet}, + stop; + {"announce/motd", "message"} -> + ?PROCNAME ! {announce_motd, From, To, Packet}, + stop; + {"announce/motd/update", "message"} -> + ?PROCNAME ! {announce_motd_update, From, To, Packet}, + stop; + {"announce/motd/delete", "message"} -> + ?PROCNAME ! {announce_motd_delete, From, To, Packet}, + stop; + _ -> + ok + end; + _ -> + ok + end. + +announce_online(From, To, Packet) -> + Access = gen_mod:get_module_opt(?MODULE, access, none), + case acl:match_rule(Access, From) of + deny -> + Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED), + ejabberd_router:route(To, From, Err); + allow -> + announce_online1(ejabberd_sm:dirty_get_sessions_list(), Packet) + end. + +announce_online1(Sessions, Packet) -> + Server = ?MYNAME, + Local = jlib:make_jid("", Server, ""), + lists:foreach( + fun({U, R}) -> + Dest = jlib:make_jid(U, Server, R), + ejabberd_router:route(Local, Dest, Packet) + end, Sessions). + +announce_motd(From, To, Packet) -> + Access = gen_mod:get_module_opt(?MODULE, access, none), + case acl:match_rule(Access, From) of + deny -> + Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED), + ejabberd_router:route(To, From, Err); + allow -> + announce_motd_update(Packet), + Sessions = ejabberd_sm:dirty_get_sessions_list(), + announce_online1(Sessions, Packet), + F = fun() -> + lists:foreach( + fun({U, _R}) -> + mnesia:write(#motd_users{luser = U}) + end, Sessions) + end, + mnesia:transaction(F) + end. + +announce_motd_update(From, To, Packet) -> + Access = gen_mod:get_module_opt(?MODULE, access, none), + case acl:match_rule(Access, From) of + deny -> + Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED), + ejabberd_router:route(To, From, Err); + allow -> + announce_motd_update(Packet) + end. + +announce_motd_update(Packet) -> + announce_motd_delete(), + F = fun() -> + mnesia:write(#motd{id = motd, packet = Packet}) + end, + mnesia:transaction(F). + +announce_motd_delete(From, To, Packet) -> + Access = gen_mod:get_module_opt(?MODULE, access, none), + case acl:match_rule(Access, From) of + deny -> + Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED), + ejabberd_router:route(To, From, Err); + allow -> + announce_motd_delete() + end. + +announce_motd_delete() -> + mnesia:clear_table(motd), + mnesia:clear_table(motd_users). + +send_motd(#jid{luser = LUser} = JID) -> + case catch mnesia:dirty_read({motd, motd}) of + [#motd{packet = Packet}] -> + case catch mnesia:dirty_read({motd_users, LUser}) of + [#motd_users{}] -> + ok; + _ -> + Local = jlib:make_jid("", ?MYNAME, ""), + ejabberd_router:route(Local, JID, Packet), + F = fun() -> + mnesia:write(#motd_users{luser = LUser}) + end, + mnesia:transaction(F) + end; + _ -> + ok + end. + |