87 lines
2.6 KiB
Python
87 lines
2.6 KiB
Python
import os
|
|
|
|
from flask import Flask, request
|
|
from typing import cast
|
|
from itsdangerous import BadSignature, URLSafeSerializer
|
|
from xkcdpass import xkcd_password
|
|
|
|
from .models import Deck, InfoBanner, Token, db
|
|
|
|
def init_password_generator():
|
|
wordfile = xkcd_password.locate_wordfile()
|
|
global words
|
|
words = xkcd_password.generate_wordlist(wordfile=wordfile, min_length=3, max_length=6)
|
|
|
|
def init_serializer(app: Flask):
|
|
global serializer
|
|
serializer = URLSafeSerializer(app.config['SECRET_KEY'])
|
|
|
|
def get_active_banner() -> InfoBanner | None:
|
|
return db.session.execute(db.select(InfoBanner).where(InfoBanner.is_active)).scalar_one_or_none()
|
|
|
|
def get_available_decks(app: Flask):
|
|
slides_dir = app.config['SLIDES_DIR']
|
|
deck_names = [name for name in os.listdir(slides_dir) if os.path.isdir(os.path.join(slides_dir, name))]
|
|
deck_names.sort()
|
|
return deck_names
|
|
|
|
def generate_username() -> str:
|
|
return cast(str, xkcd_password.generate_xkcdpassword(wordlist=words, numwords=3, delimiter="-"))
|
|
|
|
def generate_password() -> str:
|
|
return cast(str, xkcd_password.generate_xkcdpassword(wordlist=words, numwords=5, delimiter="-"))
|
|
|
|
def generate_token() -> Token:
|
|
max_tries = 100
|
|
for _ in range(max_tries):
|
|
user_name = generate_username()
|
|
|
|
if not db.session.execute(db.select(Token).where(Token.name == user_name)).scalar():
|
|
break
|
|
else:
|
|
raise RuntimeError(f"Unique username could not be generated after {max_tries} tries")
|
|
|
|
token = Token(user_name)
|
|
db.session.add(token)
|
|
db.session.commit()
|
|
return token
|
|
|
|
def serialize_token(token: Token) -> str:
|
|
return serializer.dumps(token.id)
|
|
|
|
def get_token() -> (Token | None):
|
|
token = request.cookies.get('access_token')
|
|
if not token:
|
|
return None
|
|
try:
|
|
id = serializer.loads(token)
|
|
token = db.session.execute(db.select(Token).filter_by(id=id)).scalar_one_or_none()
|
|
return token
|
|
except BadSignature:
|
|
return None
|
|
|
|
def get_unlocked_decks(token: (Token|None)):
|
|
if token is None:
|
|
return []
|
|
decks = token.decks
|
|
decks.sort(key=lambda deck: deck.deck)
|
|
return decks
|
|
|
|
def is_deck_unlocked(deck: str):
|
|
token = get_token()
|
|
if token:
|
|
return token.is_unlocked(deck)
|
|
else:
|
|
return False
|
|
|
|
def update_token(decks: list[Deck]):
|
|
"""
|
|
Adds the deck to the list of decks stored in the access token
|
|
"""
|
|
token = get_token()
|
|
if token is None:
|
|
raise ValueError("Invalid token is set")
|
|
else:
|
|
token.decks = list(set(decks + token.decks))
|
|
db.session.commit()
|