UsersMixin.clone_user()   A
last analyzed

Complexity

Conditions 2

Size

Total Lines 17
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
nop 2
dl 0
loc 17
rs 10
c 0
b 0
f 0
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
20
from enum import Enum
21
from typing import Any, List, Optional
22
23
from gvm.errors import RequiredArgument, InvalidArgument
24
from gvm.utils import add_filter, to_comma_list, to_bool
25
from gvm.xml import XmlCommand
26
27
28
class UserAuthType(Enum):
29
    """Enum for Sources allowed for authentication for the user"""
30
31
    FILE = 'file'
32
    LDAP_CONNECT = 'ldap_connect'
33
    RADIUS_CONNECT = 'radius_connect'
34
35
36
def get_user_auth_type_from_string(
37
    user_auth_type: Optional[str],
38
) -> Optional[UserAuthType]:
39
    """Convert a user auth type string into a UserAuthType instance"""
40
    if not user_auth_type:
41
        return None
42
43
    try:
44
        return UserAuthType[user_auth_type.upper()]
45
    except KeyError:
46
        raise InvalidArgument(
47
            argument='user_auth_type',
48
            function=get_user_auth_type_from_string.__name__,
49
        ) from None
50
51
52
class UsersMixin:
53
    def clone_user(self, user_id: str) -> Any:
54
        """Clone an existing user
55
56
        Arguments:
57
            user_id: UUID of existing user to clone from
58
59
        Returns:
60
            The response. See :py:meth:`send_command` for details.
61
        """
62
        if not user_id:
63
            raise RequiredArgument(
64
                function=self.clone_user.__name__, argument='user_id'
65
            )
66
67
        cmd = XmlCommand("create_user")
68
        cmd.add_element("copy", user_id)
69
        return self._send_xml_command(cmd)
70
71
    def create_user(
72
        self,
73
        name: str,
74
        *,
75
        password: Optional[str] = None,
76
        hosts: Optional[List[str]] = None,
77
        hosts_allow: Optional[bool] = False,
78
        ifaces: Optional[List[str]] = None,
79
        ifaces_allow: Optional[bool] = False,
80
        role_ids: Optional[List[str]] = None,
81
    ) -> Any:
82
        """Create a new user
83
84
        Arguments:
85
            name: Name of the user
86
            password: Password of the user
87
            hosts: A list of host addresses (IPs, DNS names)
88
            hosts_allow: If True allow only access to passed hosts otherwise
89
                deny access. Default is False for deny hosts.
90
            ifaces: A list of interface names
91
            ifaces_allow: If True allow only access to passed interfaces
92
                otherwise deny access. Default is False for deny interfaces.
93
            role_ids: A list of role UUIDs for the user
94
95
        Returns:
96
            The response. See :py:meth:`send_command` for details.
97
        """
98
        if not name:
99
            raise RequiredArgument(
100
                function=self.create_user.__name__, argument='name'
101
            )
102
103
        cmd = XmlCommand("create_user")
104
        cmd.add_element("name", name)
105
106
        if password:
107
            cmd.add_element("password", password)
108
109
        if hosts:
110
            cmd.add_element(
111
                "hosts",
112
                to_comma_list(hosts),
113
                attrs={"allow": to_bool(hosts_allow)},
114
            )
115
116
        if ifaces:
117
            cmd.add_element(
118
                "ifaces",
119
                to_comma_list(ifaces),
120
                attrs={"allow": to_bool(ifaces_allow)},
121
            )
122
123
        if role_ids:
124
            for role in role_ids:
125
                cmd.add_element("role", attrs={"id": role})
126
127
        return self._send_xml_command(cmd)
128
129
    def delete_user(
130
        self,
131
        user_id: str = None,
132
        *,
133
        name: Optional[str] = None,
134
        inheritor_id: Optional[str] = None,
135
        inheritor_name: Optional[str] = None,
136
    ) -> Any:
137
        """Deletes an existing user
138
139
        Either user_id or name must be passed.
140
141
        Arguments:
142
            user_id: UUID of the task to be deleted.
143
            name: The name of the user to be deleted.
144
            inheritor_id: The ID of the inheriting user or "self". Overrides
145
                inheritor_name.
146
            inheritor_name: The name of the inheriting user.
147
148
        """
149
        if not user_id and not name:
150
            raise RequiredArgument(
151
                function=self.delete_user.__name__, argument='user_id or name'
152
            )
153
154
        cmd = XmlCommand("delete_user")
155
156
        if user_id:
157
            cmd.set_attribute("user_id", user_id)
158
159
        if name:
160
            cmd.set_attribute("name", name)
161
162
        if inheritor_id:
163
            cmd.set_attribute("inheritor_id", inheritor_id)
164
        if inheritor_name:
165
            cmd.set_attribute("inheritor_name", inheritor_name)
