From 26646c7d7fa03227e922ca46935f6c2fc02f25b0 Mon Sep 17 00:00:00 2001 From: Nicolas Coevoet Date: Tue, 9 Feb 2021 15:06:07 +0000 Subject: [PATCH] Revert "patch From: Krytarik Raido " This reverts commit 2060b4f8c6d611bebc0b64089daa82094a495e35. --- server.py | 547 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 284 insertions(+), 263 deletions(-) diff --git a/server.py b/server.py index 4b32a3d..65f5f78 100644 --- a/server.py +++ b/server.py @@ -1,6 +1,13 @@ -import os, re, time, base64 +import http.server +import os +import time +import base64 +import re import supybot.utils as utils -import http.server, sqlite3 +import sqlite3 +import collections +import urllib.parse +from io import StringIO host = 'http://domain.tld' port = 80 @@ -9,11 +16,11 @@ webpath = '/bantracker' username = 'username' password = 'password' filename = '/home/botaccount/data/networkname/ChanTracker.db' -channels = [] # empty to allow view of all channels recorded, otherwise restrict the views to channels +channels = [] # empty to allows view of all channels recorded, otherwise restrict the views to channels # usage python server.py auth = '%s:%s' % (username,password) -base64string = base64.b64encode(auth.encode('utf-8')).decode('utf-8') +base64string = base64.b64encode(auth.encode('UTF-8')) def timeElapsed(elapsed, short=False, leadingZeroes=False, years=True, weeks=True, days=True, hours=True, minutes=True, seconds=True): @@ -58,35 +65,21 @@ def timeElapsed(elapsed, short=False, leadingZeroes=False, years=True, else: return format('%L', ret) -class MyHandler(http.server.BaseHTTPRequestHandler): +class MyHandler( http.server.BaseHTTPRequestHandler ): + server_version= "Ircd-Seven/1.1" if not standalone: def log_request(self, *args): pass # disable logging - def do_GET(self): - self.page(self.path) - - def page(self, query): - def write(subtitle, body): - page = [ - '', - '\nBanTracker%s' % (' » %s' % subtitle if subtitle else ''), - '', - '', - '\n' - ] + body + ['\n'] - self.send_response(200) - self.send_header("Content-type","text/html") - full = '\n'.join(page) - print('HTML lines %s' % len(full)) - self.send_header("Content-length",len(full)) - self.end_headers() - self.wfile.write(full.encode('utf-8')) + def do_GET( self ): + self.page( self.path ) + def page (self,query): if standalone: h = '%s:%s/' % (host,port) else: h = '%s/' % webpath + body = [] if not query: return if query.startswith('/?username='): @@ -100,260 +93,287 @@ class MyHandler(http.server.BaseHTTPRequestHandler): if aa[0] == 'password': p = aa[1] if u and p: - raw = base64.b64encode('%s:%s'.encode('utf-8') % (u,p)).decode('utf-8') - if raw != base64string: + raw = base64.encodebytes(bytes('%s:%s' % (u,p), 'UTF-8'))[:-1] + if not raw == base64string: query = '' else: - query = '/?hash=%s' % base64string + query = '/?hash=%s' % base64string.decode('UTF-8') if not query.startswith('/?hash='): - subtitle = '' - body = [ - '
' % h, - '

Username:

', - '

Password:

', - '', - '
' - ] - write(subtitle, body) + body.append('\n\nChanTracker\n') + body.append('\n') + body.append("\n\n") + body.append('
\n' % h) + body.append('

Username:

\n') + body.append('

Password:

