Commit Graph
60 Commits
Author SHA1 Message Date
kevinveenbirkenbachandClaude Opus 4.8 4136641164 fix(nextcloud): gate fileslibreofficeedit on OnlyOffice absence
OnlyOffice declares fileslibreofficeedit (and richdocuments) incompatible and
disables them on install, so the LibreOffice editor's E2E spec failed wherever
OnlyOffice was co-deployed. Enable fileslibreofficeedit only when the OnlyOffice
addon is off (addons.onlyoffice.enabled), and add the required service-coupled
addon integration hook.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 12:36:09 +02:00
kevinveenbirkenbachandClaude Opus 4.8 fc5ad87dc5 feat(roles): make referenced partner services proper shared providers
Declare the 14 services that consuming roles reference but no role provided
(bigbluebutton, xwiki, openproject, gitlab, mattermost, matrix, zammad,
openwebui, flowise, peertube, moodle, suitecrm, redis, memcached) as shared
providers: set enabled/shared/bond on each entity so the service registry
registers them and the dangling references resolve.

Add test_shared_service_provider.py (lint): fail when a referenced shared
service has no provider and its name matches a role's entity/provider that does
not register it (suppressable via '# nocheck: shared-provider').

Guard the 9 web-app shared services with the run-once 01_core.yml pattern
(main.yml includes 01_core.yml only when run_once_<role> is undefined; the core
flags itself via utils/once/flag.yml) so they deploy once when pulled in by
multiple consumers. svc-db-redis/memcached are template-only (no runtime tasks).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:17 +02:00
kevinveenbirkenbachandClaude Opus 4.8 ed4b061408 fix(web-app-nextcloud): store integration OAuth creds Nextcloud-encrypted
integration_gitlab/integration_mattermost read client_id/client_secret via
crypto->decrypt(appConfig->getValueString(lazy:true)). Provisioning set them
with 'config:app:set --sensitive', the wrong scheme -> "Authenticated
ciphertext could not be decoded" -> the connected-accounts admin page 500s,
cascading onto the discourse/matrix/mattermost addon specs.

