Passed
Pull Request — master (#467)
by Jaspar
10:26
created

UsersMixin.modify_user()   D

Complexity

Conditions 13

Size

Total Lines 93
Code Lines 47

Duplication

Lines 93
Ratio 100 %

Importance

Changes 0
Metric Value
cc 13
eloc 47
nop 13
dl 93
loc 93
rs 4.2
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.gmpv214.entities.users.UsersMixin.modify_user() 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
# pylint:  disable=redefined-builtin, arguments-differ
20
# MAYBE we should change filter to filter_string (everywhere)
21
22
from typing import Any, List, Optional
23
24
from gvm.errors import RequiredArgument
25
from gvm.protocols.gmpv208.entities.users import (
26
    UsersMixin as Gmp208UsersMixin,
27
    UserAuthType,
28
)
29
from gvm.utils import to_comma_list, to_bool
30
from gvm.xml import XmlCommand
31
32
33
class UsersMixin(Gmp208UsersMixin):
34 View Code Duplication
    def modify_user(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
35
        self,
36
        user_id: str = None,
37
        *,
38
        name: Optional[str] = None,
39
        comment: Optional[str] = None,
40
        password: Optional[str] = None,
41
        auth_source: Optional[UserAuthType] = None,
42
        role_ids: Optional[List[str]] = None,
43
        hosts: Optional[List[str]] = None,
44
        hosts_allow: Optional[bool] = False,
45
        ifaces: Optional[List[str]] = None,
46
        ifaces_allow: Optional[bool] = False,
47
        group_ids: Optional[List[str]] = None,
48
    ) -> Any:
49
50
        """Modifies an existing user. Most of the fields need to be supplied
51
        for changing a single field even if no change is wanted for those.
52
        Else empty values are inserted for the missing fields instead.
53
54
        Arguments:
55
            user_id: UUID of the user to be modified.
56
            name: The new name for the user.
57
            comment: Comment on the user.
58
            password: The password for the user.
59
            auth_source: Source allowed for authentication for this user.
60
            roles_id: List of roles UUIDs for the user.
61
            hosts: User access rules: List of hosts.
62
            hosts_allow: Defines how the hosts list is to be interpreted.
63
                If False (default) the list is treated as a deny list.
64
                All hosts are allowed by default except those provided by
65
                the hosts parameter. If True the list is treated as a
66
                allow list. All hosts are denied by default except those
67
                provided by the hosts parameter.
68
            ifaces: User access rules: List of ifaces.
69
            ifaces_allow: Defines how the ifaces list is to be interpreted.
70
                If False (default) the list is treated as a deny list.
71
                All ifaces are allowed by default except those provided by
72
                the ifaces parameter. If True the list is treated as a
73
                allow list. All ifaces are denied by default except those
74
                provided by the ifaces parameter.
75
            group_ids: List of group UUIDs for the user.
76
77
        Returns:
78
            The response. See :py:meth:`send_command` for details.
79
        """
80
        if not user_id:
81
            raise RequiredArgument(
82
                function=self.modify_user.__name__, argument='user_id'
83
            )
84
85
        cmd = XmlCommand("modify_user")
86
87
        if user_id:
88
            cmd.set_attribute("user_id", user_id)
89
90
        if name:
91
            cmd.add_element("new_name", name)
92
93
        if role_ids:
94
            for role in role_ids:
95
                cmd.add_element("role", attrs={"id": role})
96
97
        if hosts:
98
            cmd.add_element(
99
                "hosts",
100
                to_comma_list(hosts),
101
                attrs={"allow": to_bool(hosts_allow)},
102
            )
103
104
        if ifaces:
105
            cmd.add_element(
106
                "ifaces",
107
                to_comma_list(ifaces),
108
                attrs={"allow": to_bool(ifaces_allow)},
109
            )
110
111
        if comment:
112
            cmd.add_element("comment", comment)
113
114
        if password:
115
            cmd.add_element("password", password)
116
117
        if auth_source:
118
            _xmlauthsrc = cmd.add_element("sources")
119
            _xmlauthsrc.add_element("source", auth_source.value)
120
121
        if group_ids:
122
            _xmlgroups = cmd.add_element("groups")
123
            for group_id in group_ids:
124
                _xmlgroups.add_element("group", attrs={"id": group_id})
125
126
        return self._send_xml_command(cmd)
127