Passed
Push — master ( e83018...b911ae )
by Jan
05:42 queued 03:44
created

graph.client.client.parse_arguments()   A

Complexity

Conditions 1

Size

Total Lines 34
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 29
nop 2
dl 0
loc 34
ccs 10
cts 10
cp 1
crap 1
rs 9.184
c 0
b 0
f 0
1 1
from __future__ import print_function, unicode_literals
2 1
import re
3 1
import graph.xml_parser
4 1
import graph.oval_graph
5 1
import webbrowser
6 1
import json
7 1
import argparse
8
9
10 1
class client():
11 1
    def __init__(self, args):
12 1
        self.arg = self.parse_arguments(args)
13 1
        self.remove_pass_tests = self.arg.remove_pass_tests
14 1
        self.show_fail_rules = self.arg.show_fail_rules
15 1
        self.show_not_selected_rules = self.arg.show_not_selected_rules
16 1
        self.off_webbrowser = self.arg.off_web_browser
17 1
        self.source_filename = self.arg.source_filename
18 1
        self.rule_name = self.arg.rule_id
19 1
        self.xml_parser = graph.xml_parser.xml_parser(self.source_filename)
20 1
        if self.remove_pass_tests:
21
            raise NotImplementedError('Not implemented!')
22
23 1
    def run_gui_and_return_answers(self):
24 1
        try:
25 1
            from PyInquirer import style_from_dict, Token, prompt, Separator
26
            return prompt(
27
                self.get_questions(
28
                    Separator('= The Rules IDs ='),
29
                    Separator('= The not selected rule IDs =')))
30 1
        except ImportError:
31 1
            print('== The Rule IDs ==')
32 1
            rules = self.search_rules_id()
33 1
            if self.show_fail_rules:
34 1
                rules = self.get_only_fail_rule(rules)
35 1
            for rule in rules:
36 1
                print(rule['id_rule'] + r'\b')
37 1
            if self.show_not_selected_rules:
38 1
                print('== The not selected rule IDs ==')
39 1
                for rule in self._get_wanted_not_selected_rules():
40 1
                    print(rule['id_rule'] + '(Not selected)')
41 1
            return None
42
43 1
    def get_questions(self, separator_rule_ids, separator_not_selected_rule_ids):
44 1
        rules = self.search_rules_id()
45 1
        if self.show_fail_rules:
46 1
            rules = self.get_only_fail_rule(rules)
47 1
        questions = [{
48
            'type': 'checkbox',
49
            'message': 'Select rule(s)',
50
            'name': 'rules',
51
            'choices': [separator_rule_ids]
52
        }]
53 1
        for rule in rules:
54 1
            questions[0]['choices'].append(dict(name=rule['id_rule']))
55 1
        if self.show_not_selected_rules:
56
            questions[0]['choices'].append(separator_not_selected_rule_ids)
57
            for rule in self._get_wanted_not_selected_rules():
58
                questions[0]['choices'].append(
59
                    dict(name=rule['id_rule'], disabled='Not selected'))
60 1
        return questions
61
62 1
    def get_only_fail_rule(self, rules):
63 1
        return list(filter(lambda rule: rule['result'] == 'fail', rules))
64
65 1
    def _get_wanted_rules(self):
66 1
        return [
67
            x for x in self.xml_parser.get_used_rules() if re.search(
68
                self.rule_name, x['id_rule'])]
69
70 1
    def _get_wanted_not_selected_rules(self):
71 1
        return [
72
            x for x in self.xml_parser.get_notselected_rules() if re.search(
73
                self.rule_name, x['id_rule'])]
74
75 1
    def search_rules_id(self):
76 1
        rules = self._get_wanted_rules()
77 1
        notselected_rules = self._get_wanted_not_selected_rules()
78 1
        if len(notselected_rules) and not rules:
79 1
            raise ValueError(
80
                ('err- rule(s) "{}" was not selected, '
81
                 'so there are no results. The rule is'
82
                 ' "notselected" because it'
83
                 " wasn't a part of the executed profile"
84
                 " and therefore it wasn't evaluated "
85
                 "during the scan.")
86
                .format(notselected_rules[0]['id_rule']))
87 1
        elif not notselected_rules and not rules:
88 1
            raise ValueError('err- 404 rule not found!')
89
        else:
90 1
            return rules
91
92 1
    def prepare_graphs(self, rules):
93 1
        try:
94 1
            for rule in rules['rules']:
95 1
                oval_tree = graph.oval_graph.build_nodes_form_xml(
96
                    self.source_filename, rule).to_sigma_dict(0, 0)
97 1
                with open('html_interpreter/data.js', "w+") as graph_data_file:
98 1
                    graph_data_file.write("var data_json =" + str(json.dumps(
99
                        oval_tree,
100
                        sort_keys=False,
101
                        indent=4) + ";"))
102 1
                self.open_web_browser()
103 1
                print('Rule "{}" done!'.format(rule))
104 1
        except Exception as error:
105 1
            raise ValueError('Rule: "{}" Error: "{}"'.format(rule, error))
106
107 1
    def open_web_browser(self):
108 1
        if not self.off_webbrowser:
109
            try:
110
                webbrowser.get('firefox').open_new_tab(
111
                    'html_interpreter/index.html')
112
            except BaseException:
113
                webbrowser.open_new_tab('html_interpreter/index.html')
114
115 1
    def parse_arguments(self, args):
116 1
        parser = argparse.ArgumentParser(
117
            description='Client for visualization of SCAP rule evaluation results')
118 1
        parser.add_argument(
119
            '--show-fail-rules',
120
            action="store_true",
121
            default=False,
122
            help='Show only FAIL rules')
123 1
        parser.add_argument(
124
            '--show-not-selected-rules',
125
            action="store_true",
126
            default=False,
127
            help="Show notselected rules. These rules will not be visualized.")
128 1
        parser.add_argument(
129
            '--off-web-browser',
130
            action="store_true",
131
            default=False,
132
            help="It does not start the web browser.")
133 1
        parser.add_argument(
134
            '--remove-pass-tests',
135
            action="store_true",
136
            default=False,
137
            help=('Do not display passing tests for better orientation in'
138
                  ' graphs that contain a large amount of nodes.(Not implemented)'))
139 1
        parser.add_argument("source_filename", help='ARF scan file')
140 1
        parser.add_argument(
141
            "rule_id", help=(
142
                'Rule ID to be visualized. A part from the full rule ID'
143
                ' a part of the ID or a regular expression can be used.'
144
                ' If brackets are used in the regular expression '
145
                'the regular expression must be quoted.'))
146 1
        args = parser.parse_args(args)
147
148
        return args
149