Add type-safe URL override mechanism for RDP options (#182)

Introduce a generic, allow-list-gated way for the /connect endpoint to
accept RDP setting overrides via URL query parameters. Operators opt in
via client.rdpoverridablekeys; absent that allow-list, URL-driven
overrides are rejected with 400.

Override values are routed through rdp.Builder.ApplyOverrides, which
matches query keys against the rdp struct tags of RdpSettings and
validates per Go field type. Overridden fields are tracked so explicit
values always serialize even when they equal the field default. The
override pass runs before authoritative server-controlled fields
(gateway address, access token, full address, username) so those
always win.

This replaces the per-option string-splice approach considered in #181:
multimon now works via ?usemultimon=1 against an operator allow-list
containing "use multimon", and any other RDP key follows the same path
without bespoke handler code.
This commit is contained in:
bolkedebruin
2026-04-30 11:58:47 +02:00
committed by GitHub
parent a6d9379dc0
commit 754896b473
7 changed files with 525 additions and 6 deletions

View File

@@ -287,6 +287,45 @@ and RDP file will download to your desktop. This file can be opened by one
of the remote desktop clients and it will try to connect to the gateway and
desktop host behind it.
### Overriding RDP options from the URL
The `/connect` endpoint can apply caller-supplied RDP setting overrides from
URL query parameters when (and only when) the operator explicitly opts in.
This lets users vary settings such as multi-monitor, audio mode or
clipboard redirection without maintaining separate RDP templates.
The query parameter name is the underlying RDP key with whitespace removed
and lowercased. For example:
| RDP key (in the file) | Query parameter |
|-----------------------|-----------------|
| `use multimon` | `usemultimon` |
| `audiomode` | `audiomode` |
| `redirectclipboard` | `redirectclipboard` |
| `screen mode id` | `screenmodeid` |
Values are validated against the field type: booleans accept `0`/`1` or
`true`/`false`, integers must parse as base-10 numbers, strings are taken
verbatim. Unknown query parameters are ignored so the existing `host`,
etc. continue to work.
To enable, list the keys you want to expose under `client.rdpoverridablekeys`
in your YAML configuration (or via the `RDPGW_CLIENT__RDPOVERRIDABLEKEYS`
environment variable as a space-separated list):
```yaml
client:
rdpoverridablekeys:
- use multimon
- audiomode
```
With the snippet above, `https://your-gateway/connect?usemultimon=1` adds
`use multimon:i:1` to the generated RDP file. Keys that are not on the
allow-list are rejected with `400 Bad Request`. Authoritative settings
controlled by the gateway (gateway address, access token, full address,
username) always win over URL parameters even if an operator adds those
keys to the allow-list — but adding sensitive keys is still discouraged.
## Integration
The gateway exposes an endpoint for the verification of user tokens at
https://yourserver/tokeninfo . The query parameter is 'access_token' so