-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Context
Depends on #5 (worker-scanner ASM routes). The manager service needs a proxy blueprint to expose ASM endpoints to the WebUI and external clients with auth enforcement.
Files to Create / Modify
New: `services/manager-new/api/v1/asm.py`
Quart Blueprint `bp` with prefix `/api/v1/asm`.
Internal helper `_proxy(method, path, **kwargs)`:
- Forwards to `WORKER_SCANNER_URL/api/v1/asm{path}`
- Passes `Authorization` header from incoming request
- Returns `(jsonify(data), resp.status_code)`
- Handles `httpx.TimeoutException` → 504, `ConnectError` → 503
Routes (all `@auth_required`):
- `POST /scans` → proxy POST /scans
- `GET /scans` → proxy GET /scans (pass query params)
- `GET /scans/` → proxy GET /scans/
- `GET /scans//hosts` → proxy
- `GET /scans//screenshots` → proxy
- `GET /scans//certs` → proxy
- `GET /scans//diff` → proxy
- `GET /scans//report` → proxy
- `GET /settings/ports` → proxy
- `PUT /settings/ports` → proxy (also `@role_required("admin")`)
`WORKER_SCANNER_URL` from env var `WORKER_SCANNER_URL` (default: `http://worker-scanner:5001\`).
Follow pattern from `services/manager-new/api/v1/s3_scan.py` for auth decorators and Quart async patterns.
Modify: `services/manager-new/main.py`
Find where blueprints are registered (search for `register_blueprint`). Add:
```python
from api.v1 import asm as asm_api
app.register_blueprint(asm_api.bp, url_prefix="/api/v1/asm")
```
Modify: `services/manager-new/config.py`
Add `ASMConfig` Pydantic model before `ManagerConfig`:
```python
class ASMConfig(BaseModel):
enabled: bool = Field(default=True)
worker_scanner_url: str = Field(default="http://worker-scanner:5001")
s3_bucket: str = Field(default="skauswatch-asm-artifacts")
```
Add to `ManagerConfig` (or top-level config class):
```python
asm: ASMConfig = Field(default_factory=ASMConfig)
```
Modify: `docker-compose.yml`
Add `WORKER_SCANNER_URL=http://worker-scanner:5001\` to the manager-new service environment block if not already present.
Acceptance Criteria
- All 10 proxy routes work end-to-end (manager → worker-scanner)
- Auth enforced: unauthenticated requests return 401
- Admin-only `PUT /settings/ports` returns 403 for non-admin
- Timeout/connection errors return 504/503 (not 500)
- Blueprint registered in main.py without import errors
- Linting passes
Notes
- Manager uses Quart (async), not Flask — all route handlers must be `async def`
- Use `httpx.AsyncClient` for proxying (already in manager deps)
- Follow `api/v1/s3_scan.py` for the auth decorator pattern