# drift-gateway-helper — Setup Guide

## Overview

The drift-gateway-helper is a Rust HTTP service that runs on the same machine as CommuniGate Pro (CGP). It enables external (unauthenticated) access to specific features: file uploads, file viewing, Collabora document editing, format conversion, and event poll voting.

**Request flow:**

```
Browser → Cloudflare Tunnel → CGP port 8100
  → /sys/driftgw.wcgp/<path>  (WSSP forwarder script)
    → HTTPCall to 127.0.0.1:9084/<path>  (this helper)
      → XIMSS back to CGP as service account
```

The WSSP script (`driftgw.wcgp`) runs with CGP's `sysEntry` privilege, which grants HTTPCall rights. The helper then authenticates to CGP via XIMSS to read/write files and send emails.

## Prerequisites

- CommuniGate Pro 6.x running on the same machine
- Rust toolchain (for building from source) or a pre-built binary
- Cloudflare Tunnel (cloudflared) for public HTTPS access
- Collabora Online (optional, for document editing/conversion)

## Step 1 — Create a Service Account

Create a dedicated CGP account for the helper instead of using postmaster.

1. Open CGP WebAdmin (`http://127.0.0.1:8010`)
2. Go to **Accounts** → **Create Account**
3. Create `drift-service@yourdomain` with a strong password
4. Go to the account's **Settings** → **Access Rights**
5. Grant **Domain Administrator** rights (needed to access other users' private files via XIMSS)

Alternatively, use `postmaster` — it already has the required rights.

## Step 2 — Configure

Copy `config.toml.example` to `config.toml` (or edit the existing `config.toml`):

```toml
[server]
# Only listen on localhost — CGP's WSSP script forwards requests
bind = "127.0.0.1:9084"

# Upload limits
max_upload_mb = 100
max_folder_mb = 2000
request_timeout_seconds = 300
body_receive_timeout_seconds = 120

# Public URL where Collabora can reach the WSSP forwarder (for WOPI callbacks)
# This must match your Cloudflare tunnel route
external_base = "https://mail.yourdomain.com"

# Collabora Online server URL (leave empty if not using Collabora)
collabora_url = "https://collabora.yourdomain.com"

[cgp]
# CGP HTTP user interface (XIMSS endpoint)
base_url = "http://127.0.0.1:8100"

# Service account credentials
username = "drift-service@yourdomain"
password = "your-strong-password"

# XIMSS client version
xlimss_version = "6.1"

[policy]
# Block dangerous file types from anonymous uploads
upload_denylist = ["exe", "bat", "cmd", "ps1", "vbs", "msi", "scr", "jar", "dll", "com", "sys"]

# What happens when an uploaded file already exists: "reject" or "rename"
collision = "rename"

[rate_limit]
per_ip_per_minute = 1000
per_ip_per_day = 100
global_per_minute = 200

[logging]
dir = "./logs"
level = "info"
```

**Important:** Protect `config.toml` — it contains credentials. Set file permissions so only the service account can read it.

## Step 3 — Build

```bash
cd drift-gateway-helper
cargo build --release
```

The binary is at `target/release/drift-gateway-helper.exe` (Windows) or `target/release/drift-gateway-helper` (Linux).

## Step 4 — Deploy the WSSP Forwarder

The WSSP script (`driftgw.wcgp`) must be deployed to CGP's WebSkins root so it's served at `/sys/driftgw.wcgp/`. This script forwards HTTP requests from the public internet through CGP to the helper on localhost.

**Option A — Using the deploy script:**

```bash
CGP_PASSWORD='your-postmaster-password' bash scripts/deploy-wssp.sh wssp/driftgw.wcgp
```

**Option B — Manual via CGP CLI (telnet to admin port):**

```
STORESERVERSKINFILE "" FILE "driftgw.wcgp" DATA [<base64-encoded-content>]
```

**Option C — Copy to CGP program directory:**

Copy `wssp/driftgw.wcgp` to both:
- `C:\Windows\CommuniGatePro\WebSkins\driftgw.wcgp` (program dir)
- `C:\CommuniGate Files\WebSkins\driftgw.wcgp` (data dir)

Then restart CGP.

**Verify:** `curl http://127.0.0.1:8100/sys/driftgw.wcgp/health` should return `{"service":"drift-gateway-helper","status":"ok"}`.

## Step 5 — Start the Helper

```bash
cd drift-gateway-helper
./target/release/drift-gateway-helper
```

The helper reads `config.toml` from the current directory and starts listening on the configured bind address.

**Verify:** `curl http://127.0.0.1:9084/health` should return `{"service":"drift-gateway-helper","status":"ok"}`.

### Run as a Service (Windows)

Use NSSM or a scheduled task to run the helper at startup:

```cmd
nssm install drift-gateway-helper "C:\path\to\drift-gateway-helper.exe"
nssm set drift-gateway-helper AppDirectory "C:\path\to\drift-gateway-helper"
nssm start drift-gateway-helper
```

### Run as a Service (Linux)

Create `/etc/systemd/system/drift-gateway-helper.service`:

```ini
[Unit]
Description=drift gateway helper
After=network.target

[Service]
Type=simple
User=drift
WorkingDirectory=/opt/drift-gateway-helper
ExecStart=/opt/drift-gateway-helper/drift-gateway-helper
Restart=always

[Install]
WantedBy=multi-user.target
```

Then: `systemctl enable --now drift-gateway-helper`

## Step 6 — Cloudflare Tunnel Route

The helper is already reachable through CGP's `/sys/driftgw.wcgp/` path. As long as your Cloudflare tunnel routes to CGP's HTTP port, no additional tunnel route is needed.

Example `config.yml` entry:

```yaml
ingress:
  - hostname: mail.yourdomain.com
    service: http://127.0.0.1:8100
```

## Endpoints

| Path | Method | Description |
|------|--------|-------------|
| `/health` | GET | Health check |
| `/upload/~user@domain/path/pwd/KEY/` | GET | Upload drop page |
| `/upload/~user@domain/path/pwd/KEY/filename` | PUT | Upload file |
| `/view/~user@domain/path/pwd/KEY/filename` | GET | File viewer page |
| `/edit/~user@domain/path/pwd/KEY/filename` | GET | Collabora editor launcher |
| `/convert/~user@domain/path/pwd/KEY/filename` | GET | Server-side format conversion |
| `/poll/~user@domain/pollid/pwd/KEY/` | GET | External poll voting page |
| `/poll/~user@domain/pollid/pwd/KEY/` | PUT | Submit poll vote (JSON) |
| `/wopi-in/...` | * | WOPI endpoints for Collabora |
| `/edit-in/...` | GET | Folder-context Collabora launcher |
| `/save-in/...` | POST | Save temp file to target |
| `/save-as-in/...` | POST | Save-as to new name |
| `/cleanup-in/...` | POST | Remove temp file |

All external paths are accessed via the WSSP prefix:
`https://mail.yourdomain.com/sys/driftgw.wcgp/<path>`

## Security Model

- **No sessions or tokens** — uses CGP's native `accessPwd` mechanism on shared files
- External users can only access files/polls that have been explicitly shared with an access password
- The `pwd/KEY` segment in the URL is verified against the file's `accessPwd` custom attribute
- Upload file extensions are filtered by the `upload_denylist` policy
- Rate limiting protects against abuse
- The helper only listens on `127.0.0.1` — never exposed directly to the internet

## Troubleshooting

**Helper not reachable through WSSP:**
- Check CGP log for WSSP script errors (misleading 404 = script abort)
- Verify the script is deployed: `curl http://127.0.0.1:8100/sys/driftgw.wcgp/health`
- Ensure the helper is running: `curl http://127.0.0.1:9084/health`

**XIMSS login fails:**
- Check `config.toml` credentials
- Verify the service account exists and has Domain Admin rights
- Check CGP log for authentication errors

**File access denied:**
- The service account needs Domain Admin rights to access other users' files
- Verify with: login as the service account in drift, check if you can see other users' files

**Poll votes not saving:**
- Check that the poll file exists in the organizer's `private/drift-polls/` directory
- Verify the `accessPwd` on the poll file matches the URL key

**Collabora not working:**
- Verify Collabora is running: `curl https://collabora.yourdomain.com/hosting/discovery`
- Check that `external_base` in config.toml matches the public URL
- Collabora must be able to reach the WSSP forwarder via `external_base` for WOPI callbacks
