diff --git a/app.py b/app.py index 173a2c4..1351c0a 100644 --- a/app.py +++ b/app.py @@ -1,10 +1,12 @@ -from flask import Flask, render_template, redirect, url_for, request +from flask import Flask, render_template, redirect, url_for, request, abort +from flask_wtf.csrf import CSRFProtect from flask_sqlalchemy import SQLAlchemy -from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user +from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user from werkzeug.security import generate_password_hash, check_password_hash import os app = Flask(__name__) +csrf = CSRFProtect(app) app.config["SECRET_KEY"] = os.environ["FLASK_SECRET_KEY"] from urllib.parse import quote_plus @@ -38,6 +40,7 @@ class User(UserMixin, db.Model): id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(100), unique=True) password = db.Column(db.String(200)) # Increased for password hash + admin = db.Column(db.Boolean, default=False) @login_manager.user_loader @@ -81,6 +84,11 @@ def register(): password = generate_password_hash(password) new_user = User(email=email, password=password) + + # Automatically make first user admin + if User.query.count() == 0: + new_user.admin = True + db.session.add(new_user) db.session.commit() @@ -99,3 +107,27 @@ def dashboard(): def logout(): logout_user() return redirect(url_for("login")) + +@app.route("/admin", methods=["GET", "POST"]) +@login_required +def admin(): + if not current_user.admin: + abort(403) + + if request.method == "POST": + action = request.form.get("action") + user_id = request.form.get("user_id") + user = User.query.get(user_id) + + if user and user != current_user: # Prevent self-modification + if action == "promote": + user.admin = True + elif action == "demote": + user.admin = False + elif action == "delete": + db.session.delete(user) + + db.session.commit() + + users = User.query.all() + return render_template("admin.html", users=users) diff --git a/requirements.txt b/requirements.txt index 6b602d2..71ab25c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,7 @@ flask==3.0.0 flask-sqlalchemy==3.1.1 flask-login==0.6.3 +flask-wtf==1.2.1 werkzeug==3.0.0 gunicorn==21.2.0 psycopg2-binary==2.9.9 diff --git a/templates/admin.html b/templates/admin.html new file mode 100644 index 0000000..7991ed6 --- /dev/null +++ b/templates/admin.html @@ -0,0 +1,60 @@ +{% extends "base.html" %} + +{% block title %}Admin Panel{% endblock %} + +{% block content %} +
| ID | +Admin Status | +Actions | +|
|---|---|---|---|
| {{ user.id }} | +{{ user.email }} | +{% if user.admin %}Admin{% else %}User{% endif %} | ++ {% if user.admin %} + + {% else %} + + {% endif %} + + | +