Passed
Pull Request — master (#359)
by
unknown
01:15
created

gvm.protocols.gmpv9.types   F

Complexity

Total Complexity 61

Size/Duplication

Total Lines 539
Duplicated Lines 11.32 %

Importance

Changes 0
Metric Value
eloc 362
dl 61
loc 539
rs 3.52
c 0
b 0
f 0
wmc 61

9 Functions

Rating   Name   Duplication   Size   Complexity  
B get_entity_type_from_string() 29 30 7
B get_filter_type_from_string() 32 33 8
B get_alert_event_from_string() 0 29 8
A get_aggregate_statistic_from_string() 0 21 3
D get_scanner_type_from_string() 0 45 12
B get_alert_condition_from_string() 0 30 8
A get_sort_order_from_string() 0 19 3
A __get_usage_type_from_string() 0 18 3
C get_alert_method_from_string() 0 34 9

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.gmpv9.types 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) 2019 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
from enum import Enum
19
20
from typing import Optional
21
22
from gvm.errors import InvalidArgument
23
24
from gvm.protocols.gmpv8.types import (
25
    AliveTest,
26
    AssetType,
27
    CredentialFormat,
28
    CredentialType,
29
    FeedType,
30
    HostsOrdering,
31
    InfoType,
32
    PermissionSubjectType,
33
    PortRangeType,
34
    ReportFormatType,
35
    SeverityLevel,
36
    SnmpAuthAlgorithm,
37
    SnmpPrivacyAlgorithm,
38
    TicketStatus,
39
    TimeUnit,
40
    UserAuthType,
41
    get_alive_test_from_string,
42
    get_asset_type_from_string,
43
    get_credential_format_from_string,
44
    get_credential_type_from_string,
45
    get_feed_type_from_string,
46
    get_hosts_ordering_from_string,
47
    get_info_type_from_string,
48
    get_permission_subject_type_from_string,
49
    get_port_range_type_from_string,
50
    get_report_format_id_from_string,
51
    get_severity_level_from_string,
52
    get_snmp_auth_algorithm_from_string,
53
    get_snmp_privacy_algorithm_from_string,
54
    get_ticket_status_from_string,
55
    get_time_unit_from_string,
56
    get_user_auth_type_from_string,
57
)
58
59
60
__all__ = [
61
    "AggregateStatistic",
62
    "AlertCondition",
63
    "AlertEvent",
64
    "AlertMethod",
65
    "AliveTest",
66
    "AssetType",
67
    "CredentialFormat",
68
    "CredentialType",
69
    "EntityType",
70
    "FeedType",
71
    "FilterType",
72
    "HostsOrdering",
73
    "InfoType",
74
    "PermissionSubjectType",
75
    "PortRangeType",
76
    "ReportFormatType",
77
    "ScannerType",
78
    "SeverityLevel",
79
    "SnmpAuthAlgorithm",
80
    "SnmpPrivacyAlgorithm",
81
    "SortOrder",
82
    "TicketStatus",
83
    "TimeUnit",
84
    "UserAuthType",
85
    "get_aggregate_statistic_from_string",
86
    "get_alert_condition_from_string",
87
    "get_alert_event_from_string",
88
    "get_alert_method_from_string",
89
    "get_alive_test_from_string",
90
    "get_asset_type_from_string",
91
    "get_credential_format_from_string",
92
    "get_credential_type_from_string",
93
    "get_entity_type_from_string",
94
    "get_feed_type_from_string",
95
    "get_filter_type_from_string",
96
    "get_hosts_ordering_from_string",
97
    "get_info_type_from_string",
98
    "get_permission_subject_type_from_string",
99
    "get_port_range_type_from_string",
100
    "get_report_format_id_from_string",
101
    "get_scanner_type_from_string",
102
    "get_severity_level_from_string",
103
    "get_sort_order_from_string",
104
    "get_snmp_auth_algorithm_from_string",
105
    "get_snmp_privacy_algorithm_from_string",
106
    "get_ticket_status_from_string",
107
    "get_time_unit_from_string",
108
    "get_user_auth_type_from_string",
109
]
110
111
112
class AggregateStatistic(Enum):
113
    """Enum for aggregate statistic types"""
114
115
    COUNT = "count"  # Number of items
116
    C_COUNT = "c_count"  # Cumulative number of items
117
    C_SUM = "c_sum"  # Cumulative sum of values
118
    MAX = "max"  # Maximum value
119
    MEAN = "mean"  # Arithmetic mean of values
120
    MIN = "min"  # Minimum value
121
    SUM = "sum"  # Sum of values
122
    TEXT = "text"  # Text column value
123
    VALUE = "value"  # Group or subgroup column value
