Added login functionality and admin page
This commit is contained in:
parent
2186c273dd
commit
20f1d31149
75
app.py
75
app.py
@ -1,7 +1,32 @@
|
|||||||
from flask import Flask, render_template, request, jsonify
|
from flask import Flask, render_template, request, jsonify, abort, redirect, url_for
|
||||||
from services import Services
|
from flask_login import LoginManager , login_required , UserMixin , login_user, current_user, logout_user
|
||||||
app = Flask("Project Candle")
|
from forms import LoginForm
|
||||||
services = Services()
|
from services import Services, UserManager
|
||||||
|
from models import User
|
||||||
|
import sqlite3
|
||||||
|
import re
|
||||||
|
|
||||||
|
#Setup
|
||||||
|
app = Flask("Project Fish")
|
||||||
|
app.config.from_pyfile('config.py')
|
||||||
|
login_manager = LoginManager()
|
||||||
|
login_manager.login_view = "login"
|
||||||
|
login_manager.init_app(app)
|
||||||
|
|
||||||
|
sqlpath="sqlite.db"
|
||||||
|
db = sqlite3.connect(sqlpath, check_same_thread=False)
|
||||||
|
services = Services(db)
|
||||||
|
usermanager = UserManager(db)
|
||||||
|
|
||||||
|
def is_string_sanitized(data):
|
||||||
|
sanitized_string = re.sub('[^a-zA-Z0-9_@#$.\s]', '', data)
|
||||||
|
if len(data) != len(sanitized_string):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
@login_manager.user_loader
|
||||||
|
def load_user(user_id):
|
||||||
|
return usermanager.GetUserByID(user_id)
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def index():
|
def index():
|
||||||
@ -10,20 +35,42 @@ def index():
|
|||||||
@app.route("/GetServices", methods=['GET', 'POST'])
|
@app.route("/GetServices", methods=['GET', 'POST'])
|
||||||
def GetServices():
|
def GetServices():
|
||||||
nummer = (request.json)["nummer"]
|
nummer = (request.json)["nummer"]
|
||||||
|
if(not is_string_sanitized(nummer)):
|
||||||
|
return abort(401)
|
||||||
if(nummer != None and nummer != ""):
|
if(nummer != None and nummer != ""):
|
||||||
ser=services.GetServices(nummer)
|
ser=services.GetServices(nummer)
|
||||||
return jsonify(render_template("results.html", services=ser),)
|
return jsonify(render_template("results.html", services=ser),)
|
||||||
ser = services.GetAllServices()
|
ser = services.GetAllServices()
|
||||||
return render_template("results.html", services=ser)
|
return render_template("results.html", services=ser)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/admin')
|
||||||
|
@login_required
|
||||||
|
def admin():
|
||||||
|
return render_template("admin.html")
|
||||||
|
|
||||||
|
@app.route("/logout")
|
||||||
|
@login_required
|
||||||
|
def logout():
|
||||||
|
logout_user()
|
||||||
|
return render_template("index.html")
|
||||||
|
|
||||||
|
@app.route('/login' , methods=['GET' , 'POST'])
|
||||||
|
def login():
|
||||||
|
if request.method == 'POST':
|
||||||
|
username = request.form['username']
|
||||||
|
password = request.form['password']
|
||||||
|
if(not (is_string_sanitized(username) and is_string_sanitized(username))):
|
||||||
|
return abort(401)
|
||||||
|
registeredUser = usermanager.Authenticate(username, password)
|
||||||
|
if registeredUser != None:
|
||||||
|
login_user(registeredUser)
|
||||||
|
return redirect(url_for('admin'))
|
||||||
|
else:
|
||||||
|
return abort(401)
|
||||||
|
else:
|
||||||
|
return render_template("login.html")
|
||||||
|
|
||||||
def RunWeb():
|
def RunWeb():
|
||||||
app.run(debug=True)
|
app.run(debug=True)
|
||||||
|
|
||||||
@app.route('/', methods=['POST'])
|
|
||||||
def my_form_post():
|
|
||||||
text = request.form['text']
|
|
||||||
processed_text = text.upper()
|
|
||||||
print(f'Inputted text is: {processed_text}')
|
|
||||||
return processed_text
|
|
||||||
|
|
||||||
|
|
7
forms.py
Normal file
7
forms.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from wtforms import StringField, PasswordField, SubmitField
|
||||||
|
from flask_wtf import FlaskForm
|
||||||
|
|
||||||
|
class LoginForm(FlaskForm):
|
||||||
|
username = StringField('username')
|
||||||
|
password = PasswordField('password')
|
||||||
|
submit = SubmitField('Submit')
|
21
models.py
Normal file
21
models.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
from flask_login import UserMixin
|
||||||
|
|
||||||
|
class User(UserMixin):
|
||||||
|
def __init__(self , username , password , id , active=True, salt=""):
|
||||||
|
self.id = id
|
||||||
|
self.username = username
|
||||||
|
self.password = password
|
||||||
|
self.active = active
|
||||||
|
self.salt = salt
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
return self.id
|
||||||
|
|
||||||
|
def get_id(self):
|
||||||
|
return self.id
|
||||||
|
|
||||||
|
def is_active(self):
|
||||||
|
return self.active
|
||||||
|
|
||||||
|
# def get_auth_token(self):
|
||||||
|
# return make_secure_token(self.username , key='secret_key')
|
97
services.py
97
services.py
@ -1,14 +1,19 @@
|
|||||||
import datetime
|
import datetime
|
||||||
from sqlite3 import *
|
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import locale
|
import locale
|
||||||
import random
|
import random
|
||||||
locale.setlocale(locale.LC_TIME, "nl_NL.utf-8") # swedish
|
import hashlib
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
from werkzeug.datastructures import Authorization
|
||||||
|
from models import User
|
||||||
|
locale.setlocale(locale.LC_TIME, "nl_NL.utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Services:
|
class Services:
|
||||||
def __init__(self, sqlpath="sqlite.db") -> None:
|
def __init__(self, db) -> None:
|
||||||
self.sqlpath = sqlpath
|
self.db = db
|
||||||
self.db = sqlite3.connect(self.sqlpath, check_same_thread=False)
|
|
||||||
self.cursor = self.db.cursor()
|
self.cursor = self.db.cursor()
|
||||||
self.PopulateDB()
|
self.PopulateDB()
|
||||||
|
|
||||||
@ -53,19 +58,75 @@ class Services:
|
|||||||
self.cursor.execute(query)
|
self.cursor.execute(query)
|
||||||
self.db.commit()
|
self.db.commit()
|
||||||
|
|
||||||
|
class UserManager():
|
||||||
|
def __init__(self, db) -> None:
|
||||||
|
self.db = db
|
||||||
|
self.cursor = self.db.cursor()
|
||||||
|
self.PopulateDB()
|
||||||
|
|
||||||
|
def PopulateDB(self):
|
||||||
|
'''
|
||||||
|
Create db for user managment. Password is stored as a hash
|
||||||
|
'''
|
||||||
|
query = f"""CREATE TABLE IF NOT EXISTS users
|
||||||
|
(
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
name STRING,
|
||||||
|
password STRING,
|
||||||
|
salt STRING
|
||||||
|
);
|
||||||
|
"""
|
||||||
|
self.cursor.execute(query)
|
||||||
|
|
||||||
|
def AddUser(self, name, password):
|
||||||
|
salt = uuid.uuid4().hex
|
||||||
|
m = hashlib.sha512()
|
||||||
|
m.update((password + salt).encode("utf-8"))
|
||||||
|
password = m.digest().hex()
|
||||||
|
query = f"""
|
||||||
|
INSERT INTO users (name, password, salt)
|
||||||
|
VALUES('{name}', '{password}', '{salt}');
|
||||||
|
"""
|
||||||
|
self.cursor.execute(query)
|
||||||
|
self.db.commit()
|
||||||
|
|
||||||
|
def Authenticate(self, name, password):
|
||||||
|
us = self.cursor.execute(f"select * from users where name == '{name}';").fetchall()
|
||||||
|
if(us != None and len(us) > 0):
|
||||||
|
us = us[0]
|
||||||
|
m = hashlib.sha512()
|
||||||
|
m.update((password + us[3]).encode("utf-8"))
|
||||||
|
password = m.digest().hex()
|
||||||
|
if(password == us[2]):
|
||||||
|
return User(us[1], us[2], us[0], salt=us[3])
|
||||||
|
return None
|
||||||
|
|
||||||
|
def GetUserByID(self, id):
|
||||||
|
us = self.cursor.execute(f"select * from users where id == {id};").fetchall()
|
||||||
|
if(us != None):
|
||||||
|
us = us[0]
|
||||||
|
return User(us[1], us[2], us[0], salt=us[3])
|
||||||
|
return None
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
#fill db
|
#fill db
|
||||||
ser = Services()
|
db = sqlite3.connect("sqlite.db", check_same_thread=False)
|
||||||
for i in range(100):
|
ser = Services(db)
|
||||||
d = datetime.datetime.now()
|
us = UserManager(db)
|
||||||
d = d.replace(hour=random.randint(1, 23), day = random.randint(1, 28), month = random.randint(1, 12))
|
|
||||||
d = d.strftime("%Y-%m-%d %H:%M:%S")
|
# us.AddUser("Eljakim", "Kunnenwe?")
|
||||||
g = ""
|
us.Authenticate("Eljakim", "Kunnenwe?")
|
||||||
for j in range(10):
|
us.Authenticate("Eljakim", "Kunnenwe2?")
|
||||||
g += str(random.randint(1, 30))
|
# for i in range(100):
|
||||||
g += ":"
|
# d = datetime.datetime.now()
|
||||||
ser.AddService(d, g)
|
# d = d.replace(hour=random.randint(1, 23), day = random.randint(1, 28), month = random.randint(1, 12))
|
||||||
r = ser.GetAllServices()
|
# d = d.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
d = ser.GetServices(str(4))
|
# g = ""
|
||||||
print(d)
|
# for j in range(10):
|
||||||
|
# g += str(random.randint(1, 30))
|
||||||
|
# g += ":"
|
||||||
|
# ser.AddService(d, g)
|
||||||
|
# r = ser.GetAllServices()
|
||||||
|
# d = ser.GetServices(str(4))
|
||||||
|
# print(d)
|
||||||
|
|
@ -131,4 +131,43 @@
|
|||||||
margin-top: -100px;
|
margin-top: -100px;
|
||||||
margin-left: -100px;
|
margin-left: -100px;
|
||||||
font-family: "Verdana";
|
font-family: "Verdana";
|
||||||
} */
|
} */
|
||||||
|
|
||||||
|
.a_datum_block{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.a_datum_input{
|
||||||
|
padding: 1%;
|
||||||
|
position: relative;
|
||||||
|
margin:1%;
|
||||||
|
}
|
||||||
|
.a_datum_block{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.a_van_input{
|
||||||
|
padding: 1%;
|
||||||
|
margin:1%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.a_tot_input{
|
||||||
|
padding: 1%;
|
||||||
|
margin:1%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add_service_btn{
|
||||||
|
position: relative;
|
||||||
|
background-color: lightblue;
|
||||||
|
padding: 2%;
|
||||||
|
margin: 1%;
|
||||||
|
width: 20%;
|
||||||
|
left: 20%;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 26px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add_service_btn:hover{
|
||||||
|
background-color: blue;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
30
templates/admin.html
Normal file
30
templates/admin.html
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
<head>
|
||||||
|
<div class="headerblock">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<h1>Administratie</h1>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="requestblock">
|
||||||
|
<h2>Voeg dienst toe:</h2>
|
||||||
|
<div class="a_datum_block">
|
||||||
|
<input class="a_datum_input" id="datum_input" name="text" placeholder="1-11-2021">
|
||||||
|
</div>
|
||||||
|
<div class="a_datum_block">
|
||||||
|
<input class="a_van_input" id="van_input" name="text" placeholder="1">
|
||||||
|
<tr>t/m</tr>
|
||||||
|
<input class="a_tot_input" id="tot_input" name="text" placeholder="10">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="add_service_btn" onclick="AddService()">Toevoegen</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="adminresultblock" id="resultblock">
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
9
templates/login.html
Normal file
9
templates/login.html
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<form action="" method="post">
|
||||||
|
<p><input type=text name=username>
|
||||||
|
<p><input type=password name=password>
|
||||||
|
<p><input type=submit value=Login>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
@ -1,13 +0,0 @@
|
|||||||
|
|
||||||
.center {
|
|
||||||
display: block;
|
|
||||||
margin-left: 40%;
|
|
||||||
margin-right: 60%;
|
|
||||||
width: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nummer_button{
|
|
||||||
width:5%;
|
|
||||||
height: 3%;
|
|
||||||
background-color: red;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user