PermissionsMixin.create_permission()   D
last analyzed

Complexity

Conditions 12

Size

Total Lines 83
Code Lines 49

Duplication

Lines 31
Ratio 37.35 %

Importance

Changes 0
Metric Value
cc 12
eloc 49
nop 8
dl 31
loc 83
rs 4.8
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like gvm.protocols.gmpv208.entities.permissions.PermissionsMixin.create_permission() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
# -*- coding: utf-8 -*-
2
# Copyright (C) 2021 Greenbone Networks GmbH
3
#
4
# SPDX-License-Identifier: GPL-3.0-or-later
5
#
6
# This program is free software: you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation, either version 3 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
19
from enum import Enum
20
from typing import Any, Optional
21
22
from gvm.errors import RequiredArgument, InvalidArgument, InvalidArgumentType
23
from gvm.protocols.gmpv208.entities.entities import EntityType
24
from gvm.utils import add_filter, to_bool
25
from gvm.xml import XmlCommand
26
27
28
class PermissionSubjectType(Enum):
29
    """Enum for permission subject type"""
30
31
    USER = 'user'
32
    GROUP = 'group'
33
    ROLE = 'role'
34
35
36
def get_permission_subject_type_from_string(
37
    subject_type: Optional[str],
38
) -> Optional[PermissionSubjectType]:
39
    """Convert a permission subject type string to an actual
40
    PermissionSubjectType instance
41
42
    Arguments:
43
        subject_type: Permission subject type string to convert to a
44
            PermissionSubjectType
45
    """
46
    if not subject_type:
47
        return None
48
49
    try:
50
        return PermissionSubjectType[subject_type.upper()]
51
    except KeyError:
52
        raise InvalidArgument(
53
            argument='subject_type',
54
            function=get_permission_subject_type_from_string.__name__,
55
        ) from None
56
57
58
class PermissionsMixin:
59
    def clone_permission(self, permission_id: str) -> Any:
60
        """Clone an existing permission
61
62
        Arguments:
63
            permission_id: UUID of an existing permission to clone from
64
65
        Returns:
66
            The response. See :py:meth:`send_command` for details.
67
        """
68
        if not permission_id:
69
            raise RequiredArgument(
70
                function=self.clone_permission.__name__,
71
                argument='permission_id',
72
            )
73
74
        cmd = XmlCommand("create_permission")
75
        cmd.add_element("copy", permission_id)
76
        return self._send_xml_command(cmd)
77
78
    def create_permission(
79
        self,
80
        name: str,
81
        subject_id: str,
82
        subject_type: PermissionSubjectType,
83
        *,
84
        resource_id: Optional[str] = None,
85
        resource_type: Optional[EntityType] = None,
86
        comment: Optional[str] = None,
87
    ) -> Any:
88
        """Create a new permission
89
90
        Arguments:
91
            name: Name of the new permission
92
            subject_id: UUID of subject to whom the permission is granted
93
            subject_type: Type of the subject user, group or role
94
            comment: Comment for the permission
95
            resource_id: UUID of entity to which the permission applies
96
            resource_type: Type of the resource. For Super permissions user,
97
                group or role
98
99
        Returns:
100
            The response. See :py:meth:`send_command` for details.
101
        """
102
        if not name:
103
            raise RequiredArgument(
104
                function=self.create_permission.__name__, argument='name'
105
            )
106
107
        if not subject_id:
108
            raise RequiredArgument(
109
                function=self.create_permission.__name__, argument='subject_id'
110
            )
111
112
        if not isinstance(subject_type, PermissionSubjectType):
113
            raise InvalidArgumentType(
114
                function=self.create_permission.__name__,
115
                argument='subject_type',
116
                arg_type=PermissionSubjectType.__name__,
117
            )
118
119
        cmd = XmlCommand("create_permission")
120
        cmd.add_element("name", name)
121
122
        _xmlsubject = cmd.add_element("subject", attrs={"id": subject_id})
123
        _xmlsubject.add_element("type", subject_type.value)
124
125
        if comment:
126
            cmd.add_element("comment", comment)
127
128 View Code Duplication
        if resource_id or resource_type:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
129
            if not resource_id:
130
                raise RequiredArgument(
131
                    function=self.create_permission.__name__,
132
                    argument='resource_id',
133
                )
134
135
            if not resource_type:
136
                raise RequiredArgument(
137
                    function=self.create_permission.__name__,
138
                    argument='resource_type',
139
                )
140
141
            if not isinstance(resource_type, EntityType):
142
                raise InvalidArgumentType(
143
                    function=self.create_permission.__name__,
144
                    argument='resource_type',
145
                    arg_type=EntityType.__name__,
146
                )
147
148
            _xmlresource = cmd.add_element(
149
                "resource", attrs={"id": resource_id}
150
            )
151
152
            _actual_resource_type = resource_type
153
            if resource_type.value == EntityType.AUDIT.value:
154
                _actual_resource_type = EntityType.TASK
155
            elif resource_type.value == EntityType.POLICY.value:
156
                _actual_resource_type = EntityType.SCAN_CONFIG
157
158
            _xmlresource.add_element("type", _actual_resource_type.value)
159
160
        return self._send_xml_command(cmd)
