# Copyright © 2022 Aravinth Manivannan # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . from datetime import datetime, timezone from django.utils.crypto import get_random_string from django.core.mail import send_mail from django.shortcuts import redirect from django.urls import reverse from django.utils.http import urlencode from django.conf import settings def gen_secret() -> str: """ Generate random secret """ return get_random_string(32) def send_verification_email(request, challenge): verification_link = ( f"{request.scheme}://{request.get_host()}{challenge.verification_link()}" ) email = challenge.owned_by.email send_mail( subject="[Hostea] Please confirm your email address", message=f"Please confirm your email address {email}.\n {verification_link}", from_email="No reply Hostea", # TODO read from settings.py recipient_list=[email], ) EPOCH = datetime.utcfromtimestamp(0).astimezone(tz=timezone.utc) def since_epoch(date: datetime = None) -> int: """Get current time since Unix epoch in seconds""" if not date: date = datetime.now(timezone.utc) date.astimezone(tz=timezone.utc) return int((date - EPOCH).total_seconds()) class ConfirmAccess: key = "confirm_access" @staticmethod def redirect_to_sudo(request): ctx = {"next": request.path} return redirect(f"{reverse('accounts.sudo')}?{urlencode(ctx)}") @classmethod def is_valid(cls, request): if cls.key in request.session: if (since_epoch() - request.session[cls.key]) < settings.HOSTEA["ACCOUNTS"][ "SUDO_TTL" ]: return True return False @classmethod def validate_decorator(cls, request, fn, *args, **kwargs): if cls.is_valid(request): return fn(request, *args, **kwargs) else: return cls.redirect_to_sudo(request) @classmethod def set(cls, request): request.session[cls.key] = since_epoch()