Update lexicon route decorators
This commit is contained in:
parent
0481b78122
commit
d0b53af8df
|
@ -64,3 +64,8 @@ def create(
|
||||||
db.session.add(new_membership)
|
db.session.add(new_membership)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return new_membership
|
return new_membership
|
||||||
|
|
||||||
|
|
||||||
|
def try_from_ids(db: DbContext, user_id: int, lexicon_id: int) -> Membership:
|
||||||
|
"""Get a membership by the user and lexicon ids, or None if no such membership was found."""
|
||||||
|
return db(select(Membership).where(Membership.user_id == user_id).where(Membership.lexicon_id == lexicon_id)).scalar_one_or_none()
|
||||||
|
|
|
@ -1,62 +1,38 @@
|
||||||
# Standard library imports
|
|
||||||
from datetime import datetime
|
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
# Third party imports
|
from flask import g, flash, redirect, url_for
|
||||||
from flask import g, flash, redirect, url_for, current_app
|
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
|
||||||
# Module imports
|
from amanuensis.backend import lexiq, memq
|
||||||
from amanuensis.parser import filesafe_title
|
from amanuensis.db import DbContext, Lexicon, User, Membership
|
||||||
from amanuensis.models import ModelFactory, UserModel, LexiconModel
|
|
||||||
|
|
||||||
|
|
||||||
def register_custom_filters(app):
|
|
||||||
"""Adds custom filters to the Flask app"""
|
|
||||||
|
|
||||||
@app.template_filter("user_attr")
|
|
||||||
def get_user_attr(uid, attr):
|
|
||||||
factory: ModelFactory = current_app.config['model_factory']
|
|
||||||
user: UserModel = factory.user(uid)
|
|
||||||
val = getattr(user.cfg, attr)
|
|
||||||
return val
|
|
||||||
|
|
||||||
@app.template_filter("articlelink")
|
|
||||||
def article_link(title):
|
|
||||||
return url_for(
|
|
||||||
'lexicon.article',
|
|
||||||
name=g.lexicon.cfg.name,
|
|
||||||
title=filesafe_title(title))
|
|
||||||
|
|
||||||
@app.context_processor
|
|
||||||
def lexicon_status():
|
|
||||||
return dict(
|
|
||||||
PREGAME=LexiconModel.PREGAME,
|
|
||||||
ONGOING=LexiconModel.ONGOING,
|
|
||||||
COMPLETE=LexiconModel.COMPLETE)
|
|
||||||
|
|
||||||
|
|
||||||
def lexicon_param(route):
|
def lexicon_param(route):
|
||||||
"""Wrapper for loading a route's lexicon"""
|
"""
|
||||||
|
Wrapper for loading a route's lexicon to `g`.
|
||||||
|
This decorator should be applied above any other decorators that reference `g.lexicon`.
|
||||||
|
"""
|
||||||
@wraps(route)
|
@wraps(route)
|
||||||
def with_lexicon(**kwargs):
|
def with_lexicon(*args, **kwargs):
|
||||||
name = kwargs.get('name')
|
name: str = kwargs.get('name')
|
||||||
model_factory: ModelFactory = current_app.config['model_factory']
|
lexicon: Optional[Lexicon] = lexiq.try_from_name(name)
|
||||||
g.lexicon = model_factory.lexicon(name)
|
if lexicon is None:
|
||||||
if g.lexicon is None:
|
flash(f"Couldn't find a lexicon with the name \"{name}\"")
|
||||||
flash(f'Couldn\'t find a lexicon with the name "{name}"')
|
|
||||||
return redirect(url_for("home.home"))
|
return redirect(url_for("home.home"))
|
||||||
return route(**kwargs)
|
g.lexicon = lexicon
|
||||||
|
return route(*args, **kwargs)
|
||||||
return with_lexicon
|
return with_lexicon
|
||||||
|
|
||||||
|
|
||||||
def admin_required(route):
|
def admin_required(route):
|
||||||
"""
|
"""
|
||||||
Requires the user to be an admin to load this page
|
Restricts a route to users who are site admins.
|
||||||
"""
|
"""
|
||||||
@wraps(route)
|
@wraps(route)
|
||||||
def admin_route(*args, **kwargs):
|
def admin_route(*args, **kwargs):
|
||||||
if not current_user.cfg.is_admin:
|
user: User = current_user
|
||||||
|
if not user.is_site_admin:
|
||||||
flash("You must be an admin to view this page")
|
flash("You must be an admin to view this page")
|
||||||
return redirect(url_for('home.home'))
|
return redirect(url_for('home.home'))
|
||||||
return route(*args, **kwargs)
|
return route(*args, **kwargs)
|
||||||
|
@ -65,28 +41,36 @@ def admin_required(route):
|
||||||
|
|
||||||
def player_required(route):
|
def player_required(route):
|
||||||
"""
|
"""
|
||||||
Requires the user to be a player in the lexicon to load this page
|
Restricts a route to users who are players in the current lexicon.
|
||||||
"""
|
"""
|
||||||
@wraps(route)
|
@wraps(route)
|
||||||
def player_route(*args, **kwargs):
|
def player_route(*args, **kwargs):
|
||||||
if current_user.uid not in g.lexicon.cfg.join.joined:
|
db: DbContext = g.db
|
||||||
|
user: User = current_user
|
||||||
|
lexicon: Lexicon = g.lexicon
|
||||||
|
mem: Optional[Membership] = memq.try_from_ids(db, user.id, lexicon.id)
|
||||||
|
if not mem:
|
||||||
flash("You must be a player to view this page")
|
flash("You must be a player to view this page")
|
||||||
return (redirect(url_for('lexicon.contents', name=g.lexicon.cfg.name))
|
if lexicon.public:
|
||||||
if g.lexicon.cfg.join.public
|
return redirect(url_for('lexicon.contents', name=lexicon.name))
|
||||||
else redirect(url_for('home.home')))
|
else:
|
||||||
|
return redirect(url_for('home.home'))
|
||||||
return route(*args, **kwargs)
|
return route(*args, **kwargs)
|
||||||
return player_route
|
return player_route
|
||||||
|
|
||||||
|
|
||||||
def player_required_if_not_public(route):
|
def player_required_if_not_public(route):
|
||||||
"""
|
"""
|
||||||
Requires the user to be a player in the lexicon to load this page if the
|
Restricts a route to users who are players in the current lexicon if the lexicon is nonpublic.
|
||||||
lexicon has join.public = false
|
|
||||||
"""
|
"""
|
||||||
@wraps(route)
|
@wraps(route)
|
||||||
def player_route(*args, **kwargs):
|
def player_route(*args, **kwargs):
|
||||||
if ((not g.lexicon.cfg.join.public)
|
db: DbContext = g.db
|
||||||
and current_user.uid not in g.lexicon.cfg.join.joined):
|
user: User = current_user
|
||||||
|
lexicon: Lexicon = g.lexicon
|
||||||
|
if not lexicon.public:
|
||||||
|
mem: Optional[Membership] = memq.try_from_ids(db, user.id, lexicon.id)
|
||||||
|
if not mem:
|
||||||
flash("You must be a player to view this page")
|
flash("You must be a player to view this page")
|
||||||
return redirect(url_for('home.home'))
|
return redirect(url_for('home.home'))
|
||||||
return route(*args, **kwargs)
|
return route(*args, **kwargs)
|
||||||
|
@ -95,13 +79,16 @@ def player_required_if_not_public(route):
|
||||||
|
|
||||||
def editor_required(route):
|
def editor_required(route):
|
||||||
"""
|
"""
|
||||||
Requires the user to be the editor of the current lexicon to load this
|
Restricts a route to users who are editors of the current lexicon.
|
||||||
page
|
|
||||||
"""
|
"""
|
||||||
@wraps(route)
|
@wraps(route)
|
||||||
def editor_route(*args, **kwargs):
|
def editor_route(*args, **kwargs):
|
||||||
if current_user.uid != g.lexicon.cfg.editor:
|
db: DbContext = g.db
|
||||||
|
user: User = current_user
|
||||||
|
lexicon: Lexicon = g.lexicon
|
||||||
|
mem: Optional[Membership] = memq.try_from_ids(db, user.id, lexicon.id)
|
||||||
|
if not mem.is_editor:
|
||||||
flash("You must be the editor to view this page")
|
flash("You must be the editor to view this page")
|
||||||
return redirect(url_for('lexicon.contents', name=g.lexicon.cfg.name))
|
return redirect(url_for('lexicon.contents', name=lexicon.name))
|
||||||
return route(*args, **kwargs)
|
return route(*args, **kwargs)
|
||||||
return editor_route
|
return editor_route
|
||||||
|
|
Loading…
Reference in New Issue