Completed
Push — master ( 52721c...da306e )
by Jaspar
18s queued 14s
created

OverridesMixin.modify_override()   F

Complexity

Conditions 14

Size

Total Lines 90
Code Lines 52

Duplication

Lines 90
Ratio 100 %

Importance

Changes 0
Metric Value
cc 14
eloc 52
nop 13
dl 90
loc 90
rs 3.6
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.overrides.OverridesMixin.modify_override() 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
20
# MAYBE we should change filter to filter_string (everywhere)
21
22
23
from typing import Any, List, Optional
24
25
from gvm.errors import RequiredArgument, InvalidArgumentType
26
from gvm.protocols.gmpv208.entities.severity import Severity, SeverityLevel
27
from gvm.utils import add_filter, to_comma_list, to_bool
28
from gvm.xml import XmlCommand
29
30
31
class OverridesMixin:
32 View Code Duplication
    def create_override(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
33
        self,
34
        text: str,
35
        nvt_oid: str,
36
        *,
37
        days_active: Optional[int] = None,
38
        hosts: Optional[List[str]] = None,
39
        port: Optional[int] = None,
40
        result_id: Optional[str] = None,
41
        severity: Optional[Severity] = None,
42
        new_severity: Optional[Severity] = None,
43
        task_id: Optional[str] = None,
44
        threat: Optional[SeverityLevel] = None,
45
        new_threat: Optional[SeverityLevel] = None,
46
    ) -> Any:
47
        """Create a new override
48
49
        Arguments:
50
            text: Text of the new override
51
            nvt_id: OID of the nvt to which override applies
52
            days_active: Days override will be active. -1 on always, 0 off
53
            hosts: A list of host addresses
54
            port: Port to which the override applies
55
            result_id: UUID of a result to which override applies
56
            severity: Severity to which override applies
57
            new_severity: New severity for result
58
            task_id: UUID of task to which override applies
59
            threat: Severity level to which override applies. Will be converted
60
                to severity.
61
            new_threat: New severity level for results. Will be converted to
62
                new_severity.
63
64
        Returns:
65
            The response. See :py:meth:`send_command` for details.
66
        """
67
        if not text:
68
            raise RequiredArgument(
69
                function=self.create_override.__name__, argument='text'
70
            )
71
72
        if not nvt_oid:
73
            raise RequiredArgument(
74
                function=self.create_override.__name__, argument='nvt_oid'
75
            )
76
77
        cmd = XmlCommand("create_override")
78
        cmd.add_element("text", text)
79
        cmd.add_element("nvt", attrs={"oid": nvt_oid})
80
81
        if days_active is not None:
82
            cmd.add_element("active", str(days_active))
83
84
        if hosts:
85
            cmd.add_element("hosts", to_comma_list(hosts))
86
87
        if port:
88
            cmd.add_element("port", str(port))
89
90
        if result_id:
91
            cmd.add_element("result", attrs={"id": result_id})
92
93
        if severity:
94
            cmd.add_element("severity", str(severity))
95
96
        if new_severity:
97
            cmd.add_element("new_severity", str(new_severity))
98
99
        if task_id:
100
            cmd.add_element("task", attrs={"id": task_id})
101
102
        if threat is not None:
103
            if not isinstance(threat, SeverityLevel):
104
                raise InvalidArgumentType(
105
                    function=self.create_override.__name__,
106
                    argument="threat",
107
                    arg_type=SeverityLevel.__name__,
108
                )
109
110
            cmd.add_element("threat", threat.value)
111
112
        if new_threat is not None:
113
            if not isinstance(new_threat, SeverityLevel):
114
                raise InvalidArgumentType(
115
                    function=self.create_override.__name__,
116
                    argument="new_threat",
117
                    arg_type=SeverityLevel.__name__,
118
                )
119
120
            cmd.add_element("new_threat", new_threat.value)
121
122
        return self._send_xml_command(cmd)
123
124
    def clone_override(self, override_id: str) -> Any:
125
        """Clone an existing override
126
127
        Arguments:
128
            override_id: UUID of an existing override to clone from
129
130
        Returns:
131
            The response. See :py:meth:`send_command` for details.
132
        """
133
        if not override_id:
134
            raise RequiredArgument(
135
                function=self.clone_override.__name__, argument='override_id'
136
            )
137
138
        cmd = XmlCommand("create_override")
139
        cmd.add_element("copy", override_id)
140
        return self._send_xml_command(cmd)
141
142
    def delete_override(
143
        self, override_id: str, *, ultimate: Optional[bool] = False
144
    ) -> Any:
145
        """Deletes an existing override
146
147
        Arguments:
148
            override_id: UUID of the override to be deleted.
149
            ultimate: Whether to remove entirely, or to the trashcan.
150
        """
151
        if not override_id:
152
            raise RequiredArgument(
153
                function=self.delete_override.__name__, argument='override_id'
154
            )