\n') + body.append('\n') + body.append("
\n") + body.append("\n\n") + self.send_response(200) + self.send_header("Content-type","text/html") + full = ''.join(body) + self.send_header("Content-length",str(len(full))) + self.end_headers() + self.wfile.write(full.encode('UTF-8')) return - query = query.replace('%3D','=') - query = query.replace('/?hash=%s' % base64string,'') - query = query.lstrip('&') - q = '?hash=%s' % base64string - query = utils.web.urlunquote(query) - subtitle = '' - body = [ - '
', - '
' % q, - '
', - '' % base64string, - '', - '', - '
', - '
' - ] - if not query: - write(subtitle, body) - return - print(query) - subtitle = query + if query.startswith('/?hash='): + a = query.split('&')[0] + a = a.replace('/?hash=','') + query = query.replace('%3D','=') + query = query.replace('/?hash=%s' % base64string.decode('UTF-8'),'/') + q = '?hash=%s' % base64string.decode('UTF-8') + query = urllib.parse.unquote( query ) + print(query) + body.append('\n\nBanTracker - %s\n' % query) + body.append('\n') + body.append('\n') +# body.append('\n') + body.append('\n\n') + body.append('
\n') + body.append('
\n' % q) + body.append('
') + body.append('' % base64string.decode('UTF-8')) + body.append('\n') + body.append('\n') + body.append('
\n') + body.append('
\n') db = self._getbandb() c = db.cursor() - ar = [] - if query.startswith('id='): - search = query.split('=')[1] - si = int(search) - c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE id=?""",(si,)) - r = c.fetchall() - if len(r): - ban = r[0] - (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = ban - if not channels or channel in channels: - body.extend([ - '

#%d

' % id, - '

#%d by %s' % (id,h,q,utils.web.urlencode({'oper':oper}),oper), - 'in %s:' % (h,q,channel.split('#')[1],channel), - '+%s %s

' % (kind,h,q,utils.web.urlencode({'mask':mask}),mask), - '

Begin at %s

' % time.strftime('%Y-%m-%d %H:%M:%S GMT',time.gmtime(float(begin_at))) - ]) - was = float(begin_at) == float(end_at) - if was: - was = 'forever' - else: - was = timeElapsed(float(end_at) - float(begin_at)) - body.append('

Original duration: %s

' % was) - if not removed_at: - if was != 'forever': - body.append('

It will expire in %s

' % timeElapsed(float(end_at) - time.time())) - else: - body.extend(['

Removed after %s' % timeElapsed(float(removed_at)-float(begin_at)), - 'on %s' % time.strftime('%Y-%m-%d %H:%M:%S GMT',time.gmtime(float(removed_at))), - 'by %s

' % (h,q,utils.web.urlencode({'removed_by':removed_by}),removed_by)]) - c.execute("""SELECT full,log FROM nicks WHERE ban_id=?""",(id,)) - r = c.fetchall() - if len(r): - body.append('

Logs

') - for nick in r: - (full,log) = nick - body.append('

for %s

' % full) - if log != '': - body.append('') - c.execute("""SELECT oper,at,comment FROM comments WHERE ban_id=?""",(id,)) - r = c.fetchall() - if len(r): - body.extend(['

Comments

