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

gvm.protocols.gmpv8   B

Complexity

Total Complexity 51

Size/Duplication

Total Lines 277
Duplicated Lines 12.64 %

Importance

Changes 0
Metric Value
eloc 133
dl 35
loc 277
rs 7.92
c 0
b 0
f 0
wmc 51

3 Methods

Rating   Name   Duplication   Size   Complexity  
A Gmp.get_protocol_version() 0 8 1
F Gmp.modify_credential() 0 97 20
F Gmp.create_credential() 35 120 30

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like gvm.protocols.gmpv8 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.

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