155
156
        cmd = XmlCommand("delete_override")
157
        cmd.set_attribute("override_id", override_id)
158
        cmd.set_attribute("ultimate", to_bool(ultimate))
159
160
        return self._send_xml_command(cmd)
161
162 View Code Duplication
    def get_overrides(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
163
        self,
164
        *,
165
        filter: Optional[str] = None,
166
        filter_id: Optional[str] = None,
167
        details: Optional[bool] = None,
168
        result: Optional[bool] = None,
169
    ) -> Any:
170
        """Request a list of overrides
171
172
        Arguments:
173
            filter: Filter term to use for the query
174
            filter_id: UUID of an existing filter to use for the query
175
            details: Whether to include full details
176
            result: Whether to include results using the override
177
178
        Returns:
179
            The response. See :py:meth:`send_command` for details.
180
        """
181
        cmd = XmlCommand("get_overrides")
182
183
        add_filter(cmd, filter, filter_id)
184
185
        if details is not None:
186
            cmd.set_attribute("details", to_bool(details))
187
188
        if result is not None:
189
            cmd.set_attribute("result", to_bool(result))
190
191
        return self._send_xml_command(cmd)
192
193
    def get_override(self, override_id: str) -> Any:
194
        """Request a single override
195
196
        Arguments:
197
            override_id: UUID of an existing override
198
199
        Returns:
200
            The response. See :py:meth:`send_command` for details.
201
        """
202
        cmd = XmlCommand("get_overrides")
203
204
        if not override_id:
205
            raise RequiredArgument(
206
                function=self.get_override.__name__, argument='override_id'
207
            )
208
209
        cmd.set_attribute("override_id", override_id)
210
211
        # for single entity always request all details
212
        cmd.set_attribute("details", "1")
213
        return self._send_xml_command(cmd)
214
215 View Code Duplication
    def modify_override(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
216
        self,
217
        override_id: str,
218
        text: str,
219
        *,
220
        days_active: Optional[int] = None,
221
        hosts: Optional[List[str]] = None,
222
        port: Optional[int] = None,
223
        result_id: Optional[str] = None,
224
        severity: Optional[Severity] = None,
225
        new_severity: Optional[Severity] = None,
226
        task_id: Optional[str] = None,
227
        threat: Optional[SeverityLevel] = None,
228
        new_threat: Optional[SeverityLevel] = None,
229
    ) -> Any:
230
        """Modifies an existing override.
231
232
        Arguments:
233
            override_id: UUID of override to modify.
234
            text: The text of the override.
235
            days_active: Days override will be active. -1 on always,
236
                0 off.
237
            hosts: A list of host addresses
238
            port: Port to which override applies.
239
            result_id: Result to which override applies.
240
            severity: Severity to which override applies.
241
            new_severity: New severity score for result.
242
            task_id: Task to which override applies.
243
            threat: Threat level to which override applies.
244
                Will be converted to severity.
245
            new_threat: New threat level for results. Will be converted to
246
                new_severity.
247
248
        Returns:
249
            The response. See :py:meth:`send_command` for details.
250
        """
251
        if not override_id:
252
            raise RequiredArgument(
253
                function=self.modify_override.__name__, argument='override_id'
254
            )
255
        if not text:
256
            raise RequiredArgument(
257
                function=self.modify_override.__name__, argument='text'
258
            )
259
260
        cmd = XmlCommand("modify_override")
261
        cmd.set_attribute("override_id", override_id)
262
        cmd.add_element("text", text)
263
264
        if days_active is not None:
265
            cmd.add_element("active", str(days_active))
266
267
        if hosts:
268
            cmd.add_element("hosts", to_comma_list(hosts))
269
270
        if port:
271
            cmd.add_element("port", str(port))
272
273
        if result_id:
274
            cmd.add_element("result", attrs={"id": result_id})
275
276
        if severity:
277
            cmd.add_element("severity", str(severity))
278
279
        if new_severity:
280
            cmd.add_element("new_severity", str(new_severity))
281
282
        if task_id:
283
            cmd.add_element("task", attrs={"id": task_id})
284
285
        if threat is not None:
286
            if not isinstance(threat, SeverityLevel):
287
                raise InvalidArgumentType(
288
                    function=self.modify_override.__name__,
289
                    argument='threat',
290
                    arg_type=SeverityLevel.__name__,
291
                )
292
            cmd.add_element("threat", threat.value)
293
294
        if new_threat is not None:
295
            if not isinstance(new_threat, SeverityLevel):
296
                raise InvalidArgumentType(
297
                    function=self.modify_override.__name__,
298
                    argument='new_threat',
299
                    arg_type=SeverityLevel.__name__,
300
                )
301
302
            cmd.add_element("new_threat", new_threat.value)
303
304
        return self._send_xml_command(cmd)
305