Passed
Push — master ( 073977...6a9e01 )
by Matěj
03:16 queued 12s
created

oval_graph.client.client.copy_interpreter()   A

Complexity

Conditions 3

Size

Total Lines 10
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 9
nop 2
dl 0
loc 10
rs 9.95
c 0
b 0
f 0
ccs 9
cts 9
cp 1
crap 3
1 1
from __future__ import print_function, unicode_literals
2 1
from datetime import datetime
3 1
import re
4 1
import oval_graph.xml_parser
5 1
import oval_graph.oval_graph
6 1
import oval_graph.converter
7 1
import webbrowser
8 1
import json
9 1
import argparse
10 1
import tempfile
11 1
import os
12 1
import shutil
13
14
15 1
class client():
16 1
    def __init__(self, args):
17 1
        self.arg = self.parse_arguments(args)
18 1
        self.remove_pass_tests = self.arg.remove_pass_tests
19 1
        self.show_fail_rules = self.arg.show_fail_rules
20 1
        self.show_not_selected_rules = self.arg.show_not_selected_rules
21 1
        self.off_webbrowser = self.arg.off_web_browser
22 1
        self.source_filename = self.arg.source_filename
23 1
        self.tree = self.arg.tree
24 1
        self.rule_name = self.arg.rule_id
25 1
        self.xml_parser = oval_graph.xml_parser.xml_parser(
26
            self.source_filename)
27 1
        if self.tree:
28 1
            self.html_interpreter = 'tree_html_interpreter'
29
        else:
30 1
            self.html_interpreter = 'graph_html_interpreter'
31 1
        if self.remove_pass_tests:
32
            raise NotImplementedError('Not implemented!')
33
34 1
    def run_gui_and_return_answers(self):
35 1
        try:
36 1
            import inquirer
37
            return inquirer.prompt(self.get_questions())
38 1
        except ImportError:
39 1
            print('== The Rule IDs ==')
40 1
            rules = self.search_rules_id()
41 1
            if self.show_fail_rules:
42 1
                rules = self.get_only_fail_rule(rules)
43 1
            for rule in rules:
44 1
                print(rule['id_rule'] + r'\b')
45 1
            if self.show_not_selected_rules:
46 1
                print('== The not selected rule IDs ==')
47 1
                for rule in self._get_wanted_not_selected_rules():
48 1
                    print(rule['id_rule'] + '(Not selected)')
49 1
            return None
50
51 1
    def get_questions(self):
52 1
        rules = self.search_rules_id()
53 1
        if self.show_fail_rules:
54 1
            rules = self.get_only_fail_rule(rules)
55 1
        choices_ = []
56 1
        for rule in rules:
57 1
            choices_.append(rule['id_rule'])
58 1
        if self.show_not_selected_rules:
59 1
            print('== The not selected rule IDs ==')
60 1
            for rule in self._get_wanted_not_selected_rules():
61 1
                print(rule['id_rule'] + '(Not selected)')
62 1
        from inquirer.questions import Checkbox as checkbox
63 1
        questions = [
64
            checkbox(
65
                'rules',
66
                message=(
67
                    "= The Rules IDs = (move - UP and DOWN arrows,"
68
                    " select - SPACE or LEFT and RIGHT arrows, submit - ENTER)"),
69
                choices=choices_,
70
            ),
71
        ]
72 1
        return questions
73
74 1
    def get_only_fail_rule(self, rules):
75 1
        return list(filter(lambda rule: rule['result'] == 'fail', rules))
76
77 1
    def _get_wanted_rules(self):
78 1
        return [
79
            x for x in self.xml_parser.get_used_rules() if re.search(
80
                self.rule_name, x['id_rule'])]
81
82 1
    def _get_wanted_not_selected_rules(self):
83 1
        return [
84
            x for x in self.xml_parser.get_notselected_rules() if re.search(
85
                self.rule_name, x['id_rule'])]
86
87 1
    def search_rules_id(self):
88 1
        rules = self._get_wanted_rules()
89 1
        notselected_rules = self._get_wanted_not_selected_rules()
90 1
        if len(notselected_rules) and not rules:
