from datetime import datetime, timedelta import secrets from sqlalchemy.orm import DeclarativeBase from sqlalchemy.sql import func from typing import Self from flask import url_for from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() class Base(DeclarativeBase): pass class MagicToken(db.Model): id = db.Column(db.Integer, primary_key=True, autoincrement=True) token = db.Column(db.String(length=255, collation="utf8mb4_bin"), nullable=False) email = db.Column(db.String(length=255), nullable=False) expiration_date = db.Column(db.DateTime, nullable=False, server_default=func.now()) used = db.Column(db.Boolean, nullable=False, default=False) user_dn = db.Column(db.String(length=255), nullable=False) def __init__(self, token, email, expiration_date, user_dn): self.token = token self.email = email self.expiration_date = expiration_date self.user_dn = user_dn def url(self) -> str: return "https://mdp.iut-fbleau.fr" + url_for('mdp.password_reset_form', token=self.token) @staticmethod def generate(emails: list[str], user_dn: str) -> Self: token = secrets.token_urlsafe(128) expiration_date = datetime.now() + timedelta(minutes=15) return MagicToken(token, ",".join(emails), expiration_date, user_dn) def __repr__(self): return f"<MagicToken {self.id} {self.email} {self.expiration_date} {self.used} {self.user_dn}>"