Development
This commit is contained in:
parent
f5722f3c7b
commit
d60bf15ce4
15 changed files with 367 additions and 285 deletions
|
|
@ -1,13 +1,14 @@
|
|||
import copy, json, subprocess, hashlib, os, uuid
|
||||
import os as _os
|
||||
import sqlite3 as _sqlite3
|
||||
from datetime import datetime, timezone
|
||||
from flask import session
|
||||
|
||||
APP_DIR = _os.path.dirname(_os.path.abspath(__file__))
|
||||
CONFIGS_DIR = '/routlin_location'
|
||||
DATA_DIR = '/data'
|
||||
WWW_DIR = '/www'
|
||||
ACCOUNTS_FILE = f'{CONFIGS_DIR}/.dashboard-accounts'
|
||||
SESSIONS_DB = f'{CONFIGS_DIR}/.dashboard-sessions'
|
||||
ACCOUNTS_DB = f'{DATA_DIR}/.dashboard-accounts'
|
||||
CONFIG_FILE = f'{CONFIGS_DIR}/config.json'
|
||||
DASHBOARD_QUEUE = f'{CONFIGS_DIR}/.dashboard-queue'
|
||||
DASHBOARD_DONE = f'{CONFIGS_DIR}/.dashboard-done'
|
||||
|
|
@ -28,6 +29,93 @@ DASHB_INTERVAL_SECS = 30
|
|||
QUEUE_MAX_LINES = 50
|
||||
|
||||
|
||||
# Accounts DB ========================================================
|
||||
|
||||
def open_accounts_db():
|
||||
con = _sqlite3.connect(ACCOUNTS_DB, timeout=5)
|
||||
con.execute('PRAGMA journal_mode=WAL')
|
||||
con.row_factory = _sqlite3.Row
|
||||
return con
|
||||
|
||||
def init_accounts_db():
|
||||
con = open_accounts_db()
|
||||
con.executescript('''
|
||||
CREATE TABLE IF NOT EXISTS accounts (
|
||||
account_id TEXT PRIMARY KEY,
|
||||
email TEXT UNIQUE NOT NULL,
|
||||
access_level INTEGER NOT NULL DEFAULT 1,
|
||||
hashed_password TEXT NOT NULL DEFAULT '',
|
||||
created_ts INTEGER NOT NULL DEFAULT 0,
|
||||
created_by TEXT NOT NULL DEFAULT ''
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS sessions (
|
||||
session_id TEXT PRIMARY KEY,
|
||||
account_id TEXT NOT NULL,
|
||||
tz_offset_seconds INTEGER NOT NULL DEFAULT 0,
|
||||
apply_changes_immediately INTEGER NOT NULL DEFAULT 0,
|
||||
session_started_ts INTEGER NOT NULL,
|
||||
last_seen_ts INTEGER NOT NULL
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS pending_verifications (
|
||||
email TEXT PRIMARY KEY,
|
||||
hashed_password TEXT NOT NULL,
|
||||
tz_offset_seconds INTEGER NOT NULL DEFAULT 0,
|
||||
code TEXT NOT NULL,
|
||||
expires_ts INTEGER NOT NULL
|
||||
);
|
||||
''')
|
||||
con.commit()
|
||||
con.close()
|
||||
|
||||
_LEVEL_INT_TO_STR = {0: 'nothing', 1: 'viewer', 2: 'administrator', 3: 'manager'}
|
||||
_LEVEL_STR_TO_INT = {'nothing': 0, 'viewer': 1, 'administrator': 2, 'manager': 3}
|
||||
|
||||
def _account_row_to_dict(row):
|
||||
if row is None:
|
||||
return None
|
||||
import time as _t
|
||||
from datetime import datetime as _dt
|
||||
d = dict(row)
|
||||
d['email_address'] = d.pop('email', d.get('email_address', ''))
|
||||
d['access_level_int'] = d.get('access_level', 1)
|
||||
d['access_level'] = _LEVEL_INT_TO_STR.get(d['access_level_int'], 'viewer')
|
||||
d['account_status'] = 'active' if d.get('hashed_password') else 'pending'
|
||||
d['account_created_by'] = d.get('created_by', '')
|
||||
ts = d.get('created_ts', 0)
|
||||
try:
|
||||
d['account_created_ts'] = _dt.fromtimestamp(int(ts)).strftime('%Y-%m-%d %H:%M') if ts else '-'
|
||||
except Exception:
|
||||
d['account_created_ts'] = '-'
|
||||
return d
|
||||
|
||||
def get_account_by_email(email):
|
||||
try:
|
||||
con = open_accounts_db()
|
||||
row = con.execute('SELECT * FROM accounts WHERE lower(email)=?', (email.lower(),)).fetchone()
|
||||
con.close()
|
||||
return _account_row_to_dict(row)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def get_account_by_id(account_id):
|
||||
try:
|
||||
con = open_accounts_db()
|
||||
row = con.execute('SELECT * FROM accounts WHERE account_id=?', (account_id,)).fetchone()
|
||||
con.close()
|
||||
return _account_row_to_dict(row)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def list_accounts():
|
||||
try:
|
||||
con = open_accounts_db()
|
||||
rows = con.execute('SELECT * FROM accounts ORDER BY created_ts').fetchall()
|
||||
con.close()
|
||||
return [_account_row_to_dict(r) for r in rows]
|
||||
except Exception:
|
||||
return []
|
||||
|
||||
|
||||
_config_cache = None
|
||||
_config_mtime = None
|
||||
|
||||
|
|
@ -354,7 +442,6 @@ def queued_msg(cmd=None, description='', action_label='Configuration saved'):
|
|||
# Snapshot system ===================================================
|
||||
|
||||
import re as _re
|
||||
import sqlite3 as _sqlite3
|
||||
|
||||
|
||||
def _db():
|
||||
|
|
@ -845,17 +932,7 @@ def config_datasource(name):
|
|||
return rows
|
||||
|
||||
if name == 'accounts':
|
||||
try:
|
||||
with open(ACCOUNTS_FILE) as f:
|
||||
data = json.load(f)
|
||||
except Exception:
|
||||
data = {}
|
||||
rows = []
|
||||
for acct in data.get('accounts', []):
|
||||
row = dict(acct)
|
||||
row['account_status'] = 'active' if acct.get('hashed_password') else 'pending'
|
||||
rows.append(row)
|
||||
return rows
|
||||
return list_accounts()
|
||||
|
||||
if name == 'vpn_peers':
|
||||
rows = []
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue