| 
				
			 | 
			
			
				
				@@ -1,16 +1,10 @@ 
			 | 
		
		
	
		
			
			| 
				1
			 | 
			
				1
			 | 
			
			
				
				 -- Prosody IM 
			 | 
		
		
	
		
			
			| 
				2
			 | 
			
				2
			 | 
			
			
				
				 -- Copyright (C) 2017 Atlassian 
			 | 
		
		
	
		
			
			| 
				3
			 | 
			
				3
			 | 
			
			
				
				 -- 
			 | 
		
		
	
		
			
			| 
				4
			 | 
			
				
			 | 
			
			
				
				--- 
			 | 
		
		
	
		
			
			| 
				5
			 | 
			
				4
			 | 
			
			
				
				 -- This module requires net-url module 
			 | 
		
		
	
		
			
			| 
				6
			 | 
			
				5
			 | 
			
			
				
				 -- Install it using #luarocks install net-url 
			 | 
		
		
	
		
			
			| 
				7
			 | 
			
				6
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				8
			 | 
			
				
			 | 
			
			
				
				-module:set_global(); -- Global module 
			 | 
		
		
	
		
			
			| 
				9
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				10
			 | 
			
				
			 | 
			
			
				
				-local split_jid = require "util.jid".split; 
			 | 
		
		
	
		
			
			| 
				11
			 | 
			
				
			 | 
			
			
				
				-local st = require "util.stanza"; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				7
			 | 
			
			
				
				+local jid = require "util.jid"; 
			 | 
		
		
	
		
			
			| 
				12
			 | 
			
				8
			 | 
			
			
				
				 local it = require "util.iterators"; 
			 | 
		
		
	
		
			
			| 
				13
			 | 
			
				9
			 | 
			
			
				
				 local json = require "util.json"; 
			 | 
		
		
	
		
			
			| 
				14
			 | 
			
				10
			 | 
			
			
				
				 local iterators = require "util.iterators"; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -20,28 +14,99 @@ local tostring = tostring; 
			 | 
		
		
	
		
			
			| 
				20
			 | 
			
				14
			 | 
			
			
				
				 local neturl = require "net.url"; 
			 | 
		
		
	
		
			
			| 
				21
			 | 
			
				15
			 | 
			
			
				
				 local parse = neturl.parseQuery; 
			 | 
		
		
	
		
			
			| 
				22
			 | 
			
				16
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				23
			 | 
			
				
			 | 
			
			
				
				-function get_room_from_jid(jid) 
			 | 
		
		
	
		
			
			| 
				24
			 | 
			
				
			 | 
			
			
				
				-	local node, host = split_jid(jid); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				17
			 | 
			
			
				
				+-- option to enable/disable room API token verifications 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				18
			 | 
			
			
				
				+local enableTokenVerification 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				19
			 | 
			
			
				
				+    = module:get_option_boolean("enable_roomsize_token_verification", false); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				20
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				21
			 | 
			
			
				
				+local token_util = module:require "token/util".new(module); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				22
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				23
			 | 
			
			
				
				+-- no token configuration but required 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				24
			 | 
			
			
				
				+if token_util == nil and enableTokenVerification then 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				25
			 | 
			
			
				
				+    log("error", "no token configuration but it is required"); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				26
			 | 
			
			
				
				+    return; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				27
			 | 
			
			
				
				+end 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				28
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				29
			 | 
			
			
				
				+-- required parameter for custom muc component prefix, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				30
			 | 
			
			
				
				+-- defaults to "conference" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				31
			 | 
			
			
				
				+local muc_domain_prefix 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				32
			 | 
			
			
				
				+    = module:get_option_string("muc_mapper_domain_prefix", "conference"); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				33
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				34
			 | 
			
			
				
				+--- Finds and returns room by its jid 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				35
			 | 
			
			
				
				+-- @param room_jid the room jid to search in the muc component 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				36
			 | 
			
			
				
				+-- @return returns room if found or nil 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				37
			 | 
			
			
				
				+function get_room_from_jid(room_jid) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				38
			 | 
			
			
				
				+	local _, host = jid.split(room_jid); 
			 | 
		
		
	
		
			
			| 
				25
			 | 
			
				39
			 | 
			
			
				
				 	local component = hosts[host]; 
			 | 
		
		
	
		
			
			| 
				26
			 | 
			
				40
			 | 
			
			
				
				 	if component then 
			 | 
		
		
	
		
			
			| 
				27
			 | 
			
				41
			 | 
			
			
				
				 		local muc = component.modules.muc 
			 | 
		
		
	
		
			
			| 
				28
			 | 
			
				42
			 | 
			
			
				
				 		if muc and rawget(muc,"rooms") then 
			 | 
		
		
	
		
			
			| 
				29
			 | 
			
				43
			 | 
			
			
				
				 			-- We're running 0.9.x or 0.10 (old MUC API) 
			 | 
		
		
	
		
			
			| 
				30
			 | 
			
				
			 | 
			
			
				
				-			return muc.rooms[jid]; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				44
			 | 
			
			
				
				+			return muc.rooms[room_jid]; 
			 | 
		
		
	
		
			
			| 
				31
			 | 
			
				45
			 | 
			
			
				
				 		elseif muc and rawget(muc,"get_room_from_jid") then 
			 | 
		
		
	
		
			
			| 
				32
			 | 
			
				46
			 | 
			
			
				
				 			-- We're running >0.10 (new MUC API) 
			 | 
		
		
	
		
			
			| 
				33
			 | 
			
				
			 | 
			
			
				
				-			return muc.get_room_from_jid(jid); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				47
			 | 
			
			
				
				+			return muc.get_room_from_jid(room_jid); 
			 | 
		
		
	
		
			
			| 
				34
			 | 
			
				48
			 | 
			
			
				
				 		else 
			 | 
		
		
	
		
			
			| 
				35
			 | 
			
				49
			 | 
			
			
				
				 			return 
			 | 
		
		
	
		
			
			| 
				36
			 | 
			
				50
			 | 
			
			
				
				 		end 
			 | 
		
		
	
		
			
			| 
				37
			 | 
			
				51
			 | 
			
			
				
				 	end 
			 | 
		
		
	
		
			
			| 
				38
			 | 
			
				52
			 | 
			
			
				
				 end 
			 | 
		
		
	
		
			
			| 
				39
			 | 
			
				53
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				54
			 | 
			
			
				
				+--- Verifies room name, domain name with the values in the token 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				55
			 | 
			
			
				
				+-- @param token the token we received 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				56
			 | 
			
			
				
				+-- @param room_address the full room address jid 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				57
			 | 
			
			
				
				+-- @return true if values are ok or false otherwise 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				58
			 | 
			
			
				
				+function verify_token(token, room_address) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				59
			 | 
			
			
				
				+    if not enableTokenVerification then 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				60
			 | 
			
			
				
				+        return true; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				61
			 | 
			
			
				
				+    end 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				62
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				63
			 | 
			
			
				
				+    -- if enableTokenVerification is enabled and we do not have token 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				64
			 | 
			
			
				
				+    -- stop here, cause the main virtual host can have guest access enabled 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				65
			 | 
			
			
				
				+    -- (allowEmptyToken = true) and we will allow access to rooms info without 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				66
			 | 
			
			
				
				+    -- a token 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				67
			 | 
			
			
				
				+    if token == nil then 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				68
			 | 
			
			
				
				+        log("warn", "no token provided"); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				69
			 | 
			
			
				
				+        return false; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				70
			 | 
			
			
				
				+    end 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				71
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				72
			 | 
			
			
				
				+    local session = {}; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				73
			 | 
			
			
				
				+    session.auth_token = token; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				74
			 | 
			
			
				
				+    local verified, reason = token_util:process_and_verify_token(session); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				75
			 | 
			
			
				
				+    if not verified then 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				76
			 | 
			
			
				
				+        log("warn", "not a valid token %s", tostring(reason)); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				77
			 | 
			
			
				
				+        return false; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				78
			 | 
			
			
				
				+    end 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				79
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				80
			 | 
			
			
				
				+    if not token_util:verify_room(session, room_address) then 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				81
			 | 
			
			
				
				+        log("warn", "Token %s not allowed to join: %s", 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				82
			 | 
			
			
				
				+            tostring(token), tostring(room_address)); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				83
			 | 
			
			
				
				+        return false; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				84
			 | 
			
			
				
				+    end 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				85
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				86
			 | 
			
			
				
				+    return true; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				87
			 | 
			
			
				
				+end 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				88
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				89
			 | 
			
			
				
				+--- Handles request for retrieving the room size 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				90
			 | 
			
			
				
				+-- @param event the http event, holds the request query 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				91
			 | 
			
			
				
				+-- @return GET response, containing a json with participants count, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				92
			 | 
			
			
				
				+--         tha value is without counting the focus. 
			 | 
		
		
	
		
			
			| 
				40
			 | 
			
				93
			 | 
			
			
				
				 function handle_get_room_size(event) 
			 | 
		
		
	
		
			
			| 
				41
			 | 
			
				94
			 | 
			
			
				
				 	local params = parse(event.request.url.query); 
			 | 
		
		
	
		
			
			| 
				42
			 | 
			
				95
			 | 
			
			
				
				 	local room_name = params["room"]; 
			 | 
		
		
	
		
			
			| 
				43
			 | 
			
				96
			 | 
			
			
				
				 	local domain_name = params["domain"]; 
			 | 
		
		
	
		
			
			| 
				44
			 | 
			
				
			 | 
			
			
				
				-	local room_address = room_name .. "@" .. "conference." .. domain_name; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				97
			 | 
			
			
				
				+    local subdomain = params["subdomain"]; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				98
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				99
			 | 
			
			
				
				+    local room_address 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				100
			 | 
			
			
				
				+        = jid.join(room_name, muc_domain_prefix.."."..domain_name); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				101
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				102
			 | 
			
			
				
				+    if subdomain and subdomain ~= "" then 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				103
			 | 
			
			
				
				+        room_address = "["..subdomain.."]"..room_address; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				104
			 | 
			
			
				
				+    end 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				105
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				106
			 | 
			
			
				
				+    if not verify_token(params["token"], room_address) then 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				107
			 | 
			
			
				
				+        return 403; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				108
			 | 
			
			
				
				+    end 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				109
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				45
			 | 
			
				110
			 | 
			
			
				
				 	local room = get_room_from_jid(room_address); 
			 | 
		
		
	
		
			
			| 
				46
			 | 
			
				111
			 | 
			
			
				
				 	local participant_count = 0; 
			 | 
		
		
	
		
			
			| 
				47
			 | 
			
				112
			 | 
			
			
				
				  
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -52,7 +117,8 @@ function handle_get_room_size(event) 
			 | 
		
		
	
		
			
			| 
				52
			 | 
			
				117
			 | 
			
			
				
				 		if occupants then 
			 | 
		
		
	
		
			
			| 
				53
			 | 
			
				118
			 | 
			
			
				
				 			participant_count = iterators.count(room:each_occupant()); 
			 | 
		
		
	
		
			
			| 
				54
			 | 
			
				119
			 | 
			
			
				
				 		end 
			 | 
		
		
	
		
			
			| 
				55
			 | 
			
				
			 | 
			
			
				
				-		log("debug", "there are %s occupants in room", tostring(participant_count)); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				120
			 | 
			
			
				
				+		log("debug", 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				121
			 | 
			
			
				
				+            "there are %s occupants in room", tostring(participant_count)); 
			 | 
		
		
	
		
			
			| 
				56
			 | 
			
				122
			 | 
			
			
				
				 	else 
			 | 
		
		
	
		
			
			| 
				57
			 | 
			
				123
			 | 
			
			
				
				 		log("debug", "no such room exists"); 
			 | 
		
		
	
		
			
			| 
				58
			 | 
			
				124
			 | 
			
			
				
				 	end 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -70,11 +136,25 @@ function handle_get_room_size(event) 
			 | 
		
		
	
		
			
			| 
				70
			 | 
			
				136
			 | 
			
			
				
				 	return GET_response; 
			 | 
		
		
	
		
			
			| 
				71
			 | 
			
				137
			 | 
			
			
				
				 end 
			 | 
		
		
	
		
			
			| 
				72
			 | 
			
				138
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				139
			 | 
			
			
				
				+--- Handles request for retrieving the room participants details 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				140
			 | 
			
			
				
				+-- @param event the http event, holds the request query 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				141
			 | 
			
			
				
				+-- @return GET response, containing a json with participants details 
			 | 
		
		
	
		
			
			| 
				73
			 | 
			
				142
			 | 
			
			
				
				 function handle_get_room (event) 
			 | 
		
		
	
		
			
			| 
				74
			 | 
			
				143
			 | 
			
			
				
				 	local params = parse(event.request.url.query); 
			 | 
		
		
	
		
			
			| 
				75
			 | 
			
				144
			 | 
			
			
				
				 	local room_name = params["room"]; 
			 | 
		
		
	
		
			
			| 
				76
			 | 
			
				145
			 | 
			
			
				
				 	local domain_name = params["domain"]; 
			 | 
		
		
	
		
			
			| 
				77
			 | 
			
				
			 | 
			
			
				
				-	local room_address = room_name .. "@" .. "conference." .. domain_name; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				146
			 | 
			
			
				
				+    local subdomain = params["subdomain"]; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				147
			 | 
			
			
				
				+    local room_address 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				148
			 | 
			
			
				
				+        = jid.join(room_name, muc_domain_prefix.."."..domain_name); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				149
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				150
			 | 
			
			
				
				+    if subdomain ~= "" then 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				151
			 | 
			
			
				
				+        room_address = "["..subdomain.."]"..room_address; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				152
			 | 
			
			
				
				+    end 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				153
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				154
			 | 
			
			
				
				+    if not verify_token(params["token"], room_address) then 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				155
			 | 
			
			
				
				+        return 403; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				156
			 | 
			
			
				
				+    end 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				157
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				78
			 | 
			
				158
			 | 
			
			
				
				 	local room = get_room_from_jid(room_address); 
			 | 
		
		
	
		
			
			| 
				79
			 | 
			
				159
			 | 
			
			
				
				 	local participant_count = 0; 
			 | 
		
		
	
		
			
			| 
				80
			 | 
			
				160
			 | 
			
			
				
				 	local occupants_json = array(); 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -99,7 +179,8 @@ function handle_get_room (event) 
			 | 
		
		
	
		
			
			| 
				99
			 | 
			
				179
			 | 
			
			
				
				 			    end 
			 | 
		
		
	
		
			
			| 
				100
			 | 
			
				180
			 | 
			
			
				
				 			end 
			 | 
		
		
	
		
			
			| 
				101
			 | 
			
				181
			 | 
			
			
				
				 		end 
			 | 
		
		
	
		
			
			| 
				102
			 | 
			
				
			 | 
			
			
				
				-		log("debug", "there are %s occupants in room", tostring(participant_count)); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				182
			 | 
			
			
				
				+		log("debug", 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				183
			 | 
			
			
				
				+            "there are %s occupants in room", tostring(participant_count)); 
			 | 
		
		
	
		
			
			| 
				103
			 | 
			
				184
			 | 
			
			
				
				 	else 
			 | 
		
		
	
		
			
			| 
				104
			 | 
			
				185
			 | 
			
			
				
				 		log("debug", "no such room exists"); 
			 | 
		
		
	
		
			
			| 
				105
			 | 
			
				186
			 | 
			
			
				
				 	end 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -117,8 +198,8 @@ function handle_get_room (event) 
			 | 
		
		
	
		
			
			| 
				117
			 | 
			
				198
			 | 
			
			
				
				 	return GET_response; 
			 | 
		
		
	
		
			
			| 
				118
			 | 
			
				199
			 | 
			
			
				
				 end; 
			 | 
		
		
	
		
			
			| 
				119
			 | 
			
				200
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				120
			 | 
			
				
			 | 
			
			
				
				-function module.add_host(module) 
			 | 
		
		
	
		
			
			| 
				121
			 | 
			
				
			 | 
			
			
				
				-	module:depends("http"); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				201
			 | 
			
			
				
				+function module.load() 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				202
			 | 
			
			
				
				+    module:depends("http"); 
			 | 
		
		
	
		
			
			| 
				122
			 | 
			
				203
			 | 
			
			
				
				 	module:provides("http", { 
			 | 
		
		
	
		
			
			| 
				123
			 | 
			
				204
			 | 
			
			
				
				 		default_path = "/"; 
			 | 
		
		
	
		
			
			| 
				124
			 | 
			
				205
			 | 
			
			
				
				 		route = { 
			 |