Add Access Gate for Required Groups on ExApp HTTP traffic.

AppAPI cannot restrict ExApps by Nextcloud group; enforce any-of membership in-library with Wrap/Check, deploy-env helpers, and positive-only cache.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Konrad Neitzel
2026-08-27 17:10:58 +02:00
co-authored by Cursor
parent 7921694782
commit 3980263146
6 changed files with 651 additions and 8 deletions
+14 -5
View File
@@ -1,10 +1,10 @@
# go-nc-exapp
Shared Go library for Nextcloud ExApp Services: AppAPI authentication, OCS JSON calls, and per-user ExApp preferences.
Shared Go library for Nextcloud ExApp Services: AppAPI authentication, OCS JSON calls, per-user ExApp preferences, and optional Required Groups Access Gate.
Import: `gitea.neitzel.de/konrad/go-nc-exapp`
## v1 scope
## Scope
**Included**
@@ -14,10 +14,11 @@ Import: `gitea.neitzel.de/konrad/go-nc-exapp`
- **UserFromRequest** — extract the requesting user from inbound AppAPI-proxied requests
- **OCSClient** — authenticated OCS calls that always append `format=json`
- **AppAPIPreferences** — parameterized get/set of a string ExApp preference (caller supplies app id and key)
- **Access Gate** — optional Required Groups enforcement (`Wrap` + `Check`), English denied HTML, positive membership cache; env helpers for `REQUIRED_GROUPS` / `REQUIRED_GROUPS_CACHE_SECONDS`
**Excluded from v1**
**Excluded**
- ExApp lifecycle HTTP routes (`/heartbeat`, `/enabled`, …)
- ExApp lifecycle HTTP routes (`/heartbeat`, `/enabled`, …) — the Gate *skips* these by default but does not implement them
- HaRP listen / `serve()` and unix-socket bootstrap
- Top-menu, script, and iframe UI registration
- WebDAV and file storage (see **go-nc-files**)
@@ -37,15 +38,23 @@ cred := gonexapp.Credentials{
prefs := gonexapp.NewAppAPIPreferences(cred, "myexapp", "savedDefault")
value, err := prefs.Get()
groupsEnv, groupsSet := os.LookupEnv("REQUIRED_GROUPS")
groups := gonexapp.ResolveRequiredGroups(groupsEnv, groupsSet, nil)
ttl := gonexapp.ParseCacheSeconds(os.Getenv("REQUIRED_GROUPS_CACHE_SECONDS"), gonexapp.DefaultCacheSeconds)
handler := gonexapp.AccessGate{Cred: cred, Groups: groups, CacheTTL: ttl}.Wrap(inner)
```
Each ExApp chooses its own preference keys; this library does not hardcode product-specific names.
Declare `REQUIRED_GROUPS` and `REQUIRED_GROUPS_CACHE_SECONDS` in the ExApp `info.xml` so Deploy options can set them.
## Domain language
See [CONTEXT.md](./CONTEXT.md) for AppAPI credentials, requesting user, ExApp preference, and OCS terminology.
See [CONTEXT.md](./CONTEXT.md) for AppAPI credentials, Requesting user, ExApp preference, OCS, Required Groups, and Access Gate terminology.
## Related
- **go-nc-files** — WebDAV, Working Folder, Saved Default, Visit resolution
- Workspace ADR 0013 — extraction from CheckDNS
- Workspace ADR `docs/adr/go-nc-exapp/0001-required-groups-access-gate.md` — Access Gate decisions