Completed
Push — master ( 3f857f...2fa2ab )
by -
01:37
created

NaxsiWhitelist.__validate_wid()   A

Complexity

Conditions 2

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2
Metric Value
dl 0
loc 6
ccs 6
cts 6
cp 1
rs 9.4285
cc 2
crap 2
1 1
import re
2
3 1
from spike.model import db
4 1
from shlex import shlex
5
6 1
from spike.model.naxsi_rules import NaxsiRules
7 1
from flask import url_for
8
9
10 1
class NaxsiWhitelist(db.Model):
11 1
    __bind_key__ = 'rules'
12 1
    __tablename__ = 'naxsi_whitelist'
13
14 1
    id = db.Column(db.Integer, primary_key=True)
15 1
    wid = db.Column(db.String, nullable=False)
16 1
    mz = db.Column(db.String(1024), nullable=False)
17 1
    negative = db.Column(db.Integer, nullable=False, server_default='0')
18 1
    active = db.Column(db.Integer, nullable=False, server_default='1')
19 1
    timestamp = db.Column(db.Integer, nullable=False)
20 1
    whitelistset = db.Column(db.String(1024), nullable=False)
21
22 1
    def __init__(self, wid='0', mz='', active=0, negative=0, whitelistset='', timestamp=0):
23 1
        self.wid = wid
24 1
        self.mz = mz
25 1
        self.active = active
26 1
        self.negative = negative
27 1
        self.whitelistset = whitelistset
28 1
        self.timestamp = timestamp
29 1
        self.warnings = []
30 1
        self.error = []
31
32 1
    def __str__(self):
33 1
        return 'BasicRule {}wl:{} "mz:{}";'.format('negative ' if self.negative else ' ', self.wid, self.mz)
34
35 1
    def __validate_wid(self, wid):
36 1
        if not re.match(r'wl:(\-?\d+,)*\-?\d+', wid):
37 1
            self.error.append('Illegal character in the whitelist id.')
38 1
            return False
39 1
        self.wid = wid
40 1
        return True
41
42 1
    def __validate_mz(self, mz):
43
        # Borrow '__validate_matchzone' from naxsi_rules.py ?
44 1
        self.mz = mz
45 1
        return True
46
47 1
    def parse(self, str_wl):
48 1
        self.warnings = list()
49 1
        self.error = list()
50
51 1
        lexer = shlex(str_wl)
52 1
        lexer.whitespace_split = True
53 1
        split = list(iter(lexer.get_token, ''))
54
55 1
        for piece in split:
56 1
            if piece == ';':
57 1
                continue
58 1
            elif piece.startswith(('"', "'")) and (piece[0] == piece[-1]):  # remove (double-)quotes
59 1
                piece = piece[1:-1]
60
61 1
            if piece == 'BasicRule':
62 1
                continue
63 1
            elif piece.startswith('wl:'):
64 1
                self.__validate_wid(piece)
65 1
            elif piece.startswith('mz:'):
66 1
                self.__validate_mz(piece[3:])
67 1
            elif piece == 'negative':
68 1
                self.negative = True
69
            else:
70 1
                self.error.append('Unknown fragment: {}'.format(piece))
71 1
                return False
72
73 1
            if not piece.islower():
74 1
                self.warnings.append('Your whitelist is not completely in lowercase.')
75
76 1
        if 'BasicRule' not in split:
77 1
            self.error.append("No 'BasicRule' keyword in {}.".format(str_wl))
78 1
            return False
79
80 1
        return True
81
82 1
    def validate(self):
83 1
        self.warnings = list()
84 1
        self.error = list()
85
86 1
        self.__validate_wid(self.wid)
87 1
        self.__validate_mz(self.mz)
88 1
        return True
89
90 1
    def explain(self):
91 1
        def __linkify_rule(rid):
92 1
            if NaxsiRules.query.filter(NaxsiRules.sid == self.wid).first() is None:
0 ignored issues
show
Bug introduced by
The Class NaxsiRules does not seem to have a member named query.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
93 1
                return rid
94
            return '<a href="{}">{}</a>'.format(url_for('rules.view', sid=rid), self.wid)
95
96 1
        if self.wid == 'wl:0':
97 1
            ret = 'Whitelist all rules'
98 1
        elif self.wid[3:].isdigit():
99 1
            ret = 'Whitelist the rule {}'.format(__linkify_rule(self.wid[3:]))
100
        else:
101 1
            zones = list()
102 1
            for rid in self.wid[3:].split(','):
103 1
                if rid.startswith('-'):
104 1
                    zones.append('except the rule {}'.format(__linkify_rule(rid[1:])))
105
                else:
106 1
                    zones.append('the rule {}'.format(__linkify_rule(rid)))
107 1
            ret = 'Whitelist '+ ', '.join(zones)
108
109 1
        if not self.mz:
110 1
            return ret + '.'
111
112
        return ret + ' if matching in {}.'.format(self.mz)
113