166
167
        return self._send_xml_command(cmd)
168
169
    def get_users(
170
        self,
171
        *,
172
        filter_string: Optional[str] = None,
173
        filter_id: Optional[str] = None,
174
    ) -> Any:
175
        """Request a list of users
176
177
        Arguments:
178
            filter_string: Filter term to use for the query
179
            filter_id: UUID of an existing filter to use for the query
180
181
        Returns:
182
            The response. See :py:meth:`send_command` for details.
183
        """
184
        cmd = XmlCommand("get_users")
185
186
        add_filter(cmd, filter_string, filter_id)
187
188
        return self._send_xml_command(cmd)
189
190
    def get_user(self, user_id: str) -> Any:
191
        """Request a single user
192
193
        Arguments:
194
            user_id: UUID of an existing user
195
196
        Returns:
197
            The response. See :py:meth:`send_command` for details.
198
        """
199
        cmd = XmlCommand("get_users")
200
201
        if not user_id:
202
            raise RequiredArgument(
203
                function=self.get_user.__name__, argument='user_id'
204
            )
205
206
        cmd.set_attribute("user_id", user_id)
207
        return self._send_xml_command(cmd)
208
209
    def modify_user(
210
        self,
211
        user_id: str = None,
212
        name: str = None,
213
        *,
214
        new_name: Optional[str] = None,
215
        comment: Optional[str] = None,
216
        password: Optional[str] = None,
217
        auth_source: Optional[UserAuthType] = None,
218
        role_ids: Optional[List[str]] = None,
219
        hosts: Optional[List[str]] = None,
220
        hosts_allow: Optional[bool] = False,
221
        ifaces: Optional[List[str]] = None,
222
        ifaces_allow: Optional[bool] = False,
223
        group_ids: Optional[List[str]] = None,
224
    ) -> Any:
225
        """Modifies an existing user.
226
227
        Most of the fields need to be supplied
228
        for changing a single field even if no change is wanted for those.
229
        Else empty values are inserted for the missing fields instead.
230
231
        Arguments:
232
            user_id: UUID of the user to be modified. Overrides name element
233
                argument.
234
            name: The name of the user to be modified. Either user_id or name
235
                must be passed.
236
            new_name: The new name for the user.
237
            comment: Comment on the user.
238
            password: The password for the user.
239
            auth_source: Source allowed for authentication for this user.
240
            roles_id: List of roles UUIDs for the user.
241
            hosts: User access rules: List of hosts.
242
            hosts_allow: Defines how the hosts list is to be interpreted.
243
                If False (default) the list is treated as a deny list.
244
                All hosts are allowed by default except those provided by
245
                the hosts parameter. If True the list is treated as a
246
                allow list. All hosts are denied by default except those
247
                provided by the hosts parameter.
248
            ifaces: User access rules: List of ifaces.
249
            ifaces_allow: Defines how the ifaces list is to be interpreted.
250
                If False (default) the list is treated as a deny list.
251
                All ifaces are allowed by default except those provided by
252
                the ifaces parameter. If True the list is treated as a
253
                allow list. All ifaces are denied by default except those
254
                provided by the ifaces parameter.
255
            group_ids: List of group UUIDs for the user.
256
257
        Returns:
258
            The response. See :py:meth:`send_command` for details.
259
        """
260
        if not user_id and not name:
261
            raise RequiredArgument(
262
                function=self.modify_user.__name__, argument='user_id or name'
263
            )
264
265
        cmd = XmlCommand("modify_user")
266
267
        if user_id:
268
            cmd.set_attribute("user_id", user_id)
269
        else:
270
            cmd.add_element("name", name)
271
272
        if new_name:
273
            cmd.add_element("new_name", new_name)
274
275
        if role_ids:
276
            for role in role_ids:
277
                cmd.add_element("role", attrs={"id": role})
278
279
        if hosts:
280
            cmd.add_element(
281
                "hosts",
282
                to_comma_list(hosts),
283
                attrs={"allow": to_bool(hosts_allow)},
284
            )
285
286
        if ifaces:
287
            cmd.add_element(
288
                "ifaces",
289
                to_comma_list(ifaces),
290
                attrs={"allow": to_bool(ifaces_allow)},
291
            )
292
293
        if comment:
294
            cmd.add_element("comment", comment)
295
296
        if password:
297
            cmd.add_element("password", password)
298
299
        if auth_source:
300
            _xmlauthsrc = cmd.add_element("sources")
301
            _xmlauthsrc.add_element("source", auth_source.value)
302
303
        if group_ids:
304
            _xmlgroups = cmd.add_element("groups")
305
            for group_id in group_ids:
306
                _xmlgroups.add_element("group", attrs={"id": group_id})
307
308
        return self._send_xml_command(cmd)
309