', '') - c.close() - write(subtitle, body) - return - elif query.startswith('channel='): - search = '#'+query.split('=')[1] - c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE channel=? ORDER BY id DESC""",(search,)) - r = c.fetchall() - if len(r): - ar.extend(r) - elif query.startswith('removed_by='): - search = query.split('=')[1] - c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE removed_by=? ORDER BY id DESC""",(search,)) - r = c.fetchall() - if len(r): - ar.extend(r) - elif query.startswith('oper='): - search = query.split('=')[1] - c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE oper=? ORDER BY id DESC""",(search,)) - r = c.fetchall() - if len(r): - ar.extend(r) - elif query.startswith('mask='): - search = query.split('=')[1] - sg = '*%s*' % search - sl = '%%%s%%' % search - c.execute("""SELECT ban_id,full FROM nicks WHERE full GLOB ? OR full LIKE ? OR log GLOB ? OR log LIKE ? ORDER BY ban_id DESC""",(sg,sl,sg,sl)) - r = c.fetchall() - L = [] - a = {} - if len(r): - d = {} - for ban in r: - (id,full) = ban - if id not in d: - d[id] = id - for id in d: - c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE id=?""",(id,)) - r = c.fetchall() - if len(r): - for ban in r: - a[ban[0]] = ban - c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE mask GLOB ? OR mask LIKE ? ORDER BY id DESC""",(sg,sl)) - r = c.fetchall() - if len(r): - for ban in r: - a[ban[0]] = ban - if len(a): - ar = [] - for ban in list(a.keys()): - ar.append(a[ban]) - ar.sort(key=lambda x: x[0], reverse=True) - elif query.startswith('search='): - search = query.split('=')[1] - search = search.replace('+','*') - print(search) - if search: - if not re.match(r'^[0-9]+$', search): - sg = '*%s*' % search - sl = '%%%s%%' % search - si = None - c.execute("""SELECT ban_id,full FROM nicks WHERE full GLOB ? OR full LIKE ? OR log GLOB ? OR log LIKE ? ORDER BY ban_id DESC""",(sg,sl,sg,sl)) - r = c.fetchall() - else: - si = int(search) - r = [] - L = [] - a = {} - if len(r): - d = {} - for ban in r: - (id,full) = ban - if id not in d: - d[id] = id - for id in d: - c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE id=?""",(id,)) - r = c.fetchall() - if len(r): - for ban in r: - a[ban[0]] = ban - if not si: - c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE mask GLOB ? OR mask LIKE ? OR channel GLOB ? OR channel LIKE ? OR oper GLOB ? OR oper LIKE ? ORDER BY id DESC""",(sg,sl,sg,sl,sg,sl)) - else: - c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE id=?""",(si,)) + if query: + ar = [] + if query.startswith('/&id='): + search = query.split('/&id=')[1] + c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE id=? ORDER BY id DESC""",(search,)) r = c.fetchall() if len(r): - for ban in r: - a[ban[0]] = ban - if not si: - c.execute("""SELECT ban_id, comment FROM comments WHERE comment GLOB ? OR comment LIKE ? ORDER BY ban_id DESC""",(sg,sl)) - r = c.fetchall() - else: - r = [] - d = {} + ban = r[0] + (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = ban + if not len(channels) or channel in channels: + body.append('

#%s

\n' % id) + body.append('

#%s by %s in %s : +%s : %s

\n' % (id,oper,channel,kind,mask)) + body.append('

Begin at %s

\n' % time.strftime('%Y-%m-%d %H:%M:%S GMT',time.gmtime(float(begin_at)))) + was = float(begin_at) == float(end_at) + if was: + was = 'forever' + else: + was = timeElapsed(float(end_at) - float(begin_at)) + body.append('

Original duration : %s

\n' % was) + if not removed_at: + if was != 'forever': + body.append('

%s

\n' % 'It will expire in %s' % timeElapsed(float(end_at) - time.time())) + else: + body.append('

%s

\n' % 'Removed after %s on %s by %s' % (timeElapsed(float(removed_at)-float(begin_at)),time.strftime('%Y-%m-%d %H:%M:%S GMT',time.gmtime(float(removed_at))),removed_by)) + c.execute("""SELECT full, log FROM nicks WHERE ban_id=?""",(id,)) + r = c.fetchall() + if len(r): + users = r + body.append('

Logs

\n') + for u in users: + (full,log) = u + body.append('

for %s

\n' % full) + if log != '': + body.append('\n') + c.execute("""SELECT oper, at, comment FROM comments WHERE ban_id=?""",(id,)) + r = c.fetchall() + if len(r): + body.append('

Comments