Add set_encrypted_appconfig.php (crypto->encrypt + appConfig setValueString
lazy -- the exact scheme the apps' setEncryptedAppValue uses) and route both
provisioning hooks through it. Verified live: gitlab client_id is now an
encrypted blob and connected-accounts renders again.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:16 +02:00
kevinveenbirkenbachandClaude Opus 4.8 c9a431e298 fix(web-app-nextcloud): make integration_openproject NC OAuth2 client step best-effort
Push the OpenProject OAuth credentials (authorization_method, openproject_client_id,
openproject_client_secret) into Nextcloud before the NC OAuth2 client step so the
forward connect is always provisioned. The reverse-direction Nextcloud OAuth2 client
relies on occ oauth2:add-client, which Nextcloud 33 does not ship, so it is now
failed_when: false with its dependents in a guarded block — the deploy completes
instead of aborting before the Playwright suite runs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:10 +02:00
kevinveenbirkenbachandClaude Opus 4.8 1d6bc786ff refactor(web-app-nextcloud): drop redundant | default('') on always-set register stdouts
The integration_openproject / integration_gitlab provisioning and the user_ldap
config probe read their state with tasks that always run (no when:) and
failed_when: false, so their .stdout is always defined; 'X.stdout | default('') |
trim' is identical to 'X.stdout | trim'. Remove the dead default('').

Genuinely-guarding defaults are kept: the s01 config-id fallback, the skippable
ldap auto-create stdout/stderr, the regex_search None guards, and the outer
default(..., true) fresh-or-persisted secret fallback.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:10 +02:00
kevinveenbirkenbachandClaude Opus 4.8 38796b77a5 fix(web-app-nextcloud): recover integration_openproject OAuth secret on re-deploy
OpenProject only returns a fresh OAuth client secret when the application is first
created; on a re-deploy where the app already exists but Nextcloud never persisted
the secret (e.g. an earlier deploy failed downstream at the storage step), the
secret is unrecoverable and the provisioning assert tripped, aborting the play
before the Playwright suite ran.

ensure_nextcloud_storage.rb now destroys and recreates the OAuth application when
it exists but Nextcloud holds no secret (gated to the first call via the absent NC
client id), so a fresh secret is always emitted. The provision task passes the
persisted-secret read as NC_HAS_OP_SECRET only on that first call so the second
(client-register) call never destroys the freshly created app. Verified
in-container: the recovery path emits a fresh openproject_client_secret.

Also drops the redundant | default('') on the always-set
nextcloud_op_client_secret_current.stdout in this file.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:10 +02:00
kevinveenbirkenbachandClaude Opus 4.8 462c20cbb9 fix(web-app-nextcloud): integration_openproject OAuth provisioning + full e2e
- ensure_nextcloud_storage.rb: resolve the storage creator via
  User.where(admin: true) with a respond_to?(:active) guard, since OpenProject 17
  removed User::STATUSES (the prior .active.first path raised NameError)
- integration_openproject_provision.yml: parse the OAuth payload with
  regex_search('{.*}') instead of trim, so polluted runner stdout still yields
  valid JSON
- spec: assert the provisioned OAuth client is shown in admin (both sides
  coupled) and the per-user connect drives the partner /oauth/authorize with the
  client_id + response_type=code

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:09 +02:00
kevinveenbirkenbachandClaude Opus 4.8 110ca7d134 feat(web-app-nextcloud): real integration_gitlab two-way OAuth coupling
Provision a GitLab Doorkeeper OAuth application for Nextcloud and wire the
credentials into the integration_gitlab app so the per-user Connect-to-GitLab
flow reaches the partner authorize endpoint.

- provision_oauth_app.rb: create/renew the Doorkeeper app (organization_id set
  to satisfy the newer GitLab oauth_applications check constraint), emit
  CLIENT_ID/CLIENT_SECRET
- integration_gitlab_provision.yml: run it via gitlab-rails, parse the creds,
  store them with occ config:app:set --sensitive (the app stores them encrypted)
- integration_gitlab.yml: probe the partner, read persisted creds, provision
  only when the partner is up and not yet coupled
- spec: drive the real per-user OAuth connect and assert the partner
  /oauth/authorize carries the provisioned client_id + response_type=code

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:09 +02:00
kevinveenbirkenbachandClaude Opus 4.8 87c05ddc5d feat(web-app-nextcloud): real addon integration hooks (exception-only, bidirectional where needed)
Per-addon tasks/addons hooks contain only exception logic beyond the generic loader (DRY/SPOT): config-complete/per-user integrations are documented SPOT comments; mattermost/openai/openproject/suitecrm perform genuine bidirectional OAuth/API provisioning (register client on partner, write client_id/secret back) via files/{mattermost,openproject,suitecrm} scripts, gated on the partner container running. meta/addons keys for gitlab/mastodon/matrix/peertube/zammad fixed from the inert url to the admin oauth_instance_url/instances the apps actually read.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:06 +02:00
kevinveenbirkenbachandClaude Opus 4.8 4e8940caa6 refactor(web-app-nextcloud): migrate addons to unified addon syntax (req 026)
Schema-migrate every nextcloud addon to the unified per-file addon syntax (mechanism/source/required/bridges/config); add the non-proprietary integration addons (matrix, mattermost, moodle, suitecrm, zammad) and the local gitlab bridge; wire the bridged service blocks into meta/services.yml and pin every new (service,enabled)/(service,shared) pair in meta/variants.yml for variant coverage; relocate the per-addon user_ldap hook from tasks/plugin/hooks/ to tasks/addons/ for a uniform tasks/addons/ layout, dropping the obsolete vars/plugins README.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 00:16:54 +02:00