iwla

iwla Git Source Tree

Root/plugins/display/filter_users.py

1# -*- coding: utf-8 -*-
2#
3# Copyright Grégory Soutadé 2020
4
5# This file is part of iwla
6
7# iwla is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# iwla is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with iwla. If not, see <http://www.gnu.org/licenses/>.
19#
20
21import re
22
23from iwla import IWLA
24from iplugin import IPlugin
25from display import *
26
27"""
28Display hook
29
30Filter users
31
32Plugin requirements :
33 None
34
35Conf values needed :
36 filtered_users : list of filters
37 filtered_ip : list of ip (string)
38 create_filtered_page*
39
40Filter is a list of filter description combined by AND operator
41Filter description is a list of 3 elements :
42
43 * Field to match in visits
44 * Operator '=', '==', '!=', '>', '>=', '<', '<=' for int value
45 * Operator '=', '==', '!=', 'in', 'match' for str value
46 * Target value
47
48For easiest config, you can indicate both 'remote_addr' or 'ip' in field element
49
50Output files :
51 OUTPUT_ROOT/year/month/index.html
52 OUTPUT_ROOT/year/month/filtered_users.html
53
54Statistics creation :
55 None
56
57Statistics update :
58 None
59
60Statistics deletion :
61 None
62"""
63
64class IWLADisplayFilterUsers(IPlugin):
65 def __init__(self, iwla):
66 super(IWLADisplayFilterUsers, self).__init__(iwla)
67 self.API_VERSION = 1
68
69 def _check_filter(self, _filter):
70 if len(_filter) != 3:
71 raise Exception('Bad filter ' + ' '.join(_filter))
72 (field, operator, value) = _filter
73 try:
74 if type(value) == str:
75 value = int(value, 10)
76 _filter[2] = value
77 if operator not in ('=', '==', '!=', '>', '>=', '<', '<='):
78 raise Exception('Bad filter ' + ' '.join(_filter))
79 except Exception as e:
80 if field == 'ip':
81 _filter[0] = 'remote_addr'
82 if operator not in ('=', '==', '!=', 'in', 'match'):
83 raise Exception('Bad filter ' + ' '.join(_filter))
84 if operator == 'match':
85 _filter[2] = re.compile(value)
86
87 def load(self):
88 self.create_filtered_page = self.iwla.getConfValue('create_filtered_page', True)
89 self.filters = self.iwla.getConfValue('filtered_users', [])
90 self.ip_filters = self.iwla.getConfValue('filtered_ip', [])
91 for _filter in self.filters:
92 for sub_filter in _filter:
93 self._check_filter(sub_filter)
94 return True
95
96 def __do_filter(self, hit, _filter):
97 (field, operator, value) = _filter
98 if not field in hit.keys(): return False
99 hit_value = hit[field]
100 # In dict, we have something like : {dayX : value} were day0 is total
101 if type(value) == int and type(hit_value) == dict:
102 hit_value = list(hit_value.values())[0]
103 if operator == '=' or operator == '==':
104 return hit_value == value
105 elif operator == 'in':
106 return hit_value in value
107 elif operator == 'match':
108 return re.match(value, hit_value)
109 elif operator == '!=':
110 return hit_value != value
111 elif operator == '<':
112 return hit_value < value
113 elif operator == '<=':
114 return hit_value <= value
115 elif operator == '>':
116 return hit_value > value
117 elif operator == '>=':
118 return hit_value >= value
119
120 def _do_filter(self, ip, hits):
121 if ip in self.ip_filters:
122 return True
123
124 for _filter in self.filters:
125 filtered = True
126 for sub_filter in _filter:
127 if not self.__do_filter(hits[ip], sub_filter):
128 filtered = False
129 break
130 if filtered:
131 return True
132 return False
133
134 def hook(self):
135 display = self.iwla.getDisplay()
136 hits = self.iwla.getValidVisitors()
137 stats = {}
138 self.filtered_users = []
139
140 if len(self.filters) or len(self.ip_filters):
141 for (key,value) in hits.items():
142 if self._do_filter(key, hits):
143 self.filtered_users.append(hits[key])
144
145 # All in a page
146 if self.create_filtered_page:
147 title = createCurTitle(self.iwla, u'Filtered users')
148 filename = 'filtered_users.html'
149 path = self.iwla.getCurDisplayPath(filename)
150
151 page = display.createPage(title, path, self.iwla.getConfValue('css_path', []))
152 table = display.createBlock(DisplayHTMLBlockTable, self.iwla._(u'Filtered users'), [self.iwla._(u'Pages'), self.iwla._(u'Last Access')])
153 table.setColsCSSClass(['iwla_page', ''])
154 for filtered_user in self.filtered_users:
155 ip = filtered_user['remote_addr']
156 if 'dns_name_replaced' in hits[ip].keys():
157 ip_title = '<b>%s [%s]</b>' % (hits[ip]['remote_addr'], ip)
158 else:
159 ip_title = '<b>%s</b>' % (ip)
160 table.appendRow([ip_title, ''])
161 nb_hits = 0
162 nb_pages = 0
163 for r in hits[ip]['requests'][::-1]:
164 uri = r['extract_request']['extract_uri'].lower()
165 if not self.iwla.hasBeenViewed(r): continue
166 if not self.iwla.isPage(uri) or\
167 self.iwla.isMultimediaFile(uri):
168 nb_hits += 1
169 continue
170
171 nb_pages += 1
172 uri = "%s%s" % (r.get('server_name', ''),
173 r['extract_request']['extract_uri'])
174 table.appendRow([generateHTMLLink(uri), time.asctime(r['time_decoded'])])
175 stats[ip] = (nb_pages, nb_hits)
176 page.appendBlock(table)
177
178 display.addPage(page)
179
180 # Last access in index
181 title = self.iwla._(u'Filtered users')
182 if self.create_filtered_page:
183 link = '<a href=\'%s\'>%s</a>' % (filename, self.iwla._(u'Details'))
184 title = '%s - %s' % (title, link)
185
186 index = self.iwla.getDisplayIndex()
187
188 table = display.createBlock(DisplayHTMLBlockTable, title, [self.iwla._(u'Host'), self.iwla._(u'Last Access'), self.iwla._(u'Pages'), self.iwla._(u'Hits')])
189 table.setColsCSSClass(['', '', 'iwla_page', 'iwla_hit'])
190 for filtered_user in self.filtered_users:
191 ip = filtered_user['remote_addr']
192 if 'dns_name_replaced' in hits[ip].keys():
193 ip_title = '%s [%s]' % (hits[ip]['remote_addr'], ip)
194 else:
195 ip_title = ip
196 table.appendRow([ip_title, time.asctime(hits[ip]['last_access']), stats[ip][0], stats[ip][1]])
197 index.appendBlock(table)

Archive Download this file

Branches

Tags