add ratelimit class in models

This commit is contained in:
fram3d committed 2026-10-24 03:48:05 +02:00
1 parent dc50e422ba
commit 2e8b3d0b4d
1 file changed
+112 -1
+112 -1
View File
@@ -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