\n') + body.append('\n') + elif query.startswith('/&channel='): + search = '#'+query.split('/&channel=')[1] + c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE channel=? ORDER BY id DESC""",(search,)) + r = c.fetchall() if len(r): - for ban in r: + bans = r + for ban in bans: + (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = ban + ar.append([int(id),channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by]) + elif query.startswith('/&removed_by='): + search = query.split('/&removed_by=')[1] + c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE removed_by=? ORDER BY id DESC""",(search,)) + r = c.fetchall() + if len(r): + bans = r + for ban in bans: + (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = ban + ar.append([int(id),channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by]) + elif query.startswith('/&oper='): + search = query.split('/&oper=')[1] + c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE oper=? ORDER BY id DESC""",(search,)) + r = c.fetchall() + if len(r): + bans = r + for ban in bans: + (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = ban + ar.append([int(id),channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by]) + elif query.startswith('/&mask='): + search = query.split('/&mask=')[1] + glob = '*%s*' % search + like = '%'+search+'%' + c.execute("""SELECT ban_id, full FROM nicks WHERE full GLOB ? OR full LIKE ? OR log GLOB ? OR log LIKE ? ORDER BY ban_id DESC""",(glob,like,glob,like)) + L = [] + a = {} + r = c.fetchall() + if len(r): + bans = r + d = {} + for ban in bans: (id,full) = ban - d[id] = id + if not id in d: + d[id] = id for id in d: - if id not in a: - c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE id=?""",(id,)) - r = c.fetchall() - if len(r): - for ban in r: - a[ban[0]] = ban + c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE id=? ORDER BY id DESC""",(int(id),)) + r = c.fetchall() + if len(r): + bans = r + for ban in bans: + (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = ban + a[str(id)] = ban + c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE mask GLOB ? OR mask LIKE ? ORDER BY id DESC""",(glob,like)) + r = c.fetchall() + if len(r): + bans = r + for ban in bans: + (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = ban + a[str(id)] = ban if len(a): ar = [] - for ban in list(a.keys()): - ar.append(a[ban]) - ar.sort(key=lambda x: x[0], reverse=True) - if len(ar): - print('Found %s results' % len(ar)) - body.extend([ - '

Results %s

' % search, - '
', - '', - '' - ]) - for ban in ar: - (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = ban - if not channels or channel in channels: - s = time.strftime('%Y-%m-%d %H:%M:%S GMT',time.gmtime(float(begin_at))) - body.extend([ - '', - '' % (h,q,id,id), - '' % (h,q,channel.split('#')[1],channel), - '' % (h,q,utils.web.urlencode({'oper':oper}),oper), - '' % kind, - '' % (h,q,utils.web.urlencode({'mask':mask}),mask), - '' % s - ]) - if end_at and end_at != begin_at: - s = time.strftime('%Y-%m-%d %H:%M:%S GMT',time.gmtime(float(end_at))) - body.append('' % s) - else: - body.append('') - if removed_at: - s = time.strftime('%Y-%m-%d %H:%M:%S GMT',time.gmtime(float(removed_at))) - body.append('' % s) - else: - body.append('') - if removed_by: - body.append('' % (h,q,utils.web.urlencode({'removed_by':removed_by}),removed_by)) - else: - body.append('') -# affected = '' -# try: -# c.execute("""SELECT full, log FROM nicks WHERE ban_id=?""",(id,)) -# affected = len(c.fetchall()) -# except: + for ban in a: + (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = a[ban] + ar.append([int(id),channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by]) + def sort_function (item): + return item[0] + ar.sort(key=sort_function) + ar.sort(reverse=True) + elif query.startswith('/&search='): + search = query.split('/&search=')[1] + search = search.replace('+','*') + print(search) + if search: + s = '*%s*' % search + qu = '%'+search+'%' + c.execute("""SELECT ban_id, full FROM nicks WHERE full GLOB ? OR full LIKE ? OR log GLOB ? OR log LIKE ? ORDER BY ban_id DESC""",(s,qu,s,qu)) + L = [] + a = {} + r = c.fetchall() + if len(r): + bans = r + d = {} + for ban in bans: + (id,full) = ban + if not id in d: + d[id] = id + for id in d: + c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE id=? ORDER BY id DESC""",(int(id),)) + r = c.fetchall() + if len(r): + bans = r + for ban in bans: + (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = ban + a[id] = ban + c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE mask GLOB ? OR mask LIKE ? OR channel GLOB ? OR channel LIKE ? OR oper GLOB ? OR oper LIKE ? ORDER BY id DESC""",(s,qu,s,qu,s,qu)) + r = c.fetchall() + if len(r): + bans = r + for ban in bans: + (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = ban + a[id] = ban + c.execute("""SELECT ban_id, comment FROM comments WHERE comment GLOB ? OR comment LIKE ? ORDER BY ban_id DESC""",(s,qu)) + r = c.fetchall() + d = {} + if len(r): + bans = r + for ban in bans: + (id,full) = ban + d[id] = id + for id in d: + if not id in a: + c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE id=? ORDER BY id DESC LIMIT 1""",(int(id),)) + r = c.fetchall() + if len(r): + bans = r + for ban in bans: + (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = ban + a[id] = ban + if len(a): + ar = [] + for ban in a: + (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = a[ban] + ar.append([int(id),channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by]) + def sort_function (item): + return item[0] + ar.sort(key=sort_function) + ar.sort(reverse=True) + else: + body.append('

