mod_privilege/mod_privilege.lua
author Ben Smith <bens@effortlessis.com>
Tue, 14 May 2024 07:31:34 -0700
changeset 5912 dcea4b4c415d
parent 5877 a88c43de648c
permissions -rw-r--r--
Tweaking documentation to clarify that Oauth2 can be used for VirtualHosts and Component installations.
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
5877
a88c43de648c mod_privilege: Fix IQ privileges advertising for multiple namespaces
nicoco <nicoco@nicoco.fr>
parents: 4998
diff changeset
    72
        local perm_el = st.stanza("perm", {access="iq"})
4941
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
5877
a88c43de648c mod_privilege: Fix IQ privileges advertising for multiple namespaces
nicoco <nicoco@nicoco.fr>
parents: 4998
diff changeset
    84
                perm_el:tag("namespace", {ns=namespace, type=perm_type}):up()
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    85
        end
5877
a88c43de648c mod_privilege: Fix IQ privileges advertising for multiple namespaces
nicoco <nicoco@nicoco.fr>
parents: 4998
diff changeset
    86
        message:add_child(perm_el)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    87
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    88
    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
    89
end
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
    90
1711
64b3d1eb0cfe mod_privilege: fixed various issues reported by luacheck
Goffi <goffi@goffi.org>
parents: 1671
diff changeset
    91
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
    92
    -- fill the presence sets according to perms
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    93
    if _PRESENCE_MANAGED:contains(perms.presence) then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    94
        presence_man_ent:add(to_jid)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    95
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    96
    if perms.presence == 'roster' then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    97
        presence_roster:add(to_jid)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    98
    end
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
    99
end
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
   100
1711
64b3d1eb0cfe mod_privilege: fixed various issues reported by luacheck
Goffi <goffi@goffi.org>
parents: 1671
diff changeset
   101
local function advertise_presences(session, to_jid, perms)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   102
    -- send presence status for already connected entities
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   103
    -- as explained in § 7.1
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   104
    -- people in roster are probed only for active sessions
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   105
    -- TODO: manage roster load for inactive sessions
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   106
    if not perms.presence then return; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   107
    local to_probe = {}
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   108
    for _, user_session in pairs(full_sessions) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   109
        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
   110
            local presence = st.clone(user_session.presence)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   111
            presence.attr.to = to_jid
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   112
            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
   113
            session.send(presence)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   114
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   115
        if perms.presence == "roster" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   116
            -- 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
   117
            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
   118
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   119
            if user_session.roster then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   120
                local bare_jid = jid.bare(user_session.full_jid)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   121
                for entity, item in pairs(user_session.roster) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   122
                    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
   123
                        local _, host = jid.split(entity)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   124
                        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
   125
                            -- 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
   126
                            to_probe[entity] = bare_jid
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
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   132
    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
   133
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   134
    -- now we probe peoples for "roster" presence permission
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   135
    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
   136
        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
   137
        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
   138
        prosody.core_route_stanza(nil, probe)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   139
    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
   140
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
   141
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   142
1711
64b3d1eb0cfe mod_privilege: fixed various issues reported by luacheck
Goffi <goffi@goffi.org>
parents: 1671
diff changeset
   143
