diff --git a/ER-rar-index.graphml b/ER-rar-index.graphml
index 52f96ae..6ed562a 100644
--- a/ER-rar-index.graphml
+++ b/ER-rar-index.graphml
@@ -235,6 +235,7 @@
IDSESSKEY
+ USERIDCREATEDLIFE
diff --git a/flask/app.py b/flask/app.py
index f18152b..5a329e9 100644
--- a/flask/app.py
+++ b/flask/app.py
@@ -1,9 +1,12 @@
-from flask import Flask,redirect,url_for,request,render_template
+from flask import Flask,redirect,url_for,request,render_template,make_response
from datetime import datetime
+from hashlib import sha256
+from uuid import uuid4 as uuid
## Import db class from func.py and initialise it
from func import db
db=db()
+db.startup()
app = Flask(__name__)
@@ -12,7 +15,7 @@ app = Flask(__name__)
def timectime(s):
return datetime.utcfromtimestamp(s).strftime('%Y-%m-%d %H:%M')
@app.template_filter('spacer')
-def timectime(s):
+def convsize(s):
sizes=("B","KB","MB","GB","TB")
n=0
while s > 1000:
@@ -20,12 +23,58 @@ def timectime(s):
s=s/1000
return str("%.2f" % s)+sizes[n]
-
## WEB FRONTEND
@app.route('/')
def homepage():
+ # try to get sesskey, else logout state
+ try:
+ # get sesskey and get info about user
+ sesskey=request.cookies.get('session')
+ res,userid=db.check_sesskey(sesskey)
+ if not res:
+ return 500
+ userdata=db.get_user_info(userid)
+ logged_in=True
+ except Exception as e:
+ logged_in=False
+ userdata=()
+
archives=db.get_n_archives()
- return render_template("home.html", title="Homepage",archives=archives)
+ return render_template("home.html", title="Homepage",userdata=userdata,login=logged_in,archives=archives)
+
+@app.route('/user')
+@app.route('/user/')
+def userpage(userid:int=0):
+ if userid==0:
+ return make_response(redirect('/'))
+
+@app.route('/login', methods=["GET","POST"])
+def loginpage():
+ # POST: Process login request
+ if request.method == 'POST':
+ username=request.form['username']
+ password=sha256(request.form['password'].encode()).hexdigest()
+ code,userid,passhash=db.get_passhash(username)
+ if code != 200:
+ return passhash
+ # if passwords match, create session and return cookie
+ if password.upper() == passhash.upper():
+ lifetime=3000000 # lifetime of the sesskey in seconds
+ sesskey=str(uuid())
+ db.set_sesskey(sesskey,userid,lifetime)
+ resp=setcookie("session",sesskey,lifetime)
+ return resp
+ else:
+ return "
You've entered the wrong password. This incident will be reported.
Go back and try again. " + password.upper() + " " + passhash.upper() # TODO: DELETE
+ # GET: Login form
+ else:
+ return render_template("login.html", title="Login")
+
+## FUNCTIONS
+def setcookie(name:str,value:str,lifetime:int=10000):
+ resp = make_response(redirect('/'))
+ resp.set_cookie(name, value, max_age=lifetime)
+ return resp
## API CALLS
diff --git a/flask/func.py b/flask/func.py
index 6b589c3..55e4a8c 100644
--- a/flask/func.py
+++ b/flask/func.py
@@ -1,6 +1,7 @@
## MAIN FUNCTIONS FILE FOR BACK-BACKEND OF FLASK
import mariadb as sql
from os import environ
+import time
## params populated with environment variables, defaults can be changed for a permanent solution
conn_params={
@@ -13,13 +14,13 @@ conn_params={
class db:
def __init__(self):
self.conn=sql.connect(**conn_params)
+ self.conn.autocommit=True
self.cur=self.conn.cursor()
## Creates all archives, if they don't exist already
## Called only on startup, hence the name
def startup(self):
- self.cur.execute("""
- CREATE TABLE IF NOT EXISTS Archs(
+ self.cur.execute("""CREATE TABLE IF NOT EXISTS Archs(
ID int PRIMARY KEY AUTO_INCREMENT,
NAME text NOT NULL,
HASH text NOT NULL,
@@ -27,44 +28,77 @@ class db:
IMPORTED int,
CATEGORY int,
OWNER int
- );
- CREATE TABLE IF NOT EXISTS Users(
+ );""")
+ self.cur.execute("""CREATE TABLE IF NOT EXISTS Users(
ID int PRIMARY KEY AUTO_INCREMENT,
UNAME text NOT NULL,
DNAME text NOT NULL,
CREATED int NOT NULL,
STATE text,
PASSHASH text NOT NULL
- );
- CREATE TABLE IF NOT EXISTS Sessions(
+ );""")
+ self.cur.execute("""CREATE TABLE IF NOT EXISTS Sessions(
ID int PRIMARY KEY AUTO_INCREMENT,
SESSKEY text NOT NULL,
+ USERID int NOT NULL,
CREATED int NOT NULL,
LIFE int
- );
- CREATE TABLE IF NOT EXISTS Cats(
+ );""")
+ self.cur.execute("""CREATE TABLE IF NOT EXISTS Cats(
ID int PRIMARY KEY AUTO_INCREMENT,
CATEGORY text NOT NULL,
PARENT int,
DESCRIPTION text
- );
- CREATE TABLE IF NOT EXISTS ArchLab(
+ );""")
+ self.cur.execute("""CREATE TABLE IF NOT EXISTS ArchLab(
ID int PRIMARY KEY AUTO_INCREMENT,
ARCHID int NOT NULL,
LABID int NOT NULL
- );
- CREATE TABLE IF NOT EXISTS Labs(
+ );""")
+ self.cur.execute("""CREATE TABLE IF NOT EXISTS Labs(
ID int PRIMARY KEY AUTO_INCREMENT,
LABEL text NOT NULL,
CATEGORY text,
TYPE int NOT NULL
- );
- CREATE TABLE IF NOT EXISTS LabType(
+ );""")
+ self.cur.execute("""CREATE TABLE IF NOT EXISTS LabType(
ID int PRIMARY KEY AUTO_INCREMENT,
NAME text NOT NULL,
DESCRIPTION text
- );
- """)
+ );""")
+
+ ## Gets the passhash from a specific user
+ ## OUTPUT: (If user exists) int=200, passhash:str
+ ## (If user does not exist) int=400, Exception:str
+ def get_passhash(self, username:str):
+ self.cur.execute(f"SELECT ID,PASSHASH FROM Users WHERE UNAME='{username}'")
+ try:
+ resp=self.cur.fetchone()
+ except Exception as e:
+ return 400, e, NULL
+ return 200, resp[0], resp[1]
+
+ ## Checks if sesskey exists and is not expired
+ ## OUTPUT: (if valiid) bool=True, USERID:str
+ ## (in invalid) bool=False, str=""
+ def check_sesskey(self, sesskey:str):
+ self.cur.execute(f"SELECT SESSKEY,USERID FROM Sessions WHERE SESSKEY='{sesskey}'")
+ entry=self.cur.fetchone()
+ if sesskey in entry:
+ return True, entry[1]
+ else:
+ return False, ""
+
+ ## Sets a session key. That's it.
+ def set_sesskey(self, sesskey:str, userid:int, lifetime:int):
+ self.cur.execute(f"INSERT INTO Sessions(SESSKEY,USERID,CREATED,LIFE) VALUES('{sesskey}',{userid},{time.time()},{lifetime})")
+
+ ## Gets and returns all user info about one (1) user
+ ## OUTPUT: tuple=(ID:int,UNAME:str,DNAME:str,CREATED:int,STATE:text,PASSHASH:text)
+ def get_user_info(self, userid:int):
+ print("USERID:::::::::::" + userid)
+ self.cur.execute(f"SELECT * FROM Users WHERE ID='{userid}'")
+ return self.cur.fetchone()
## Returns all relevant information about one (1) archive
## OUTPUT: archive:tuple=(NAME:str,HASH:str,IMPORTED[UNIX]:int,CATEGORY,str,CATEGORY.DESCRIPTION:str,UNAME:str,DNAME:str)
@@ -86,7 +120,7 @@ class db:
return archive, labels
## Returns n archives, sorted by (imported )time or size
- ## OUTPUT: archives:array=[…,(NAME:str,SIZE:str,IMPORTED[UNIX]:int),…]
+ ## OUTPUT: archives:array=[…,(ID:int,NAME:str,SIZE:str,IMPORTED[UNIX]:int),…]
def get_n_archives(self, sorttype:str="time",category:int=0, count:int=20):
global cur
match sorttype:
@@ -94,7 +128,7 @@ class db:
sorttype="SIZE"
case _:
sorttype="IMPORTED"
- self.cur.execute(f"""SELECT NAME,SIZE,IMPORTED FROM Archs{"" if category==0 else " WHERE CATEGORY=" + category} ORDER BY {sorttype} DESC LIMIT {count};""")
+ self.cur.execute(f"""SELECT ID,NAME,SIZE,IMPORTED FROM Archs{"" if category==0 else " WHERE CATEGORY=" + category} ORDER BY {sorttype} DESC LIMIT {count};""")
archives=self.cur.fetchall()
return archives
diff --git a/flask/static/base.css b/flask/static/base.css
index cce6ae8..30291ea 100644
--- a/flask/static/base.css
+++ b/flask/static/base.css
@@ -23,7 +23,6 @@ header > div#container {
}
.big-button {
- width: 2em;
height: 2em;
margin: auto 0.1em;
border: none;
diff --git a/flask/static/home.css b/flask/static/home.css
index 5ccd682..dc61c44 100644
--- a/flask/static/home.css
+++ b/flask/static/home.css
@@ -6,6 +6,13 @@ div.grid-item {
border: 2px black solid;
}
+a.grid-item {
+ text-decoration: none;
+ display: contents;
+ height: 100%;
+ color: black;
+}
+
div.clickable:hover {
- background: grey;
+ background: lightgrey;
}
\ No newline at end of file
diff --git a/flask/static/login.css b/flask/static/login.css
new file mode 100644
index 0000000..9d2e21a
--- /dev/null
+++ b/flask/static/login.css
@@ -0,0 +1,9 @@
+div.grid-container {
+ margin: 2em 0 0 1em;
+ display: inline-grid;
+ grid-template-columns: auto auto;
+}
+
+div.grid-container > * {
+ margin: 1em auto;
+}
\ No newline at end of file
diff --git a/flask/templates/base.html b/flask/templates/base.html
index a58cf17..f8326ab 100644
--- a/flask/templates/base.html
+++ b/flask/templates/base.html
@@ -11,7 +11,15 @@
{{title}}
diff --git a/flask/templates/login.html b/flask/templates/login.html
new file mode 100644
index 0000000..6fb0c68
--- /dev/null
+++ b/flask/templates/login.html
@@ -0,0 +1,15 @@
+{% extends "base.html" %}
+
+{% block meta %}
+
+{% endblock %}
+
+{% block content %}
+
+{% endblock %}
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index 8ab6294..f0b97de 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1 +1,3 @@
-flask
\ No newline at end of file
+flask
+mariadb
+hashlib
\ No newline at end of file