linuxrouter/docker/routlin-dash/app/pages/clientcredentials/view.py
2026-06-08 00:28:33 -04:00

111 lines
4.1 KiB
Python

import json
import sqlite3
import time
import config_utils
import factory
import settings
PRO_LICENSE = settings.is_pro()
USER_TYPE_LABELS = {0: 'Captive Portal', 1: '802.1X'}
def _load_credentials():
try:
conn = sqlite3.connect(config_utils.CREDENTIALS_DB)
conn.row_factory = sqlite3.Row
conn.execute("""
CREATE TABLE IF NOT EXISTS credentials (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL UNIQUE COLLATE NOCASE,
password TEXT NOT NULL,
description TEXT NOT NULL DEFAULT '',
user_type INTEGER NOT NULL,
digest_type INTEGER NOT NULL,
vlan TEXT NOT NULL DEFAULT '',
enabled INTEGER NOT NULL DEFAULT 1,
date_set INTEGER NOT NULL,
session_seconds INTEGER NOT NULL DEFAULT 0,
expires_seconds INTEGER NOT NULL DEFAULT 0
)
""")
conn.execute("""
CREATE TABLE IF NOT EXISTS sessions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
ip TEXT NOT NULL,
credential_id INTEGER REFERENCES credentials(id) ON DELETE CASCADE,
started_at INTEGER NOT NULL,
expires_at INTEGER,
mac TEXT NOT NULL DEFAULT ''
)
""")
conn.commit()
rows = conn.execute("SELECT * FROM credentials ORDER BY id").fetchall()
conn.close()
return rows
except Exception:
return []
def _format_session(session_seconds):
if not session_seconds:
return 'No limit'
if session_seconds % 86400 == 0:
n = session_seconds // 86400
return f"{n} day{'s' if n != 1 else ''}"
hours = session_seconds / 3600
return f"{hours:g} h"
def collect_tokens(cfg):
tokens = config_utils.collect_layout_tokens(cfg)
tokens['PRO_NOTE'] = (
'' if PRO_LICENSE else
'<div class="info-bar info-bar-info">'
'<span>Client Credentials is a Routlin Pro feature. '
'Credentials can be viewed but not added or edited without a Pro license.</span></div>'
)
tokens['ADD_CREDENTIAL_DISABLED'] = 'true'
tokens['RADIUS_DEFAULT_SESSION_SECONDS_JS'] = str(
cfg.get('radius', {}).get('options', {}).get('default_session_seconds', 0) or 0
)
vlans = [v for v in cfg.get('vlans', []) if not v.get('is_vpn')]
tokens['VLAN_OPTIONS'] = json.dumps(
[{'value': '', 'label': '-- Select VLAN --'}] +
[{'value': v['name'], 'label': f"{v['name']} (VLAN {v['vlan_id']})"} for v in vlans]
)
captive_vlans = [v for v in cfg.get('vlans', []) if v.get('restricted_vlan') == 'c']
tokens['CAPTIVE_VLAN_OPTIONS'] = json.dumps(
[{'value': '', 'label': '-- Select VLAN --'}] +
[
{
'value': v['name'],
'label': f"{v['name']} (VLAN {v['vlan_id']})",
'require_upw': v.get('captive_portal', {}).get('require_username_password',
v.get('require_username_password', False)),
'default_session_seconds': v.get('captive_portal', {}).get('default_session_seconds',
v.get('default_session_seconds', 0)),
}
for v in captive_vlans
]
)
raw_rows = _load_credentials()
display_rows = []
for row in raw_rows:
r = dict(row)
r.pop('password', None)
r['user_type_label'] = USER_TYPE_LABELS.get(r.get('user_type'), str(r.get('user_type', '')))
r['expires_label'] = _format_session(r.get('session_seconds', 0))
display_rows.append(r)
content = factory.load_json(f'{factory.PAGES_DIR}/clientcredentials/content.json')
for table_item in factory.iter_table_items(content.get('items', [])):
ds = table_item.get('datasource', '')
data = display_rows if ds == 'sqlite:client_credentials' else []
tokens[factory.table_token_key(ds)] = factory.build_table(table_item, tokens, data)
return tokens