MUC: Use a timestamp to keep track of when to unlock room instead of a timer (so...
[prosody.git] / plugins / muc / lock.lib.lua
1 -- Prosody IM
2 -- Copyright (C) 2008-2010 Matthew Wild
3 -- Copyright (C) 2008-2010 Waqas Hussain
4 -- Copyright (C) 2014 Daurnimator
5 --
6 -- This project is MIT/X11 licensed. Please see the
7 -- COPYING file in the source package for more information.
8 --
9
10 local st = require "util.stanza";
11
12 local lock_rooms = module:get_option_boolean("muc_room_locking", false);
13 local lock_room_timeout = module:get_option_number("muc_room_lock_timeout", 300);
14
15 local function lock(room)
16         module:fire_event("muc-room-locked", {room = room;});
17         room._data.locked = os.time() + lock_room_timeout;
18 end
19 local function unlock(room)
20         module:fire_event("muc-room-unlocked", {room = room;});
21         room._data.locked = nil;
22 end
23 local function is_locked(room)
24         local ts = room._data.locked or false;
25         if ts then
26                 if ts < os.time() then return true; end
27                 unlock(room);
28         end
29         return false;
30 end
31
32 if lock_rooms then
33         module:hook("muc-room-pre-create", function(event)
34                 -- Older groupchat protocol doesn't lock
35                 if not event.stanza:get_child("x", "http://jabber.org/protocol/muc") then return end
36                 -- Lock room at creation
37                 local room = event.room;
38                 lock(room);
39         end, 10);
40 end
41
42 -- Don't let users into room while it is locked
43 module:hook("muc-occupant-pre-join", function(event)
44         if not event.is_new_room and is_locked(event.room) then -- Deny entry
45                 event.origin.send(st.error_reply(event.stanza, "cancel", "item-not-found"));
46                 return true;
47         end
48 end, -30);
49
50 -- When config is submitted; unlock the room
51 module:hook("muc-config-submitted", function(event)
52         if is_locked(event.room) then
53                 unlock(event.room);
54         end
55 end, -1);
56
57 return {
58         lock = lock;
59         unlock = unlock;
60         is_locked = is_locked;
61 };