diff --git a/buckler.py b/buckler.py index 342abd3..0f58f8b 100644 --- a/buckler.py +++ b/buckler.py @@ -6,6 +6,7 @@ import json import secrets import functools from datetime import datetime +from collections import defaultdict from aiohttp import web import jinja2 @@ -37,14 +38,17 @@ def auth_required(func): if not sid or not user_id: raise web.HTTPFound(location=login_url) async with request.app['pool'].acquire() as conn: - sessions = await conn.fetch( - "SELECT * FROM user_session " - "WHERE user_id = $1 AND expires > NOW()", - user_id) - session = [s for s in sessions if s.get('id') == sid] + session = await conn.fetchrow( + "SELECT user_info.id, user_info.username, user_info.admin, " + "user_session.last_used " + "FROM user_info LEFT JOIN user_session " + "ON (user_info.id = user_session.user_id) " + "WHERE user_info.id = $1 AND user_session.id = $2 " + "AND user_session.expires > NOW()", + user_id, sid) if session: + request['session'] = dict(session) resp = await func(request, *args, **kwargs) - session = session[0] tz = session['last_used'].tzinfo delta = datetime.now(tz) - session['last_used'] if delta.seconds > 600: @@ -76,6 +80,27 @@ def auth_required(func): @auth_required async def index(request): """The index page.""" + async with request.app['pool'].acquire() as conn: + avail_sites = await conn.fetch( + "SELECT app_info.name, app_info.url " + "FROM app_info LEFT JOIN app_user " + "ON (app_info.id = app_user.app_id) " + "WHERE app_user.user_id = $1", + request['session']['id']) + if request['session']['admin']: + apps = await conn.fetch( + "SELECT name FROM app_info") + user_perms = await conn.fetch( + "SELECT user_info.id, user_info.username, app_user.app_id " + "FROM user_info LEFT JOIN app_user " + "ON (user_info.id = app_user.user_id)") + + if request['session']['admin']: + apps = [app['name'] for app in apps] + users = defaultdict(lambda: [False]*len(apps)) + for user_perm in user_perms: + users[user_perm['username']][user_perm['app_id']-1] = True + users_json = json.dumps(users) return render_template("index.html", request, locals()) @@ -101,8 +126,11 @@ async def login(request): return render_template("login.html", request, locals()) if argon2.verify(password, user_info['password_hash']): - index_url = request.app.router['index'].url_for() - resp = web.HTTPFound(location=index_url) + url = request.cookies.get('redirect') + if not url: + url = request.app.router['index'].url_for() + resp = web.HTTPFound(location=url) + resp.set_cookie('redirect', '', max_age=0) resp.set_cookie( 'userid', user_info['id'], @@ -240,7 +268,6 @@ async def get_session(request): 'meta': data_meta, 'session_data': json.loads(data_meta.pop('session_data'))} - print(data) return web.json_response(data) else: error = {'error': "User ID or Session ID invalid."} diff --git a/static/buckler.css b/static/buckler.css new file mode 100644 index 0000000..d28b286 --- /dev/null +++ b/static/buckler.css @@ -0,0 +1,46 @@ +body { + margin-left: 10%; + margin-right: 10%; + background-color: lightgray; + font-family: Helvetica,sans-serif; +} + +header { + margin-bottom: 3em; + display: flex; +} + +#logo { + height: 5em; + margin-right: 1em; +} + +main { + display: grid; + gap: 2em; + background-color: whitesmoke; + padding: 5%; + border-radius: 0.5em; + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), + 0 3px 1px -2px rgba(0, 0, 0, 0.2), + 0 1px 5px 0 rgba(0, 0, 0, 0.12); +} + +#avail_sites { + margin: 0; + padding-left: 1em; + list-style-type: none; +} + +#users { + border: 1px solid lightgray; + border-collapse: collapse; +} + +#users tr { + border: 1px solid lightgray; +} + +#users td { + text-align: center; +} diff --git a/static/buckler.js b/static/buckler.js new file mode 100644 index 0000000..dbbe081 --- /dev/null +++ b/static/buckler.js @@ -0,0 +1,20 @@ +function perm_change(row) { + let user_perms = users_perms[row.children[0].textContent]; + let row_perms = []; + for (let child of row.children) { + if (child.firstChild.type == "checkbox") { + if (child.firstChild.checked) { + row_perms.push(true); + } else { + row_perms.push(false); + } + } + } + let perms_changed = false; + for (let i = 0; i < user_perms.length; i++) { + if (user_perms[i] != row_perms[i]) { + perms_changed = true; + } + } + console.log("perms_changed = " + perms_changed); +} diff --git a/static/buckler_icon.svg b/static/buckler_icon.svg new file mode 100644 index 0000000..ce8889d --- /dev/null +++ b/static/buckler_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/templates/index.html b/templates/index.html index 2a4f6b0..d26fd90 100644 --- a/templates/index.html +++ b/templates/index.html @@ -2,9 +2,49 @@ Buckler + + + -

Buckler

- Secret page. +
+ +

Buckler

+
+
+
+ Available sites + +
+ {% if request['session']['admin'] %} + + + + + {% for app in apps %} + + {% endfor %} + + + + {% for username, values in users.items() %} + + + {% for value in values %} + + {% endfor %} + + + {% endfor %} + +
User{{ app }}
{{ username }}
+ {% endif %} +
diff --git a/templates/login.html b/templates/login.html index 98ca177..6abd2fa 100644 --- a/templates/login.html +++ b/templates/login.html @@ -4,16 +4,20 @@ Buckler - Login -

Buckler Login

-
- -
- -
- {% if login_failed %} - - {% endif %} - -
+
+

Buckler Login

+
+
+
+ +
+ +
+ {% if login_failed %} + + {% endif %} + +
+