Development
This commit is contained in:
parent
19be151c70
commit
f5722f3c7b
8 changed files with 178 additions and 90 deletions
|
|
@ -1,6 +1,6 @@
|
|||
from pathlib import Path
|
||||
from flask import Blueprint, request, session, redirect, flash
|
||||
import json, re
|
||||
import json, os, re, sqlite3
|
||||
from datetime import datetime, timezone
|
||||
import auth
|
||||
import config_utils
|
||||
|
|
@ -100,6 +100,24 @@ def accounts_edit():
|
|||
return redirect(f'/{_PAGE}')
|
||||
|
||||
|
||||
@bp.route('/action/accountmanage/session_invalidate', methods=['POST'])
|
||||
@auth.require_level('manager')
|
||||
def session_invalidate():
|
||||
sid = request.form.get('session_id', '').strip()
|
||||
if not sid:
|
||||
flash('Invalid request.', 'error')
|
||||
return redirect(f'/{_PAGE}')
|
||||
try:
|
||||
con = sqlite3.connect(config_utils.SESSIONS_DB, timeout=5)
|
||||
con.execute('DELETE FROM sessions WHERE session_id=?', (sid,))
|
||||
con.commit()
|
||||
con.close()
|
||||
flash('Session invalidated.', 'success')
|
||||
except Exception:
|
||||
flash('Failed to invalidate session.', 'error')
|
||||
return redirect(f'/{_PAGE}')
|
||||
|
||||
|
||||
@bp.route('/action/accountmanage/accounts_delete', methods=['POST'])
|
||||
@auth.require_level('manager')
|
||||
def accounts_delete():
|
||||
|
|
@ -118,7 +136,10 @@ def accounts_delete():
|
|||
|
||||
target = accounts[row_index]
|
||||
|
||||
if target.get('email_address', '').lower() == session.get('email_address', '').lower():
|
||||
target_email = target.get('email_address', '').lower()
|
||||
current_email = session.get('email_address', '').lower()
|
||||
initial_email = os.environ.get('INITIAL_MANAGER_EMAIL', '').strip().lower()
|
||||
if target_email == current_email and target_email != initial_email:
|
||||
flash('You cannot remove your own account.', 'error')
|
||||
return redirect(f'/{_PAGE}')
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import json
|
||||
import sqlite3
|
||||
import time
|
||||
from datetime import datetime, timezone
|
||||
import config_utils
|
||||
|
|
@ -14,28 +15,53 @@ def _fmt_ts(ts):
|
|||
|
||||
|
||||
def _active_sessions_table():
|
||||
rows = config_utils.get_active_sessions()
|
||||
no_data = '<p class="text-muted" style="margin:0">No active sessions.</p>'
|
||||
try:
|
||||
con = sqlite3.connect(config_utils.SESSIONS_DB, timeout=5)
|
||||
rows = con.execute(
|
||||
'SELECT session_id, email, access_level, created_at, last_seen'
|
||||
' FROM sessions ORDER BY last_seen DESC'
|
||||
).fetchall()
|
||||
con.close()
|
||||
except Exception:
|
||||
rows = []
|
||||
|
||||
if not rows:
|
||||
return no_data
|
||||
return '<p class="text-muted" style="margin:0">No active sessions.</p>'
|
||||
|
||||
now = int(time.time())
|
||||
trs = ''
|
||||
for email, access_level, logged_in_at, last_seen in rows:
|
||||
ago = config_utils.relative_time(int(last_seen), now)
|
||||
for sid, email, access_level, created_at, last_seen in rows:
|
||||
online = (now - int(last_seen)) < 300
|
||||
badge = (
|
||||
'<span class="badge badge-enabled">Online</span>'
|
||||
if online else
|
||||
'<span class="badge badge-disabled">Offline</span>'
|
||||
)
|
||||
btn = (
|
||||
f'<form method="post" action="/action/accountmanage/session_invalidate"'
|
||||
f' style="display:inline;margin:0">'
|
||||
f'<input type="hidden" name="session_id" value="{factory.e(sid)}">'
|
||||
f'<button type="submit" class="btn btn-danger btn-sm">Invalidate</button>'
|
||||
f'</form>'
|
||||
)
|
||||
trs += (
|
||||
f'<tr>'
|
||||
f'<td class="table-cell">{factory.e(email)}</td>'
|
||||
f'<td class="table-cell">{factory.e(access_level)}</td>'
|
||||
f'<td class="table-cell">{_fmt_ts(logged_in_at)}</td>'
|
||||
f'<td class="table-cell">{factory.e(ago)} ago</td>'
|
||||
f'<td class="table-cell">{badge}</td>'
|
||||
f'<td class="table-cell">{_fmt_ts(created_at)}</td>'
|
||||
f'<td class="table-cell">{_fmt_ts(last_seen)}</td>'
|
||||
f'<td class="table-cell">{btn}</td>'
|
||||
f'</tr>'
|
||||
)
|
||||
return (
|
||||
'<table class="data-table"><thead><tr>'
|
||||
'<th class="table-header">Email</th>'
|
||||
'<th class="table-header">Access Level</th>'
|
||||
'<th class="table-header">Status</th>'
|
||||
'<th class="table-header">Logged In</th>'
|
||||
'<th class="table-header">Last Seen</th>'
|
||||
'<th class="table-header"></th>'
|
||||
'</tr></thead><tbody>' + trs + '</tbody></table>'
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue