linuxrouter/docker/routlin-dash/app/pages/accountmanage/view.py

97 lines
3.6 KiB
Python
Raw Normal View History

2026-06-02 00:47:03 -04:00
import json
2026-06-10 13:16:28 -04:00
import sqlite3
2026-06-10 10:06:13 -04:00
import time
2026-06-10 14:23:47 -04:00
from datetime import datetime
2026-06-07 00:21:08 -04:00
import config_utils
import factory
2026-06-02 00:47:03 -04:00
2026-06-10 14:23:47 -04:00
def _fmt_ts(ts, now):
2026-06-10 10:06:13 -04:00
try:
2026-06-10 14:23:47 -04:00
dt = datetime.fromtimestamp(int(ts))
ago = config_utils.relative_time(int(ts), now)
return f'{dt.strftime("%Y-%m-%d %H:%M")} ({ago} ago)'
2026-06-10 10:06:13 -04:00
except Exception:
return '-'
2026-06-10 14:23:47 -04:00
_LEVEL_INT_TO_STR = {0: 'nothing', 1: 'viewer', 2: 'administrator', 3: 'manager'}
2026-06-10 10:06:13 -04:00
def _active_sessions_table():
2026-06-10 13:16:28 -04:00
try:
2026-06-10 14:23:47 -04:00
con = sqlite3.connect(config_utils.ACCOUNTS_DB, timeout=5)
con.row_factory = sqlite3.Row
2026-06-10 13:16:28 -04:00
rows = con.execute(
2026-06-10 14:23:47 -04:00
'''SELECT s.session_id, a.email, a.access_level,
s.session_started_ts, s.last_seen_ts
FROM sessions s
JOIN accounts a ON a.account_id = s.account_id
ORDER BY s.last_seen_ts DESC'''
2026-06-10 13:16:28 -04:00
).fetchall()
con.close()
except Exception:
rows = []
2026-06-10 10:06:13 -04:00
if not rows:
2026-06-10 13:16:28 -04:00
return '<p class="text-muted" style="margin:0">No active sessions.</p>'
2026-06-10 10:06:13 -04:00
now = int(time.time())
trs = ''
2026-06-10 14:23:47 -04:00
for row in rows:
sid = row['session_id']
email = row['email']
access_level = _LEVEL_INT_TO_STR.get(row['access_level'], 'viewer')
started_ts = row['session_started_ts']
last_seen = row['last_seen_ts']
online = (now - int(last_seen)) < 300
ago = config_utils.relative_time(int(last_seen), now)
tip = factory.e(f'Last seen {ago} ago')
badge_cls = 'badge-enabled' if online else 'badge-disabled'
badge_lbl = 'Online' if online else 'Offline'
badge = (
f'<span class="tooltip-wrap" data-tooltip="{tip}">'
f'<span class="badge {badge_cls}">{badge_lbl}</span>'
f'</span>'
2026-06-10 13:16:28 -04:00
)
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>'
)
2026-06-10 10:06:13 -04:00
trs += (
f'<tr>'
f'<td class="table-cell">{factory.e(email)}</td>'
f'<td class="table-cell">{factory.e(access_level)}</td>'
2026-06-10 13:16:28 -04:00
f'<td class="table-cell">{badge}</td>'
2026-06-10 14:23:47 -04:00
f'<td class="table-cell">{_fmt_ts(started_ts, now)}</td>'
2026-06-10 13:16:28 -04:00
f'<td class="table-cell">{btn}</td>'
2026-06-10 10:06:13 -04:00
f'</tr>'
)
return (
'<table class="data-table"><thead><tr>'
'<th class="table-header">Email</th>'
'<th class="table-header">Access Level</th>'
2026-06-10 13:16:28 -04:00
'<th class="table-header">Status</th>'
2026-06-10 10:06:13 -04:00
'<th class="table-header">Logged In</th>'
2026-06-10 13:16:28 -04:00
'<th class="table-header"></th>'
2026-06-10 10:06:13 -04:00
'</tr></thead><tbody>' + trs + '</tbody></table>'
)
2026-06-02 00:47:03 -04:00
def collect_tokens(cfg):
2026-06-07 00:21:08 -04:00
tokens = config_utils.collect_layout_tokens(cfg)
2026-06-02 12:49:39 -04:00
tokens['ACCOUNT_LEVEL_OPTIONS'] = json.dumps([
{'value': 'viewer', 'label': 'Viewer (read-only access to live data)'},
{'value': 'administrator', 'label': 'Administrator (can modify configuration)'},
{'value': 'manager', 'label': 'Manager (full access including account management)'},
])
2026-06-10 10:06:13 -04:00
tokens['ACTIVE_SESSIONS_TABLE'] = _active_sessions_table()
2026-06-07 00:21:08 -04:00
content = factory.load_json(f'{factory.PAGES_DIR}/accountmanage/content.json')
for table_item in factory.iter_table_items(content.get('items', [])):
2026-06-02 12:49:39 -04:00
ds = table_item.get('datasource', '')
2026-06-07 00:21:08 -04:00
tokens[factory.table_token_key(ds)] = factory.build_table(table_item, tokens, config_utils.load_datasource(ds))
2026-06-02 12:49:39 -04:00
return tokens