local function on_auth(event)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   144
    -- Check if entity is privileged according to configuration,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   145
    -- and set session.privileges accordingly
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   146
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   147
    local session = event.session
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   148
    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
   149
    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
   150
        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
   151
    end
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
   152
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   153
    local conf_ent_priv = config_priv[bare_jid]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   154
    local ent_priv = {}
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   155
    if conf_ent_priv ~= nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   156
        module:log("debug", "Entity is privileged")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   157
        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
   158
            local value = conf_ent_priv[perm_type]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   159
            if value ~= nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   160
                if not allowed_values:contains(value) then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   161
                    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
   162
                    module:log('warn', 'Setting '..perm_type..' privilege to none')
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   163
                    ent_priv[perm_type] = nil
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   164
                elseif value == 'none' then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   165
                    ent_priv[perm_type] = nil
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   166
                else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   167
                    ent_priv[perm_type] = value
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   168
                end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   169
            else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   170
                ent_priv[perm_type] = nil
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
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   173
        -- extra checks for presence permission
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   174
        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
   175
            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
   176
            module:log("warn", "Setting presence permission to none")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   177
            ent_priv.presence = nil
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   178
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   179
        -- iq permission
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   180
        local iq_perm_config = conf_ent_priv["iq"]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   181
        if iq_perm_config ~= nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   182
            local iq_perm = {}
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   183
            ent_priv["iq"] = iq_perm
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   184
            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
   185
                iq_perm[ns] = {
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   186
                    ["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
   187
                    ["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
   188
                }
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   189
            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   190
        else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   191
            ent_priv["iq"] = nil
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   192
        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
   193
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   194
        if session.type == "component" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   195
            -- we send the message stanza only for component
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   196
            -- 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
   197
            advertise_perm(session, bare_jid, ent_priv)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   198
            set_presence_perm_set(bare_jid, ent_priv)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   199
            advertise_presences(session, bare_jid, ent_priv)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   200
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   201
    end
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
   202
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   203
    session.privileges[_MODULE_HOST] = ent_priv
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
   204
end
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
   205
1711
64b3d1eb0cfe mod_privilege: fixed various issues reported by luacheck
Goffi <goffi@goffi.org>
parents: 1671
diff changeset
   206
local function on_presence(event)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   207
    -- Permission are already checked at this point,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   208
    -- we only advertise them to the entity
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   209
    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
   210
    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
   211
    if session_privileges then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   212
        advertise_perm(session, session.full_jid, session_privileges)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   213
        set_presence_perm_set(session.full_jid, session_privileges)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   214
        advertise_presences(session, session.full_jid, session_privileges)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   215
    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
   216
end
495a093798eb mod_privilege: added permissions notification on initial presence for entities which are not components
Goffi <goffi@goffi.org>
parents: 1662
diff changeset
   217
1712
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
   218
local function on_component_auth(event)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   219
    -- react to component-authenticated event from this host
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   220
    -- 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
   221
    -- needed for the component to get delegations advertising
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   222
    for callback in connected_cb:items() do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   223
        callback(event)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   224
    end
1712
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
   225
end
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
   226
1779
0d78bb31348e mod_privilege: fixed bad calling of on_auth for components
Goffi <goffi@goffi.org>
parents: 1712
diff changeset
   227
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
   228
    connected_cb:add(on_auth)
0d78bb31348e mod_privilege: fixed bad calling of on_auth for components
Goffi <goffi@goffi.org>
parents: 1712
diff changeset
   229
end
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
   230
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
   231
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
   232
module:hook('presence/initial', on_presence)
1662
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
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
   235
--> roster permission <--
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
   236
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   237
-- get
1662
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
   238
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
   239
    local session, stanza = event.origin, event.stanza
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   240
    if not stanza.attr.to then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   241
        -- we don't want stanzas addressed to /self
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   242
        return
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   243
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   244
    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
   245
    local session_privileges = get_session_privileges(session, host)
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   246
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   247
    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
   248
        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
   249
        -- following code is adapted from mod_remote_roster
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   250
        local roster = roster_manager.load_roster(node, host)
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   251
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   252
        local reply = st.reply(stanza):query("jabber:iq:roster")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   253
        for entity_jid, item in pairs(roster) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   254
            if entity_jid and entity_jid ~= "pending" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   255
                reply:tag("item", {
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   256
                    jid = entity_jid,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   257
                    subscription = item.subscription,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   258
                    ask = item.ask,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   259
                    name = item.name,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   260
                })
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   261
                for group in pairs(item.groups) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   262
                    reply:tag("group"):text(group):up()
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   263
                end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   264
                reply:up(); -- move out from item
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
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   267
        -- end of code adapted from mod_remote_roster
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   268
        session.send(reply)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   269
    else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   270
        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
   271
        session.send(st.error_reply(stanza, 'auth', 'forbidden'))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   272
    end
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   273
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   274
    return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   275
end)
1662
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
   276
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   277
-- set
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   278
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
   279
    local session, stanza = event.origin, event.stanza
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   280
    if not stanza.attr.to then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   281
        -- we don't want stanzas addressed to /self
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   282
        return
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   283
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   284
    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
   285
    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
   286
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   287
    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
   288
        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
   289
        -- following code is adapted from mod_remote_roster
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   290
        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
   291
        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
   292
        if not(roster) then return; end
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   293
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   294
        local query = stanza.tags[1]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   295
        for _, item in ipairs(query.tags) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   296
            if item.name == "item"
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   297
                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
   298
                    -- Protection against overwriting roster.pending, until we move it
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   299
                and item.attr.jid ~= "pending" then
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   300
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   301
                local item_jid = jid.prep(item.attr.jid)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   302
                local _, host, resource = jid.split(item_jid)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   303
                if not resource then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   304
                    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
   305
                        if item.attr.subscription == "remove" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   306
                            local r_item = roster[item_jid]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   307
                            if r_item then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   308
                                roster[item_jid] = nil
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   309
                                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
   310
                                    session.send(st.reply(stanza))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   311
                                    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
   312
                                else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   313
                                    roster[item_jid] = item
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   314
                                    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
   315
                                end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   316
                            else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   317
                                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
   318
                            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   319
                        else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   320
                            local subscription = item.attr.subscription
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   321
                            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
   322
                                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
   323
                            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   324
                            local r_item = {name = item.attr.name, groups = {}}
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   325
                            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
   326
                            r_item.subscription = subscription
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   327
                            if subscription ~= "both" and subscription ~= "to" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   328
                                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
   329
                            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   330
                            for _, child in ipairs(item) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   331
                                if child.name == "group" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   332
                                    local text = table.concat(child)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   333
                                    if text and text ~= "" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   334
                                        r_item.groups[text] = true
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
                            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   338
                            local olditem = roster[item_jid]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   339
                            roster[item_jid] = r_item
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   340
                            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
   341
                                session.send(st.reply(stanza))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   342
                                -- and push change to all resources
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   343
                                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
   344
                            else -- Adding to roster failed
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   345
                                roster[item_jid] = olditem
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   346
                                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
   347
                            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   348
                        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   349
                    else -- Trying to add self to roster
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   350
                        session.send(st.error_reply(stanza, "cancel", "not-allowed"))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   351
                    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   352
                else -- Invalid JID added to roster
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   353
                    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
   354
                    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
   355
                end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   356
            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
   357
                session.send(st.error_reply(stanza, "modify", "bad-request"))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   358
            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   359
        end -- for loop end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   360
        -- end of code adapted from mod_remote_roster
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   361
    else -- The permission is not granted
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   362
        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
   363
        session.send(st.error_reply(stanza, 'auth', 'forbidden'))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   364
    end
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   365
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   366
    return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   367
end)
1665
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
69aa2b54ba8a mod_privilege: implemented message privilege
Goffi <goffi@goffi.org>
parents: 1664
diff changeset
   370
