diff --git a/ChangeLog b/ChangeLog index 8f63ca567..a982a99e0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2008-06-13 Badlop + * src/mod_muc/mod_muc_room.erl: Allow admins to send messages to + rooms even if not joined (EJAB-645) + * doc/guide.tex: Likewise + * doc/guide.html: Likewise + * src/ejabberd.cfg.example: Add registration_timeout (EJAB-653) * doc/guide.tex: Table of listener modules converted to diff --git a/doc/guide.html b/doc/guide.html index 23a4703d9..b94c65959 100644 --- a/doc/guide.html +++ b/doc/guide.html @@ -1922,9 +1922,11 @@ allowed to modify the ’persistent’ chatroom option
access_admin
This option specifies who is allowed to administrate the Multi-User Chat service (the default value is none, which means that only the room creator can -administer his room). By sending a message to the service JID, -administrators can send service messages that will be displayed in every -active room. +administer his room). +The administrators can send a normal message to the service JID, +and it will be shown in every active room as a service message. +The administrators can send a groupchat message to the JID of an active room, +and the message will be shown in the room as a service message.
history_size
A small history of the current discussion is sent to users when they enter the room. With this option you can define the number of history messages diff --git a/doc/guide.tex b/doc/guide.tex index 7612c9a29..73d889fc5 100644 --- a/doc/guide.tex +++ b/doc/guide.tex @@ -2522,9 +2522,11 @@ Module options: \titem{access\_admin} \ind{options!access\_admin}This option specifies who is allowed to administrate the Multi-User Chat service (the default value is \term{none}, which means that only the room creator can - administer his room). By sending a message to the service JID, - administrators can send service messages that will be displayed in every - active room. + administer his room). + The administrators can send a normal message to the service JID, + and it will be shown in every active room as a service message. + The administrators can send a groupchat message to the JID of an active room, + and the message will be shown in the room as a service message. \titem{history\_size} \ind{options!history\_size}A small history of the current discussion is sent to users when they enter the room. With this option you can define the number of history messages diff --git a/src/mod_muc/mod_muc_room.erl b/src/mod_muc/mod_muc_room.erl index 91da61e2b..e858d680f 100644 --- a/src/mod_muc/mod_muc_room.erl +++ b/src/mod_muc/mod_muc_room.erl @@ -204,7 +204,8 @@ normal_state({route, From, "", {xmlelement, "message", Attrs, Els} = Packet}, StateData) -> Lang = xml:get_attr_s("xml:lang", Attrs), - case is_user_online(From, StateData) of + case is_user_online(From, StateData) orelse + is_user_allowed_message_nonparticipant(From, StateData) of true -> case xml:get_attr_s("type", Attrs) of "groupchat" -> @@ -784,11 +785,10 @@ route(Pid, From, ToNick, Packet) -> process_groupchat_message(From, {xmlelement, "message", Attrs, _Els} = Packet, StateData) -> Lang = xml:get_attr_s("xml:lang", Attrs), - case is_user_online(From, StateData) of + case is_user_online(From, StateData) orelse + is_user_allowed_message_nonparticipant(From, StateData) of true -> - {ok, #user{nick = FromNick, role = Role}} = - ?DICT:find(jlib:jid_tolower(From), - StateData#state.users), + {FromNick, Role} = get_participant_data(From, StateData), if (Role == moderator) or (Role == participant) or ((StateData#state.config)#config.moderated == false) -> @@ -873,6 +873,36 @@ process_groupchat_message(From, {xmlelement, "message", Attrs, _Els} = Packet, {next_state, normal_state, StateData} end. + +%% @doc Check if this non participant can send message to room. +%% +%% XEP-0045 v1.23: +%% 7.9 Sending a Message to All Occupants +%% an implementation MAY allow users with certain privileges +%% (e.g., a room owner, room admin, or service-level admin) +%% to send messages to the room even if those users are not occupants. +%% +%% Check the mod_muc option access_message_nonparticipant and wether this JID +%% is allowed or denied +is_user_allowed_message_nonparticipant(JID, StateData) -> + {_AccessRoute, _AccessCreate, AccessAdmin, _AccessPersistent} = StateData#state.access, + case acl:match_rule(StateData#state.server_host, AccessAdmin, JID) of + allow -> + true; + _ -> false + end. + +%% @doc Get information of this participant, or default values. +%% If the JID is not a participant, return values for a service message. +get_participant_data(From, StateData) -> + case ?DICT:find(jlib:jid_tolower(From), StateData#state.users) of + {ok, #user{nick = FromNick, role = Role}} -> + {FromNick, Role}; + error -> + {"", moderator} + end. + + process_presence(From, Nick, {xmlelement, "presence", Attrs, _Els} = Packet, StateData) -> Type = xml:get_attr_s("type", Attrs),