91 1
            raise ValueError(
92
                ('err- rule(s) "{}" was not selected, '
93
                 "so there are no results. The rule is"
94
                 ' "notselected" because it'
95
                 " wasn't a part of the executed profile"
96
                 " and therefore it wasn't evaluated "
97
                 "during the scan.")
98
                .format(notselected_rules[0]['id_rule']))
99 1
        elif not notselected_rules and not rules:
100 1
            raise ValueError('err- 404 rule not found!')
101
        else:
102 1
            return rules
103
104 1
    def create_dict_of_rule(self, rule_id):
105 1
        converter = oval_graph.converter.converter(
106
            oval_graph.oval_graph.build_nodes_form_xml(
107
                self.source_filename, rule_id))
108 1
        if self.tree:
109 1
            return converter.to_JsTree_dict()
110 1
        return converter.to_sigma_dict(0, 0)
111
112 1
    def save_dict(self, dict_, src):
113 1
        with open(os.path.join(src, 'data.js'), "w+") as data_file:
114 1
            data_file.write("var data_json =" + str(json.dumps(
115
                dict_, sort_keys=False, indent=4) + ";"))
116
117 1
    def copy_interpreter(self, dst):
118 1
        src = self.xml_parser.get_src(self.html_interpreter)
119 1
        os.mkdir(dst)
120 1
        for item in os.listdir(src):
121 1
            s = os.path.join(src, item)
122 1
            d = os.path.join(dst, item)
123 1
            if os.path.isdir(s):
124 1
                shutil.copytree(s, d)
125
            else:
126 1
                shutil.copy2(s, d)
127
128 1
    def prepare_data(self, rules):
129 1
        try:
130 1
            out = []
131 1
            for rule in rules['rules']:
132 1
                oval_tree = self.create_dict_of_rule(rule)
133 1
                date = str(datetime.now().strftime("_%d-%m-%Y_%H:%M:%S"))
134 1
                src = os.path.join(
135
                    tempfile.gettempdir(),
136
                    'graph-of-' + rule + date)
137 1
                self.copy_interpreter(src)
138 1
                self.save_dict(oval_tree, src)
139 1
                self.open_web_browser(src)
140 1
                print('Rule "{}" done!'.format(rule))
141 1
                out.append(src)
142 1
            return out
143 1
        except Exception as error:
144 1
            raise ValueError('Rule: "{}" Error: "{}"'.format(rule, error))
145
146 1
    def open_web_browser(self, src):
147 1
        if not self.off_webbrowser:
148
            src = os.path.join(src, 'index.html')
149
            try:
150
                webbrowser.get('firefox').open_new_tab(src)
151
            except BaseException:
152
                webbrowser.open_new_tab(src)
153
154 1
    def parse_arguments(self, args):
155 1
        parser = argparse.ArgumentParser(
156
            description="Client for visualization of SCAP rule evaluation results")
157 1
        parser.add_argument(
158
            '--show-fail-rules',
159
            action="store_true",
160
            default=False,
161
            help="Show only FAIL rules")
162 1
        parser.add_argument(
163
            '--show-not-selected-rules',
164
            action="store_true",
165
            default=False,
166
            help="Show notselected rules. These rules will not be visualized.")
167 1
        parser.add_argument(
168
            '--off-web-browser',
169
            action="store_true",
170
            default=False,
171
            help="It does not start the web browser.")
172 1
        parser.add_argument(
173
            '--tree',
174
            action="store_true",
175
            default=False,
176
            help="Render the graph in a form of directory tree")
177 1
        parser.add_argument(
178
            '--remove-pass-tests',
179
            action="store_true",
180
            default=False,
181
            help=(
182
                "Do not display passing tests for better orientation in"
183
                " graphs that contain a large amount of nodes.(Not implemented)"))
184 1
        parser.add_argument("source_filename", help="ARF scan file")
185 1
        parser.add_argument(
186
            "rule_id", help=(
187
                "Rule ID to be visualized. A part from the full rule ID"
188
                " a part of the ID or a regular expression can be used."
189
                " If brackets are used in the regular expression "
190
                "the regular expression must be quoted."))
191 1
        args = parser.parse_args(args)
192
193
        return args
194