Metadata-Version: 2.3
Name: remote-desktop-dashboard
Version: 2.10.2
Summary: Remote Desktop Dashboard — monitor machines and connect via Microsoft Windows App
Project-URL: Homepage, https://github.com/your-org/remote-desktop-dashboard
Project-URL: Documentation, https://github.com/your-org/remote-desktop-dashboard#readme
Project-URL: Repository, https://github.com/your-org/remote-desktop-dashboard
Author: Operations
License: MIT
Keywords: dashboard,fastapi,monitoring,rdp,remote-desktop,windows
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Web Environment
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: System Administrators
Classifier: Operating System :: Microsoft :: Windows
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: System :: Monitoring
Requires-Python: >=3.10
Requires-Dist: alembic>=1.14.0
Requires-Dist: cryptography>=43.0.0
Requires-Dist: fastapi>=0.115.0
Requires-Dist: httpx>=0.28.0
Requires-Dist: psutil>=6.1.0
Requires-Dist: pydantic-settings>=2.6.0
Requires-Dist: pydantic>=2.10.0
Requires-Dist: python-multipart>=0.0.17
Requires-Dist: pywin32>=308; sys_platform == 'win32'
Requires-Dist: sqlalchemy>=2.0.36
Requires-Dist: uvicorn[standard]>=0.32.0
Requires-Dist: wmi>=1.5.1; sys_platform == 'win32'
Provides-Extra: dev
Requires-Dist: httpx>=0.28.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
Requires-Dist: pytest>=8.3.0; extra == 'dev'
Provides-Extra: postgres
Requires-Dist: psycopg2-binary>=2.9.10; extra == 'postgres'
Description-Content-Type: text/markdown

# Remote Desktop Dashboard

A LAN-only, browser-based dashboard for monitoring and connecting to a fleet
of Windows benches over RDP. Operators see who is using each machine, reserve
one with a single click, and the dashboard launches Microsoft Windows App (or
mstsc) for them. A small PowerShell agent on each bench locally enforces who
is allowed to RDP — including blocking local administrators bypassing the
"Remote Desktop Users" group, via per-IP firewall rules.

---

## Quick start (server-side, one machine on the LAN)

```powershell
pip install remote-desktop-dashboard
remote-desktop-dashboard
```

Then open `http://localhost:8080/` in a browser on the same machine.

Default port is 8080. The first time you start it, it writes
`%LOCALAPPDATA%\RemoteDesktopDashboard\admin.env` with sensible defaults.

---

## How users on OTHER PCs open the dashboard

The dashboard is just a web server on TCP **8080**. Anyone on the same LAN
who can reach the server PC can use it — **no install on their machine**.

1. On the **server PC** (the one running the dashboard), allow inbound TCP
   8080 through Windows Firewall (run in an elevated PowerShell):

   ```powershell
   New-NetFirewallRule -DisplayName "Remote Desktop Dashboard" `
     -Direction Inbound -Protocol TCP -LocalPort 8080 `
     -Action Allow -Profile Any
   ```

2. Find the server PC's LAN IP:

   ```powershell
   ipconfig | Select-String IPv4
   ```

   Or click the **share** icon in the top right of the dashboard — it shows
   every LAN URL the server is reachable on, with one-click copy.

3. From any other PC on the LAN, open
   `http://<server-pc-ip>:8080/` in a browser. That's it.

There is **no login wall** — anyone who can reach this URL can use the
dashboard. Admin-only actions (push install, force release, kick others,
emergency restore RDP, manage machines, server settings) are gated behind
the **Admin PIN** (see below).

---

## Roles

There are two roles, enforced server-side:

| Role         | What they can do                                                          | How they are recognized           |
| ------------ | ------------------------------------------------------------------------- | --------------------------------- |
| **Operator** | View status, connect, release their own lock, view audit log             | Anyone who opens the dashboard URL |
| **Admin**    | All of the above **plus** push-install agent, force release, kick others, emergency-restore RDP, manage machines, edit server settings | Knows the **Admin PIN** |

Most users only ever need to be operators. They just open the dashboard
URL, type their name and RDP credentials once (the server remembers them
per-name across PCs), and connect.

### Admin PIN

The Admin PIN is a single, server-wide secret set by **whoever installed
the dashboard**, in `%LOCALAPPDATA%\RemoteDesktopDashboard\admin.env`:

