diff --git a/DV8-Expo/requirements.txt b/DV8-Expo/requirements.txt index 35a3568..c9f6a71 100644 --- a/DV8-Expo/requirements.txt +++ b/DV8-Expo/requirements.txt @@ -3,6 +3,7 @@ Flask Flask-SQLAlchemy Flask-Migrate Flask-Login +WTForms Flask-WTF Flask-Assets Flask-Caching diff --git a/DV8-Expo/run.sh b/DV8-Expo/run.sh index 6bbddba..ff16c1e 100644 --- a/DV8-Expo/run.sh +++ b/DV8-Expo/run.sh @@ -8,7 +8,7 @@ then fi # Check if there are any changes to the database -if ! $(flask --app website db check | grep -q "No changes in schema detected."); +if ! $(flask --app website db check) | grep -q "No changes in schema detected."; then echo "Database changes detected! Migrating..." flask --app website db migrate diff --git a/DV8-Expo/website/__init__.py b/DV8-Expo/website/__init__.py index cf5f325..c62deee 100644 --- a/DV8-Expo/website/__init__.py +++ b/DV8-Expo/website/__init__.py @@ -1,30 +1,21 @@ -from flask import Flask, render_template, request, redirect, flash -from flask_login import login_required, login_user, logout_user, current_user +from flask import Flask from flask_assets import Bundle -from flask_wtf import FlaskForm -from wtforms import StringField -from wtforms.validators import DataRequired from website.models import Users from website.extensions import db, migrate, login_manager, assets from website.config import INSTANCE_DIR, MIGRATION_DIR +from website import routes -class LoginForm(FlaskForm): - uuid = StringField( - "uuid", - validators=[DataRequired()], - render_kw={"placeholder": "12345678-ABCD-ABCD-ABCD-123456789EFG"}, - ) - - -app = Flask(__name__, instance_path=INSTANCE_DIR) +app = Flask(__name__) # instance_path=INSTANCE_DIR app.config.from_pyfile("config.py") db.init_app(app) -migrate.init_app(app, db, directory=MIGRATION_DIR) +migrate.init_app(app, db) # directory=MIGRATION_DIR with app.app_context(): db.create_all() +login_manager.init_app(app) + assets.init_app(app) styles = Bundle( "sass/styles.sass", @@ -36,26 +27,9 @@ assets.register("styles", styles) scripts = Bundle("js/*.js", filters="jsmin", output="gen/packed.js") assets.register("scripts", scripts) +app.register_blueprint(routes.blueprint) + @login_manager.user_loader def load_user(user_id): - return Users.get(user_id) - - -@app.route("/") -def index(): - return render_template("index.html") - - -@app.route("/login", methods=["GET", "POST"]) -def login(): - form = LoginForm() - - if form.validate_on_submit(): - if user := Users.query.filter_by(uuid=str(form.uuid)).first(): - login_user(user, remember=True) - return redirect(index) - else: - flash("Inncorrect login") - - return render_template("login.html", form=form) + return Users.query.filter_by(id=user_id).first() diff --git a/DV8-Expo/website/config.py b/DV8-Expo/website/config.py index 3e0f2d8..6ed6d01 100644 --- a/DV8-Expo/website/config.py +++ b/DV8-Expo/website/config.py @@ -6,7 +6,8 @@ def env(key): return os.getenv(key) -SECRET_KEY = env("FLASK_KEY") +# SECRET_KEY = env("FLASK_KEY") +SECRET_KEY = "dev" SQLALCHEMY_DATABASE_URI = "sqlite:///site.db" diff --git a/DV8-Expo/website/models.py b/DV8-Expo/website/models.py index 43a06dd..d2bb9f2 100644 --- a/DV8-Expo/website/models.py +++ b/DV8-Expo/website/models.py @@ -38,3 +38,6 @@ class Authors(db.Model): class Users(db.Model, UserMixin): id = db.Column(db.Integer, primary_key=True) uuid = db.Column(db.String, nullable=False) + + def get_id(self): + return int(self.id) diff --git a/DV8-Expo/website/routes.py b/DV8-Expo/website/routes.py new file mode 100644 index 0000000..c09c745 --- /dev/null +++ b/DV8-Expo/website/routes.py @@ -0,0 +1,42 @@ +from flask import Blueprint, render_template, redirect, flash +from flask_login import login_user, logout_user, login_required +from flask_wtf import FlaskForm +from wtforms import StringField +from wtforms.validators import DataRequired +from website.models import Users + + +blueprint = Blueprint("website", __name__) + + +class LoginForm(FlaskForm): + uuid = StringField( + "uuid", + validators=[DataRequired()], + render_kw={"placeholder": "12345678-ABCD-ABCD-ABCD-123456789EFG"}, + ) + + +@blueprint.route("/") +def index(): + return render_template("index.html") + + +@blueprint.route("/login", methods=["GET", "POST"]) +def login(): + form = LoginForm() + + if form.validate_on_submit(): + if user := Users.query.filter_by(uuid=str(form.uuid.data)).first(): + login_user(user, remember=True) + return redirect("/") + else: + flash("Incorrect login") + + return render_template("login.html", form=form) + +@blueprint.route("/logout") +@login_required +def logout(): + logout_user() + return redirect("/") diff --git a/DV8-Expo/website/static/gen/packed.css b/DV8-Expo/website/static/gen/packed.css index 82f8307..2ac2c87 100644 --- a/DV8-Expo/website/static/gen/packed.css +++ b/DV8-Expo/website/static/gen/packed.css @@ -1 +1 @@ -:root{--primary:#332f2f;--secondary:#d7cec9;--primary-button:#C0AB83;--secondary-button:#DDD1C1;--accent:#c2a588;--radius:1rem;--main-font:'Rubik',sans-serif;--monospace-font:'JetBrains Mono',monospace;--nav:#262323}@keyframes glow{0%{opacity:0}50%{opacity:1}100%{opacity:0}}nav{padding:0 .5rem;width:100%;height:3rem;display:flex;flex-direction:row;align-items:center;position:fixed;top:0;left:0;background:transparent;color:var(--primary);z-index:100;transition:color .2s ease-in-out}nav::before{content:"";position:absolute;top:-100%;left:0;width:100%;height:100%;background:var(--nav);transition:top .2s ease-in-out;z-index:-1}nav>span{width:100%}nav>a{margin:0 .75rem;font-size:1.1rem;font-weight:bold;font-family:var(--main-font);text-decoration:none;color:inherit;transition:color .2s ease-in-out,font-weight .2s}nav>a:hover{color:var(--accent)}nav.scrolled{color:var(--secondary)}nav.scrolled>a{font-weight:normal}nav.scrolled::before{top:0}header{margin-bottom:3rem;padding:2rem;height:calc(100vh - 6rem);display:flex;flex-direction:column;justify-content:center;align-items:center;text-align:center;font-family:var(--main-font);color:var(--primary)}header>h1{margin:0;font-size:3rem}header>h1>span{font-family:var(--monospace-font);color:var(--accent)}header>p{margin:0;font-size:1.2rem}header>i{margin:1rem 0 0;font-size:1.2rem;animation:glow 3s ease-in-out infinite}section{margin:0 auto 1rem;padding:1rem;max-width:75rem;display:flex;flex-direction:column;justify-content:center;text-align:center}section>h2{margin:0 0 1rem;font-size:2rem;font-weight:bold}section>p{margin:0 0 1rem;font-size:1rem}section.center{height:100%;justify-content:center;align-items:center}div.games{margin:1rem;display:grid;grid-template-columns:repeat(auto-fit,minmax(20rem,1fr));gap:2rem}@media(max-width:24rem){div.games{margin:0;display:flex;flex-direction:column;gap:1rem}}div.login{padding:.5rem;background-color:var(--primary);color:var(--secondary);border-radius:var(--radius)}div.login>p{margin:0 0 .5rem;padding:.5rem;background-color:var(--accent);color:var(--primary);border-radius:calc(calc(var(--radius) - .5rem) / 2)}div.login>p:first-child{border-top-left-radius:calc(var(--radius) - .5rem);border-top-right-radius:calc(var(--radius) - .5rem)}div.login>form{display:flex;flex-direction:row}div.login>form>input{padding:.5rem 1rem;width:100%;font-size:1rem;font-family:var(--monospace-font);background-color:var(--secondary);color:var(--primary);border-radius:calc(calc(var(--radius) - .5rem) / 2) 0 0 calc(var(--radius) - .5rem);border:none;transition:transform .1s ease-in-out,border-radius .1s ease-in-out}div.login>form>input:hover,div.login>form>input:focus-visible{outline:none}div.login>form>button{padding:.5rem 1rem;font-size:1rem;background-color:var(--primary-button);color:var(--primary);border-radius:0 calc(calc(var(--radius) - .5rem) / 2) calc(var(--radius) - .5rem) 0;border:none;transition:transform .1s ease-in-out,border-radius .1s ease-in-out}div.login>form>button:hover,div.login>form>button:focus-visible{outline:none;background-color:var(--secondary-button)}.game-box{margin:0 auto;padding:.5rem;width:100%;height:auto;display:flex;flex-direction:column;font-family:var(--main-font);background-color:var(--primary);color:var(--secondary);border-radius:var(--radius);box-shadow:0 .2rem 1rem 0 var(--primary);overflow:hidden;transition:box-shadow .1s ease-in-out,transform .1s ease-in-out}.game-box>img{margin:0 0 .5rem;width:auto;height:10rem;object-fit:cover;display:block;border-radius:calc(var(--radius) - .5rem) calc(var(--radius) - .5rem) calc(calc(var(--radius) - .5rem) / 2) calc(calc(var(--radius) - .5rem) / 2)}.game-box>h2{margin:0 0 .5rem;font-size:1.5rem;font-weight:bold}.game-box>p{height:100%;margin:0 0 1rem;font-size:1rem}.game-box>.options{display:flex;flex-direction:row;gap:.5rem;font-family:var(--monospace-font)}.game-box>.options>a{margin:0;padding:.5rem 1rem;height:2.5rem;display:flex;justify-content:center;align-items:center;font-size:1rem;text-decoration:none;background-color:var(--primary-button);color:var(--primary);border-radius:calc(calc(var(--radius) - .5rem) / 2);transition:transform .1s ease-in-out,border-radius .1s ease-in-out}.game-box>.options>a>i{font-size:1.2rem}.game-box>.options>a:first-child{border-bottom-left-radius:calc(var(--radius) - .5rem)}.game-box>.options>a:last-child{border-bottom-right-radius:calc(var(--radius) - .5rem)}.game-box>.options>a:hover,.game-box>.options>a:focus-visible{outline:none;transform:translateY(-0.1rem)}*{box-sizing:border-box}html{font-family:var(--main-font);background-color:var(--secondary);color:var(--primary)}body{margin:0;padding:0;min-height:100vh;display:grid;grid-template-rows:1fr auto}.background{background-color:var(--primary);position:absolute;inset:0;overflow:hidden;z-index:1}.background>img{position:absolute;inset:-5%;width:110%;height:110%;object-fit:cover;filter:blur(0.25rem);opacity:.3}.background::after{content:'';position:absolute;inset:0;background-image:linear-gradient(to top,var(--secondary),transparent);z-index:+1}main{padding-top:3rem;position:relative;z-index:2}footer{margin:auto 0 0;padding:.5rem;position:relative;display:flex;justify-content:center;align-items:center;background-color:var(--primary);color:var(--secondary);z-index:2}footer>p{margin:0;font-size:.8rem;font-family:var(--monospace-font);text-align:center;color:var(--secondary)}footer>p>a{margin:0;font-size:inherit;font-family:inherit;color:var(--accent);text-decoration:none;cursor:pointer}footer>p>a:hover{text-decoration:underline} \ No newline at end of file +:root{--primary:#332f2f;--secondary:#d7cec9;--primary-button:#C0AB83;--secondary-button:#DDD1C1;--accent:#c2a588;--radius:1rem;--main-font:'Rubik',sans-serif;--monospace-font:'JetBrains Mono',monospace;--nav:#262323}@keyframes glow{0%{opacity:0}50%{opacity:1}100%{opacity:0}}nav{padding:0 .5rem;width:100%;height:3rem;display:flex;flex-direction:row;align-items:center;position:fixed;top:0;left:0;background:transparent;color:var(--primary);z-index:100;transition:color .1s ease-in-out}nav::before{content:"";position:absolute;top:-100%;left:0;width:100%;height:100%;background:var(--nav);transition:top .2s ease-in-out;z-index:-1}nav>span{width:100%}nav>a{margin:0 .75rem;font-size:1.1rem;font-weight:bold;font-family:var(--main-font);text-decoration:none;color:inherit;transition:color .1s ease-in-out,font-weight .1s ease-in-out}nav>a:hover{color:var(--accent)}nav.scrolled{color:var(--secondary)}nav.scrolled>a{font-weight:normal}nav.scrolled::before{top:0}header{margin-bottom:3rem;padding:2rem;height:calc(100vh - 6rem);display:flex;flex-direction:column;justify-content:center;align-items:center;text-align:center;font-family:var(--main-font);color:var(--primary)}header>h1{margin:0;font-size:3rem}header>h1>span{font-family:var(--monospace-font);color:var(--accent)}header>p{margin:0;font-size:1.2rem}header>i{margin:1rem 0 0;font-size:1.2rem;animation:glow 3s ease-in-out infinite}section{margin:0 auto 1rem;padding:1rem;max-width:75rem;display:flex;flex-direction:column;justify-content:center;text-align:center}section>h2{margin:0 0 1rem;font-size:2rem;font-weight:bold}section>p{margin:0 0 1rem;font-size:1rem}section.center{height:100%;justify-content:center;align-items:center}div.games{margin:1rem;display:grid;grid-template-columns:repeat(auto-fit,minmax(20rem,1fr));gap:2rem}@media(max-width:24rem){div.games{margin:0;display:flex;flex-direction:column;gap:1rem}}div.login{padding:.5rem;background-color:var(--primary);color:var(--secondary);border-radius:var(--radius)}div.login>p{margin:0 0 .5rem;padding:.5rem;background-color:var(--accent);color:var(--primary);border-radius:calc(calc(var(--radius) - .5rem) / 2)}div.login>p:first-child{border-top-left-radius:calc(var(--radius) - .5rem);border-top-right-radius:calc(var(--radius) - .5rem)}div.login>form{display:flex;flex-direction:row}div.login>form>input{padding:.5rem 1rem;width:100%;font-size:1rem;font-family:var(--monospace-font);background-color:var(--secondary);color:var(--primary);border-radius:calc(calc(var(--radius) - .5rem) / 2) 0 0 calc(var(--radius) - .5rem);border:none;transition:transform .1s ease-in-out,border-radius .1s ease-in-out}div.login>form>input:hover,div.login>form>input:focus-visible{outline:none}div.login>form>button{padding:.5rem 1rem;font-size:1rem;background-color:var(--primary-button);color:var(--primary);border-radius:0 calc(calc(var(--radius) - .5rem) / 2) calc(var(--radius) - .5rem) 0;border:none;transition:transform .1s ease-in-out,border-radius .1s ease-in-out}div.login>form>button:hover,div.login>form>button:focus-visible{outline:none;background-color:var(--secondary-button)}.game-box{margin:0 auto;padding:.5rem;width:100%;height:auto;display:flex;flex-direction:column;font-family:var(--main-font);background-color:var(--primary);color:var(--secondary);border-radius:var(--radius);box-shadow:0 .2rem 1rem 0 var(--primary);overflow:hidden;transition:box-shadow .1s ease-in-out,transform .1s ease-in-out}.game-box>img{margin:0 0 .5rem;width:auto;height:10rem;object-fit:cover;display:block;border-radius:calc(var(--radius) - .5rem) calc(var(--radius) - .5rem) calc(calc(var(--radius) - .5rem) / 2) calc(calc(var(--radius) - .5rem) / 2)}.game-box>h2{margin:0 0 .5rem;font-size:1.5rem;font-weight:bold}.game-box>p{height:100%;margin:0 0 1rem;font-size:1rem}.game-box>.options{display:flex;flex-direction:row;gap:.5rem;font-family:var(--monospace-font)}.game-box>.options>a{margin:0;padding:.5rem 1rem;height:2.5rem;display:flex;justify-content:center;align-items:center;font-size:1rem;text-decoration:none;background-color:var(--primary-button);color:var(--primary);border-radius:calc(calc(var(--radius) - .5rem) / 2);transition:transform .1s ease-in-out,border-radius .1s ease-in-out}.game-box>.options>a>i{font-size:1.2rem}.game-box>.options>a:first-child{border-bottom-left-radius:calc(var(--radius) - .5rem)}.game-box>.options>a:last-child{border-bottom-right-radius:calc(var(--radius) - .5rem)}.game-box>.options>a:hover,.game-box>.options>a:focus-visible{outline:none;transform:translateY(-0.1rem)}*{box-sizing:border-box}html{font-family:var(--main-font);background-color:var(--secondary);color:var(--primary)}body{margin:0;padding:0;min-height:100vh;display:grid;grid-template-rows:1fr auto}.background{background-color:var(--primary);position:absolute;inset:0;overflow:hidden;z-index:1}.background>img{position:absolute;inset:-5%;width:110%;height:110%;object-fit:cover;filter:blur(0.25rem);opacity:.3}.background::after{content:'';position:absolute;inset:0;background-image:linear-gradient(to top,var(--secondary),transparent);z-index:+1}main{padding-top:3rem;position:relative;z-index:2}footer{margin:auto 0 0;padding:.5rem;position:relative;display:flex;justify-content:center;align-items:center;background-color:var(--primary);color:var(--secondary);z-index:2}footer>p{margin:0;font-size:.8rem;font-family:var(--monospace-font);text-align:center;color:var(--secondary)}footer>p>a{margin:0;font-size:inherit;font-family:inherit;color:var(--accent);text-decoration:none;cursor:pointer}footer>p>a:hover{text-decoration:underline} \ No newline at end of file diff --git a/DV8-Expo/website/templates/base.html b/DV8-Expo/website/templates/base.html index c004b1b..a5a3129 100644 --- a/DV8-Expo/website/templates/base.html +++ b/DV8-Expo/website/templates/base.html @@ -25,12 +25,10 @@ diff --git a/DV8-Expo/website/templates/login.html b/DV8-Expo/website/templates/login.html index a3d23b1..0591f7f 100644 --- a/DV8-Expo/website/templates/login.html +++ b/DV8-Expo/website/templates/login.html @@ -12,7 +12,7 @@

Do not share your UUID

{% endif %} {% endwith %} -
+ {{ form.csrf_token }} {{ form.uuid(size=36) }}