mod_privilege/mod_privilege.lua
author Matthew Wild <mwild1@gmail.com>
Sat, 24 Sep 2022 09:25:46 +0100
changeset 5062 39c2824c2880
parent 4998 cce12a660b98
child 5877 a88c43de648c
permissions -rw-r--r--
mod_cloud_notify: README overhaul
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1671
c81a981479d4 mod_privilege: implemented probing of rosters items (for existing sessions only) on connection + use a globally shared table for priv_session (and fixed last_presence)
Goffi <goffi@goffi.org>
parents: 1670
diff changeset
     1
-- XEP-0356 (Privileged Entity)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
     2
-- Copyright (C) 2015-2022 Jérôme Poisson
1662
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
     3
--
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
     4
-- This module is MIT/X11 licensed. Please see the
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
     5
-- COPYING file in the source package for more information.
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
     6
--
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
     7
-- Some parts come from mod_remote_roster (module by Waqas Hussain and Kim Alvefur, see https://code.google.com/p/prosody-modules/)
1662
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
     8
1671
c81a981479d4 mod_privilege: implemented probing of rosters items (for existing sessions only) on connection + use a globally shared table for priv_session (and fixed last_presence)
Goffi <goffi@goffi.org>
parents: 1670
diff changeset
     9
-- TODO: manage external <presence/> (for "roster" presence permission) when the account with the roster is offline
1662
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
    10
1994
c4da3d9f212d mod_privilege: fixed imports, using "/" instead of "." was causing caching issues
Goffi <goffi@goffi.org>
parents: 1993
diff changeset
    11
local jid = require("util.jid")
c4da3d9f212d mod_privilege: fixed imports, using "/" instead of "." was causing caching issues
Goffi <goffi@goffi.org>
parents: 1993
diff changeset
    12
local set = require("util.set")
c4da3d9f212d mod_privilege: fixed imports, using "/" instead of "." was causing caching issues
Goffi <goffi@goffi.org>
parents: 1993
diff changeset
    13
local st = require("util.stanza")
c4da3d9f212d mod_privilege: fixed imports, using "/" instead of "." was causing caching issues
Goffi <goffi@goffi.org>
parents: 1993
diff changeset
    14
local roster_manager = require("core.rostermanager")
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    15
local usermanager_user_exists = require "core.usermanager".user_exists
1665
69aa2b54ba8a mod_privilege: implemented message privilege
Goffi <goffi@goffi.org>
parents: 1664
diff changeset
    16
local hosts = prosody.hosts
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    17
local full_sessions = prosody.full_sessions
1671
c81a981479d4 mod_privilege: implemented probing of rosters items (for existing sessions only) on connection + use a globally shared table for priv_session (and fixed last_presence)
Goffi <goffi@goffi.org>
parents: 1670
diff changeset
    18
c81a981479d4 mod_privilege: implemented probing of rosters items (for existing sessions only) on connection + use a globally shared table for priv_session (and fixed last_presence)
Goffi <goffi@goffi.org>
parents: 1670
diff changeset
    19
local priv_session = module:shared("/*/privilege/session")
c81a981479d4 mod_privilege: implemented probing of rosters items (for existing sessions only) on connection + use a globally shared table for priv_session (and fixed last_presence)
Goffi <goffi@goffi.org>
parents: 1670
diff changeset
    20
1712
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
    21
if priv_session.connected_cb == nil then
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    22
    -- set used to have connected event listeners
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    23
    -- which allows a host to react on events from
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    24
    -- other hosts
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    25
    priv_session.connected_cb = set.new()
1667
ca07a6ada631 mod_privilege: presence permission configuration check + use global set to know privileged entities to advertise
Goffi <goffi@goffi.org>
parents: 1666
diff changeset
    26
end
1712
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
    27
local connected_cb = priv_session.connected_cb
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
    28
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
    29
-- the folowing sets are used to forward presence stanza
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
    30
-- the folowing sets are used to forward presence stanza
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
    31
local presence_man_ent = set.new()
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
    32
local presence_roster = set.new()
1662
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
    33
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
    34
local _ALLOWED_ROSTER = set.new({'none', 'get', 'set', 'both'})
1662
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
    35
local _ROSTER_GET_PERM = set.new({'get', 'both'})
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
    36
local _ROSTER_SET_PERM = set.new({'set', 'both'})
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
    37
local _ALLOWED_MESSAGE = set.new({'none', 'outgoing'})
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
    38
local _ALLOWED_PRESENCE = set.new({'none', 'managed_entity', 'roster'})
1669
746d94f37a4c mod_privilege: presence already known are advertised to privileged entity (for "maneger_entity" permission only so far)
Goffi <goffi@goffi.org>
parents: 1668
diff changeset
    39
local _PRESENCE_MANAGED = set.new({'managed_entity', 'roster'})
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
    40
local _TO_CHECK = {roster=_ALLOWED_ROSTER, message=_ALLOWED_MESSAGE, presence=_ALLOWED_PRESENCE}
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    41
local _PRIV_ENT_NS = 'urn:xmpp:privilege:2'
1665
69aa2b54ba8a mod_privilege: implemented message privilege
Goffi <goffi@goffi.org>
parents: 1664
diff changeset
    42
local _FORWARDED_NS = 'urn:xmpp:forward:0'
1959
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
    43
local _MODULE_HOST = module:get_host()
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
    44
1662
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
    45
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    46
module:log("debug", "Loading privileged entity module ")
1662
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
    47
1667
ca07a6ada631 mod_privilege: presence permission configuration check + use global set to know privileged entities to advertise
Goffi <goffi@goffi.org>
parents: 1666
diff changeset
    48
1662
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
    49
--> Permissions management <--
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
    50
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    51
local config_priv = module:get_option("privileged_entities", {})
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
    52
1959
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
    53
local function get_session_privileges(session, host)
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
    54
    if not session.privileges then return nil end
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
    55
    return session.privileges[host]
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
    56
end
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
    57
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
    58
1711
64b3d1eb0cfe mod_privilege: fixed various issues reported by luacheck
Goffi <goffi@goffi.org>
parents: 1671
diff changeset
    59
local function advertise_perm(session, to_jid, perms)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    60
    -- send <message/> stanza to advertise permissions
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    61
    -- as expained in § 4.2
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    62
    local message = st.message({from=module.host, to=to_jid})
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    63
                      :tag("privilege", {xmlns=_PRIV_ENT_NS})
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
    64
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    65
    for _, perm in pairs({'roster', 'message', 'presence'}) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    66
        if perms[perm] then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    67
            message:tag("perm", {access=perm, type=perms[perm]}):up()
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    68
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    69
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    70
    local iq_perm = perms["iq"]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    71
    if iq_perm ~= nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    72
        message:tag("perm", {access="iq"})
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    73
        for namespace, ns_perm in pairs(iq_perm) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    74
                local perm_type
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    75
                if ns_perm.set and ns_perm.get then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    76
                    perm_type = "both"
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    77
                elseif ns_perm.set then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    78
                    perm_type = "set"
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    79
                elseif ns_perm.get then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    80
                    perm_type = "get"
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    81
                else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    82
                    perm_type = nil
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    83
                end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    84
                message:tag("namespace", {ns=namespace, type=perm_type})
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    85
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    86
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    87
    session.send(message)
1666
d440a22fa0af mod_privilege: advertise_perm method now use session.send instead of module:send to avoid to go back in hook
Goffi <goffi@goffi.org>
parents: 1665
diff changeset
    88
end
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
    89
1711
64b3d1eb0cfe mod_privilege: fixed various issues reported by luacheck
Goffi <goffi@goffi.org>
parents: 1671
diff changeset
    90
local function set_presence_perm_set(to_jid, perms)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    91
    -- fill the presence sets according to perms
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    92
    if _PRESENCE_MANAGED:contains(perms.presence) then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    93
        presence_man_ent:add(to_jid)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    94
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    95
    if perms.presence == 'roster' then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    96
        presence_roster:add(to_jid)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    97
    end
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
    98
end
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
    99
1711
64b3d1eb0cfe mod_privilege: fixed various issues reported by luacheck
Goffi <goffi@goffi.org>
parents: 1671
diff changeset
   100
local function advertise_presences(session, to_jid, perms)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   101
    -- send presence status for already connected entities
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   102
    -- as explained in § 7.1
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   103
    -- people in roster are probed only for active sessions
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   104
    -- TODO: manage roster load for inactive sessions
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   105
    if not perms.presence then return; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   106
    local to_probe = {}
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   107
    for _, user_session in pairs(full_sessions) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   108
        if user_session.presence and _PRESENCE_MANAGED:contains(perms.presence) then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   109
            local presence = st.clone(user_session.presence)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   110
            presence.attr.to = to_jid
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   111
            module:log("debug", "sending current presence for "..tostring(user_session.full_jid))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   112
            session.send(presence)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   113
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   114
        if perms.presence == "roster" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   115
            -- we reset the cache to avoid to miss a presence that just changed
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   116
            priv_session.last_presence = nil
1671
c81a981479d4 mod_privilege: implemented probing of rosters items (for existing sessions only) on connection + use a globally shared table for priv_session (and fixed last_presence)
Goffi <goffi@goffi.org>
parents: 1670
diff changeset
   117
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   118
            if user_session.roster then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   119
                local bare_jid = jid.bare(user_session.full_jid)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   120
                for entity, item in pairs(user_session.roster) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   121
                    if entity~=false and entity~="pending" and (item.subscription=="both" or item.subscription=="to") then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   122
                        local _, host = jid.split(entity)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   123
                        if not hosts[host] then -- we don't probe jid from hosts we manage
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   124
                            -- using a table with entity as key avoid probing several time the same one
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   125
                            to_probe[entity] = bare_jid
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   126
                        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   127
                    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   128
                end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   129
            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   130
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   131
    end
1671
c81a981479d4 mod_privilege: implemented probing of rosters items (for existing sessions only) on connection + use a globally shared table for priv_session (and fixed last_presence)
Goffi <goffi@goffi.org>
parents: 1670
diff changeset
   132
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   133
    -- now we probe peoples for "roster" presence permission
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   134
    for probe_to, probe_from in pairs(to_probe) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   135
        module:log("debug", "probing presence for %s (on behalf of %s)", tostring(probe_to), tostring(probe_from))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   136
        local probe = st.presence({from=probe_from, to=probe_to, type="probe"})
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   137
        prosody.core_route_stanza(nil, probe)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   138
    end
1669
746d94f37a4c mod_privilege: presence already known are advertised to privileged entity (for "maneger_entity" permission only so far)
Goffi <goffi@goffi.org>
parents: 1668
diff changeset
   139
end
746d94f37a4c mod_privilege: presence already known are advertised to privileged entity (for "maneger_entity" permission only so far)
Goffi <goffi@goffi.org>
parents: 1668
diff changeset
   140
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   141
1711
64b3d1eb0cfe mod_privilege: fixed various issues reported by luacheck
Goffi <goffi@goffi.org>
parents: 1671
diff changeset
   142
local function on_auth(event)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   143
    -- Check if entity is privileged according to configuration,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   144
    -- and set session.privileges accordingly
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   145
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   146
    local session = event.session
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   147
    local bare_jid = jid.join(session.username, session.host)
1959
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
   148
    if not session.privileges then
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
   149
        session.privileges = {}
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
   150
    end
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
   151
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   152
    local conf_ent_priv = config_priv[bare_jid]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   153
    local ent_priv = {}
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   154
    if conf_ent_priv ~= nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   155
        module:log("debug", "Entity is privileged")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   156
        for perm_type, allowed_values in pairs(_TO_CHECK) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   157
            local value = conf_ent_priv[perm_type]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   158
            if value ~= nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   159
                if not allowed_values:contains(value) then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   160
                    module:log('warn', 'Invalid value for '..perm_type..' privilege: ['..value..']')
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   161
                    module:log('warn', 'Setting '..perm_type..' privilege to none')
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   162
                    ent_priv[perm_type] = nil
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   163
                elseif value == 'none' then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   164
                    ent_priv[perm_type] = nil
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   165
                else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   166
                    ent_priv[perm_type] = value
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   167
                end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   168
            else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   169
                ent_priv[perm_type] = nil
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   170
            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   171
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   172
        -- extra checks for presence permission
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   173
        if ent_priv.presence == 'roster' and not _ROSTER_GET_PERM:contains(ent_priv.roster) then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   174
            module:log("warn", "Can't allow roster presence privilege without roster \"get\" privilege")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   175
            module:log("warn", "Setting presence permission to none")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   176
            ent_priv.presence = nil
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   177
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   178
        -- iq permission
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   179
        local iq_perm_config = conf_ent_priv["iq"]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   180
        if iq_perm_config ~= nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   181
            local iq_perm = {}
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   182
            ent_priv["iq"] = iq_perm
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   183
            for ns, ns_perm_config in pairs(iq_perm_config) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   184
                iq_perm[ns] = {
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   185
                    ["get"] = ns_perm_config == "get" or ns_perm_config == "both",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   186
                    ["set"] = ns_perm_config == "set" or ns_perm_config == "both"
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   187
                }
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   188
            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   189
        else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   190
            ent_priv["iq"] = nil
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   191
        end
1667
ca07a6ada631 mod_privilege: presence permission configuration check + use global set to know privileged entities to advertise
Goffi <goffi@goffi.org>
parents: 1666
diff changeset
   192
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   193
        if session.type == "component" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   194
            -- we send the message stanza only for component
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   195
            -- it will be sent at first <presence/> for other entities
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   196
            advertise_perm(session, bare_jid, ent_priv)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   197
            set_presence_perm_set(bare_jid, ent_priv)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   198
            advertise_presences(session, bare_jid, ent_priv)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   199
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   200
    end
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
   201
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   202
    session.privileges[_MODULE_HOST] = ent_priv
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
   203
end
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
   204
1711
64b3d1eb0cfe mod_privilege: fixed various issues reported by luacheck
Goffi <goffi@goffi.org>
parents: 1671
diff changeset
   205
local function on_presence(event)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   206
    -- Permission are already checked at this point,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   207
    -- we only advertise them to the entity
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   208
    local session = event.origin
1959
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
   209
    local session_privileges = get_session_privileges(session, _MODULE_HOST)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   210
    if session_privileges then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   211
        advertise_perm(session, session.full_jid, session_privileges)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   212
        set_presence_perm_set(session.full_jid, session_privileges)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   213
        advertise_presences(session, session.full_jid, session_privileges)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   214
    end
1663
495a093798eb mod_privilege: added permissions notification on initial presence for entities which are not components
Goffi <goffi@goffi.org>
parents: 1662
diff changeset
   215
end
495a093798eb mod_privilege: added permissions notification on initial presence for entities which are not components
Goffi <goffi@goffi.org>
parents: 1662
diff changeset
   216
1712
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
   217
local function on_component_auth(event)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   218
    -- react to component-authenticated event from this host
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   219
    -- and call the on_auth methods from all other hosts
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   220
    -- needed for the component to get delegations advertising
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   221
    for callback in connected_cb:items() do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   222
        callback(event)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   223
    end
1712
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
   224
end
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
   225
1779
0d78bb31348e mod_privilege: fixed bad calling of on_auth for components
Goffi <goffi@goffi.org>
parents: 1712
diff changeset
   226
if module:get_host_type() ~= "component" then
0d78bb31348e mod_privilege: fixed bad calling of on_auth for components
Goffi <goffi@goffi.org>
parents: 1712
diff changeset
   227
    connected_cb:add(on_auth)
0d78bb31348e mod_privilege: fixed bad calling of on_auth for components
Goffi <goffi@goffi.org>
parents: 1712
diff changeset
   228
end
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
   229
module:hook('authentication-success', on_auth)
1712
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
   230
module:hook('component-authenticated', on_component_auth)
1663
495a093798eb mod_privilege: added permissions notification on initial presence for entities which are not components
Goffi <goffi@goffi.org>
parents: 1662
diff changeset
   231
module:hook('presence/initial', on_presence)
1662
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
   232
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
   233
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
   234
--> roster permission <--
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
   235
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   236
-- get
1662
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
   237
module:hook("iq-get/bare/jabber:iq:roster:query", function(event)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   238
    local session, stanza = event.origin, event.stanza
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   239
    if not stanza.attr.to then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   240
        -- we don't want stanzas addressed to /self
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   241
        return
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   242
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   243
    local node, host = jid.split(stanza.attr.to)
1959
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
   244
    local session_privileges = get_session_privileges(session, host)
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   245
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   246
    if session_privileges and _ROSTER_GET_PERM:contains(session_privileges.roster) then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   247
        module:log("debug", "Roster get from allowed privileged entity received")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   248
        -- following code is adapted from mod_remote_roster
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   249
        local roster = roster_manager.load_roster(node, host)
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   250
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   251
        local reply = st.reply(stanza):query("jabber:iq:roster")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   252
        for entity_jid, item in pairs(roster) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   253
            if entity_jid and entity_jid ~= "pending" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   254
                reply:tag("item", {
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   255
                    jid = entity_jid,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   256
                    subscription = item.subscription,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   257
                    ask = item.ask,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   258
                    name = item.name,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   259
                })
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   260
                for group in pairs(item.groups) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   261
                    reply:tag("group"):text(group):up()
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   262
                end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   263
                reply:up(); -- move out from item
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   264
            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   265
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   266
        -- end of code adapted from mod_remote_roster
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   267
        session.send(reply)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   268
    else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   269
        module:log("warn", "Entity "..tostring(session.full_jid).." try to get roster without permission")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   270
        session.send(st.error_reply(stanza, 'auth', 'forbidden'))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   271
    end
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   272
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   273
    return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   274
end)
1662
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
   275
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   276
-- set
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   277
module:hook("iq-set/bare/jabber:iq:roster:query", function(event)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   278
    local session, stanza = event.origin, event.stanza
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   279
    if not stanza.attr.to then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   280
        -- we don't want stanzas addressed to /self
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   281
        return
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   282
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   283
    local from_node, from_host = jid.split(stanza.attr.to)
1959
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
   284
    local session_privileges = get_session_privileges(session, from_host)
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   285
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   286
    if session_privileges and _ROSTER_SET_PERM:contains(session_privileges.roster) then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   287
        module:log("debug", "Roster set from allowed privileged entity received")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   288
        -- following code is adapted from mod_remote_roster
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   289
        if not(usermanager_user_exists(from_node, from_host)) then return; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   290
        local roster = roster_manager.load_roster(from_node, from_host)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   291
        if not(roster) then return; end
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   292
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   293
        local query = stanza.tags[1]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   294
        for _, item in ipairs(query.tags) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   295
            if item.name == "item"
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   296
                and item.attr.xmlns == "jabber:iq:roster" and item.attr.jid
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   297
                    -- Protection against overwriting roster.pending, until we move it
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   298
                and item.attr.jid ~= "pending" then
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   299
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   300
                local item_jid = jid.prep(item.attr.jid)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   301
                local _, host, resource = jid.split(item_jid)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   302
                if not resource then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   303
                    if item_jid ~= stanza.attr.to then -- not self-item_jid
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   304
                        if item.attr.subscription == "remove" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   305
                            local r_item = roster[item_jid]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   306
                            if r_item then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   307
                                roster[item_jid] = nil
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   308
                                if roster_manager.save_roster(from_node, from_host, roster) then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   309
                                    session.send(st.reply(stanza))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   310
                                    roster_manager.roster_push(from_node, from_host, item_jid)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   311
                                else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   312
                                    roster[item_jid] = item
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   313
                                    session.send(st.error_reply(stanza, "wait", "internal-server-error", "Unable to save roster"))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   314
                                end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   315
                            else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   316
                                session.send(st.error_reply(stanza, "modify", "item-not-found"))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   317
                            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   318
                        else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   319
                            local subscription = item.attr.subscription
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   320
                            if subscription ~= "both" and subscription ~= "to" and subscription ~= "from" and subscription ~= "none" then -- TODO error on invalid
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   321
                                subscription = roster[item_jid] and roster[item_jid].subscription or "none"
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   322
                            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   323
                            local r_item = {name = item.attr.name, groups = {}}
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   324
                            if r_item.name == "" then r_item.name = nil; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   325
                            r_item.subscription = subscription
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   326
                            if subscription ~= "both" and subscription ~= "to" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   327
                                r_item.ask = roster[item_jid] and roster[item_jid].ask
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   328
                            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   329
                            for _, child in ipairs(item) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   330
                                if child.name == "group" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   331
                                    local text = table.concat(child)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   332
                                    if text and text ~= "" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   333
                                        r_item.groups[text] = true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   334
                                    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   335
                                end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   336
                            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   337
                            local olditem = roster[item_jid]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   338
                            roster[item_jid] = r_item
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   339
                            if roster_manager.save_roster(from_node, from_host, roster) then -- Ok, send success
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   340
                                session.send(st.reply(stanza))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   341
                                -- and push change to all resources
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   342
                                roster_manager.roster_push(from_node, from_host, item_jid)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   343
                            else -- Adding to roster failed
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   344
                                roster[item_jid] = olditem
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   345
                                session.send(st.error_reply(stanza, "wait", "internal-server-error", "Unable to save roster"))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   346
                            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   347
                        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   348
                    else -- Trying to add self to roster
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   349
                        session.send(st.error_reply(stanza, "cancel", "not-allowed"))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   350
                    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   351
                else -- Invalid JID added to roster
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   352
                    module:log("warn", "resource: %s , host: %s", tostring(resource), tostring(host))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   353
                    session.send(st.error_reply(stanza, "modify", "bad-request")); -- FIXME what's the correct error?
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   354
                end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   355
            else -- Roster set didn't include a single item, or its name wasn't  'item'
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   356
                session.send(st.error_reply(stanza, "modify", "bad-request"))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   357
            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   358
        end -- for loop end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   359
        -- end of code adapted from mod_remote_roster
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   360
    else -- The permission is not granted
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   361
        module:log("warn", "Entity "..tostring(session.full_jid).." try to set roster without permission")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   362
        session.send(st.error_reply(stanza, 'auth', 'forbidden'))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   363
    end
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   364
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   365
    return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   366
end)
1665
69aa2b54ba8a mod_privilege: implemented message privilege
Goffi <goffi@goffi.org>
parents: 1664
diff changeset
   367
69aa2b54ba8a mod_privilege: implemented message privilege
Goffi <goffi@goffi.org>
parents: 1664
diff changeset
   368
69aa2b54ba8a mod_privilege: implemented message privilege
Goffi <goffi@goffi.org>
parents: 1664
diff changeset
   369
--> message permission <--
69aa2b54ba8a mod_privilege: implemented message privilege
Goffi <goffi@goffi.org>
parents: 1664
diff changeset
   370
3397
7454274ead2f mod_privilege: fixed routing issue with message permission:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
   371
local function clean_xmlns(node)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   372
    -- Recursively remove "jabber:client" attribute from node.
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   373
    -- In Prosody internal routing, xmlns should not be set.
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   374
    -- Keeping xmlns would lead to issues like mod_smacks ignoring the outgoing stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   375
    -- so we remove all xmlns attributes with a value of "jabber:client"
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   376
    if node.attr.xmlns == 'jabber:client' then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   377
        for childnode in node:childtags() do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   378
            clean_xmlns(childnode)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   379
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   380
        node.attr.xmlns = nil
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   381
    end
3397
7454274ead2f mod_privilege: fixed routing issue with message permission:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
   382
end
7454274ead2f mod_privilege: fixed routing issue with message permission:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
   383
1665
69aa2b54ba8a mod_privilege: implemented message privilege
Goffi <goffi@goffi.org>
parents: 1664
diff changeset
   384
module:hook("message/host", function(event)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   385
    local session, stanza = event.origin, event.stanza
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   386
    local privilege_elt = stanza:get_child('privilege', _PRIV_ENT_NS)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   387
    if privilege_elt==nil then return; end
1959
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
   388
    local _, to_host = jid.split(stanza.attr.to)
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
   389
    local session_privileges = get_session_privileges(session, to_host)
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
   390
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   391
    if session_privileges and session_privileges.message=="outgoing" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   392
        if #privilege_elt.tags==1 and privilege_elt.tags[1].name == "forwarded"
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   393
            and privilege_elt.tags[1].attr.xmlns==_FORWARDED_NS then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   394
            local message_elt = privilege_elt.tags[1]:get_child('message', 'jabber:client')
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   395
            if message_elt ~= nil then
4998
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   396
                local username, from_host, from_resource = jid.split(message_elt.attr.from)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   397
                if from_resource == nil and hosts[from_host] then -- we only accept bare jids from one of the server hosts
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   398
                    clean_xmlns(message_elt);  -- needed do to proper routing
4998
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   399
                    local session = {
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   400
                        username = username;
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   401
                        host = from_host;
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   402
                        type = "c2s";
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   403
                        log = module._log;
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   404
                    }
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   405
                    -- at this point everything should be alright, we can send the message
4998
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   406
                    prosody.core_post_stanza(session, message_elt, true)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   407
                else -- trying to send a message from a forbidden entity
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   408
                    module:log("warn", "Entity "..tostring(session.full_jid).." try to send a message from "..tostring(message_elt.attr.from))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   409
                    session.send(st.error_reply(stanza, 'auth', 'forbidden'))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   410
                end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   411
            else -- incorrect message child
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   412
                session.send(st.error_reply(stanza, "modify", "bad-request", "invalid forwarded <message/> element"))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   413
            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   414
        else -- incorrect forwarded child
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   415
            session.send(st.error_reply(stanza, "modify", "bad-request", "invalid <forwarded/> element"))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   416
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   417
    else -- The permission is not granted
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   418
        module:log("warn", "Entity "..tostring(session.full_jid).." try to send message without permission")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   419
        session.send(st.error_reply(stanza, 'auth', 'forbidden'))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   420
    end
1665
69aa2b54ba8a mod_privilege: implemented message privilege
Goffi <goffi@goffi.org>
parents: 1664
diff changeset
   421
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   422
    return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   423
end)
1668
6bdcb1418029 mod_privilege: implemented "managed_entity" presence
Goffi <goffi@goffi.org>
parents: 1667
diff changeset
   424
6bdcb1418029 mod_privilege: implemented "managed_entity" presence
Goffi <goffi@goffi.org>
parents: 1667
diff changeset
   425
6bdcb1418029 mod_privilege: implemented "managed_entity" presence
Goffi <goffi@goffi.org>
parents: 1667
diff changeset
   426
--> presence permission <--
6bdcb1418029 mod_privilege: implemented "managed_entity" presence
Goffi <goffi@goffi.org>
parents: 1667
diff changeset
   427
1711
64b3d1eb0cfe mod_privilege: fixed various issues reported by luacheck
Goffi <goffi@goffi.org>
parents: 1671
diff changeset
   428
local function same_tags(tag1, tag2)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   429
    -- check if two tags are equivalent
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   430
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   431
    if tag1.name ~= tag2.name then return false; end
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   432
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   433
    if #tag1 ~= #tag2 then return false; end
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   434
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   435
    for name, value in pairs(tag1.attr) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   436
        if tag2.attr[name] ~= value then return false; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   437
    end
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   438
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   439
    for i=1,#tag1 do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   440
        if type(tag1[i]) == "string" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   441
            if tag1[i] ~= tag2[i] then return false; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   442
        else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   443
            if not same_tags(tag1[i], tag2[i]) then return false; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   444
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   445
    end
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   446
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   447
    return true
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   448
end
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   449
1711
64b3d1eb0cfe mod_privilege: fixed various issues reported by luacheck
Goffi <goffi@goffi.org>
parents: 1671
diff changeset
   450
local function same_presences(presence1, presence2)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   451
    -- check that 2 <presence/> stanzas are equivalent (except for "to" attribute)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   452
    -- /!\ if the id change but everything else is equivalent, this method return false
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   453
    -- this behaviour may change in the future
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   454
    if presence1.attr.from ~= presence2.attr.from or presence1.attr.id ~= presence2.attr.id
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   455
        or presence1.attr.type ~= presence2.attr.type then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   456
        return false
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   457
    end
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   458
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   459
    if presence1.attr.id and presence1.attr.id == presence2.attr.id then return true; end
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   460
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   461
    if #presence1 ~= #presence2 then return false; end
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   462
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   463
    for i=1,#presence1 do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   464
        if type(presence1[i]) == "string" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   465
            if presence1[i] ~= presence2[i] then return false; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   466
        else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   467
            if not same_tags(presence1[i], presence2[i]) then return false; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   468
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   469
    end
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   470
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   471
    return true
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   472
end
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   473
1711
64b3d1eb0cfe mod_privilege: fixed various issues reported by luacheck
Goffi <goffi@goffi.org>
parents: 1671
diff changeset
   474
local function forward_presence(presence, to_jid)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   475
    local presence_fwd = st.clone(presence)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   476
    presence_fwd.attr.to = to_jid
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   477
    module:log("debug", "presence forwarded to "..to_jid..": "..tostring(presence_fwd))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   478
    module:send(presence_fwd)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   479
    -- cache used to avoid to send several times the same stanza
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   480
    priv_session.last_presence = presence
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   481
end
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   482
1668
6bdcb1418029 mod_privilege: implemented "managed_entity" presence
Goffi <goffi@goffi.org>
parents: 1667
diff changeset
   483
module:hook("presence/bare", function(event)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   484
    if presence_man_ent:empty() and presence_roster:empty() then return; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   485
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   486
    local stanza = event.stanza
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   487
    if stanza.attr.type == nil or stanza.attr.type == "unavailable" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   488
        if not stanza.attr.to then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   489
            for entity in presence_man_ent:items() do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   490
                if stanza.attr.from ~= entity then forward_presence(stanza, entity); end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   491
            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   492
        else -- directed presence
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   493
            -- we ignore directed presences from our own host, as we already have them
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   494
            local _, from_host = jid.split(stanza.attr.from)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   495
            if hosts[from_host] then return; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   496
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   497
            -- we don't send several time the same presence, as recommended in §7 #2
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   498
            if priv_session.last_presence and same_presences(priv_session.last_presence, stanza) then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   499
               return
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   500
            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   501
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   502
            for entity in presence_roster:items() do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   503
                if stanza.attr.from ~= entity then forward_presence(stanza, entity); end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   504
            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   505
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   506
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   507
end, 150)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   508
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   509
--> IQ permission <--
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   510
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   511
module:hook("iq/bare/".._PRIV_ENT_NS..":privileged_iq", function(event)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   512
    local session, stanza = event.origin, event.stanza
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   513
    if not stanza.attr.to then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   514
        -- we don't want stanzas addressed to /self
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   515
        return
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   516
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   517
    local from_node, from_host, from_resource = jid.split(stanza.attr.to)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   518
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   519
    if from_resource ~= nil or not usermanager_user_exists(from_node, from_host) then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   520
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   521
            st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   522
                stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   523
                "auth",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   524
                "forbidden",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   525
                "wrapping <IQ> stanza recipient must be a bare JID of a local user"
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   526
            )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   527
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   528
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   529
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   530
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   531
    local session_privileges = get_session_privileges(session, from_host)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   532
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   533
    if session_privileges == nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   534
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   535
            st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   536
                stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   537
                "auth",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   538
                "forbidden",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   539
                "no privilege granted"
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   540
            )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   541
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   542
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   543
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   544
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   545
    local iq_privileges = session_privileges["iq"]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   546
    if iq_privileges == nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   547
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   548
            session.send(st.error_reply(stanza, "auth", "forbidden", "you are not allowed to send privileged <IQ> stanzas"))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   549
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   550
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   551
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   552
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   553
    local privileged_iq = stanza:get_child("privileged_iq", _PRIV_ENT_NS)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   554
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   555
    local wrapped_iq = privileged_iq.tags[1]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   556
    if wrapped_iq == nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   557
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   558
            st.error_reply(stanza, "auth", "forbidden", "missing <IQ> stanza to send")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   559
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   560
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   561
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   562
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   563
    if wrapped_iq.attr.xmlns ~= "jabber:client" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   564
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   565
            st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   566
                stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   567
                "auth",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   568
                "forbidden",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   569
                'wrapped <IQ> must have a xmlns of "jabber:client"'
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   570
                )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   571
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   572
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   573
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   574
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   575
    clean_xmlns(wrapped_iq)
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   576
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   577
    if #wrapped_iq.tags ~= 1 then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   578
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   579
            st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   580
                stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   581
                "auth",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   582
                "forbidden",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   583
                'invalid payload in wrapped <IQ>'
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   584
                )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   585
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   586
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   587
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   588
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   589
    local payload = wrapped_iq.tags[1]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   590
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   591
    local priv_ns = payload.attr.xmlns
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   592
    if priv_ns == nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   593
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   594
            st.error_reply(stanza, "auth", "forbidden", "xmlns not set in privileged <IQ>")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   595
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   596
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   597
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   598
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   599
    local ns_perms = iq_privileges[priv_ns]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   600
    local iq_type = stanza.attr.type
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   601
    if ns_perms == nil or iq_type == nil or not ns_perms[iq_type] then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   602
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   603
            session.send(st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   604
                stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   605
                "auth",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   606
                "forbidden",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   607
                "you are not allowed to send privileged <IQ> stanzas of this type and namespace")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   608
            )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   609
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   610
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   611
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   612
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   613
    if wrapped_iq.attr.from ~= nil and wrapped_iq.attr.from ~= stanza.attr.to then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   614
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   615
            st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   616
                stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   617
                "auth",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   618
                "forbidden",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   619
                'wrapped <IQ> "from" attribute is inconsistent with main <IQ> "to" attribute'
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   620
            )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   621
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   622
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   623
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   624
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   625
    wrapped_iq.attr.from = stanza.attr.to
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   626
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   627
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   628
    if wrapped_iq.attr.type ~= iq_type then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   629
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   630
            st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   631
                stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   632
                "auth",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   633
                "forbidden",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   634
                'invalid wrapped <IQ>: type mismatch'
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   635
            )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   636
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   637
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   638
    end
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   639
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   640
    if wrapped_iq.attr.id == nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   641
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   642
            st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   643
                stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   644
                "auth",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   645
                "forbidden",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   646
                'invalid wrapped <IQ>: missing "id" attribute'
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   647
            )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   648
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   649
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   650
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   651
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   652
    -- at this point, wrapped_iq is considered valid, and privileged entity is allowed to send it
4998
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   653
    local username, from_host, _ = jid.split(wrapped_iq.attr.from)
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   654
    local newsession = {
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   655
        username = username;
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   656
        host = from_host;
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   657
	    full_jid = stanza.attr.to;
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   658
        type = "c2s";
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   659
        log = module._log;
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   660
    }
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   661
4998
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   662
    module:send_iq(wrapped_iq,newsession)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   663
        :next(function (response)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   664
            local reply = st.reply(stanza);
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   665
            response.stanza.attr.xmlns = 'jabber:client'
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   666
            reply:tag("privilege", {xmlns = _PRIV_ENT_NS})
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   667
            :tag("forwarded", {xmlns = _FORWARDED_NS})
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   668
            :add_child(response.stanza)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   669
            session.send(reply)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   670
        end,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   671
        function(response)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   672
            module:log("error", "Error while sending privileged <IQ>: %s", response);
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   673
            session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   674
                st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   675
                    stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   676
                    "cancel",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   677
                    "internal-server-error"
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   678
                )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   679
            )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   680
        end)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   681
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   682
    return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   683
end)