openscap_report.scap_results_parser.parsers.oval_test_parser   A
last analyzed

Complexity

Total Complexity 29

Size/Duplication

Total Lines 168
Duplicated Lines 0 %

Test Coverage

Coverage 98.98%

Importance

Changes 0
Metric Value
eloc 130
dl 0
loc 168
ccs 97
cts 98
cp 0.9898
rs 10
c 0
b 0
f 0
wmc 29

14 Methods

Rating   Name   Duplication   Size   Complexity  
A OVALTestParser._get_data_by_id() 0 5 2
A OVALTestParser._get_system_data_by_id() 0 4 1
A OVALTestParser._resolve_reference() 0 21 4
A OVALTestParser._get_collected_objects_by_id() 0 4 1
A OVALTestParser._get_objects_by_id() 0 4 1
A OVALTestParser._get_oval_definitions() 0 3 1
A OVALTestParser._get_referenced_endpoints() 0 16 4
A OVALTestParser.get_test_info() 0 33 4
A OVALTestParser._get_states_by_id() 0 4 1
B OVALTestParser._iter_over_data_and_get_references() 0 14 6
A OVALTestParser._get_oval_system_characteristics() 0 4 1
A OVALTestParser.__init__() 0 20 1
A OVALTestParser._get_variables_by_id() 0 4 1
A OVALTestParser._get_tests() 0 3 1
1
# Copyright 2022, Red Hat, Inc.
2
# SPDX-License-Identifier: LGPL-2.1-or-later
3
4 1
import logging
5 1
from collections import defaultdict
6
7 1
from ..data_structures import OvalTest
8 1
from ..namespaces import NAMESPACES
9 1
from .oval_object_parser import OVALObjectParser
10 1
from .oval_state_parser import OVALStateParser
11 1
from .oval_variable_parser import OVALVariableParser
12
13
14 1
class OVALTestParser:  # pylint: disable=R0902
15 1
    def __init__(self, oval_report, oval_var_id_to_value_id, ref_values):
16 1
        self.oval_report = oval_report
17 1
        self.oval_definitions = self._get_oval_definitions()
18 1
        self.tests = self._get_tests()
19 1
        self.objects = self._get_objects_by_id()
20 1
        self.states = self._get_states_by_id()
21 1
        self.variables = self._get_variables_by_id()
22 1
        self.oval_system_characteristics = self._get_oval_system_characteristics()
23 1
        self.collected_objects = self._get_collected_objects_by_id()
24 1
        self.system_data = self._get_system_data_by_id()
25 1
        self.variable_parser = OVALVariableParser(
26
            self.variables,
27
            oval_var_id_to_value_id,
28
            ref_values
29
        )
30 1
        self.states_parser = OVALStateParser(self.states)
31 1
        self.objects_parser = OVALObjectParser(
32
            self.objects,
33
            self.collected_objects,
34
            self.system_data
35
        )
36
37 1
    def _get_oval_system_characteristics(self):
38 1
        return self.oval_report.find(
39
            ('.//XMLSchema:results/XMLSchema:system'
40
             '/oval-characteristics:oval_system_characteristics'), NAMESPACES)
41
42 1
    @staticmethod
43 1
    def _get_data_by_id(data):
44 1
        if data is None:
45 1
            return {}
46 1
        return {item.attrib.get('id'): item for item in data}
47
48 1
    def _get_collected_objects_by_id(self):
49 1
        data = self.oval_system_characteristics.find(
50
            './/oval-characteristics:collected_objects', NAMESPACES)
51 1
        return self._get_data_by_id(data)
52
53 1
    def _get_system_data_by_id(self):
54 1
        data = self.oval_system_characteristics.find(
55
            './/oval-characteristics:system_data', NAMESPACES)
56 1
        return self._get_data_by_id(data)
57
58 1
    def _get_oval_definitions(self):
59 1
        return self.oval_report.find(
60
            ('.//oval-definitions:oval_definitions'), NAMESPACES)
61
62 1
    def _get_tests(self):
63 1
        data = self.oval_definitions.find('.//oval-definitions:tests', NAMESPACES)
64 1
        return self._get_data_by_id(data)
65
66 1
    def _get_objects_by_id(self):
67 1
        data = self.oval_definitions.find(
68
            ('.//oval-definitions:objects'), NAMESPACES)
69 1
        return self._get_data_by_id(data)
70
71 1
    def _get_states_by_id(self):
72 1
        data = self.oval_definitions.find(
73
            ('.//oval-definitions:states'), NAMESPACES)
