Compare commits

...

4 Commits

Author SHA1 Message Date
e615f774ad
add user input sanitation 2024-01-18 15:00:13 +01:00
ed38156e77
add sql db and config file to install scripts for saving 2024-01-18 14:26:27 +01:00
4b82097fd9
update debian control info 2024-01-18 14:05:50 +01:00
d0d9529e41
add task deleting 2024-01-18 14:04:00 +01:00
10 changed files with 150 additions and 8 deletions

View File

@ -7,5 +7,5 @@ Installed-Size: 2000
Depends: gunicorn, python3-flask-sqlalchemy Depends: gunicorn, python3-flask-sqlalchemy
Homepage: https://gitea.dmz.rs/Decentrala/taskmanager Homepage: https://gitea.dmz.rs/Decentrala/taskmanager
Maintainer: Decentrala <dmz@dmz.rs> Maintainer: Decentrala <dmz@dmz.rs>
Description: Web app Description: Interactive TODO list Web app
Version: 1.0.2 Version: 1.0.3

View File

@ -2,3 +2,11 @@
/usr/bin/systemctl enable taskmanager.service /usr/bin/systemctl enable taskmanager.service
/var/taskmanager/init_db.py /var/taskmanager/init_db.py
/sbin/service taskmanager start /sbin/service taskmanager start
if [ -f /tmp/oldtaskmanagerconfig.ini ] ; then
cp /tmp/oldtaskmanagerconfig.ini /var/taskmanager/taskmanager/config.ini
rm /tmp/oldtaskmanagerconfig.ini
fi
if [ -f /tmp/oldtaskmanager.db ] ; then
cp /tmp/oldtaskmanager.db /var/taskmanager/instance/taskmanager.db
rm /tmp/oldtaskmanager.db
fi

View File

@ -0,0 +1,6 @@
if [ -f /var/taskmanager/taskmanager/config.ini ] ; then
cp /var/taskmanager/taskmanager/config.ini /tmp/oldtaskmanagerconfig.ini
fi
if [ -f /var/taskmanager/instance/taskmanager.db ] ; then
cp /var/taskmanager/instance/taskmanager.db /tmp/oldtaskmanager.db
fi

View File

@ -1,3 +1,9 @@
#!/bin/sh #!/bin/sh
/sbin/service taskmanager stop /sbin/service taskmanager stop
/usr/bin/systemctl disable taskmanager.service /usr/bin/systemctl disable taskmanager.service
if [ -f /var/taskmanager/taskmanager/config.ini ] ; then
cp /var/taskmanager/taskmanager/config.ini /tmp/oldtaskmanagerconfig.ini
fi
if [ -f /var/taskmanager/instance/taskmanager.db ] ; then
cp /var/taskmanager/instance/taskmanager.db /tmp/oldtaskmanager.db
fi

2
taskmanager/config.ini Normal file
View File

@ -0,0 +1,2 @@
[credentials]
ADMINPASS = defaultpassword

View File

@ -4,6 +4,7 @@ class Task(db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False) name = db.Column(db.String, nullable=False)
desc = db.Column(db.String, nullable=True) desc = db.Column(db.String, nullable=True)
creatorid = db.Column(db.Integer, nullable=True)
class User(db.Model): class User(db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)

View File