```
RDD_ADMIN_PIN=pick-something-only-you-know
```

Restart the dashboard after changing it.

The PIN is **not shown anywhere in the UI** for non-admins. To use it,
click the lock icon ("Admin") at the top right and type the PIN. The UI
remembers it for the current browser tab (cleared on close) and unlocks
admin-only actions. Click the icon again to sign out.

---

## Bench agent (recommended)

For each bench you want to lock, push-install the PowerShell agent from
the dashboard:

1. In `admin.env` on the server set
   `RDD_BENCH_AGENT_TOKEN=<long-random-string>` and restart the
   dashboard. (This is the shared secret the agents use to authenticate
   to the dashboard.)
2. Make sure the dashboard's monitor service account is a **local admin**
   on every bench.
3. Open the dashboard, sign in as admin, open **Settings**, scroll to
   **Bench Agent**, and click **Push install** next to each bench.

The agent:

- Manages the local "Remote Desktop Users" group based on the current
  dashboard lock.
- Manages a local Windows Firewall rule on TCP 3389 so that, when a
  bench is locked, only the lock owner's IP can RDP — this blocks even
  local administrators from RDPing directly (which would otherwise
  bypass the group check).
- Kicks unauthorized RDP sessions if they sneak in.
- Heartbeats back to the dashboard every few seconds.

### Emergency: restore native RDP on a bench

If something goes wrong with the firewall rule and you can't get back
into a bench, the admin can hit **Restore native RDP** in the dashboard
(detail panel on the right of the Status tab). This tells the agent to:

1. Remove the custom firewall lock rule.
2. Re-enable the built-in Windows "Remote Desktop" rules.
3. Release the dashboard lock.

If the agent is offline, the dashboard also shows a PowerShell snippet
you can paste on the bench from an elevated shell. It does the same
three things directly.

---

## Configuration (`admin.env`)

On Windows, `%LOCALAPPDATA%\RemoteDesktopDashboard\admin.env`.
The most relevant keys:

| Key                                | Purpose                                                          | Default      |
| ---------------------------------- | ---------------------------------------------------------------- | ------------ |
| `RDD_ADMIN_PIN`                    | The Admin PIN gating admin actions                                | unset        |
| `RDD_BENCH_AGENT_TOKEN`            | Shared secret the bench agents use to authenticate               | unset        |
| `RDD_BENCH_AGENT_FIREWALL_LOCK`    | If true (default), the agent enforces the per-IP firewall lock  | `true`       |
| `RDD_MONITOR_DOMAIN/USERNAME/PASSWORD` | Service account used to poll sessions on each bench           | unset        |

Most users never have to edit this file. The dashboard's Settings drawer
edits the monitor account fields directly; the file is updated for you.

---

## Troubleshooting

- **Machines show red even though they're online.**
  The dashboard now treats a heartbeating bench agent as proof the
  machine is online. If you've installed the agent and the dot is still
  red, open the agent's **Diagnose** button in Settings → Bench Agent;
  the most common cause is the agent failed to start (scheduled task
  `RDD-Bench-Agent` last-result != 0).

- **Chained RDP still works** (RDPing into Bench A, then RDPing from
  Bench A to Bench B). Make sure the bench agent on Bench B is running
  v2.1.0 or later (`Agent v2.1.0 online` in Inventory). The firewall
  rule is what blocks this; if it's not applied, see **Diagnose**.

- **"Invalid admin PIN."** The PIN is whatever is on the right-hand
  side of `RDD_ADMIN_PIN=` in `admin.env` on the **server**, with no
  surrounding quotes and no leading/trailing spaces.

- **I locked myself out of a bench.** Click the Admin lock icon →
  sign in → open the bench's detail panel → **Restore native RDP**.
  If the agent is offline, paste the shown PowerShell on the bench.

---

## Development

```powershell
git clone <this repo>
cd remote_desktop_dashboard
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -e ".[dev]"
pytest
```

The PowerShell agent and installer scripts ship in
`src/remote_desktop_dashboard/data/`. They are parser-checked on
every test run (`tests/test_bench_agent_scripts.py`) — silent agent
crashes from PowerShell parse errors used to be a recurring problem, so
that test gates every release.
