mod_privilege/mod_privilege.lua
changeset 1662 1146cb4493a9
parent 1661 7116bc76663b
child 1663 495a093798eb
equal deleted inserted replaced
1661:7116bc76663b 1662:1146cb4493a9
       
     1 -- XEP-0356 (Privileged Entity)
       
     2 -- Copyright (C) 2015 Jérôme Poisson
       
     3 --
       
     4 -- This module is MIT/X11 licensed. Please see the
       
     5 -- COPYING file in the source package for more information.
       
     6 
       
     7 
     1 local jid = require("util/jid")
     8 local jid = require("util/jid")
     2 local set = require("util/set")
     9 local set = require("util/set")
     3 local st = require("util/stanza")
    10 local st = require("util/stanza")
       
    11 local roster_manager = require("core/rostermanager")
       
    12 
     4 local _ALLOWED_ROSTER = set.new({'none', 'get', 'set', 'both'})
    13 local _ALLOWED_ROSTER = set.new({'none', 'get', 'set', 'both'})
       
    14 local _ROSTER_GET_PERM = set.new({'get', 'both'})
       
    15 local _ROSTER_SET_PERM = set.new({'set', 'both'})
     5 local _ALLOWED_MESSAGE = set.new({'none', 'outgoing'})
    16 local _ALLOWED_MESSAGE = set.new({'none', 'outgoing'})
     6 local _ALLOWED_PRESENCE = set.new({'none', 'managed_entity', 'roster'})
    17 local _ALLOWED_PRESENCE = set.new({'none', 'managed_entity', 'roster'})
     7 local _TO_CHECK = {roster=_ALLOWED_ROSTER, message=_ALLOWED_MESSAGE, presence=_ALLOWED_PRESENCE}
    18 local _TO_CHECK = {roster=_ALLOWED_ROSTER, message=_ALLOWED_MESSAGE, presence=_ALLOWED_PRESENCE}
     8 local _PRIV_ENT_NS = 'urn:xmpp:privilege:1'
    19 local _PRIV_ENT_NS = 'urn:xmpp:privilege:1'
     9 
    20 
    10 module:log("info", "Loading privileged entity module ");
    21 
       
    22 module:log("debug", "Loading privileged entity module ");
       
    23 
       
    24 --> Permissions management <--
    11 
    25 
    12 privileges = module:get_option("privileged_entities", {})
    26 privileges = module:get_option("privileged_entities", {})
    13 
       
    14 module:log("warn", "Connection, HOST="..tostring(module:get_host()).." ("..tostring(module:get_host_type())..")")
       
    15 
    27 
    16 function advertise_perm(to_jid, perms)
    28 function advertise_perm(to_jid, perms)
    17 	-- send <message/> stanza to advertise permissions
    29 	-- send <message/> stanza to advertise permissions
    18 	-- as expained in section 4.2
    30 	-- as expained in section 4.2
    19 	local message = st.message({to=to_jid})
    31 	local message = st.message({to=to_jid})
    32 	-- Check if entity is privileged according to configuration,
    44 	-- Check if entity is privileged according to configuration,
    33 	-- and set session.privileges accordingly
    45 	-- and set session.privileges accordingly
    34 	
    46 	
    35 	local session = event.session
    47 	local session = event.session
    36 	local bare_jid = jid.join(session.username, session.host)
    48 	local bare_jid = jid.join(session.username, session.host)
    37 	module:log("info", "======>>> on_auth, type="..tostring(event.session.type)..", jid="..tostring(bare_jid));
       
    38 
    49 
    39 	local ent_priv = privileges[bare_jid]
    50 	local ent_priv = privileges[bare_jid]
    40 	if ent_priv ~= nil then
    51 	if ent_priv ~= nil then
    41 		module:log("debug", "Entity is privileged")
    52 		module:log("debug", "Entity is privileged")
    42 		for perm_type, allowed_values in pairs(_TO_CHECK) do
    53 		for perm_type, allowed_values in pairs(_TO_CHECK) do
    62 	session.privileges = ent_priv
    73 	session.privileges = ent_priv
    63 end
    74 end
    64 
    75 
    65 module:hook('authentication-success', on_auth)
    76 module:hook('authentication-success', on_auth)
    66 module:hook('component-authenticated', on_auth)
    77 module:hook('component-authenticated', on_auth)
       
    78 
       
    79 
       
    80 --> roster permission <--
       
    81 
       
    82 module:hook("iq-get/bare/jabber:iq:roster:query", function(event)
       
    83 	local session, stanza = event.origin, event.stanza;
       
    84 	if not stanza.attr.to then
       
    85 		-- we don't want stanzas addressed to /self
       
    86 		return;
       
    87 	end
       
    88 	
       
    89 	if session.privileges and _ROSTER_GET_PERM:contains(session.privileges.roster) then
       
    90 		module:log("debug", "Roster get from allowed privileged entity received")
       
    91 		-- following code is adapted from mod_remote_roster
       
    92 		local node, host = jid.split(stanza.attr.to);
       
    93 		local roster = roster_manager.load_roster(node, host);
       
    94 		
       
    95 		local reply = st.reply(stanza):query("jabber:iq:roster");
       
    96 		for entity_jid, item in pairs(roster) do
       
    97 			if entity_jid and entity_jid ~= "pending" then
       
    98 				local node, host = jid.split(entity_jid);
       
    99 					reply:tag("item", {
       
   100 						jid = entity_jid,
       
   101 						subscription = item.subscription,
       
   102 						ask = item.ask,
       
   103 						name = item.name,
       
   104 					});
       
   105 					for group in pairs(item.groups) do
       
   106 						reply:tag("group"):text(group):up();
       
   107 					end
       
   108 					reply:up(); -- move out from item
       
   109 			end
       
   110 		end
       
   111 		session.send(reply);
       
   112 	else
       
   113 	    module:log("warn", "Entity "..tostring(session.full_jid).." try to get roster without permission")
       
   114 		session.send(st.error_reply(stanza, 'auth', 'forbidden'))
       
   115 	end
       
   116 	
       
   117 	return true
       
   118 
       
   119 end);