diff --git a/README_DASHBOARD.md b/README_DASHBOARD.md index c4295d2..48b8e88 100644 --- a/README_DASHBOARD.md +++ b/README_DASHBOARD.md @@ -35,22 +35,23 @@ Web dashboard to view and edit the `portal_auth` database. **Only users with rol ## Deployment to Auth LXC (10.110.60.210) -From your machine (with SSH access to the server): +The LXC has no direct access to Git. Deploy by **uploading the project from your PC** via SSH/rsync. + +From your PC (with SSH and rsync): ```bash ./deploy/deploy.sh ``` +Or explicitly from the project dir: + +```bash +./deploy/deploy-from-pc.sh +``` + This will: -- **First time:** Clone the repo from Git to `/opt/portal-auth-dashboard` on `root@10.110.60.210`, create venv, install dependencies, create `.env` from `deploy/.env.server` if missing, install and start the systemd unit. -- **Later runs:** Pull latest from `origin/main`, reinstall dependencies, restart the service. - -If the Git server is not reachable from the deploy target (e.g. private repo), set `GIT_REPO_URL` with credentials before running: - -```bash -export GIT_REPO_URL="http://nearxos:YOUR_TOKEN@10.20.30.250:3000/nearxos/portal-auth-dashboard.git" -./deploy/deploy.sh -``` +- **Rsync** the project to `root@10.110.60.210:/opt/portal-auth-dashboard` (excluding `.env`, `.git`, `venv`). +- **On the server:** create/update venv, install dependencies, create `.env` from `deploy/.env.server` if missing, install and restart the systemd unit. **After first deploy**, on the server set the real credentials: diff --git a/app.py b/app.py index c5cdaba..7407745 100644 --- a/app.py +++ b/app.py @@ -1,4 +1,6 @@ from flask import Flask, render_template, request, redirect, url_for, session, flash +import traceback +import sys import config from auth_helpers import verify_admin from db import get_cursor @@ -7,6 +9,20 @@ app = Flask(__name__) app.secret_key = config.SECRET_KEY +@app.errorhandler(500) +def handle_500(e): + tb = traceback.format_exc() + print(tb, file=sys.stderr, flush=True) + # Show traceback in response for debugging (remove in production if desired) + escaped = tb.replace("<", "<").replace(">", ">") + return ( + "
The error has been logged. Details below (also in journalctl -u portal-auth-dashboard):
" + "" + escaped + "", + 500, + ) + + def login_required(f): from functools import wraps @wraps(f) @@ -68,12 +84,12 @@ def table_view(name): with get_cursor() as cur: cur.execute(f'SELECT * FROM "{name}" ORDER BY 1 DESC LIMIT 500') rows = cur.fetchall() - # Convert dict rows to list of dicts with string values for display; keep raw row for actions (e.g. session_id, id) + # Convert to plain dicts so Jinja and serialization don't hit RealDictRow issues data = [] + raw_rows = [] for r in rows: data.append({k: (str(v) if v is not None else "") for k, v in r.items()}) - # Keep original rows for action URLs (session_id, id) so we don't rely on truncated display - raw_rows = rows + raw_rows.append(dict(r)) columns = list(rows[0].keys()) if rows else TABLE_COLUMNS.get(name, []) return render_template("table.html", table_name=name, rows=data, raw_rows=raw_rows, columns=columns) diff --git a/deploy/deploy-from-pc.sh b/deploy/deploy-from-pc.sh new file mode 100755 index 0000000..0197012 --- /dev/null +++ b/deploy/deploy-from-pc.sh @@ -0,0 +1,8 @@ +#!/bin/bash +# Deploy from this PC via SSH: upload project with rsync, then setup/restart on server. +# Usage: ./deploy/deploy-from-pc.sh +# Requires: rsync, SSH access to root@10.110.60.210 (LXC has no Git access). +set -e +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$(dirname "$SCRIPT_DIR")" +exec "$SCRIPT_DIR/deploy.sh" diff --git a/deploy/deploy.sh b/deploy/deploy.sh index 3d3954f..f63bcf2 100755 --- a/deploy/deploy.sh +++ b/deploy/deploy.sh @@ -1,44 +1,47 @@ #!/bin/bash -# Deploy Portal Auth Dashboard to root@10.110.60.210 from Git -# Repo: http://10.20.30.250:3000/nearxos/portal-auth-dashboard +# Deploy Portal Auth Dashboard to root@10.110.60.210 by uploading from this PC via SSH/rsync. +# LXC has no direct access to Git; run this script from your PC. set -e TARGET="root@10.110.60.210" APP_DIR="/opt/portal-auth-dashboard" -# Set GIT_REPO_URL with credentials if clone/pull needs auth, e.g.: -# export GIT_REPO_URL="http://nearxos:YOUR_TOKEN@10.20.30.250:3000/nearxos/portal-auth-dashboard.git" -GIT_REPO_URL="${GIT_REPO_URL:-http://10.20.30.250:3000/nearxos/portal-auth-dashboard.git}" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_DIR="$(dirname "$SCRIPT_DIR")" -echo "=== Deploying from Git: ${GIT_REPO_URL%%@*}@... ===" - -# Escape single quotes for use inside single-quoted ssh string -GIT_REPO_URL_SAFE=$(echo "$GIT_REPO_URL" | sed "s/'/'\\\\''/g") +echo "=== Uploading project to $TARGET via rsync ===" +ssh "$TARGET" "mkdir -p $APP_DIR; command -v rsync >/dev/null 2>&1 || (apt-get update -qq && apt-get install -y rsync)" +rsync -av \ + --exclude '.env' \ + --exclude '.git' \ + --exclude '__pycache__' \ + --exclude '*.pyc' \ + --exclude 'venv' \ + "$PROJECT_DIR/" \ + "$TARGET:$APP_DIR/" +echo "=== Setting up on server ===" ssh "$TARGET" "set -e APP_DIR='$APP_DIR' - GIT_REPO_URL='$GIT_REPO_URL_SAFE' - - if [ ! -d \"\$APP_DIR\" ]; then - echo '=== First-time clone ===' - git clone \"\$GIT_REPO_URL\" \"\$APP_DIR\" - cd \"\$APP_DIR\" + cd \"\$APP_DIR\" + if [ ! -d venv ] || [ ! -f venv/bin/pip ]; then + echo 'Creating venv and installing dependencies...' + rm -rf venv + apt-get update -qq + command -v python3 >/dev/null 2>&1 || apt-get install -y python3 + apt-get install -y python3-venv python3-pip python3 -m venv venv ./venv/bin/pip install -r requirements.txt - if [ ! -f .env ]; then - [ -f deploy/.env.server ] && cp deploy/.env.server .env || true - grep -q 'REPLACE_WITH' .env 2>/dev/null && echo 'Edit .env on server: DB_AUTH_PASSWORD and SECRET_KEY' || true - fi - cp deploy/portal-auth-dashboard.service /etc/systemd/system/ - systemctl daemon-reload - systemctl enable portal-auth-dashboard - systemctl restart portal-auth-dashboard else - echo '=== Updating from Git ===' - cd \"\$APP_DIR\" - git fetch origin - git reset --hard origin/main + echo 'Updating dependencies...' ./venv/bin/pip install -q -r requirements.txt - systemctl restart portal-auth-dashboard fi + if [ ! -f .env ]; then + [ -f deploy/.env.server ] && cp deploy/.env.server .env || true + grep -q 'REPLACE_WITH' .env 2>/dev/null && echo 'Edit .env on server: DB_AUTH_PASSWORD and SECRET_KEY' || true + fi + cp deploy/portal-auth-dashboard.service /etc/systemd/system/ + systemctl daemon-reload + systemctl enable portal-auth-dashboard + systemctl restart portal-auth-dashboard echo '=== Status ===' systemctl status portal-auth-dashboard --no-pager" diff --git a/templates/base.html b/templates/base.html index 618fd55..33ffa71 100644 --- a/templates/base.html +++ b/templates/base.html @@ -22,7 +22,7 @@ Sessions Auth logs API tokens - {{ session.admin_username }} + {{ session.get('admin_username', '') }} Log out {% endif %}