124
125
126
def get_aggregate_statistic_from_string(
127
    aggregate_statistic: Optional[str],
128
) -> Optional[AggregateStatistic]:
129
    """
130
    Convert a aggregate statistic string to an actual AggregateStatistic
131
    instance.
132
133
    Arguments:
134
        aggregate_statistic: Aggregate statistic string to convert to a
135
            AggregateStatistic
136
    """
137
    if not aggregate_statistic:
138
        return None
139
140
    try:
141
        return AggregateStatistic[aggregate_statistic.upper()]
142
    except KeyError:
143
        raise InvalidArgument(
144
            argument='aggregate_statistic',
145
            function=get_aggregate_statistic_from_string.__name__,
146
        ) from None
147
148
149
class EntityType(Enum):
150
    """Enum for entity types """
151
152
    AGENT = "agent"
153
    ALERT = "alert"
154
    ASSET = "asset"
155
    AUDIT = "audit"
156
    CERT_BUND_ADV = "cert_bund_adv"
157
    CPE = "cpe"
158
    CREDENTIAL = "credential"
159
    CVE = "cve"
160
    DFN_CERT_ADV = "dfn_cert_adv"
161
    FILTER = "filter"
162
    GROUP = "group"
163
    HOST = "host"
164
    INFO = "info"
165
    NOTE = "note"
166
    NVT = "nvt"
167
    OPERATING_SYSTEM = "os"
168
    OVALDEF = "ovaldef"
169
    OVERRIDE = "override"
170
    PERMISSION = "permission"
171
    POLICY = "policy"
172
    PORT_LIST = "port_list"
173
    REPORT = "report"
174
    REPORT_FORMAT = "report_format"
175
    RESULT = "result"
176
    ROLE = "role"
177
    SCAN_CONFIG = "config"
178
    SCANNER = "scanner"
179
    SCHEDULE = "schedule"
180
    TAG = "tag"
181
    TARGET = "target"
182
    TASK = "task"
183
    TICKET = "ticket"
184
    TLS_CERTIFICATE = "tls_certificate"
185
    USER = "user"
186
    VULNERABILITY = "vuln"
187
188
189 View Code Duplication
def get_entity_type_from_string(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
190
    entity_type: Optional[str],
191
) -> Optional[EntityType]:
192
    """Convert a entity type string to an actual EntityType instance
193
194
    Arguments:
195
        entity_type: Entity type string to convert to a EntityType
196
    """
197
    if not entity_type:
198
        return None
199
200
    if entity_type == 'vuln':
201
        return EntityType.VULNERABILITY
202
203
    if entity_type == 'os':
204
        return EntityType.OPERATING_SYSTEM
205
206
    if entity_type == 'config':
207
        return EntityType.SCAN_CONFIG
208
209
    if entity_type == 'tls_certificate':
210
        return EntityType.TLS_CERTIFICATE
211
212
    try:
213
        return EntityType[entity_type.upper()]
214
    except KeyError:
215
        raise InvalidArgument(
216
            argument='entity_type',
217
            function=get_entity_type_from_string.__name__,
218
        ) from None
219
220
221
class AlertEvent(Enum):
222
    """Enum for alert event types """
223
224
    TASK_RUN_STATUS_CHANGED = 'Task run status changed'
225
    UPDATED_SECINFO_ARRIVED = 'Updated SecInfo arrived'
226
    NEW_SECINFO_ARRIVED = 'New SecInfo arrived'
227
    TICKET_RECEIVED = 'Ticket received'
228
    ASSIGNED_TICKET_CHANGED = 'Assigned ticket changed'
229
    OWNED_TICKET_CHANGED = 'Owned ticket changed'
230
231
232
def get_alert_event_from_string(
233
    alert_event: Optional[str],
234
) -> Optional[AlertEvent]:
235
    """Convert an alert event string into a AlertEvent instance """
236
    if not alert_event:
237
        return None
238
239
    alert_event = alert_event.lower()
240
241
    if alert_event == 'task run status changed':
242
        return AlertEvent.TASK_RUN_STATUS_CHANGED
243
244
    if alert_event == 'updated secinfo arrived':
245
        return AlertEvent.UPDATED_SECINFO_ARRIVED
246
247
    if alert_event == 'new secinfo arrived':
248
        return AlertEvent.NEW_SECINFO_ARRIVED
249
250
    if alert_event == 'ticket received':
251
        return AlertEvent.TICKET_RECEIVED
252
253
    if alert_event == 'assigned ticket changed':
254
        return AlertEvent.ASSIGNED_TICKET_CHANGED
255
256
    if alert_event == 'owned ticket changed':