--> message permission <--
69aa2b54ba8a mod_privilege: implemented message privilege
Goffi <goffi@goffi.org>
parents: 1664
diff changeset
   371
3397
7454274ead2f mod_privilege: fixed routing issue with message permission:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
   372
local function clean_xmlns(node)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   373
    -- Recursively remove "jabber:client" attribute from node.
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   374
    -- In Prosody internal routing, xmlns should not be set.
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   375
    -- 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
   376
    -- 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
   377
    if node.attr.xmlns == 'jabber:client' then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   378
        for childnode in node:childtags() do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   379
            clean_xmlns(childnode)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   380
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   381
        node.attr.xmlns = nil
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   382
    end
3397
7454274ead2f mod_privilege: fixed routing issue with message permission:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
   383
end
7454274ead2f mod_privilege: fixed routing issue with message permission:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
   384
1665
69aa2b54ba8a mod_privilege: implemented message privilege
Goffi <goffi@goffi.org>
parents: 1664
diff changeset
   385
module:hook("message/host", function(event)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   386
    local session, stanza = event.origin, event.stanza
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   387
    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
   388
    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
   389
    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
   390
    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
   391
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   392
    if session_privileges and session_privileges.message=="outgoing" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   393
        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
   394
            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
   395
            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
   396
            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
   397
                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
   398
                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
   399
                    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
   400
                    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
   401
                        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
   402
                        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
   403
                        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
   404
                        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
   405
                    }
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   406
                    -- 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
   407
                    prosody.core_post_stanza(session, message_elt, true)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   408
                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
   409
                    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
   410
                    session.send(st.error_reply(stanza, 'auth', 'forbidden'))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   411
                end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   412
            else -- incorrect message child
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   413
                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
   414
            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   415
        else -- incorrect forwarded child
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   416
            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
   417
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   418
    else -- The permission is not granted
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   419
        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
   420
        session.send(st.error_reply(stanza, 'auth', 'forbidden'))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   421
    end