nothing found

\n') + if len(ar): + print('found %s results' % len(ar)) + i = 0 + body.append('

results %s

' % search) + body.append('
IDChannelOperatorTypeMaskBegin dateEnd dateRemovedRemoved by
%d%s%s+%s%s%s%s%s%s
\n') + body.append('\n') + body.append('\n') + while i < len(ar): + (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = ar[i] + if not len(channels) or channel in channels: + body.append('\n') + body.append('\n' % (h,q,id,id)) + body.append('\n' % (h,q,channel.split('#')[1],channel)) + body.append('\n' % (h,q,urllib.parse.urlencode({'oper':oper}),oper)) + body.append('\n' % kind) + body.append('\n' % (h,q,urllib.parse.urlencode({'mask':mask}),mask)) + s = time.strftime('%Y-%m-%d %H:%M:%S GMT',time.gmtime(float(begin_at))) + body.append('\n' % s) + if end_at and end_at != begin_at: + s = time.strftime('%Y-%m-%d %H:%M:%S GMT',time.gmtime(float(end_at))) + body.append( '\n' % s) + else: + body.append( '') + if removed_at: + s = time.strftime('%Y-%m-%d %H:%M:%S GMT',time.gmtime(float(removed_at))) + body.append( '' % s) + else: + body.append( '\n' ) + if removed_by: + body.append( '\n' % (h,q,urllib.parse.urlencode({'removed_by':removed_by}),removed_by)) + else: + body.append( '\n') # affected = '' -# body.append('' % affected) - body.append('') - body.extend(['', '
IDChannelOperatorKindTargetBegin dateEnd dateRemoved dateRemoved by
%s%s%s+%s%s%s%s%s%s%s
']) - else: - body.append('

Nothing found

') +# try: +# c.execute("""SELECT full, log FROM nicks WHERE ban_id=?""",(id,)) +# affected = len(c.fetchall()) +# except: +# affected = '' +# body.append( '%s\n' % affected) + body.append( '\n') + i = i+1 + body.append('\n') + body.append('
\n') + body.append("") + self.send_response(200) + self.send_header("Content-type","text/html") + full = ''.join(body) + print('html lines %s' % len(full)) + self.send_header("Content-length",len(full)) + self.end_headers() + self.wfile.write(full.encode('UTF-8')) c.close() - write(subtitle, body) - def _getbandb(self): + def _getbandb (self): if os.path.exists(filename): db = sqlite3.connect(filename,timeout=10) + db.text_factory = str return db db = sqlite3.connect(filename) + db.text_factory = str c = db.cursor() c.execute("""CREATE TABLE bans ( id INTEGER PRIMARY KEY, @@ -367,23 +387,24 @@ class MyHandler(http.server.BaseHTTPRequestHandler): removed_by VARCHAR(1000) )""") c.execute("""CREATE TABLE nicks ( - ban_id INTEGER, + ban_id INTEGER, ban VARCHAR(1000) NOT NULL, full VARCHAR(1000) NOT NULL, - log TEXT NOT NULL + log TEXT NOT NULL )""") c.execute("""CREATE TABLE comments ( ban_id INTEGER, - oper VARCHAR(1000) NOT NULL, + oper VARCHAR(1000) NOT NULL, at TIMESTAMP NOT NULL, comment TEXT NOT NULL )""") db.commit() return db -def httpd(handler_class=MyHandler, server_address=('', port)): +def httpd(handler_class=MyHandler, server_address = ('', port), ): srvr = http.server.HTTPServer(server_address, handler_class) srvr.serve_forever() if __name__ == "__main__": - httpd() + httpd( ) +