add ratelimit class in models
This commit is contained in:
1 file changed
+112
-1
+112
-1
@@ -1,6 +1,8 @@
|
||||
import ldap3
|
||||
from ldap3 import Server,Connection,ALL,MODIFY_REPLACE
|
||||
from datetime import datetime
|
||||
import datetime as dt
|
||||
import os
|
||||
|
||||
OBJECTCLASSES = ['top', 'person', 'organizationalPerson', 'inetOrgPerson', 'posixAccount', 'shadowAccount']
|
||||
USERATTRIBUTES = ['cn' , 'sn', 'givenName', 'uid', 'uidNumber' , 'gidNumber', 'homeDirectory', 'loginShell', 'gecos' , 'shadowLastChange', 'shadowMax', 'userPassword', 'mail', 'description']
|
||||
@@ -184,7 +186,7 @@ class LUSER():
|
||||
messured in days from UNIX epoch
|
||||
'''
|
||||
|
||||
return str((datetime.utcnow() - datetime(1970,1,1)).days)
|
||||
return str((datetime.now() - datetime(1970,1,1)).days)
|
||||
|
||||
def add(self, user, password):
|
||||
'''
|
||||
@@ -323,3 +325,112 @@ class LUSER():
|
||||
userpass = userpass.decode('utf-8')
|
||||
|
||||
return userpass
|
||||
|
||||
class ratelimit():
|
||||
'''
|
||||
Class that manages rate limiting
|
||||
|
||||
period := time period in seconds when the limit restarts
|
||||
limit := maxiumum number of actions allowed in the time period
|
||||
path := path to the file where the number of occurances are stored
|
||||
'''
|
||||
|
||||
def save(self):
|
||||
f = open(self.path,'w')
|
||||
f.write(str(self.period) + "\n")
|
||||
f.write(str(self.limit) + "\n")
|
||||
f.write(self.startdate.isoformat() + "\n")
|
||||
f.write(str(self.current) + "\n")
|
||||
f.close()
|
||||
|
||||
def load(self):
|
||||
f = open(self.path,'r')
|
||||
self.period = int(f.readline())
|
||||
self.limit = int(f.readline())
|
||||
self.startdate = datetime.fromisoformat(f.readline()[:-1])
|
||||
self.current = int(f.readline())
|
||||
f.close()
|
||||
|
||||
def parseperiod(self, period: str)->int:
|
||||
last = period[-1]
|
||||
|
||||
if last.isalpha() == False:
|
||||
return int(period)
|
||||
|
||||
number = int(period[:-1])
|
||||
|
||||
if last == 's':
|
||||
return number
|
||||
if last == 'm':
|
||||
return number * 60
|
||||
if last == 'h':
|
||||
return number * 3600
|
||||
if last == 'd':
|
||||
return number * 86400
|
||||
if last == 'w':
|
||||
return number * 604800
|
||||
|
||||
raise ValueError("Write the period in seconds as intiger or with accepted units as suffix: s(seconds), m(minutes), h(hours), d(days), w(weeks)")
|
||||
|
||||
def __init__(self, period : str, limit : int, path : str):
|
||||
self.period = self.parseperiod(period)
|
||||
self.limit = limit
|
||||
self.path = path
|
||||
|
||||
# date from when the period start
|
||||
self.startdate = datetime.now()
|
||||
|
||||
# current number of actions in this time period
|
||||
self.current = 0
|
||||
|
||||
if os.path.exists(path) == True:
|
||||
setperiod = self.period
|
||||
setlimit = self.limit
|
||||
self.load()
|
||||
self.period = setperiod
|
||||
self.limit = setlimit
|
||||
|
||||
# actions might have happened before the new smaller period started
|
||||
if setperiod < self.period:
|
||||
self.current = 0
|
||||
|
||||
self.save()
|
||||
|
||||
self.update()
|
||||
|
||||
def check(self, actions = 1)->bool:
|
||||
self.update()
|
||||
if self.current + actions > self.limit:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def add(self, actions = 1)->int:
|
||||
self.update()
|
||||
if self.check(actions):
|
||||
self.current += actions
|
||||
else:
|
||||
return 0
|
||||
|
||||
self.save()
|
||||
return self.current
|
||||
|
||||
def sub(self, actions = 1)->int:
|
||||
self.update()
|
||||
self.current -= actions
|
||||
if self.current < 0:
|
||||
self.current = 0
|
||||
self.save()
|
||||
return self.current
|
||||
|
||||
def update(self)->bool:
|
||||
r = False
|
||||
self.load()
|
||||
delta = (datetime.now() - self.startdate).seconds
|
||||
if delta > self.period:
|
||||
self.startdate += dt.timedelta(seconds=(delta - delta%self.period))
|
||||
self.current = 0
|
||||
r = True
|
||||
self.save()
|
||||
return r
|
||||
|
||||
Reference in new issue
Block a user