257
        return AlertEvent.OWNED_TICKET_CHANGED
258
259
    raise InvalidArgument(
260
        argument='alert_event', function=get_alert_event_from_string.__name__
261
    )
262
263
264
class AlertCondition(Enum):
265
    """Enum for alert condition types """
266
267
    ALWAYS = 'Always'
268
    ERROR = 'Error'
269
    SEVERITY_AT_LEAST = 'Severity at least'
270
    SEVERITY_CHANGED = 'Severity changed'
271
    FILTER_COUNT_CHANGED = 'Filter count changed'
272
    FILTER_COUNT_AT_LEAST = 'Filter count at least'
273
274
275
def get_alert_condition_from_string(
276
    alert_condition: Optional[str],
277
) -> Optional[AlertCondition]:
278
    """Convert an alert condition string into a AlertCondition instance """
279
    if not alert_condition:
280
        return None
281
282
    alert_condition = alert_condition.lower()
283
284
    if alert_condition == 'error':
285
        return AlertCondition.ERROR
286
287
    if alert_condition == 'always':
288
        return AlertCondition.ALWAYS
289
290
    if alert_condition == 'filter count changed':
291
        return AlertCondition.FILTER_COUNT_CHANGED
292
293
    if alert_condition == 'filter count at least':
294
        return AlertCondition.FILTER_COUNT_AT_LEAST
295
296
    if alert_condition == 'severity at least':
297
        return AlertCondition.SEVERITY_AT_LEAST
298
299
    if alert_condition == 'severity changed':
300
        return AlertCondition.SEVERITY_CHANGED
301
302
    raise InvalidArgument(
303
        argument='alert_condition',
304
        function=get_alert_condition_from_string.__name__,
305
    )
306
307
308
class AlertMethod(Enum):
309
    """Enum for alert method type"""
310
311
    SCP = "SCP"
312
    SEND = "Send"
313
    SMB = "SMB"
314
    SNMP = "SNMP"
315
    SYSLOG = "Syslog"
316
    EMAIL = "Email"
317
    START_TASK = "Start Task"
318
    HTTP_GET = "HTTP Get"
319
    SOURCEFIRE_CONNECTOR = "Sourcefire Connector"
320
    VERINICE_CONNECTOR = "verinice Connector"
321
    TIPPINGPOINT = "TippingPoint SMS"
322
    ALEMBA_VFIRE = "Alemba vFire"
323
324
325
def get_alert_method_from_string(
326
    alert_method: Optional[str],
327
) -> Optional[AlertMethod]:
328
    """Convert an alert method string into a AlertCondition instance """
329
    if not alert_method:
330
        return None
331
332
    alert_method = alert_method.upper()
333
334
    if alert_method == 'START TASK':
335
        return AlertMethod.START_TASK
336
337
    if alert_method == 'HTTP GET':
338
        return AlertMethod.HTTP_GET
339
340
    if alert_method == 'SOURCEFIRE CONNECTOR':
341
        return AlertMethod.SOURCEFIRE_CONNECTOR
342
343
    if alert_method == 'VERINICE CONNECTOR':
344
        return AlertMethod.VERINICE_CONNECTOR
345
346
    if alert_method == 'TIPPINGPOINT SMS':
347
        return AlertMethod.TIPPINGPOINT
348
349
    if alert_method == 'ALEMBA VFIRE':
350
        return AlertMethod.ALEMBA_VFIRE
351
352
    try:
353
        return AlertMethod[alert_method]
354
    except KeyError:
355
        raise InvalidArgument(
356
            argument='alert_method',
357
            function=get_alert_method_from_string.__name__,
358
        ) from None
359
360
361
class FilterType(Enum):
362
    """Enum for filter types """
363
364
    AGENT = "agent"
365
    ALERT = "alert"
366
    ASSET = "asset"
367
    SCAN_CONFIG = "config"
368
    CREDENTIAL = "credential"
369
    FILTER = "filter"
370
    GROUP = "group"
371
    HOST = "host"
372
    NOTE = "note"
373
    OPERATING_SYSTEM = "os"
374
    OVERRIDE = "override"
375
    PERMISSION = "permission"
376
    PORT_LIST = "port_list"
377
    REPORT = "report"
378
    REPORT_FORMAT = "report_format"
379
    RESULT = "result"
380
    ROLE = "role"
381
    SCHEDULE = "schedule"
382
    ALL_SECINFO = "secinfo"
383
    TAG = "tag"
384
    TARGET = "target"
385
    TASK = "task"
386
    TICKET = "ticket"
387
    TLS_CERTIFICATE = "tls_certificate"
388
    USER = "user"
389
    VULNERABILITY = "vuln"
