Compare commits

...

3 Commits

Author SHA1 Message Date
0f8f691a3e admin panel 2019-09-27 13:57:00 -04:00
8daf81ac46 implemented /change_password 2019-09-27 13:53:36 -04:00
74cd0713ec sort sessions by last_used 2019-09-26 19:26:29 -04:00
4 changed files with 98 additions and 34 deletions

View File

@ -45,7 +45,7 @@ async def index(request):
request['session']['id'])
active_sessions = await conn.fetch(
"SELECT id, ip_address, date_created, last_used FROM user_session "
"WHERE user_id = $1",
"WHERE user_id = $1 ORDER BY last_used DESC",
request['session']['id'])
if request['session']['admin']:
@ -58,11 +58,33 @@ async def index(request):
return render_template("index.html", request, locals())
@routes.get(config.url_prefix + '/change_password', name='change_password')
@routes.post(config.url_prefix + '/change_password', name='change_password')
@auth.auth_required
async def change_password(request):
"""Allows a user to change their password."""
pass
data = await request.post()
current_pw = data.get('current_password')
new_pw = data.get('new_password')
verify_pw = data.get('verify_password')
if not all(current_pw, new_pw, verify_pw):
return
if not new_pw == verify_pw:
return
async with request.app['pool'].acquire() as conn:
pw_hash = conn.fetchrow(
"SELECT password_hash FROM user_info WHERE id = $1",
request['session']['id'])
if not argon2.verify(current_pw, pw_hash['password_hash']):
return
h = argon2.hash(new_pw)
conn.execute(
"UPDATE user_info SET password_hash = $1 WHERE id = $2",
h, request['session']['id'])
index_url = request.app.router['index'].url_for()
raise web.HTTPFound(location=index_url)
@routes.get(config.url_prefix + '/login', name='login')

View File

@ -3,6 +3,7 @@ body {
margin-right: 10%;
background-color: lightgray;
font-family: Helvetica,sans-serif;
font-size: 14px;
}
header {
@ -29,12 +30,21 @@ main section {
0 1px 5px 0 rgba(0, 0, 0, 0.12);
}
h2 {
.sub_section {
box-shadow: none;
border: 1px solid lightgray;
}
h2, h3 {
font-size: 16px;
margin: 0;
cursor: pointer;
}
h3 {
font-size: 14px;
}
#avail_sites {
margin: 0;
padding-left: 1em;
@ -54,3 +64,17 @@ tr {
td {
text-align: center;
}
#change_password {
border: none;
border-collapse: separate;
width: auto;
}
#change_password tr {
border: none;
}
#change_password td {
text-align: left;
}

View File

@ -1,5 +1,10 @@
function load() {
let headers = document.querySelectorAll('h2');
headers = Array.prototype.slice.call(headers);
let headers3 = document.querySelectorAll('h3');
headers3 = Array.prototype.slice.call(headers3);
headers = headers.concat(headers3);
headers.forEach(function(header) {
header.addEventListener('click', function() {
let article = this.nextElementSibling;

View File

@ -30,31 +30,36 @@
</section>
{% if request['session']['admin'] %}
<section>
<h2>User Permissions</h2>
<h2>Admin Panel</h2>
<article style="display: none;">
<hr>
<table id="users">
<thead>
<tr>
<th>User</th>
{% for app in apps %}
<th>{{ app['name'] }}</th>
{% endfor %}
<th></th>
</tr>
</thead>
<tbody>
{% for username, values in users.items() %}
<tr>
<td>{{ username }}</td>
{% for name, value in values.items() %}
<td><input aria-label="{{ username }}-{{ name }}" data-app-name={{ name }} type="checkbox" onchange="perm_change(this.parentElement.parentElement)"{% if value %} checked{% endif %}></td>
{% endfor %}
<td><input type="submit"></td>
</tr>
{% endfor %}
</tbody>
</table>
<section class="sub_section">
<h3>User Permissions</h3>
<article style="display: none;">
<hr>
<table id="users">
<thead>
<tr>
<th>User</th>
{% for app in apps %}
<th>{{ app['name'] }}</th>
{% endfor %}
<th></th>
</tr>
</thead>
<tbody>
{% for username, values in users.items() %}
<tr>
<td>{{ username }}</td>
{% for name, value in values.items() %}
<td><input aria-label="{{ username }}-{{ name }}" data-app-name={{ name }} type="checkbox" onchange="perm_change(this.parentElement.parentElement)"{% if value %} checked{% endif %}></td>
{% endfor %}
<td><input type="submit"></td>
</tr>
{% endfor %}
</tbody>
</table>
</article>
</section>
</article>
</section>
{% endif %}
@ -63,12 +68,20 @@
<article style="display: none;">
<hr>
<form action="{{ request.app.router['change_password'].url_for() }}" method="post" enctype="application/x-www-form-urlencoded">
<label for="current_password">Current password</label>
<input id="current_password" name="current_password" type="password"><br>
<label for="new_password">New password</label>
<input id="new_password" name="new_password" type="password"><br>
<label for="verify_password">Verify password</label>
<input id="verify_password" name="verify_password" type="password"><br>
<table id="change_password">
<tr>
<td><label for="current_password">Current password</label></td>
<td><input id="current_password" name="current_password" type="password"></td>
</tr>
<tr>
<td><label for="new_password">New password</label></td>
<td><input id="new_password" name="new_password" type="password"></td>
</tr>
<tr>
<td><label for="verify_password">Verify password</label></td>
<td><input id="verify_password" name="verify_password" type="password"></td>
</tr>
</table>
<input type="submit" value="Submit">
</form>
</article>