feat(portal): real OCIS storage data via refresh-token service auth

The Storage page + endpoint landed earlier but had no working OCIS
backend credential. OCIS has no service-account/client-credentials grant
and trusts a single issuer, and basic auth resolves no user in our
external-IdP setup — so authenticate OcisClient via an OIDC
refresh-token bootstrap instead:

- One-time headless login of svc-platform-api against the ocis provider
  (public client ocis-web, issuer .../o/ocis/) yields a refresh token,
  persisted in Mongo (ocis_credentials) and rotated on every use.
- OcisClient mints access tokens with the refresh_token grant; the
  service user holds the OCIS admin role (OCIS_ADMIN_USER_ID) so
  libregraph ListAllDrives works.
- scripts/bootstrap-ocis.mjs re-runs the bootstrap if the token lapses.
- Dashboard Plan card gains a storage capacity bar beside seats;
  hidden when storage is unavailable.
- compose + .env.example: OCIS service OIDC env and admin user id.
- docs/NEXT-STEPS: document the mechanism and the dead-end alternatives.
This commit is contained in:
Ronni Baslund
2026-05-31 21:29:17 +02:00
parent 559348f6bc
commit f8618b2bbc
8 changed files with 335 additions and 60 deletions
@@ -325,7 +325,12 @@ services:
PROXY_AUTOPROVISION_ACCOUNTS: "true"
PROXY_USER_OIDC_CLAIM: preferred_username
PROXY_USER_CS3_CLAIM: username
OCIS_ADMIN_USER_ID: ""
# Grant the OCIS admin role to the platform-api service user (autoprovisioned
# OCIS account of svc-platform-api). Admin is required for libregraph
# ListAllDrives, which powers the customer-admin Storage page. The UUID is
# the svc user's OCIS account id; stable as long as the OCIS data volume
# persists. Empty in fresh setups until the OCIS bootstrap has run.
OCIS_ADMIN_USER_ID: ${OCIS_ADMIN_USER_ID:-}
IDM_CREATE_DEMO_USERS: "false"
IDM_ADMIN_PASSWORD: ${OCIS_ADMIN_PASSWORD}
STORAGE_USERS_DRIVER: ocis # Local filesystem in dev