From dc0cde61a014ae64756634c66877b4ad5d7d6b30 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 8 Jun 2018 11:40:54 -0400 Subject: [PATCH] Basic admin page --- app.py | 38 +++++++++++++++++++++++++++++++++++++- database.py | 27 +++++++++++++++++++++++++++ init_script.sql | 5 +++++ requirements.txt | 3 ++- templates/admin.html | 26 ++++++++++++++++++++++++++ templates/dashboard.html | 13 +++++++++++++ 6 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 templates/admin.html create mode 100644 templates/dashboard.html diff --git a/app.py b/app.py index 04aaf91..89f3826 100644 --- a/app.py +++ b/app.py @@ -1,4 +1,4 @@ -from flask import Flask, render_template, redirect, request, flash, abort, Response, send_from_directory +from flask import Flask, render_template, redirect, request, flash, abort, Response, send_from_directory, session import os import json import time @@ -192,6 +192,42 @@ def enqueue(): return redirect("/submit") +@app.route("/admin") +def admin_login_form(): + if "username" in session: + return redirect("/dashboard") + return render_template("admin.html", recaptcha=recaptcha) + + +@app.route("/login", methods=["POST"]) +def admin_login(): + + if recaptcha.verify(): + + username = request.form.get("username") + password = request.form.get("password") + + if db.check_login(username, password): + session["username"] = username + flash("Logged in", "success") + return redirect("/dashboard") + + flash("Invalid username/password combo", "danger") + return redirect("/admin") + + else: + flash("Invalid captcha", "danger") + return redirect("/admin") + + +@app.route("/dashboard") +def admin_dashboard(): + if "username" in session: + return render_template("dashboard.html") + else: + return abort(403) + + if __name__ == '__main__': if config.USE_SSL: context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) diff --git a/database.py b/database.py index e1df446..fd80a31 100644 --- a/database.py +++ b/database.py @@ -2,6 +2,7 @@ import sqlite3 import datetime import json import os +import bcrypt class InvalidQueryException(Exception): @@ -367,3 +368,29 @@ class Database: cursor.execute("DELETE FROM Website WHERE id=?", (website_id, )) conn.commit() + + def check_login(self, username, password) -> bool: + with sqlite3.connect(self.db_path) as conn: + cursor = conn.cursor() + + cursor.execute("SELECT password FROM Admin WHERE username=?", (username, )) + + db_user = cursor.fetchone() + + if db_user: + return bcrypt.checkpw(password.encode(), db_user[0]) + return False + + def generate_login(self, username, password) -> None: + + with sqlite3.connect(self.db_path) as conn: + cursor = conn.cursor() + + hashed_pw = bcrypt.hashpw(password.encode(), bcrypt.gensalt(14)) + + cursor.execute("INSERT INTO Admin (username, password) VALUES (?,?)", (username, hashed_pw)) + conn.commit() + + + + diff --git a/init_script.sql b/init_script.sql index 35bf695..c2d9afc 100644 --- a/init_script.sql +++ b/init_script.sql @@ -42,6 +42,11 @@ CREATE TABLE Queue ( priority INTEGER ); +CREATE TABLE Admin ( + username TEXT PRIMARY KEY NOT NULL, + password TEXT +) + -- Full Text Index CREATE VIRTUAL TABLE File_index USING fts5 ( diff --git a/requirements.txt b/requirements.txt index 9356725..618a493 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,4 +7,5 @@ flask_recaptcha Flask-Caching praw humanfriendly -apscheduler \ No newline at end of file +apscheduler +bcrypt \ No newline at end of file diff --git a/templates/admin.html b/templates/admin.html new file mode 100644 index 0000000..89474a4 --- /dev/null +++ b/templates/admin.html @@ -0,0 +1,26 @@ +{% extends "layout.html" %} +{% set title = "Admin login - OD-Database" %} + +{% block body %} +
+
+
Admin login
+
+
+ +
+ +
+
+ +
+ + {{ recaptcha.get_code()|safe }} + + + +
+
+
+
+{% endblock body %} diff --git a/templates/dashboard.html b/templates/dashboard.html new file mode 100644 index 0000000..d5bd32e --- /dev/null +++ b/templates/dashboard.html @@ -0,0 +1,13 @@ +{% extends "layout.html" %} +{% set title = "Dashboard - OD-Database" %} + +{% block body %} +
+
+
Dashboard
+
+ todo +
+
+
+{% endblock body %}