1665
69aa2b54ba8a mod_privilege: implemented message privilege
Goffi <goffi@goffi.org>
parents: 1664
diff changeset
   422
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   423
    return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   424
end)
1668
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
6bdcb1418029 mod_privilege: implemented "managed_entity" presence
Goffi <goffi@goffi.org>
parents: 1667
diff changeset
   427
--> presence permission <--
6bdcb1418029 mod_privilege: implemented "managed_entity" presence
Goffi <goffi@goffi.org>
parents: 1667
diff changeset
   428
1711
64b3d1eb0cfe mod_privilege: fixed various issues reported by luacheck
Goffi <goffi@goffi.org>
parents: 1671
diff changeset
   429
local function same_tags(tag1, tag2)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   430
    -- check if two tags are equivalent
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   431
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   432
    if tag1.name ~= tag2.name then return false; end
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   433
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   434
    if #tag1 ~= #tag2 then return false; end
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   435
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   436
    for name, value in pairs(tag1.attr) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   437
        if tag2.attr[name] ~= value then return false; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   438
    end
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   439
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   440
    for i=1,#tag1 do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   441
        if type(tag1[i]) == "string" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   442
            if tag1[i] ~= tag2[i] then return false; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   443
        else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   444
            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
   445
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   446
    end
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   447
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   448
    return true
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   449
end
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   450
1711
64b3d1eb0cfe mod_privilege: fixed various issues reported by luacheck
Goffi <goffi@goffi.org>
parents: 1671
diff changeset
   451
local function same_presences(presence1, presence2)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   452
    -- 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
   453
    -- /!\ 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
   454
    -- this behaviour may change in the future
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   455
    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
   456
        or presence1.attr.type ~= presence2.attr.type then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   457
        return false
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   458
    end
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   459
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   460
    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
   461
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   462
    if #presence1 ~= #presence2 then return false; end
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   463
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   464
    for i=1,#presence1 do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   465
        if type(presence1[i]) == "string" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   466
            if presence1[i] ~= presence2[i] then return false; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   467
        else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   468
            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
   469
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   470
    end
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   471
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   472
    return true
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   473
end
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   474
1711
64b3d1eb0cfe mod_privilege: fixed various issues reported by luacheck
Goffi <goffi@goffi.org>
parents: 1671
diff changeset
   475
local function forward_presence(presence, to_jid)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   476
    local presence_fwd = st.clone(presence)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   477
    presence_fwd.attr.to = to_jid
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   478
    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
   479
    module:send(presence_fwd)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   480
    -- 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
   481
    priv_session.last_presence = presence
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   482
end
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   483
1668
6bdcb1418029 mod_privilege: implemented "managed_entity" presence
Goffi <goffi@goffi.org>
parents: 1667
diff changeset
   484
