Some work on users

This commit is contained in:
simon 2018-04-24 12:02:25 -04:00
parent fe52ecceff
commit 43725a2e73
6 changed files with 217 additions and 10 deletions

59
run.py
View File

@ -1,16 +1,18 @@
from flask import Flask, render_template, request, redirect, flash, session, abort, send_file from flask import Flask, render_template, request, redirect, flash, session, abort, send_file
from storage import Directory, Option, Task from storage import Directory, Option, Task, User
from storage import LocalStorage, DuplicateDirectoryException from storage import LocalStorage, DuplicateDirectoryException, DuplicateUserException
from crawler import RunningTask, TaskManager from crawler import RunningTask, TaskManager
import json import json
import os import os
import shutil import shutil
import bcrypt
import config import config
import humanfriendly import humanfriendly
from search import Search from search import Search
from PIL import Image from PIL import Image
from io import BytesIO from io import BytesIO
app = Flask(__name__) app = Flask(__name__)
app.secret_key = "A very secret key" app.secret_key = "A very secret key"
storage = LocalStorage(config.db_path) storage = LocalStorage(config.db_path)
@ -32,6 +34,59 @@ def get_dir_size(path):
return size return size
@app.route("/user/<user>")
def user_manage(user):
return user
@app.route("/logout")
def logout():
session.pop("username")
session.pop("admin")
flash("Successfully logged out", "success")
return redirect("/")
@app.route("/login", methods=['POST'])
def login():
username = request.form["username"]
password = request.form["password"]
if storage.auth_user(username, password):
session["username"] = username
session["admin"] = storage.users()[username].admin
print(session["admin"])
flash("Successfully logged in", "success")
else:
flash("Invalid username or password", "danger")
return redirect("/")
@app.route("/user")
def user_page():
return render_template("user.html", users=storage.users())
@app.route("/user/add", methods=['POST'])
def user_add():
username = request.form["username"]
password = bcrypt.hashpw(request.form["password"].encode("utf-8"), bcrypt.gensalt(config.bcrypt_rounds))
is_admin = True if "is_admin" in request.form else False
try:
storage.save_user(User(username, password, is_admin))
flash("Created new user", "success")
except DuplicateUserException:
flash("<strong>Couldn't create user</strong> Make sure that the username is unique", "danger")
return redirect("/user")
@app.route("/suggest") @app.route("/suggest")
def suggest(): def suggest():

View File

@ -389,3 +389,35 @@ class LocalStorage:
conn.commit() conn.commit()
c.close() c.close()
conn.close() conn.close()
def set_access(self, username, dir_id, has_access):
conn = sqlite3.connect(self.db_path)
c = conn.cursor()
if has_access:
try:
c.execute("INSERT INTO User_canRead_Directory VALUES (?,?)", (username, dir_id))
except sqlite3.IntegrityError:
pass
else:
c.execute("DELETE FROM User_canRead_Directory WHERE username=? AND directory_id=?", (username, dir_id))
conn.commit()
c.close()
conn.close()
def get_access(self, username):
conn = sqlite3.connect(self.db_path)
c = conn.cursor()
c.execute("SELECT * FROM User_canRead_Directory WHERE username=?", (username,))
accesses = c.fetchall()
access_list = []
for access in accesses:
access_list.append(access[1])
return access_list

View File

