diff --git a/.gitignore b/.gitignore index 0a93a67..a8e852f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ build/ **/*.egg-info **/__pycache__ mounts/ -**/*.pem \ No newline at end of file +**/*.pem +**/*.secret diff --git a/pyproject.toml b/pyproject.toml index 080e34f..46f89b2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,6 +29,7 @@ packages = ["roc_fnb"] [project.scripts] # Put scripts here +bootstrap-first-admin = "roc_fnb.scripts.bootstrap_first_admin:bootstrap_first_admin" [tool.yapf] -based_on_style = "facebook" \ No newline at end of file +based_on_style = "facebook" diff --git a/roc_fnb/scripts/__init__.py b/roc_fnb/scripts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/roc_fnb/scripts/bootstrap_first_admin.py b/roc_fnb/scripts/bootstrap_first_admin.py new file mode 100644 index 0000000..8aef1ea --- /dev/null +++ b/roc_fnb/scripts/bootstrap_first_admin.py @@ -0,0 +1,24 @@ +from click import command, option, prompt, confirm +from roc_fnb.website.database import Database +from roc_fnb.website.models.user import User + + +@command +@option('--name', '-n', type=str, required=True) +@option('--email', '-e', type=str, required=True) +def bootstrap_first_admin(name: str, email: str): + password = prompt('Enter the account password', + hide_input=True, prompt_suffix=': ') + confirmation = prompt('Confirm the account password', + hide_input=True, prompt_suffix=': ') + if password != confirmation: + raise ValueError('passwords did not match') + admin = User.create(email, name, password, moderator=True, admin=True) + db = Database.from_env() + db.store_user(admin) + if confirm('Display an auth token for testing?', default=False): + print(admin.jwt) + + +if __name__ == '__main__': + bootstrap_first_admin() diff --git a/roc_fnb/website/server.py b/roc_fnb/website/server.py index 083e0fc..e6facd1 100644 --- a/roc_fnb/website/server.py +++ b/roc_fnb/website/server.py @@ -1,19 +1,59 @@ -from flask import Flask, redirect, url_for, request, send_file +from pathlib import Path +from sys import stderr + +from flask import (Flask, redirect, url_for, request, send_file, make_response, + abort, render_template, g) + +from roc_fnb.website.database import Database +from roc_fnb.website.models.user import User + +db = Database.from_env() app = Flask( import_name=__name__.split('.')[0], - static_url_path='/' + static_url_path='/', + template_folder=Path(__file__).absolute().parent / 'templates', + static_folder=Path(__file__).absolute().parent / 'static', ) + +@app.before_request +def decode_user(): + if token := request.cookies.get('auth-token'): + g.user = User.verify_jwt(token) + + @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 + response = make_response(redirect('/me')) + response.set_cookie('auth-token', user.jwt) + return response + +@app.get('/login') +def render_login_page(): + return render_template('login.html') + +@app.get('/me') +def get_profile(): + if g.user is not None: + return render_template('profile.html', user=g.user) + abort(401) diff --git a/roc_fnb/website/templates/base.html b/roc_fnb/website/templates/base.html new file mode 100644 index 0000000..682d919 --- /dev/null +++ b/roc_fnb/website/templates/base.html @@ -0,0 +1,27 @@ + + + + + + Rochester Food Not Bombs + + + + + + + + + {% block content %} + {% endblock %} + + + \ No newline at end of file diff --git a/roc_fnb/website/templates/login.html b/roc_fnb/website/templates/login.html new file mode 100644 index 0000000..3d32889 --- /dev/null +++ b/roc_fnb/website/templates/login.html @@ -0,0 +1,60 @@ +{% extends "base.html" %} {% block content %} + + + + +

Rochester Food Not Bombs!

+ +

Login:

+ +
+ + +
+
+ + +
+
+ +
+ +{% endblock %} diff --git a/roc_fnb/website/templates/profile.html b/roc_fnb/website/templates/profile.html new file mode 100644 index 0000000..5f1ae5a --- /dev/null +++ b/roc_fnb/website/templates/profile.html @@ -0,0 +1,7 @@ +{% extends "base.html" %} +{% block content %} + +

Rochester Food Not Bombs!

+ +

This will be the profile/settings page for {{user.name}}

+{% endblock %} \ No newline at end of file