Skip to content

Sbussiso/OpenSentry-Command

Repository files navigation

OpenSentry Command

A lightweight, modern web UI for discovering and managing OpenSentry devices on your network. It supports mDNS discovery, optional device status verification, and OAuth2/OIDC login with an automatic local-login fallback if the identity provider is unavailable.

Features

  • Discovery via mDNS using service _opensentry._tcp.local.
  • Optional /status fetch per device (with Bearer token)
  • OAuth2/OIDC login (Authorization Code + PKCE) with confidential/public clients
  • One-time local-login fallback if the OAuth2 server is down
  • Device list management and basic test tools (health, stream, reachability)
  • Simple REST API powering the UI

Requirements

  • Python 3.12+
  • uv for zero-config runs

Documentation

Quickstart

  • Start the UI (deps auto-installed on first run):
uv run main.py

The app binds to port 5000 or the nearest open port above it (printed on startup). Visit the printed URL, e.g. http://127.0.0.1:5000.

  • Environment overrides:
    • PORT: Force a specific port.
    • HOST: Bind host (default 0.0.0.0).
    • SECRET_KEY: Flask session secret (defaults to a dev value; set in production).

Authentication Modes

Open the Settings page (/settings) and select:

  • local: Built-in username/password login (admin / admin) for development.
  • oauth2: External provider using OIDC discovery.

Settings are persisted to config_store.json at the repository root. You can also edit this file directly. Relevant fields:

{
  "auth_mode": "local" | "oauth2",
  "oauth2_base_url": "http://127.0.0.1:8000",
  "oauth2_client_id": "<your-client-id>",
  "oauth2_client_secret": "<optional-secret>",
  "oauth2_scope": "openid profile email offline_access"
}

OAuth2/OIDC Setup

When using auth_mode=oauth2, configure your provider:

  • Discovery: Provide oauth2_base_url (issuer base). The app fetches /.well-known/openid-configuration.
  • Redirect URI: Add http://127.0.0.1:5000/oauth2/callback to the client’s allowed list. If you access the UI via another host (e.g. http://10.0.0.246:5000), add that callback too.
  • Client type:
    • Public: set token auth to none. The app uses PKCE (S256) automatically.
    • Confidential: set token auth to client_secret_post and populate oauth2_client_secret in Settings.
  • Scopes: Ensure your client policy allows the scopes you request (default openid profile email offline_access).

If the provider is temporarily unavailable, the app shows a dedicated page and offers a one-time local-login fallback. This fallback is session-scoped and does not modify persisted settings.

Discovery and Status

  • Service type: _opensentry._tcp.local. with TXT keys like id, name, ver, caps, auth, api, path, proto.
  • Ensure devices advertise via mDNS (e.g., OPENSENTRY_MDNS_DISABLE=0) and multicast is allowed by your network/firewall.
  • In the UI:
    • Provide a Bearer token if your devices protect /status.
    • Toggle “Include /status” to fetch detailed capabilities.
    • Adjust discovery timeout if your network is slow.

CLI: discover.py

You can run the discovery CLI directly:

uv run discover.py --timeout 3.0 --status --token <TOKEN>

Key flags:

  • --timeout seconds (default 3.0)
  • --service mDNS type (default _opensentry._tcp.local.)
  • --json JSON output only
  • --status fetch /status for each device
  • --token Bearer token for /status

REST API Overview

  • GET /api/discover?timeout=3.0&status=1&token=...
    • Returns discovered devices with optional status.
  • GET /api/devices · POST /api/devices · PATCH /api/devices · DELETE /api/devices
    • Manage the pinned device list used by the UI.
  • GET /api/status?ip=<ip>&port=<port>&token=<bearer>&timeout=1.5
    • Proxy /status with optional Bearer token.
  • GET /api/device_status?ip=<ip>&port=<port>&token=<bearer>
    • Returns raw device /status or 502 on failure.
  • GET /stream_proxy?ip=<ip>&port=<port>&path=/video_feed&token=<bearer>
    • Minimal streaming proxy for testing.
  • Test helpers: GET /api/test/tcp, GET /api/test/health, GET /api/test/stream, GET /api/test/run_all
  • Settings: GET /api/settings, POST /api/settings
  • OAuth utility: GET /api/oauth2/test?base_url=...

Troubleshooting

  • Nothing shows up in discovery

    • Increase timeout (e.g., 6.0s).
    • Verify mDNS and multicast on your network.
    • Test device directly:
      curl -sS http://<ip>:<port>/health
      curl -sS -H "Authorization: Bearer $OPENSENTRY_API_TOKEN" http://<ip>:<port>/status
  • OAuth2 shows “Invalid OAuth2 callback”

    • Ensure the callback URI in your provider exactly matches how you access the app (host/port).
    • This app signs the state value (HMAC) and also stores it in session; either form will validate. If the provider still fails, check app logs for: OAuth2 callback invalid: ... and adjust host/port or redirect URIs.
  • Provider down / maintenance

    • The app displays an “OAuth2 Unavailable” page and offers to “Use local login for now”. This is session-only and does not change saved settings.

Development Notes

  • Project metadata in pyproject.toml (Python 3.12+, deps: Flask, requests, zeroconf).
  • App entrypoint: main.py (Flask).
  • Templates in templates/.
  • Discovery helpers: discover.py (mDNS), probe.py (reachability, health, status tests).
  • Persistent stores: config_store.json (settings), devices_store.json (devices) — created on first write.

Security

  • This is a development-focused tool. Do not expose it to the internet as-is.
  • Set a strong SECRET_KEY in production, serve via HTTPS, and set SESSION_COOKIE_SECURE=True.

License

MIT

About

A lightweight, modern web UI for discovering and managing OpenSentry devices on your network.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors