2021-05-16 17:50:22 +02:00
|
|
|
import atexit
|
2023-03-09 19:59:25 +01:00
|
|
|
import random
|
|
|
|
import string
|
2021-05-16 17:50:22 +02:00
|
|
|
|
|
|
|
from apscheduler.schedulers.background import BackgroundScheduler
|
|
|
|
|
2023-03-09 19:59:25 +01:00
|
|
|
def generate_secret():
|
|
|
|
return ''.join(random.choices(string.ascii_uppercase + string.digits, k=7))
|
|
|
|
|
2021-05-16 17:50:22 +02:00
|
|
|
banned = {}
|
|
|
|
active = False
|
|
|
|
threshold = -1
|
2023-03-09 19:59:25 +01:00
|
|
|
secrets = [generate_secret(), generate_secret()]
|
2021-05-18 05:41:02 +02:00
|
|
|
|
2021-11-24 18:41:12 +01:00
|
|
|
def forgive_banned():
|
2021-05-16 17:50:22 +02:00
|
|
|
global banned
|
2021-11-24 18:49:07 +01:00
|
|
|
global threshold
|
2021-05-16 17:50:22 +02:00
|
|
|
|
2021-11-24 18:41:12 +01:00
|
|
|
clear_list = []
|
|
|
|
|
|
|
|
for ip in banned:
|
|
|
|
if banned[ip] <= 0:
|
|
|
|
clear_list.append(ip)
|
|
|
|
else:
|
2021-11-24 18:49:07 +01:00
|
|
|
banned[ip] = min(threshold, banned[ip]) - 1
|
2021-11-24 18:41:12 +01:00
|
|
|
|
|
|
|
for ip in clear_list:
|
|
|
|
del banned[ip]
|
2021-05-18 05:41:02 +02:00
|
|
|
|
2023-03-09 19:59:25 +01:00
|
|
|
def rotate_secrets():
|
|
|
|
global secrets
|
|
|
|
secrets[0] = secrets[1]
|
|
|
|
secrets[1] = generate_secret()
|
|
|
|
|
|
|
|
def secret_match(s):
|
|
|
|
return s in secrets
|
|
|
|
|
|
|
|
def get_current_secret():
|
|
|
|
return secrets[1]
|
2022-02-20 09:09:02 +01:00
|
|
|
|
2021-05-18 05:41:02 +02:00
|
|
|
def setup(violations_threshold=100):
|
2021-05-16 17:50:22 +02:00
|
|
|
global active
|
|
|
|
global threshold
|
|
|
|
|
|
|
|
active = True
|
|
|
|
threshold = violations_threshold
|
|
|
|
|
|
|
|
scheduler = BackgroundScheduler()
|
2022-07-15 19:03:13 +02:00
|
|
|
scheduler.add_job(func=forgive_banned, trigger="interval", minutes=30)
|
2023-03-09 19:59:25 +01:00
|
|
|
scheduler.add_job(func=rotate_secrets, trigger="interval", minutes=30)
|
|
|
|
|
2021-05-16 17:50:22 +02:00
|
|
|
scheduler.start()
|
|
|
|
|
|
|
|
# Shut down the scheduler when exiting the app
|
|
|
|
atexit.register(lambda: scheduler.shutdown())
|
|
|
|
|
|
|
|
|
|
|
|
def report(request_ip):
|
2021-05-16 17:52:39 +02:00
|
|
|
if active:
|
|
|
|
banned[request_ip] = banned.get(request_ip, 0)
|
|
|
|
banned[request_ip] += 1
|
2021-11-05 14:55:45 +01:00
|
|
|
|
|
|
|
|
|
|
|
def decrease(request_ip):
|
|
|
|
if banned[request_ip] > 0:
|
|
|
|
banned[request_ip] -= 1
|
|
|
|
|
|
|
|
|
|
|
|
def has_violation(request_ip):
|
|
|
|
return request_ip in banned and banned[request_ip] > 0
|
2021-05-16 17:50:22 +02:00
|
|
|
|
2021-05-18 05:41:02 +02:00
|
|
|
|
2021-05-16 17:50:22 +02:00
|
|
|
def is_banned(request_ip):
|
|
|
|
# More than X offences?
|
2021-05-16 17:59:39 +02:00
|
|
|
return active and banned.get(request_ip, 0) >= threshold
|