@ -65,15 +65,27 @@
<li class="nav-item"> <li class="nav-item">
<a class="nav-link {% if "task" == active_page %}active{% endif %}" href="/task">Tasks</a> <a class="nav-link {% if "task" == active_page %}active{% endif %}" href="/task">Tasks</a>
</li> </li>
<li class="nav-item">
<a class="nav-link {% if "user" == active_page %}active{% endif %}" href="/user">Users</a>
</li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link {% if "dashboard" == active_page %}active{% endif %}" href="/dashboard">Dashboard</a> <a class="nav-link {% if "dashboard" == active_page %}active{% endif %}" href="/dashboard">Dashboard</a>
</li> </li>
</ul> </ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" placeholder="Username"> {% if session["username"] %}
<input class="form-control mr-sm-2" type="password" placeholder="Password"> <span>
Logged in as <i>{{ session["username"] }}</i>
{% if session["admin"] %}(Admin){% endif %}
</span>
<a href="/logout" class="btn btn-outline-warning" style="margin-left: 8px">Logout</a>
{% else %}
<form class="form-inline my-2 my-lg-0" method="POST" action="/login">
<input class="form-control mr-sm-2" placeholder="Username" name="username">
<input class="form-control mr-sm-2" type="password" placeholder="Password" name="password">
<button class="btn btn-outline-success my-2 my-sm-0">Login</button> <button class="btn btn-outline-success my-2 my-sm-0">Login</button>
</form> </form>
{% endif %}
</div> </div>
</nav> </nav>

61
templates/user.html Normal file
View File

@ -0,0 +1,61 @@
{% extends "layout.html" %}
{% set active_page = "user" %}
{% block body %}
<div class="container">
<div class="card">
<div class="card-header">Create user</div>
<div class="card-body">
<form method="POST" action="/user/add">
<div class="input-group form-group">
<div class="input-group-prepend">
<div class="input-group-text">
<label for="is_admin" style="margin: 0 8px 0 0">Set admin</label>
<input title="Set user as admin" type="checkbox" id="is_admin" name="is_admin">
</div>
</div>
<input type="text" class="form-control" placeholder="Username" name="username">
</div>
<div class="form-group">
<input type="password" class="form-control" placeholder="Password" name="password">
</div>
<button type="submit" class="btn btn-success"><i class="fas fa-plus"></i> Add User</button>
</form>
</div>
</div>
<div class="card">
<div class="card-header">Users</div>
<div class="card-body">
<table class="info-table table-hover table-striped">
<thead>
<tr>
<th>User</th>
<th>Admin</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user }}</td>
<td><i class="far {{ "fa-check-square" if users[user].admin else "fa-square" }}"></i></td>
<td><a href="/user/{{ user }}" class="btn btn-primary">Manage</a></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock body %}

View File

@ -0,0 +1,33 @@
{% extends "layout.html" %}
{% block body %}
<div class="card">
<div class="card-header">Directory permissions</div>
<div class="card-body">
<table class="info-table table-hover table-striped">
<thead>
<tr>
<th>Directory</th>
<th>Search access</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user }}</td>
<td><i class="far {{ "fa-check-square" if users[user].admin else "fa-square" }}"></i></td>
<td><a href="/user/{{ user }}" class="btn btn-primary">Manage</a></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock body %}

View File

@ -2,8 +2,6 @@ from unittest import TestCase
from storage import LocalStorage, Directory, DuplicateDirectoryException, User, DuplicateUserException, Option, Task from storage import LocalStorage, Directory, DuplicateDirectoryException, User, DuplicateUserException, Option, Task
import os import os
import os
dir_name = os.path.dirname(os.path.abspath(__file__)) dir_name = os.path.dirname(os.path.abspath(__file__))
@ -219,4 +217,20 @@ class LocalStorageTest(TestCase):
with self.assertRaises(KeyError): with self.assertRaises(KeyError):
_ = s2.tasks()[task_id] _ = s2.tasks()[task_id]
def test_set_access(self):
s = LocalStorage(dir_name + "/test_database.db")
dir_id = s.save_directory(Directory("/some/dir", True, [], "my dir"))
dir_id2 = s.save_directory(Directory("/some/dir2", True, [], "my dir2"))
dir_id3 = s.save_directory(Directory("/some/dir3", True, [], "my dir3"))
s.save_user(User("bob", b"", False))
s.set_access("bob", dir_id, True)
s.set_access("bob", dir_id2, True)
s.set_access("bob", dir_id3, True)
s.set_access("bob", dir_id3, False)
self.assertEqual(s.get_access("bob"), [dir_id, dir_id2])