1
|
|
|
''' |
2
|
|
|
Modules form my lib and for create ID |
3
|
|
|
''' |
4
|
1 |
|
import uuid |
5
|
|
|
|
6
|
1 |
|
import oval_graph.evaluate |
7
|
|
|
|
8
|
|
|
|
9
|
|
|
''' |
10
|
|
|
This module contains methods and classes for |
11
|
|
|
constructing and controlling an oval tree. |
12
|
|
|
''' |
13
|
|
|
|
14
|
|
|
|
15
|
1 |
|
class OvalNode(): |
16
|
|
|
''' |
17
|
|
|
The OvalNode object is one node of oval_graph. |
18
|
|
|
|
19
|
|
|
Attributes: |
20
|
|
|
node_id (str): id of node |
21
|
|
|
node_type (str): type node |
22
|
|
|
value (str): value of node for operator and, or, one etc... and for value true, |
23
|
|
|
false, error etc... |
24
|
|
|
negation (bool): value indicating whether the node is negated |
25
|
|
|
comment (str): some comment about node |
26
|
|
|
tag (str): tag specifies if the node represents OVAL test, |
27
|
|
|
OVAL definition or XCCDF rule |
28
|
|
|
test_result_details (dict|None): information about test |
29
|
|
|
children ([OvalNode]): children of node |
30
|
|
|
''' |
31
|
|
|
|
32
|
1 |
|
def __init__(self, **kwargs): |
33
|
|
|
""" |
34
|
|
|
Note: |
35
|
|
|
This metode construct OvalNode and validate values of parameteres. |
36
|
|
|
|
37
|
|
|
Required args: |
38
|
|
|
node_id (str|int): identifies node |
39
|
|
|
node_type (str): type of node (value or operator) |
40
|
|
|
value (str): value of node |
41
|
|
|
|
42
|
|
|
Optional args: |
43
|
|
|
negation (bool): value indicating whether the node is negated (empty eq False) |
44
|
|
|
comment (str): text about node (empty eq None) |
45
|
|
|
tag (str): tag specifies if the node represents OVAL test, |
46
|
|
|
OVAL definition or XCCDF rule (empty eq None) |
47
|
|
|
test_result_details (dict|None): information about test (empty eq None) |
48
|
|
|
children ([OvalNode]): array of children of node (empty eq empty array) |
49
|
|
|
""" |
50
|
1 |
|
try: |
51
|
1 |
|
self.node_id = kwargs['node_id'] |
52
|
1 |
|
self.node_type = self._validate_type(kwargs['node_type']) |
53
|
1 |
|
self.value = self._validate_value(kwargs['value']) |
54
|
|
|
|
55
|
1 |
|
self._check_missing_children_for_operator( |
56
|
|
|
kwargs.get('children', None)) |
57
|
1 |
|
self.negation = self._validate_negation( |
58
|
|
|
kwargs.get('negation', False)) |
59
|
1 |
|
except KeyError: |
60
|
1 |
|
raise Exception("err - Missing required argument!") |
61
|
|
|
|
62
|
1 |
|
self.comment = kwargs.get('comment', None) |
63
|
1 |
|
self.tag = kwargs.get('tag', None) |
64
|
1 |
|
self.test_result_details = kwargs.get('test_result_details', None) |
65
|
|
|
|
66
|
1 |
|
input_children = kwargs.get('children', None) |
67
|
1 |
|
self.children = [] |
68
|
1 |
|
if input_children: |
69
|
1 |
|
for child in input_children: |
70
|
1 |
|
self._add_child(child) |
71
|
|
|
|
72
|
1 |
|
def _validate_negation(self, input_negation): |
73
|
1 |
|
if not isinstance(input_negation, bool): |
74
|
1 |
|
raise TypeError("err - Bad value of negation argument!") |
75
|
1 |
|
return input_negation |
76
|
|
|
|
77
|
1 |
|
def _validate_type(self, input_node_type): |
78
|
1 |
|
node_type = input_node_type.lower() |
79
|
1 |
|
if node_type not in ("value", "operator"): |
80
|
1 |
|
raise TypeError("err - Bad value of node_type argument!") |
81
|
1 |
|
return node_type |
82
|
|
|
|
83
|
1 |
|
def _validate_value(self, input_value): |
84
|
1 |
|
value = input_value.lower() |
85
|
|
|
|
86
|
1 |
|
allowed_values = [ |
87
|
|
|
"true", |
88
|
|
|
"false", |
89
|
|
|
"error", |
90
|
|
|
"unknown", |
91
|
|
|
"noteval", |
92
|
|
|
"notappl"] |
93
|
1 |
|
allowed_operators = ["or", "and", "one", "xor"] |
94
|
|
|
|
95
|
1 |
|
if self.node_type == "value" and value not in allowed_values: |
96
|
1 |
|
raise TypeError( |
97
|
|
|
"err - Bad value of value argument for value type!") |
98
|
|
|
|
99
|
1 |
|
if self.node_type == "operator" and value not in allowed_operators: |
100
|
1 |
|
raise TypeError( |
101
|
|
|
"err - Bad value of value argument for operator type!") |
102
|
|
|
|
103
|
1 |
|
return value |
104
|
|
|
|
105
|
1 |
|
def _check_missing_children_for_operator(self, children): |
106
|
1 |
|
if children is None and self.node_type == "operator": |
107
|
1 |
|
raise ValueError( |
108
|
|
|
"err- Operator node must has child!") |
109
|
|
|
|
110
|
1 |
|
def __repr__(self): |
111
|
1 |
|
return self.value |
112
|
|
|
|
113
|
1 |
|
def _add_child(self, node): |
114
|
1 |
|
if self.node_type == "operator": |
115
|
1 |
|
assert isinstance(node, OvalNode) |
116
|
1 |
|
self.children.append(node) |
117
|
|
|
else: |
118
|
1 |
|
self.children = None |
119
|
1 |
|
raise ValueError( |
120
|
|
|
"err- Value node don't has any child!") |
121
|
|
|
|
122
|
1 |
|
def _get_result_counts(self): |
123
|
1 |
|
result = { |
124
|
|
|
'true_cnt': 0, |
125
|
|
|
'false_cnt': 0, |
126
|
|
|
'error_cnt': 0, |
127
|
|
|
'unknown_cnt': 0, |
128
|
|
|
'noteval_cnt': 0, |
129
|
|
|
'notappl_cnt': 0 |
130
|
|
|
} |
131
|
|
|
|
132
|
1 |
|
for child in self.children: |
133
|
1 |
|
if child.value == 'true' and not child.negation: |
134
|
1 |
|
result['true_cnt'] += 1 |
135
|
1 |
|
elif child.value == 'true' and child.negation: |
136
|
1 |
|
result['false_cnt'] += 1 |
137
|
1 |
|
elif child.value == 'false' and not child.negation: |
138
|
1 |
|
result['false_cnt'] += 1 |
139
|
1 |
|
elif child.value == 'false' and child.negation: |
140
|
1 |
|
result['true_cnt'] += 1 |
141
|
|
|
else: |
142
|
1 |
|
if child.node_type == "operator": |
143
|
1 |
|
result[child.evaluate_tree() + "_cnt"] += 1 |
144
|
|
|
else: |
145
|
1 |
|
result[child.value + "_cnt"] += 1 |
146
|
1 |
|
return result |
147
|
|
|
|
148
|
1 |
|
def evaluate_tree(self): |
149
|
1 |
|
result = self._get_result_counts() |
150
|
1 |
|
out_result = None |
151
|
1 |
|
if oval_graph.evaluate.is_notapp_result(result): |
152
|
1 |
|
out_result = "notappl" |
153
|
|
|
else: |
154
|
1 |
|
if self.value == "or": |
155
|
1 |
|
out_result = oval_graph.evaluate.oval_operator_or(result) |
156
|
1 |
|
elif self.value == "and": |
157
|
1 |
|
out_result = oval_graph.evaluate.oval_operator_and(result) |
158
|
1 |
|
elif self.value == "one": |
159
|
1 |
|
out_result = oval_graph.evaluate.oval_operator_one(result) |
160
|
1 |
|
elif self.value == "xor": |
161
|
1 |
|
out_result = oval_graph.evaluate.oval_operator_xor(result) |
162
|
|
|
|
163
|
1 |
|
if out_result == 'true' and self.negation: |
164
|
1 |
|
out_result = 'false' |
165
|
1 |
|
elif out_result == 'false' and self.negation: |
166
|
1 |
|
out_result = 'true' |
167
|
|
|
|
168
|
1 |
|
return out_result |
169
|
|
|
|
170
|
1 |
|
def save_tree_to_dict(self): |
171
|
1 |
|
if not self.children: |
172
|
1 |
|
return { |
173
|
|
|
'node_id': self.node_id, |
174
|
|
|
'type': self.node_type, |
175
|
|
|
'value': self.value, |
176
|
|
|
'negation': self.negation, |
177
|
|
|
'comment': self.comment, |
178
|
|
|
'tag': self.tag, |
179
|
|
|
'test_result_details': self.test_result_details, |
180
|
|
|
'child': None |
181
|
|
|
} |
182
|
1 |
|
return { |
183
|
|
|
'node_id': self.node_id, |
184
|
|
|
'type': self.node_type, |
185
|
|
|
'value': self.value, |
186
|
|
|
'negation': self.negation, |
187
|
|
|
'comment': self.comment, |
188
|
|
|
'tag': self.tag, |
189
|
|
|
'test_result_details': self.test_result_details, |
190
|
|
|
'child': [child.save_tree_to_dict() for child in self.children] |
191
|
|
|
} |
192
|
|
|
|
193
|
1 |
|
def find_node_with_ID(self, node_id): |
194
|
1 |
|
if self.node_id == node_id: |
195
|
1 |
|
return self |
196
|
|
|
else: |
197
|
1 |
|
for child in self.children: |
198
|
1 |
|
if child.node_id == node_id: |
199
|
1 |
|
return child |
200
|
1 |
|
for child in self.children: |
201
|
1 |
|
if child.children != []: |
202
|
1 |
|
return child.find_node_with_ID(node_id) |
203
|
|
|
|
204
|
1 |
|
def add_to_tree(self, node_id, newNode): |
205
|
1 |
|
self.find_node_with_ID(node_id)._add_child(newNode) |
206
|
|
|
|
207
|
1 |
|
def change_tree_value(self, node_id, value): |
208
|
1 |
|
self.find_node_with_ID(node_id).value = value |
209
|
|
|
|
210
|
|
|
|
211
|
1 |
|
def restore_dict_to_tree(dict_of_tree): |
212
|
1 |
|
if dict_of_tree["child"] is None: |
213
|
1 |
|
return OvalNode( |
214
|
|
|
node_id=dict_of_tree["node_id"], |
215
|
|
|
node_type=dict_of_tree["type"], |
216
|
|
|
value=dict_of_tree["value"], |
217
|
|
|
negation=dict_of_tree["negation"], |
218
|
|
|
comment=dict_of_tree["comment"], |
219
|
|
|
tag=dict_of_tree["tag"], |
220
|
|
|
test_result_details=dict_of_tree["test_result_details"]) |
221
|
1 |
|
return OvalNode( |
222
|
|
|
node_id=dict_of_tree["node_id"], |
223
|
|
|
node_type=dict_of_tree["type"], |
224
|
|
|
value=dict_of_tree["value"], |
225
|
|
|
negation=dict_of_tree["negation"], |
226
|
|
|
comment=dict_of_tree["comment"], |
227
|
|
|
tag=dict_of_tree["tag"], |
228
|
|
|
test_result_details=dict_of_tree["test_result_details"], |
229
|
|
|
children=[restore_dict_to_tree(i) for i in dict_of_tree["child"]]) |
230
|
|
|
|