2 -- Copyright (C) 2008-2010 Matthew Wild
3 -- Copyright (C) 2008-2010 Waqas Hussain
4 -- Copyright (C) 2014 Daurnimator
6 -- This project is MIT/X11 licensed. Please see the
7 -- COPYING file in the source package for more information.
10 local st
= require
"util.stanza";
11 local dt
= require
"util.datetime";
13 local muc_util
= module
:require
"muc/util";
14 local valid_roles
= muc_util
.valid_roles
;
16 local function create_subject_message(from
, subject
)
17 return st
.message({from
= from
; type = "groupchat"})
18 :tag("subject"):text(subject
or ""):up();
21 local function get_changesubject(room
)
22 return room
._data
.changesubject
;
25 local function set_changesubject(room
, changesubject
)
26 changesubject
= changesubject
and true or nil;
27 if get_changesubject(room
) == changesubject
then return false; end
28 room
._data
.changesubject
= changesubject
;
32 module
:hook("muc-disco#info", function (event
)
33 table.insert(event
.form
, {
34 name
= "muc#roominfo_changesubject";
37 event
.formdata
["muc#roominfo_changesubject"] = get_changesubject(event
.room
);
40 module
:hook("muc-config-form", function(event
)
41 table.insert(event
.form
, {
42 name
= "muc#roomconfig_changesubject";
44 label
= "Allow anyone to set the room's subject";
45 desc
= "Choose whether anyone, or only moderators, may set the room's subject";
46 value
= get_changesubject(event
.room
);
50 module
:hook("muc-config-submitted/muc#roomconfig_changesubject", function(event
)
51 if set_changesubject(event
.room
, event
.value
) then
52 event
.status_codes
["104"] = true;
56 local function get_subject(room
)
57 -- a <message/> stanza from the room JID (or from the occupant JID of the entity that set the subject)
58 return room
._data
.subject_from
or room
.jid
, room
._data
.subject
;
61 local function send_subject(room
, to
, time
)
62 local msg
= create_subject_message(get_subject(room
));
66 xmlns
= "urn:xmpp:delay",
68 stamp
= dt
.datetime(time
);
71 room
:route_stanza(msg
);
74 local function set_subject(room
, from
, subject
)
75 if subject
== "" then subject
= nil; end
76 local old_from
, old_subject
= get_subject(room
);
77 if old_subject
== subject
and old_from
== from
then return false; end
78 room
._data
.subject_from
= from
;
79 room
._data
.subject
= subject
;
80 room
._data
.subject_time
= os
.time();
81 local msg
= create_subject_message(from
, subject
);
82 room
:broadcast_message(msg
);
86 -- Send subject to joining user
87 module
:hook("muc-occupant-session-new", function(event
)
88 send_subject(event
.room
, event
.stanza
.attr
.from
, event
.room
._data
.subject_time
);
91 -- Prosody has made the decision that messages with <subject/> are exclusively subject changes
92 -- e.g. body will be ignored; even if the subject change was not allowed
93 module
:hook("muc-occupant-groupchat", function(event
)
94 local stanza
= event
.stanza
;
95 local subject
= stanza
:get_child("subject");
97 if stanza
:get_child("body") or stanza
:get_child("thread") then
98 -- Note: A message with a <subject/> and a <body/> or a <subject/> and
99 -- a <thread/> is a legitimate message, but it SHALL NOT be interpreted
100 -- as a subject change.
103 local room
= event
.room
;
104 local occupant
= event
.occupant
;
105 -- Role check for subject changes
106 local role_rank
= valid_roles
[occupant
and occupant
.role
or "none"];
107 if role_rank
>= valid_roles
.moderator
or
108 ( role_rank
>= valid_roles
.participant
and get_changesubject(room
) ) then -- and participant
109 set_subject(room
, occupant
.nick
, subject
:get_text());
113 event
.origin
.send(st
.error_reply(stanza
, "auth", "forbidden", "You are not allowed to change the subject"));
120 get_changesubject
= get_changesubject
;
121 set_changesubject
= set_changesubject
;