@ -2,6 +2,14 @@ from flask import render_template, request, redirect
from taskmanager import app, db from taskmanager import app, db
from taskmanager.functions import * from taskmanager.functions import *
from taskmanager.models import * from taskmanager.models import *
import configparser
CONFIG_PATH = "/var/taskmanager/taskmanager/config.ini"
config = configparser.ConfigParser()
config.read(CONFIG_PATH)
ADMINPASS = config.get('credentials', 'ADMINPASS')
@app.route('/', methods=['GET']) @app.route('/', methods=['GET'])
def index(): def index():
@ -15,7 +23,28 @@ def addtask():
elif request.method == 'POST': elif request.method == 'POST':
taskname = request.form['taskname'] taskname = request.form['taskname']
taskdesc = request.form['taskdesc'] taskdesc = request.form['taskdesc']
sqladdtask = Task(name = taskname, desc = taskdesc) username = request.form['username']
# Input sanitation
if not taskname.isalnum():
return "Task name has to be made only of letters or numbers."
if not username.isalnum():
return "Username has to be made only of letters or numbers."
if not taskdesc.isprintable():
return "Task description has to be made of printable characters."
if len(taskname) < 1 or len(taskname) > 40:
return "Task name lenght invalid, only smaller then 40 charachters allowed"
if len(taskdesc) > 2000:
return "Task description lenght invalid, only smaller then 2000 charachters allowed"
if username == "":
creatorid = None
else:
try:
creatorid = User.query.filter_by(username = username).first().id
except:
return 'No user with this username. Please <a href="/register">register</a>.'
if creatorid is None:
return 'No user with this username. Please <a href="/register">register</a>.'
sqladdtask = Task(name = taskname, desc = taskdesc, creatorid = creatorid)
try: try:
db.session.add(sqladdtask) db.session.add(sqladdtask)
db.session.commit() db.session.commit()
@ -31,6 +60,18 @@ def register():
username = request.form['username'] username = request.form['username']
contact = request.form['contact'] contact = request.form['contact']
password = request.form['password'] password = request.form['password']
if not username.isalnum():
return "Username has to be made only of letters or numbers."
if not contact.isprintable():
return "Contact information has to be made of printable characters."
if not password.isprintable():
return "Password has to be made of printable characters."
if len(username) < 1 or len(username) > 40:
return "Username lenght invalid, only smaller then 40 charachters allowed"
if len(contact) > 100:
return "Contact lenght invalid, only smaller then 100 charachters allowed"
if len(password) > 500:
return "Password lenght invalid, only smaller then 500 charachters allowed"
sqladduser = User(username = username, contact = contact, password = password) sqladduser = User(username = username, contact = contact, password = password)
try: try:
db.session.add(sqladduser) db.session.add(sqladduser)
@ -45,21 +86,27 @@ def register():
@app.route('/projects/<int:task_id>', methods=['GET','POST']) @app.route('/projects/<int:task_id>', methods=['GET','POST'])
def project(task_id:int): def project(task_id:int):
users = gettaskusers(task_id)
if request.method == 'GET':
try: try:
task = Task.query.get(task_id) task = Task.query.get(task_id)
except: except:
return 'Task not found, bad URL' return 'Task not found, bad URL'
if task is None:
return 'Task not found, bad URL'
users = gettaskusers(task_id)
if request.method == 'GET':
return render_template("project.html", task = task, users = users) return render_template("project.html", task = task, users = users)
elif request.method == 'POST': elif request.method == 'POST':
username = request.form['username'] username = request.form['username']
if len(username) < 1 or len(username) > 40:
return "Username lenght invalid, only smaller then 40 charachters allowed"
if username in users: if username in users:
return 'User already added to task' return 'User already added to task'
try: try:
userid = User.query.filter_by(username = username).first().id userid = User.query.filter_by(username = username).first().id
except: except:
return 'User not found, please <a href="/register">register</a>.' return 'User not found, please <a href="/register">register</a>.'
if userid is None:
return 'User not found, please <a href="/register">register</a>.'
sqladduser = TaskUser(userid = userid, taskid = task_id) sqladduser = TaskUser(userid = userid, taskid = task_id)
try: try:
db.session.add(sqladduser) db.session.add(sqladduser)
@ -68,3 +115,36 @@ def project(task_id:int):
except: except:
return 'Adding user failed' return 'Adding user failed'
@app.route('/projects/<int:task_id>/del', methods=['GET','POST'])
def deltask(task_id:int):
try:
task = Task.query.get(task_id)
except:
return 'Task not found, bad URL'
if task is None:
return 'Task not found, bad URL'
creatorid = task.creatorid
if request.method == 'GET':
if creatorid is None:
try:
db.session.delete(task)
db.session.commit()
return 'Task deleted'
except:
return 'Deleting task failed'
else:
return render_template('deltask.html', task = task)
if request.method == 'POST':
password = request.form['password']
if len(password) < 1 or len(password) > 500:
return "Password lenght invalid, only smaller then 500 charachters allowed"
# Check password
if password != ADMINPASS and password != User.query.get(creatorid).password:
return 'Wrong password'
# Delete task
try:
db.session.delete(task)
db.session.commit()
return 'Task deleted'
except:
return 'Deleting task failed'

View File

@ -25,7 +25,11 @@
</div> </div>
<div class="form-input"> <div class="form-input">
<label for="taskdesc" class="label">Description:</label> <label for="taskdesc" class="label">Description:</label>
<input type="text" name="taskdesc" id="taskdesc" required /> <input type="text" name="taskdesc" id="taskdesc" placeholder="optional"/>
</div>
<div class="form-input">
<label for="username" class="label">Username:</label>
<input type="text" name="username" id="username" placeholder="optional"/>
</div> </div>
<div class="btn-wrap"> <div class="btn-wrap">
<button class="btn">Submit</button> <button class="btn">Submit</button>

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="/static/style.css" />
<title>Delete task</title>
</head>
<body>
<header>
<nav class="container">
<ul>
<li class="current"><a href="/">Home</a></li>
<li><a href="/register">Register</a></li>
</ul>
</nav>
</header>
<main class="container page page-addtask">
<h1>Create new task</h1>
<div class="form-wrap">
<form action="/projects/{{task.id}}/del" method="POST">
<p> Task creator's password <p>
<div class="form-input">
<label for="password" class="label">password:</label>
<input type="password" name="password" id="password" required />
</div>
<div class="btn-wrap">
<button class="btn">DELETE</button>
</div>
</div>
</form>
</main>
</body>
</html>

View File

@ -43,6 +43,7 @@
<button class="btn">Submit</button> <button class="btn">Submit</button>
</div> </div>
</form> </form>
<p><a href="/projects/{{task.id}}/del">DELETE TASK</a><p>
</div> </div>
</div> </div>
</section> </section>