from functools import wraps import json from pathlib import Path from random import randbytes from sys import stderr from flask import (Flask, redirect, url_for, request, send_file, make_response, abort, render_template, session, g) from roc_fnb.util.env_file import env_file from roc_fnb.website.database import Database from roc_fnb.website.models.user import JwtUser db = Database.from_env() app = Flask( import_name=__name__.split('.')[0], static_url_path='/', template_folder=Path(__file__).absolute().parent / 'templates', static_folder=Path(__file__).absolute().parent / 'static', ) app.secret_key = env_file('FLASK_SECRET', default_file='./flask.secret', default_fn=lambda: randbytes(12)) @app.before_request def decode_user(): if user := session.get('user'): g.user = JwtUser.from_json(data=json.loads(user)) def require_user(admin = False, moderator = False): """ A decorator for any routes which require authentication. https://stackoverflow.com/a/51820573 """ def _require_user(handler): @wraps(handler) def __require_user(): if getattr(g, 'user', None) is None \ or (admin and not user.admin) \ or (moderator and not user.moderator): abort(401) return handler() return __require_user return _require_user @app.route('/ig') def ig_redir(): return redirect('https://instagram.com/RocFNB') @app.route('/donate') def donate_redir(): return redirect('https://venmo.com/RocFoodNotBombs') @app.route('/') def index(): return redirect('/index.html') @app.post('/login') def submit_login(): form = request.json user = db.get_user_by_name(form['name']) if not user.check_password(form['password']): abort(401) # unauthorized session['user'] = json.dumps(user.public_fields) return redirect('/me') @app.get('/login') def render_login_page(): if getattr(g, 'user', None): return redirect('/me') return render_template('login.html') @app.get('/me') @require_user() def get_profile(): return render_template('profile.html', user=g.user)