module:hook("presence/bare", function(event)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   485
    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
   486
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   487
    local stanza = event.stanza
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   488
    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
   489
        if not stanza.attr.to then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   490
            for entity in presence_man_ent:items() do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   491
                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
   492
            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   493
        else -- directed presence
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   494
            -- 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
   495
            local _, from_host = jid.split(stanza.attr.from)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   496
            if hosts[from_host] then return; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   497
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   498
            -- 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
   499
            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
   500
               return
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   501
            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   502
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   503
            for entity in presence_roster:items() do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   504
                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
   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
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   508
end, 150)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   509
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   510
--> IQ permission <--
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   511
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   512
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
   513
    local session, stanza = event.origin, event.stanza
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   514
    if not stanza.attr.to then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   515
        -- we don't want stanzas addressed to /self
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   516
        return
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   517
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   518
    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
   519
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   520
    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
   521
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   522
            st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   523
                stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   524
                "auth",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   525
                "forbidden",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   526
                "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
   527
            )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   528
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   529
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   530
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   531
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   532
    local session_privileges = get_session_privileges(session, from_host)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   533
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   534
    if session_privileges == nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   535
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   536
            st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   537
                stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   538
                "auth",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   539
                "forbidden",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   540
                "no privilege granted"
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
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   543
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   544
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   545
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   546
    local iq_privileges = session_privileges["iq"]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   547
    if iq_privileges == nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   548
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   549
            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
   550
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   551
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   552
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   553
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   554
    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
   555
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   556
    local wrapped_iq = privileged_iq.tags[1]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   557
    if wrapped_iq == nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   558
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   559
            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
   560
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   561
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   562
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   563
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   564
    if wrapped_iq.attr.xmlns ~= "jabber:client" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   565
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   566
            st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   567
                stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   568
                "auth",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   569
                "forbidden",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   570
                'wrapped <IQ> must have a xmlns of "jabber:client"'
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
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   573
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   574
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   575
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   576
    clean_xmlns(wrapped_iq)
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   577
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   578
    if #wrapped_iq.tags ~= 1 then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   579
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   580
            st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   581
                stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   582
                "auth",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   583
                "forbidden",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   584
                'invalid payload in wrapped <IQ>'
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
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   587
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   588
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   589
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   590
    local payload = wrapped_iq.tags[1]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   591
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   592
    local priv_ns = payload.attr.xmlns
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   593
    if priv_ns == nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   594
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   595
            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
   596
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   597
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   598
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   599
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   600
    local ns_perms = iq_privileges[priv_ns]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   601
    local iq_type = stanza.attr.type
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   602
    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
   603
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   604
            session.send(st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   605
                stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   606
                "auth",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   607
                "forbidden",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   608
                "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
   609
            )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   610
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   611
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   612
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   613
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   614
    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
   615
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   616
            st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   617
                stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   618
                "auth",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   619
                "forbidden",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   620
                '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
   621
            )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   622
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   623
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   624
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   625
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   626
    wrapped_iq.attr.from = stanza.attr.to
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   627
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   628
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   629
    if wrapped_iq.attr.type ~= iq_type then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   630
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   631
            st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   632
                stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   633
                "auth",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   634
                "forbidden",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   635
                'invalid wrapped <IQ>: type mismatch'
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
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   638
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   639
    end
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   640
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   641
    if wrapped_iq.attr.id == nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   642
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   643
            st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   644
                stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   645
                "auth",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   646
                "forbidden",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   647
                'invalid wrapped <IQ>: missing "id" attribute'
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
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   650
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   651
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   652
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   653
    -- 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
   654
    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
   655
    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
   656
        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
   657
        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
   658
	    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
   659
        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
   660
        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
   661
    }
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   662
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
   663
    module:send_iq(wrapped_iq,newsession)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   664
        :next(function (response)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   665
            local reply = st.reply(stanza);
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   666
            response.stanza.attr.xmlns = 'jabber:client'
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   667
            reply:tag("privilege", {xmlns = _PRIV_ENT_NS})
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   668
            :tag("forwarded", {xmlns = _FORWARDED_NS})
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   669
            :add_child(response.stanza)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   670
            session.send(reply)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   671
        end,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   672
        function(response)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   673
            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
   674
            session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   675
                st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   676
                    stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   677
                    "cancel",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   678
                    "internal-server-error"
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
            )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   681
        end)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   682
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   683
    return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   684
end)