390
391
392 View Code Duplication
def get_filter_type_from_string(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
393
    filter_type: Optional[str],
394
) -> Optional[FilterType]:
395
    """Convert a filter type string to an actual FilterType instance
396
397
    Arguments:
398
        filter_type (str): Filter type string to convert to a FilterType
399
    """
400
    if not filter_type:
401
        return None
402
403
    if filter_type == 'vuln':
404
        return FilterType.VULNERABILITY
405
406
    if filter_type == 'os':
407
        return FilterType.OPERATING_SYSTEM
408
409
    if filter_type == 'config':
410
        return FilterType.SCAN_CONFIG
411
412
    if filter_type == 'secinfo':
413
        return FilterType.ALL_SECINFO
414
415
    if filter_type == 'tls_certificate':
416
        return FilterType.TLS_CERTIFICATE
417
418
    try:
419
        return FilterType[filter_type.upper()]
420
    except KeyError:
421
        raise InvalidArgument(
422
            argument='filter_type',
423
            function=get_filter_type_from_string.__name__,
424
        ) from None
425
426
427
class ScannerType(Enum):
428
    """ Enum for scanner type """
429
430
    OSP_SCANNER_TYPE = "1"
431
    OPENVAS_SCANNER_TYPE = "2"
432
    CVE_SCANNER_TYPE = "3"
433
    GMP_SCANNER_TYPE = "4"  # formerly slave scanner
434
    GREENBONE_SENSOR_SCANNER_TYPE = "5"
435
436
437
def get_scanner_type_from_string(
438
    scanner_type: Optional[str],
439
) -> Optional[ScannerType]:
440
    """Convert a scanner type string to an actual ScannerType instance
441
442
    Arguments:
443
        scanner_type: Scanner type string to convert to a ScannerType
444
    """
445
    if not scanner_type:
446
        return None
447
448
    scanner_type = scanner_type.lower()
449
450
    if (
451
        scanner_type == ScannerType.OSP_SCANNER_TYPE.value
452
        or scanner_type == 'osp'
453
    ):
454
        return ScannerType.OSP_SCANNER_TYPE
455
456
    if (
457
        scanner_type == ScannerType.OPENVAS_SCANNER_TYPE.value
458
        or scanner_type == 'openvas'
459
    ):
460
        return ScannerType.OPENVAS_SCANNER_TYPE
461
462
    if (
463
        scanner_type == ScannerType.CVE_SCANNER_TYPE.value
464
        or scanner_type == 'cve'
465
    ):
466
        return ScannerType.CVE_SCANNER_TYPE
467
468
    if (
469
        scanner_type == ScannerType.GMP_SCANNER_TYPE.value
470
        or scanner_type == 'gmp'
471
    ):
472
        return ScannerType.GMP_SCANNER_TYPE
473
474
    if (
475
        scanner_type == ScannerType.GREENBONE_SENSOR_SCANNER_TYPE.value
476
        or scanner_type == 'greenbone'
477
    ):
478
        return ScannerType.GREENBONE_SENSOR_SCANNER_TYPE
479
480
    raise InvalidArgument(
481
        argument='scanner_type', function=get_scanner_type_from_string.__name__
482
    )
483
484
485
class SortOrder(Enum):
486
    """Enum for sort order"""
487
488
    ASCENDING = "ascending"
489
    DESCENDING = "descending"
490
491
492
def get_sort_order_from_string(
493
    sort_order: Optional[str],
494
) -> Optional[SortOrder]:
495
    """
496
    Convert a sort order string to an actual SortOrder instance.
497
498
    Arguments:
499
        sort_order: Sort order string to convert to a SortOrder
500
    """
501
    if not sort_order:
502
        return None
503
504
    try:
505
        return SortOrder[sort_order.upper()]
506
    except KeyError:
507
        raise InvalidArgument(
508
            argument='sort_order',
509
            function=get_sort_order_from_string.__name__,
510
        ) from None
511
512
513
class _UsageType(Enum):
514
    """Enum for usage types """
515
516
    AUDIT = "audit"
517
    POLICY = "policy"
518
    SCAN = "scan"
519
520
521
def __get_usage_type_from_string(
522
    usage_type: Optional[str],
523
) -> Optional[_UsageType]:
524
    """Convert a usage type string to an actual _UsageType instance
525
526
    Arguments:
527
        entity_type: Usage type string to convert to a _UsageType
528
    """
529
    if not usage_type:
530
        return None
531
532
    try:
533
        return _UsageType[usage_type.upper()]
534
    except KeyError:
535
        raise InvalidArgument(
536
            argument='usage_type',
537
            function=__get_usage_type_from_string.__name__,
538
        ) from None
539