Completed
Push — master ( 43a11b...86dfcb )
by -
01:38
created

NaxsiWhitelist.generate_from_nxlog()   A

Complexity

Conditions 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1.125
Metric Value
dl 0
loc 3
ccs 1
cts 2
cp 0.5
rs 10
cc 1
crap 1.125
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 1
class NaxsiWhitelist(db.Model):
10 1
    __bind_key__ = 'rules'
11 1
    __tablename__ = 'naxsi_whitelist'
12
13 1
    id = db.Column(db.Integer, primary_key=True)
14 1
    wid = db.Column(db.String, nullable=False, unique=True)
15 1
    mz = db.Column(db.String(1024), nullable=False)
16 1
    negative = db.Column(db.Integer, nullable=False, server_default='0')
17 1
    active = db.Column(db.Integer, nullable=False, server_default='1')
18 1
    timestamp = db.Column(db.Integer, nullable=False)
19 1
    whitelistset = db.Column(db.String(1024), nullable=False)
20
21 1
    def __init__(self, wid='0', mz='', active=0, negative=0, whitelistset='', timestamp=0):
22 1
        self.wid = wid
23 1
        self.mz = mz
24 1
        self.active = active
25 1
        self.negative = negative
26 1
        self.whitelistset = whitelistset
27 1
        self.timestamp = timestamp
28 1
        self.warnings = []
29 1
        self.error = []
30
31 1
    def __str__(self):
32 1
        return 'BasicRule {}wl:{} "mz:{}";'.format('negative ' if self.negative else ' ', self.wid, self.mz)
33
34 1
    def __validate_id(self, wid):
35 1
        if not re.match(r':(\-?\d+,)\-?\d+', wid):
36 1
            self.error.append('Illegal character in the whitelist id.')
37 1
            return False
38
        self.wid = wid
39
        return True
40
41 1
    def __validate_mz(self, mz):
42
        # Borrow '__validate_matchzone' from naxsi_rules.py ?
43 1
        self.mz = mz
44 1
        return True
45
46 1
    def parse(self, str_wl):
47 1
        self.warnings = list()
48 1
        self.error = list()
49
50 1
        lexer = shlex(str_wl)
51 1
        lexer.whitespace_split = True
52 1
        split = list(iter(lexer.get_token, ''))
53
54 1
        for piece in split:
55 1
            if piece == ';':
56 1
                continue
57 1
            elif piece.startswith(('"', "'")) and (piece[0] == piece[-1]):  # remove (double-)quotes
58 1
                piece = piece[1:-1]
59
60 1
            if piece.startswith('wl:'):
61 1
                self.__validate_id(piece[3:])
62 1
            elif piece.startswith('mz:'):
63 1
                self.__validate_mz(piece[3:])
64 1
            elif piece == 'negative':
65 1
                self.negative = True
66 1
            else:
67
                self.error.append('Unknown fragment: {}'.format(piece))
68
                return False
69 1
70 1
        if 'BasicRule' not in split:
71
            self.error.append('No "BasicRule" keyword in {}'.format(str_wl))
72 1
            return False
73
74
        return True
75
76 1
    def explain(self):
77
        def __linkify_rule(rid):
78 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...
79 1
                return rid
80
            return '<a href="{}">{}</a>'.format(url_for('rules.view', sid=rid), self.wid)
81
82
        if self.wid == '0':
83
            ret = 'Whitelist all rules'
84 1
        elif self.wid.isdigit():
85 1
            ret = 'Whitelist the rule {}'.format(__linkify_rule(self.wid))
86
        else:
87
            zones = list()
88
            for rid in self.wid.split(','):
89
                if rid.startswith('-'):
90
                    zones.append('except the rule {}'.format(__linkify_rule(self.wid)))
91
                else:
92
                    zones.append('the rule {}'.format(__linkify_rule(self.wid)))
93
            ret = 'Whitelist '+ ', '.join(zones)
94
95
        if not self.mz:
96
            return ret + '.'
97 1
98
        return ret + ' if matching in {}.'.format(self.mz)
99