diff --git a/app/auth/routes.py b/app/auth/routes.py index b3c3651a..5391a9e2 100644 --- a/app/auth/routes.py +++ b/app/auth/routes.py @@ -9,7 +9,7 @@ from wtforms import Label from app import db, cache from app.auth import bp from app.auth.forms import LoginForm, RegistrationForm, ResetPasswordRequestForm, ResetPasswordForm -from app.auth.util import random_token, normalize_utf, ip2location +from app.auth.util import random_token, normalize_utf, ip2location, no_admins_logged_in_recently from app.email import send_verification_email, send_password_reset_email from app.models import User, utcnow, IpBan, UserRegistration, Notification, Site from app.utils import render_template, ip_address, user_ip_banned, user_cookie_banned, banned_ip_addresses, \ @@ -91,6 +91,11 @@ def register(): disallowed_usernames = ['admin'] if current_user.is_authenticated: return redirect(url_for('main.index')) + + # Abandoned open instances automatically close registrations after one week + if g.site.registration_mode == 'Open' and no_admins_logged_in_recently(): + g.site.registration_mode = 'Closed' + form = RegistrationForm() # Recaptcha is optional if not current_app.config['RECAPTCHA_PUBLIC_KEY'] or not current_app.config['RECAPTCHA_PRIVATE_KEY']: diff --git a/app/auth/util.py b/app/auth/util.py index 851e7777..9f5c0272 100644 --- a/app/auth/util.py +++ b/app/auth/util.py @@ -1,9 +1,11 @@ import random +from datetime import timedelta from unicodedata import normalize from flask import current_app from app import cache +from app.models import Site, utcnow from app.utils import get_request @@ -41,3 +43,16 @@ def ip2location(ip: str): postal = '' return {'city': data['city'], 'region': data['region'], 'country': data['country'], 'postal': postal, 'timezone': data['timezone']} + + +def no_admins_logged_in_recently(): + a_week_ago = utcnow() - timedelta(days=7) + for user in Site.admins(): + if user.last_seen > a_week_ago: + return False + + for user in Site.staff(): + if user.last_seen > a_week_ago: + return False + + return True