role.py 5.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# Copyright (c) 2017, Daniele Venzano
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Interface to PostgresQL for Zoe state."""

import logging

from zoe_lib.state.base import BaseTable, BaseRecord

log = logging.getLogger(__name__)


class Role(BaseRecord):
    """A role object describes the permissions of groups of users."""

    def __init__(self, d, sql_manager):
        super().__init__(d, sql_manager)

        self.name = d['name']
        self.can_see_status = d['can_see_status']
        self.can_change_config = d['can_change_config']
        self.can_operate_others = d['can_operate_others']
        self.can_delete_executions = d['can_delete_executions']
36
37
        self.can_access_api = d['can_access_api']
        self.can_customize_resources = d['can_customize_resources']
38
        self.can_access_full_zapp_shop = d['can_access_full_zapp_shop']
39
40
41
42
43
44
45
46
47

    def serialize(self):
        """Generates a dictionary that can be serialized in JSON."""
        return {
            'id': self.id,
            'name': self.name,
            'can_see_status': self.can_see_status,
            'can_change_config': self.can_change_config,
            'can_operate_others': self.can_operate_others,
48
49
            'can_delete_executions': self.can_delete_executions,
            'can_access_api': self.can_access_api,
50
51
            'can_customize_resources': self.can_customize_resources,
            'can_access_full_zapp_shop': self.can_access_full_zapp_shop
52
53
        }

54
55
56
57
58
59
60
61
62
    def __repr__(self):
        return self.name

    def __eq__(self, other):
        if isinstance(other, Role):
            return self.id == other.id
        else:
            return False

63
64
65
66
67
68
69
70
71
72
73
74
75
76

class RoleTable(BaseTable):
    """Abstraction for the role table in the database."""
    def __init__(self, sql_manager):
        super().__init__(sql_manager, "role")

    def create(self):
        """Create the role table."""
        self.cursor.execute('''CREATE TABLE role (
            id SERIAL PRIMARY KEY,
            name TEXT NOT NULL,
            can_see_status BOOLEAN NOT NULL DEFAULT FALSE,
            can_change_config BOOLEAN NOT NULL DEFAULT FALSE,
            can_operate_others BOOLEAN NOT NULL DEFAULT FALSE,
77
78
            can_delete_executions BOOLEAN NOT NULL DEFAULT FALSE,
            can_access_api BOOLEAN NOT NULL DEFAULT FALSE,
79
80
            can_customize_resources BOOLEAN NOT NULL DEFAULT FALSE,
            can_access_full_zapp_shop BOOLEAN NOT NULL DEFAULT FALSE
81
        )''')
82
83
        self.cursor.execute('''INSERT INTO role (id, name, can_see_status, can_change_config, can_operate_others, can_delete_executions, can_access_api, can_customize_resources, can_access_full_zapp_shop) VALUES (DEFAULT, 'admin', TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE)''')
        self.cursor.execute('''INSERT INTO role (id, name, can_see_status, can_access_api, can_customize_resources, can_access_full_zapp_shop) VALUES (DEFAULT, 'superuser', TRUE, TRUE, TRUE, TRUE)''')
84
        self.cursor.execute('''INSERT INTO role (id, name) VALUES (DEFAULT, 'user')''')
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

    def select(self, only_one=False, **kwargs):
        """
        Return a list of roles.

        :param only_one: only one result is expected
        :type only_one: bool
        :param kwargs: filter services based on their fields/columns
        :return: one or more ports
        """
        q_base = 'SELECT * FROM role'
        if len(kwargs) > 0:
            q = q_base + " WHERE "
            filter_list = []
            args_list = []
            for key, value in kwargs.items():
                filter_list.append('{} = %s'.format(key))
                args_list.append(value)
            q += ' AND '.join(filter_list)
            query = self.cursor.mogrify(q, args_list)
        else:
            query = self.cursor.mogrify(q_base)

        self.cursor.execute(query)
        if only_one:
            row = self.cursor.fetchone()
            if row is None:
                return None
113
            return Role(row, self.sql_manager)
114
        else:
115
            return [Role(x, self.sql_manager) for x in self.cursor]
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

    def insert(self, name):
        """Adds a new role to the state."""
        query = self.cursor.mogrify('INSERT INTO role (id, name) VALUES (DEFAULT, %s) RETURNING id', (name,))
        self.cursor.execute(query)
        self.sql_manager.commit()
        return self.cursor.fetchone()[0]

    def delete(self, role_id):
        """Delete a role from the state."""
        query = 'UPDATE "user" SET role_id = (SELECT id from role WHERE name=\'user\') WHERE role_id=%s'
        self.cursor.execute(query, (role_id,))
        query = "DELETE FROM role WHERE id = %s"
        self.cursor.execute(query, (role_id,))
        self.sql_manager.commit()