diff options
author | Mickaël Rémond <mickael.remond@process-one.net> | 2007-08-03 08:53:05 +0000 |
---|---|---|
committer | Mickaël Rémond <mickael.remond@process-one.net> | 2007-08-03 08:53:05 +0000 |
commit | c72cb51c7308e74c2a93b069654434662daa657d (patch) | |
tree | 13bbf1f07a84e2d9bc29c9e608f9f5e6c432c578 | |
parent | * src/mod_muc/mod_muc.erl: Added default_room_options option (diff) |
* src/mod_announce.erl: Added support to all the announce features described in documentation. Access to all announce features through command line, adhoc commands and disco (Thanks to Badlop) (EJAB-18).
* src/gen_mod.erl: Likewise.
* doc/guide.tex: Likewise.
SVN Revision: 858
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | doc/guide.html | 6 | ||||
-rw-r--r-- | doc/guide.tex | 8 | ||||
-rw-r--r-- | src/gen_mod.erl | 17 | ||||
-rw-r--r-- | src/mod_announce.erl | 163 |
5 files changed, 180 insertions, 23 deletions
@@ -1,3 +1,12 @@ +2007-08-03 Mickael Remond <mickael.remond@process-one.net> + + * src/mod_announce.erl: Added support to all the announce features + described in documentation. Access to all announce features + through command line, adhoc commands and disco (Thanks to + Badlop) (EJAB-18). + * src/gen_mod.erl: Likewise. + * doc/guide.tex: Likewise. + 2007-08-02 Alexey Shchepin <alexey@sevcom.net> * src/mod_muc/mod_muc.erl: Added default_room_options option diff --git a/doc/guide.html b/doc/guide.html index a61d0893c..8012e5b76 100644 --- a/doc/guide.html +++ b/doc/guide.html @@ -1410,7 +1410,7 @@ with: <A NAME="modannounce"></A> </P><P>This module enables configured users to broadcast announcements and to set the message of the day (MOTD). Configured users can do these actions with their -Jabber client by sending messages to specific JIDs. These JIDs are listed in +Jabber client using Ad-hoc commands or by sending messages to specific JIDs. These JIDs are listed in next paragraph. The first JID in each entry will apply only to the virtual host <TT>example.org</TT>, while the JID between brackets will apply to all virtual hosts: @@ -1463,7 +1463,9 @@ Only administrators can send announcements: {mod_announce, [{access, announce}]}, ... ]}. -</PRE></LI></UL><!--TOC subsection <TT>mod_disco</TT>--> +</PRE></LI></UL><P>Note that <TT>mod_announce</TT> can be resource intensive on large +deployments as it can broadcast lot of messages. This module should be +disabled for instances of ejabberd with hundreds of thousands users.</P><!--TOC subsection <TT>mod_disco</TT>--> <H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc33">3.3.4</A>  <TT>mod_disco</TT></H3><!--SEC END --><P> <A NAME="moddisco"></A> </P><P>This module adds support for Service Discovery (<A HREF="http://www.xmpp.org/extensions/xep-0030.html">XEP-0030</A>). With diff --git a/doc/guide.tex b/doc/guide.tex index 8d8c1f0d8..ed608075b 100644 --- a/doc/guide.tex +++ b/doc/guide.tex @@ -1744,7 +1744,7 @@ Examples: This module enables configured users to broadcast announcements and to set the message of the day (MOTD). Configured users can do these actions with their -\Jabber{} client by sending messages to specific JIDs. These JIDs are listed in +\Jabber{} client using Ad-hoc commands or by sending messages to specific JIDs. These JIDs are listed in next paragraph. The first JID in each entry will apply only to the virtual host \jid{example.org}, while the JID between brackets will apply to all virtual hosts: @@ -1790,7 +1790,7 @@ Examples: ]}. \end{verbatim} \item Administrators as well as the direction can send announcements: - \begin{verbatim} +\begin{verbatim} {acl, direction, {user, "big_boss", "example.org"}}. {acl, direction, {user, "assistant", "example.org"}}. {acl, admins, {user, "admin", "example.org"}}. @@ -1807,6 +1807,10 @@ Examples: \end{verbatim} \end{itemize} +Note that \modannounce{} can be resource intensive on large +deployments as it can broadcast lot of messages. This module should be +disabled for instances of ejabberd with hundreds of thousands users. + \subsection{\moddisco{}} \label{moddisco} \ind{modules!\moddisco{}}\ind{protocols!XEP-0030: Service Discovery}\ind{protocols!XEP-0011: Jabber Browsing}\ind{protocols!XEP-0094: Agent Information} diff --git a/src/gen_mod.erl b/src/gen_mod.erl index 7ba6db182..eed3e4405 100644 --- a/src/gen_mod.erl +++ b/src/gen_mod.erl @@ -107,6 +107,23 @@ get_opt(Opt, Opts, Default) -> Val end. +get_module_opt(global, Module, Opt, Default) -> + Hosts = ?MYHOSTS, + [Value | Values] = lists:map( + fun(Host) -> + get_module_opt(Host, Module, Opt, Default) + end, + Hosts), + Same_all = lists:all( + fun(Other_value) -> + Other_value == Value + end, + Values), + case Same_all of + true -> Value; + false -> Default + end; + get_module_opt(Host, Module, Opt, Default) -> OptsList = ets:lookup(ejabberd_modules, {Module, Host}), case OptsList of diff --git a/src/mod_announce.erl b/src/mod_announce.erl index 8cabf748a..deccafcb0 100644 --- a/src/mod_announce.erl +++ b/src/mod_announce.erl @@ -57,6 +57,9 @@ loop() -> {announce_all, From, To, Packet} -> announce_all(From, To, Packet), loop(); + {announce_all_hosts_all, From, To, Packet} -> + announce_all_hosts_all(From, To, Packet), + loop(); {announce_online, From, To, Packet} -> announce_online(From, To, Packet), loop(); @@ -66,12 +69,21 @@ loop() -> {announce_motd, From, To, Packet} -> announce_motd(From, To, Packet), loop(); + {announce_all_hosts_motd, From, To, Packet} -> + announce_all_hosts_motd(From, To, Packet), + loop(); {announce_motd_update, From, To, Packet} -> announce_motd_update(From, To, Packet), loop(); + {announce_all_hosts_motd_update, From, To, Packet} -> + announce_all_hosts_motd_update(From, To, Packet), + loop(); {announce_motd_delete, From, To, Packet} -> announce_motd_delete(From, To, Packet), loop(); + {announce_all_hosts_motd_delete, From, To, Packet} -> + announce_all_hosts_motd_delete(From, To, Packet), + loop(); _ -> loop() end. @@ -100,6 +112,9 @@ announce(From, To, Packet) -> {"announce/all", "message"} -> Proc ! {announce_all, From, To, Packet}, stop; + {"announce/all-hosts/all", "message"} -> + Proc ! {announce_all_hosts_all, From, To, Packet}, + stop; {"announce/online", "message"} -> Proc ! {announce_online, From, To, Packet}, stop; @@ -109,12 +124,21 @@ announce(From, To, Packet) -> {"announce/motd", "message"} -> Proc ! {announce_motd, From, To, Packet}, stop; + {"announce/all-hosts/motd", "message"} -> + Proc ! {announce_all_hosts_motd, From, To, Packet}, + stop; {"announce/motd/update", "message"} -> Proc ! {announce_motd_update, From, To, Packet}, stop; + {"announce/all-hosts/motd/update", "message"} -> + Proc ! {announce_all_hosts_motd_update, From, To, Packet}, + stop; {"announce/motd/delete", "message"} -> Proc ! {announce_motd_delete, From, To, Packet}, stop; + {"announce/all-hosts/motd/delete", "message"} -> + Proc ! {announce_all_hosts_motd_delete, From, To, Packet}, + stop; _ -> ok end; @@ -134,16 +158,24 @@ disco_identity(Acc, _From, _To, Node, Lang) -> case Node of "announce/all" -> ?INFO_COMMAND(Lang, Node); - "announce/all-hosts/online" -> + "announce/all-hosts/all" -> ?INFO_COMMAND(Lang, Node); "announce/online" -> ?INFO_COMMAND(Lang, Node); + "announce/all-hosts/online" -> + ?INFO_COMMAND(Lang, Node); "announce/motd" -> ?INFO_COMMAND(Lang, Node); + "announce/all-hosts/motd" -> + ?INFO_COMMAND(Lang, Node); "announce/motd/delete" -> ?INFO_COMMAND(Lang, Node); + "announce/all-hosts/motd/delete" -> + ?INFO_COMMAND(Lang, Node); "announce/motd/update" -> ?INFO_COMMAND(Lang, Node); + "announce/all-hosts/motd/update" -> + ?INFO_COMMAND(Lang, Node); _ -> Acc end. @@ -176,7 +208,12 @@ disco_features(Acc, From, #jid{lserver = LServer} = _To, end; disco_features(Acc, From, #jid{lserver = LServer} = _To, - "announce/all-hosts/online", _Lang) -> + Node, _Lang) + when (Node == "announce/all-hosts/online") + or (Node == "announce/all-hosts/all") + or (Node == "announce/all-hosts/motd") + or (Node == "announce/all-hosts/motd/update") + or (Node == "announce/all-hosts/motd/delete") -> case gen_mod:is_loaded(LServer, mod_adhoc) of false -> Acc; @@ -257,8 +294,12 @@ disco_items(Acc, From, #jid{lserver = LServer} = To, "announce", Lang) -> announce_items(Acc, From, To, Lang) end; -disco_items(Acc, From, #jid{lserver = LServer} = _To, - "announce/all-hosts/online", _Lang) -> +disco_items(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) + when (Node == "announce/all-hosts/online") + or (Node == "announce/all-hosts/all") + or (Node == "announce/all-hosts/motd") + or (Node == "announce/all-hosts/motd/update") + or (Node == "announce/all-hosts/motd/delete") -> case gen_mod:is_loaded(LServer, mod_adhoc) of false -> Acc; @@ -308,7 +349,11 @@ announce_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, Lang) Access2 = gen_mod:get_module_opt(global, ?MODULE, access, none), Nodes2 = case acl:match_rule(global, Access2, From) of allow -> - [?NODE_TO_ITEM(Lang, Server, "announce/all-hosts/online")]; + [?NODE_TO_ITEM(Lang, Server, "announce/all-hosts/all"), + ?NODE_TO_ITEM(Lang, Server, "announce/all-hosts/online"), + ?NODE_TO_ITEM(Lang, Server, "announce/all-hosts/motd"), + ?NODE_TO_ITEM(Lang, Server, "announce/all-hosts/motd/update"), + ?NODE_TO_ITEM(Lang, Server, "announce/all-hosts/motd/delete")]; deny -> [] end, @@ -335,7 +380,12 @@ announce_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, Lang) announce_commands(_Acc, From, To, #adhoc_request{ - node = "announce/all-hosts/online"} = Request) -> + node = Node} = Request) + when (Node == "announce/all-hosts/online") + or (Node == "announce/all-hosts/all") + or (Node == "announce/all-hosts/motd") + or (Node == "announce/all-hosts/motd/update") + or (Node == "announce/all-hosts/motd/delete") -> Access = gen_mod:get_module_opt(global, ?MODULE, access, none), Allow = acl:match_rule(global, Access, From), ?COMMANDS_RESULT(Allow, From, To, Request); @@ -400,7 +450,8 @@ generate_adhoc_form(Lang, Node) -> {"type", "form"}], [{xmlelement, "title", [], [{xmlcdata, get_title(Lang, Node)}]}] ++ - if Node == "announce/motd/delete" -> + if (Node == "announce/motd/delete") + or (Node == "announce/all-hosts/motd/delete") -> [{xmlelement, "field", [{"var", "confirm"}, {"type", "boolean"}, @@ -485,6 +536,13 @@ handle_adhoc_form(From, #jid{lserver = LServer} = To, true -> adhoc:produce_response(Response) end; + {"announce/all-hosts/motd/delete", _} -> + if Confirm -> + Proc ! {announce_all_hosts_motd_delete, From, To, Packet}, + adhoc:produce_response(Response); + true -> + adhoc:produce_response(Response) + end; {_, []} -> %% An announce message with no body is definitely an operator error. %% Throw an error and give him/her a chance to send message again. @@ -497,6 +555,9 @@ handle_adhoc_form(From, #jid{lserver = LServer} = To, {"announce/all", _} -> Proc ! {announce_all, From, To, Packet}, adhoc:produce_response(Response); + {"announce/all-hosts/all", _} -> + Proc ! {announce_all_hosts_all, From, To, Packet}, + adhoc:produce_response(Response); {"announce/online", _} -> Proc ! {announce_online, From, To, Packet}, adhoc:produce_response(Response); @@ -506,9 +567,15 @@ handle_adhoc_form(From, #jid{lserver = LServer} = To, {"announce/motd", _} -> Proc ! {announce_motd, From, To, Packet}, adhoc:produce_response(Response); + {"announce/all-hosts/motd", _} -> + Proc ! {announce_all_hosts_motd, From, To, Packet}, + adhoc:produce_response(Response); {"announce/motd/update", _} -> Proc ! {announce_motd_update, From, To, Packet}, adhoc:produce_response(Response); + {"announce/all-hosts/motd/update", _} -> + Proc ! {announce_all_hosts_motd_update, From, To, Packet}, + adhoc:produce_response(Response); _ -> %% This can't happen, as we haven't registered any other %% command nodes. @@ -519,16 +586,24 @@ get_title(Lang, "announce") -> translate:translate(Lang, "Announcements"); get_title(Lang, "announce/all") -> translate:translate(Lang, "Send announcement to all users"); +get_title(Lang, "announce/all-hosts/all") -> + translate:translate(Lang, "Send announcement to all users on all hosts"); get_title(Lang, "announce/online") -> translate:translate(Lang, "Send announcement to all online users"); get_title(Lang, "announce/all-hosts/online") -> translate:translate(Lang, "Send announcement to all online users on all hosts"); get_title(Lang, "announce/motd") -> translate:translate(Lang, "Set message of the day and send to online users"); +get_title(Lang, "announce/all-hosts/motd") -> + translate:translate(Lang, "Set message of the day on all hosts and send to online users"); get_title(Lang, "announce/motd/update") -> translate:translate(Lang, "Update message of the day (don't send)"); +get_title(Lang, "announce/all-hosts/motd/update") -> + translate:translate(Lang, "Update message of the day on all hosts (don't send)"); get_title(Lang, "announce/motd/delete") -> - translate:translate(Lang, "Delete message of the day"). + translate:translate(Lang, "Delete message of the day"); +get_title(Lang, "announce/all-hosts/motd/delete") -> + translate:translate(Lang, "Delete message of the day on all hosts"). %------------------------------------------------------------------------- @@ -548,6 +623,21 @@ announce_all(From, To, Packet) -> end, ejabberd_auth:get_vh_registered_users(Host)) end. +announce_all_hosts_all(From, To, Packet) -> + Access = gen_mod:get_module_opt(global, ?MODULE, access, none), + case acl:match_rule(global, Access, From) of + deny -> + Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), + ejabberd_router:route(To, From, Err); + allow -> + Local = jlib:make_jid("", To#jid.server, ""), + lists:foreach( + fun({User, Server}) -> + Dest = jlib:make_jid(User, Server, ""), + ejabberd_router:route(Local, Dest, Packet) + end, ejabberd_auth:dirty_get_registered_users()) + end. + announce_online(From, To, Packet) -> Host = To#jid.lserver, Access = gen_mod:get_module_opt(Host, ?MODULE, access, none), @@ -589,18 +679,32 @@ announce_motd(From, To, Packet) -> Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), ejabberd_router:route(To, From, Err); allow -> - announce_motd_update(To#jid.lserver, Packet), - Sessions = ejabberd_sm:get_vh_session_list(Host), - announce_online1(Sessions, To#jid.server, Packet), - F = fun() -> - lists:foreach( - fun({U, S, _R}) -> - mnesia:write(#motd_users{us = {U, S}}) - end, Sessions) - end, - mnesia:transaction(F) + announce_motd(Host, Packet) + end. + +announce_all_hosts_motd(From, To, Packet) -> + Access = gen_mod:get_module_opt(global, ?MODULE, access, none), + case acl:match_rule(global, Access, From) of + deny -> + Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), + ejabberd_router:route(To, From, Err); + allow -> + Hosts = ?MYHOSTS, + [announce_motd(Host, Packet) || Host <- Hosts] end. +announce_motd(Host, Packet) -> + announce_motd_update(Host, Packet), + Sessions = ejabberd_sm:get_vh_session_list(Host), + announce_online1(Sessions, Host, Packet), + F = fun() -> + lists:foreach( + fun({U, S, _R}) -> + mnesia:write(#motd_users{us = {U, S}}) + end, Sessions) + end, + mnesia:transaction(F). + announce_motd_update(From, To, Packet) -> Host = To#jid.lserver, Access = gen_mod:get_module_opt(Host, ?MODULE, access, none), @@ -612,6 +716,17 @@ announce_motd_update(From, To, Packet) -> announce_motd_update(Host, Packet) end. +announce_all_hosts_motd_update(From, To, Packet) -> + Access = gen_mod:get_module_opt(global, ?MODULE, access, none), + case acl:match_rule(global, Access, From) of + deny -> + Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), + ejabberd_router:route(To, From, Err); + allow -> + Hosts = ?MYHOSTS, + [announce_motd_update(Host, Packet) || Host <- Hosts] + end. + announce_motd_update(LServer, Packet) -> announce_motd_delete(LServer), F = fun() -> @@ -630,6 +745,17 @@ announce_motd_delete(From, To, Packet) -> announce_motd_delete(Host) end. +announce_all_hosts_motd_delete(From, To, Packet) -> + Access = gen_mod:get_module_opt(global, ?MODULE, access, none), + case acl:match_rule(global, Access, From) of + deny -> + Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), + ejabberd_router:route(To, From, Err); + allow -> + Hosts = ?MYHOSTS, + [announce_motd_delete(Host) || Host <- Hosts] + end. + announce_motd_delete(LServer) -> F = fun() -> mnesia:delete({motd, LServer}), @@ -754,4 +880,3 @@ update_motd_users_table() -> ?INFO_MSG("Recreating motd_users table", []), mnesia:transform_table(motd_users, ignore, Fields) end. - |