Completed
Push — master ( 42f470...4e3fbe )
by
unknown
25s queued 10s
created

gvm.protocols.gmpv8.Gmp.create_credential()   F

Complexity

Conditions 30

Size

Total Lines 120
Code Lines 67

Duplication

Lines 35
Ratio 29.17 %

Importance

Changes 0
Metric Value
cc 30
eloc 67
nop 16
dl 35
loc 120
rs 0
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.gmpv8.Gmp.create_credential() 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) 2018 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=arguments-differ
20
21
"""
22
Module for communication with gvmd in `Greenbone Management Protocol version 8`_
23
24
**GMP Version 8 has not been released yet**
25
26
.. _Greenbone Management Protocol version 8:
27
    https://docs.greenbone.net/API/GMP/gmp-8.0.html
28
"""
29
30
from gvm.errors import InvalidArgument, RequiredArgument
31
from gvm.utils import get_version_string
32
from gvm.xml import XmlCommand
33
34
from .gmpv7 import Gmp as Gmpv7
35
36
CREDENTIAL_TYPES = (
37
    'cc',
38
    'snmp',
39
    'up',
40
    'usk',
41
    'smime',
42
    'pgp',
43
)
44
45
PROTOCOL_VERSION = (8,)
46
47
48
class Gmp(Gmpv7):
49
50
    @staticmethod
51
    def get_protocol_version():
52
        """Allow to determine the Greenbone Management Protocol version.
53
54
            Returns:
55
                str: Implemented version of the Greenbone Management Protocol
56
        """
57
        return get_version_string(PROTOCOL_VERSION)
58
59
    def create_credential(self, name, credential_type, *, comment=None,
0 ignored issues
show
Comprehensibility introduced by
This function exceeds the maximum number of variables (19/15).
Loading history...
60
                          allow_insecure=False, certificate=None,
61
                          key_phrase=None, private_key=None,
62
                          login=None, password=None, auth_algorithm=None,
63
                          community=None, privacy_algorithm=None,
64
                          privacy_password=None, public_key=None):
65
        """Create a new credential
66
67
        Arguments:
68
            name (str): Name of the new credential
69
            credential_type (str): The credential type. One of 'cc', 'snmp',
70
                'up', 'usk', 'smime', 'pgp'
71
            comment (str, optional): Comment for the credential
72
            allow_insecure (boolean, optional): Whether to allow insecure use of
73
                the credential
74
            certificate (str, optional): Certificate for the credential
75
            key_phrase (str, optional): Key passphrase for the private key
76
            private_key (str, optional): Private key to use for login
77
            login (str, optional): Username for the credential
78
            password (str, optional): Password for the credential
79
            community (str, optional): The SNMP community
80
            privacy_algorithm (str, optional): The SNMP privacy algorithm,
81
                either aes or des.
82
            privacy_password (str, optional): The SNMP privacy password
83
            public_key: (str, optional): PGP public key in *armor* plain text
84
                format
85
86
        Returns:
87
            The response. See :py:meth:`send_command` for details.
88
        """
89
        if not name:
90
            raise RequiredArgument('create_credential requires name argument')
91
92
        if credential_type not in CREDENTIAL_TYPES:
93
            raise InvalidArgument(
94
                'create_credential requires type to be either cc, snmp, up,'
95
                'smime, pgp or usk')
96
97
        cmd = XmlCommand('create_credential')
98
        cmd.add_element('name', name)
99
100
        cmd.add_element('type', credential_type)
101
102
        if comment:
103
            cmd.add_element('comment', comment)
104
105
        if allow_insecure:
106
            cmd.add_element('allow_insecure', '1')
107
108
109
        if credential_type == 'cc' or credential_type == 'smime':
0 ignored issues
show
Unused Code introduced by
Consider merging these comparisons with "in" to "credential_type in ('cc', 'smime')"
Loading history...
110
            if not certificate:
111
                raise RequiredArgument(
112
                    'create_credential requires certificate argument for '
113
                    'credential_type {0}'.format(credential_type))
114
115
            cmd.add_element('certificate', certificate)
116
117
        if (credential_type == 'up' or credential_type == 'usk' or \
0 ignored issues
show
Unused Code introduced by
Consider merging these comparisons with "in" to "credential_type in ('up', 'usk', 'snmp')"
Loading history...
118
                credential_type == 'snmp'):
119
            if not login:
120
                raise RequiredArgument(
121
                    'create_credential requires login argument for '
122
                    'credential_type {0}'.format(credential_type))
123
124
            cmd.add_element('login', login)
125
126
        if (credential_type == 'up' or credential_type == 'snmp') and password:
0 ignored issues
show
Unused Code introduced by
Consider merging these comparisons with "in" to "credential_type in ('up', 'snmp')"
Loading history...
127
            cmd.add_element('password', password)
128
129 View Code Duplication
        if credential_type == 'usk':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
130
            if not private_key:
131
                raise RequiredArgument(
132
                    'create_credential requires certificate argument for '
133
                    'credential_type usk')
134
135
            _xmlkey = cmd.add_element('key')
136
            _xmlkey.add_element('private', private_key)
137
138
            if key_phrase:
139
                _xmlkey.add_element('phrase', key_phrase)
140
141
        if credential_type == 'cc' and private_key:
142
            _xmlkey = cmd.add_element('key')