161
162
    def delete_permission(
163
        self, permission_id: str, *, ultimate: Optional[bool] = False
164
    ) -> Any:
165
        """Deletes an existing permission
166
167
        Arguments:
168
            permission_id: UUID of the permission to be deleted.
169
            ultimate: Whether to remove entirely, or to the trashcan.
170
        """
171
        if not permission_id:
172
            raise RequiredArgument(
173
                function=self.delete_permission.__name__,
174
                argument='permission_id',
175
            )
176
177
        cmd = XmlCommand("delete_permission")
178
        cmd.set_attribute("permission_id", permission_id)
179
        cmd.set_attribute("ultimate", to_bool(ultimate))
180
181
        return self._send_xml_command(cmd)
182
183 View Code Duplication
    def get_permissions(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
184
        self,
185
        *,
186
        filter_string: Optional[str] = None,
187
        filter_id: Optional[str] = None,
188
        trash: Optional[bool] = None,
189
    ) -> Any:
190
        """Request a list of permissions
191
192
        Arguments:
193
            filter_string: Filter term to use for the query
194
            filter_id: UUID of an existing filter to use for the query
195
            trash: Whether to get permissions in the trashcan instead
196
197
        Returns:
198
            The response. See :py:meth:`send_command` for details.
199
        """
200
        cmd = XmlCommand("get_permissions")
201
202
        add_filter(cmd, filter_string, filter_id)
203
204
        if trash is not None:
205
            cmd.set_attribute("trash", to_bool(trash))
206
207
        return self._send_xml_command(cmd)
208
209
    def get_permission(self, permission_id: str) -> Any:
210
        """Request a single permission
211
212
        Arguments:
213
            permission_id: UUID of an existing permission
214
215
        Returns:
216
            The response. See :py:meth:`send_command` for details.
217
        """
218
        cmd = XmlCommand("get_permissions")
219
220
        if not permission_id:
221
            raise RequiredArgument(
222
                function=self.get_permission.__name__, argument='permission_id'
223
            )
224
225
        cmd.set_attribute("permission_id", permission_id)
226
        return self._send_xml_command(cmd)
227
228
    def modify_permission(
229
        self,
230
        permission_id: str,
231
        *,
232
        comment: Optional[str] = None,
233
        name: Optional[str] = None,
234
        resource_id: Optional[str] = None,
235
        resource_type: Optional[EntityType] = None,
236
        subject_id: Optional[str] = None,
237
        subject_type: Optional[PermissionSubjectType] = None,
238
    ) -> Any:
239
        """Modifies an existing permission.
240
241
        Arguments:
242
            permission_id: UUID of permission to be modified.
243
            comment: The comment on the permission.
244
            name: Permission name, currently the name of a command.
245
            subject_id: UUID of subject to whom the permission is granted
246
            subject_type: Type of the subject user, group or role
247
            resource_id: UUID of entity to which the permission applies
248
            resource_type: Type of the resource. For Super permissions user,
249
                group or role
250
251
        Returns:
252
            The response. See :py:meth:`send_command` for details.
253
        """
254
        if not permission_id:
255
            raise RequiredArgument(
256
                function=self.modify_permission.__name__,
257
                argument='permission_id',
258
            )
259
260
        cmd = XmlCommand("modify_permission")
261
        cmd.set_attribute("permission_id", permission_id)
262
263
        if comment:
264
            cmd.add_element("comment", comment)
265
266
        if name:
267
            cmd.add_element("name", name)
268
269 View Code Duplication
        if resource_id or resource_type:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
270
            if not resource_id:
271
                raise RequiredArgument(
272
                    function=self.modify_permission.__name__,
273
                    argument='resource_id',
274
                )
275
276
            if not resource_type:
277
                raise RequiredArgument(
278
                    function=self.modify_permission.__name__,
279
                    argument='resource_type',
280
                )
281
282
            if not isinstance(resource_type, EntityType):
283
                raise InvalidArgumentType(
284
                    function=self.modify_permission.__name__,
285
                    argument='resource_type',
286
                    arg_type=EntityType.__name__,
287
                )
288
289
            _xmlresource = cmd.add_element(
290
                "resource", attrs={"id": resource_id}
291
            )
292
            _actual_resource_type = resource_type
293
            if resource_type.value == EntityType.AUDIT.value:
294
                _actual_resource_type = EntityType.TASK
295
            elif resource_type.value == EntityType.POLICY.value:
296
                _actual_resource_type = EntityType.SCAN_CONFIG
297
            _xmlresource.add_element("type", _actual_resource_type.value)
298
299
        if subject_id or subject_type:
300
            if not subject_id:
301
                raise RequiredArgument(
302
                    function=self.modify_permission.__name__,
303
                    argument='subject_id',
304
                )
305
306
            if not isinstance(subject_type, PermissionSubjectType):
307
                raise InvalidArgumentType(
308
                    function=self.modify_permission.__name__,
309
                    argument='subject_type',
310
                    arg_type=PermissionSubjectType.__name__,
311
                )
312
313
            _xmlsubject = cmd.add_element("subject", attrs={"id": subject_id})
314
            _xmlsubject.add_element("type", subject_type.value)
315
316
        return self._send_xml_command(cmd)
317