74 1
        return self._get_data_by_id(data)
75
76 1
    def _get_variables_by_id(self):
77 1
        data = self.oval_definitions.find(
78
            ('.//oval-definitions:variables'), NAMESPACES)
79 1
        return self._get_data_by_id(data)
80
81 1
    @staticmethod
82 1
    def _iter_over_data_and_get_references(dict_, out, data_id, map_referenced_oval_endpoints):
83 1
        for key, value in dict_.items():
84 1
            if isinstance(value, dict):
85 1
                OVALTestParser._iter_over_data_and_get_references(
86
                    value, out, data_id, map_referenced_oval_endpoints
87
                )
88
            else:
89 1
                matches_key = ["object_reference", "var_ref", "object_ref", "filter"]
90 1
                matches_val = [":var:", ":obj:", ":ste:"]
91 1
                if any(s in key for s in matches_key) and any(s in value for s in matches_val):
92 1
                    out.append(value)
93 1
                    if value not in map_referenced_oval_endpoints[data_id]:
94 1
                        map_referenced_oval_endpoints[data_id].append(value)
95
96 1
    def _resolve_reference(self, ref_id, new_ref, out, map_referenced_oval_endpoints):
97 1
        if ":var:" in ref_id:
98 1
            variable = self.variable_parser.get_variable(ref_id)
99 1
            self._iter_over_data_and_get_references(
100
                variable.variable_data, new_ref, ref_id, map_referenced_oval_endpoints
101
            )
102 1
            out[ref_id] = variable
103 1
        elif ":obj:" in ref_id:
104 1
            object_ = self.objects_parser.get_object(ref_id)
105 1
            self._iter_over_data_and_get_references(
106
                object_.object_data, new_ref, ref_id, map_referenced_oval_endpoints
107
            )
108 1
            out[ref_id] = object_
109 1
        elif ":ste:" in ref_id:
110 1
            state = self.states_parser.get_state(ref_id)
111 1
            self._iter_over_data_and_get_references(
112
                state.state_data, new_ref, ref_id, map_referenced_oval_endpoints
113
            )
114 1
            out[ref_id] = state
115
        else:
116
            logging.warning(ref_id)
117
118 1
    def _get_referenced_endpoints(self, oval_object, oval_states, map_referenced_oval_endpoints):
119 1
        references = []
120 1
        object_data = oval_object.object_data if oval_object is not None else {}
121 1
        self._iter_over_data_and_get_references(
122
            object_data, references, oval_object.object_id, map_referenced_oval_endpoints,
123
        )
124 1
        for state in oval_states:
125 1
            self._iter_over_data_and_get_references(
126
                state.state_data, references, state.state_id, map_referenced_oval_endpoints,
127
            )
128
129 1
        out = {}
130 1
        while len(references) != 0:
131 1
            ref = references.pop()
132 1
            self._resolve_reference(ref, references, out, map_referenced_oval_endpoints)
133 1
        return out
134
135 1
    def get_test_info(self, test_id):
136 1
        test = self.tests[test_id]
137
138 1
        list_object_of_test = test.xpath('.//*[local-name()="object"]')
139 1
        list_state_of_test = test.xpath('.//*[local-name()="state"]')
140
141 1
        oval_object_el = list_object_of_test.pop() if list_object_of_test else None
142
143 1
        oval_object = None
144 1
        oval_states = []
145
146 1
        if oval_object_el is not None:
147 1
            oval_object = self.objects_parser.get_object(oval_object_el.get("object_ref", ""))
148
149 1
        for oval_state_el in list_state_of_test:
150 1
            oval_states.append(self.states_parser.get_state(oval_state_el.get("state_ref", "")))
151
152 1
        map_referenced_oval_endpoints = defaultdict(list)
153
154 1
        referenced_oval_endpoints = self._get_referenced_endpoints(
155
            oval_object, oval_states, map_referenced_oval_endpoints
156
        )
157
158 1
        return OvalTest(
159
            test_id=test_id,
160
            check_existence=test.attrib.get("check_existence", ""),
161
            check=test.attrib.get("check", ""),
162
            test_type=test.tag[test.tag.index('}') + 1:],
163
            comment=test.attrib.get("comment", ""),
164
            oval_object=oval_object,
165
            oval_states=oval_states,
166
            referenced_oval_endpoints=referenced_oval_endpoints,
167
            map_referenced_oval_endpoints=dict(map_referenced_oval_endpoints),
168
        )
169