Projet

Général

Profil

0001-new-notify-command-to-handle-role-provisionning-depr.patch

Benjamin Dauvergne, 09 septembre 2015 09:41

Télécharger (4,83 ko)

Voir les différences:

Subject: [PATCH] new notify command to handle role
 provisionning/deprovisionning messages (fixes #8219)

It gets wcs roles from uuid or slug of the authentic2 role; if role is
using a slug it's replaced by the uuid. It handles rename by using uuid
as the slug of roles.

Targetted tenants are identified through their SAML entity id.
 wcs/ctl/notify.py | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 104 insertions(+)
 create mode 100644 wcs/ctl/notify.py
wcs/ctl/notify.py
1
# w.c.s. - web application for online forms
2
# Copyright (C) 2005-2014  Entr'ouvert
3
#
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, see <http://www.gnu.org/licenses/>.
16

  
17
import os
18
import sys
19
import json
20

  
21
from wcs.roles import Role
22
from qommon.ctl import Command
23
from qommon.publisher import get_cfg
24

  
25

  
26
class CmdNotify(Command):
27
    name = 'notify'
28

  
29
    def execute(self, base_options, sub_options, args):
30
        import publisher
31

  
32
        self.base_options = base_options
33
        if sub_options.extra:
34
            if not self.config.has_section('extra'):
35
                self.config.add_section('extra')
36
            for i, extra in enumerate(sub_options.extra):
37
                self.config.set('extra', 'cmd_line_extra_%d' % i, extra)
38
        publisher.WcsPublisher.configure(self.config)
39
        pub = publisher.WcsPublisher.create_publisher()
40

  
41
        global_app_dir = pub.app_dir
42

  
43
        if args[1] == '-':
44
            # get environment definition from stdin
45
            notification = json.load(sys.stdin)
46
        else:
47
            notification = json.load(file(args[1]))
48

  
49
        if not isinstance(notification, dict) \
50
            or '@type' not in notification \
51
            or notification['@type'] not in ['provision', 'deprovision'] \
52
            or 'objects' not in notification \
53
            or 'audience' not in notification \
54
            or not isinstance(notification['audience'], list) \
55
                or not isinstance(notification['objects'], list):
56
            sys.exit(1)
57
        action = notification['@type']
58
        audience = notification['audience']
59
        full = notification['full'] if full in notification else False
60
        for hostname in os.listdir(global_app_dir):
61
            pub.app_dir = os.path.join(global_app_dir, hostname)
62
            pub.set_config()
63
            # Verify tenant is in audience
64
            entity_id = get_cfg('sp', {}).get('saml2_providerid')
65
            if not entity_id or entity_id not in audience:
66
                continue
67

  
68
            uuids = set()
69
            # Now provision/deprovision
70
            for o in notification['objects']:
71
                t = o['@type']
72
                if t != 'role' \
73
                   or 'uuid' not in o \
74
                   or 'name' not in o \
75
                   or 'slug' not in o:
76
                    continue
77
                uuid = o['uuid'].encode(publisher.site_charset)
78
                uuids.add(uuid)
79
                slug = o['slug'].encode(publisher.site_charset)
80
                name = o['name'].encode(publisher.site_charset)
81
                # Find existing role
82
                try:
83
                    role = Role.get_on_index(uuid, 'slug')
84
                except KeyError:
85
                    try:
86
                        role = Role.get_on_index(slug, 'slug')
87
                    except KeyError:
88
                        # New role
89
                        if action != 'provision':
90
                            continue
91
                        role = Role(name=name)
92
                if action == 'provision':
93
                    # Provision/rename
94
                    role.name = name
95
                    role.slug = uuid
96
                    role.store()
97
                elif action == 'provision':
98
                    # Deprovision
99
                    role.remove_self()
100
            # All roles have been sent
101
            if full:
102
                for role in Role.select():
103
                    if role.slug not in uuids:
104
                        role.remove_self()
0
-