143
            _xmlkey.add_element('private', private_key)
144
145 View Code Duplication
        if credential_type == 'snmp':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
146
            if auth_algorithm not in ('md5', 'sha1'):
147
                raise InvalidArgument(
148
                    'create_credential requires auth_algorithm to be either '
149
                    'md5 or sha1')
150
151
            cmd.add_element('auth_algorithm', auth_algorithm)
152
153
            if community:
154
                cmd.add_element('community', community)
155
156
            if privacy_algorithm is not None or privacy_password:
157
                _xmlprivacy = cmd.add_element('privacy')
158
159
                if privacy_algorithm is not None:
160
                    if privacy_algorithm not in ('aes', 'des'):
161
                        raise InvalidArgument(
162
                            'create_credential requires algorithm to be either '
163
                            'aes or des')
164
165
                    _xmlprivacy.add_element('algorithm', privacy_algorithm)
166
167
                if privacy_password:
168
                    _xmlprivacy.add_element('password', privacy_password)
169
170
        if credential_type == 'pgp':
171
            if not public_key:
172
                raise RequiredArgument(
173
                    'Creating a pgp credential requires a public_key argument')
174
175
            _xmlkey = cmd.add_element('key')
176
            _xmlkey.add_element('public', public_key)
177
178
        return self._send_xml_command(cmd)
179
180
    def modify_credential(self, credential_id, name=None, comment=None,
0 ignored issues
show
best-practice introduced by
Too many arguments (16/15)
Loading history...
Comprehensibility introduced by
This function exceeds the maximum number of variables (20/15).
Loading history...
181
                          allow_insecure=None, certificate=None,
182
                          key_phrase=None, private_key=None, login=None,
183
                          password=None, auth_algorithm=None, community=None,
184
                          privacy_algorithm=None, privacy_password=None,
185
                          credential_type=None, public_key=None):
186
        """Modifies an existing credential.
187
188
        Arguments:
189
            credential_id (str): UUID of the credential
190
            name (str, optional): Name of the credential
191
            comment (str, optional): Comment for the credential
192
            allow_insecure (boolean, optional): Whether to allow insecure use of
193
                 the credential
194
            certificate (str, optional): Certificate for the credential
195
            key_phrase (str, optional): Key passphrase for the private key
196
            private_key (str, optional): Private key to use for login
197
            login (str, optional): Username for the credential
198
            password (str, optional): Password for the credential
199
            auth_algorithm (str, optional): The auth_algorithm,
200
                either md5 or sha1.
201
            community (str, optional): The SNMP community
202
            privacy_algorithm (str, optional): The SNMP privacy algorithm,
203
                either aes or des.
204
            privacy_password (str, optional): The SNMP privacy password
205
            credential_type (str, optional): The credential type. One of 'cc',
206
                'snmp', 'up', 'usk', 'smime', 'pgp'
207
            public_key: (str, optional): PGP public key in *armor* plain text
208
                fromat
209
210
        Returns:
211
            The response. See :py:meth:`send_command` for details.
212
        """
213
        if not credential_id:
214
            raise RequiredArgument('modify_credential requires '
215
                                   'a credential_id attribute')
216
217
        cmd = XmlCommand('modify_credential')
218
        cmd.set_attribute('credential_id', credential_id)
219
220
        if credential_type:
221
            if credential_type not in CREDENTIAL_TYPES:
222
                raise RequiredArgument(
223
                    'modify_credential requires type to be either cc, snmp, up '
224
                    'smime, pgp or usk')
225
            cmd.add_element('type', credential_type)
226
227
        if comment:
228
            cmd.add_element('comment', comment)
229
230
        if name:
231
            cmd.add_element('name', name)
232
233
        if allow_insecure:
234
            cmd.add_element('allow_insecure', allow_insecure)
235
236
        if certificate:
237
            cmd.add_element('certificate', certificate)
238
239
        if key_phrase or private_key:
240
            if not key_phrase or not private_key:
241
                raise RequiredArgument('modify_credential requires '
242
                                       'a key_phrase and private_key arguments')
243
            _xmlkey = cmd.add_element('key')
244
            _xmlkey.add_element('phrase', key_phrase)
245
            _xmlkey.add_element('private', private_key)
246
247
        if login:
248
            cmd.add_element('login', login)
249
250
        if password:
251
            cmd.add_element('password', password)
252
253
        if auth_algorithm:
254
            if auth_algorithm not in ('md5', 'sha1'):
255
                raise RequiredArgument('modify_credential requires '
256
                                       'auth_algorithm to be either '
257
                                       'md5 or sha1')
258
            cmd.add_element('auth_algorithm', auth_algorithm)
259
260
        if community:
261
            cmd.add_element('community', community)
262
263
        if privacy_algorithm:
264
            if privacy_algorithm not in ('aes', 'des'):
265
                raise RequiredArgument('modify_credential requires '
266
                                       'privacy_algorithm to be either'
267
                                       'aes or des')
268
            _xmlprivacy = cmd.add_element('privacy')
269
            _xmlprivacy.add_element('algorithm', privacy_algorithm)
270
            _xmlprivacy.add_element('password', privacy_password)
271
272
        if public_key:
273
            _xmlkey = cmd.add_element('key')
274
            _xmlkey.add_element('public', public_key)
275
276
        return self._send_xml_command(cmd)
277