Skip to content

fix(#144): MEDIUM: the user id is baked into every CalDAV collection path and calendar_id, - #432

Merged
BeSovereign merged 1 commit into
mainfrom
fix/issue-144
Oct 15, 2026
Merged

BeSovereign merged 1 commit into
mainfrom
fix/issue-144

Conversation

@BeSovereign

Copy link
Copy Markdown
Contributor

Refs #144

In AUTH_METHOD=oidc the OIDC sub is now the storage identity everywhere: the internal Radicale account URL and login, booking accounts, calendar access (owner and shares matched only by user id, no login-name lookup), share invitations and the Radicale auth plugin (exact user id match first); a sub that is not one safe path segment is refused with 401 at the OIDC callback and the proxy header, never rewritten. This closes the account/rights mismatch that hid OIDC users' calendars and the leak that let a member whose login name equals another sub act as that member; two obsolete login-name test cases were updated and CONCEPTS.md now records the decision.

Driver gates (measured, not claimed)

  • Suites: lint: 1 passed, 0 failed | node: 1768 passed, 0 failed | python: 106 passed, 0 failed | e2e: 76 passed, 0 failed
  • Red/green check on declared tests: server/test/issue144_user_id_caldav_collection_path.test.js, server/test/python/test_issue144_radicale_sub_identity.py
red/green output
RED without the change:
AssertionError: '2' != '1'
- 2
+ 1


======================================================================
FAIL: test_sub_owns_its_collection_root_and_not_another (test_issue144_radicale_sub_identity.TestRadicaleSubIdentity.test_sub_owns_its_collection_root_and_not_another)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/agent-user/Coding/Freeshard/vacation_framework/worktrees/issue-144/server/test/python/test_issue144_radicale_sub_identity.py", line 92, in test_sub_owns_its_collection_root_and_not_another
    self.assertEqual(self.rights.authorization(user, "/1/"), "RW")
AssertionError: '' != 'RW'
+ RW


----------------------------------------------------------------------
Ran 2 tests in 0.219s

FAILED (failures=2)


GREEN with the change:
269
      ...
    # Subtest: a sub that is not a safe path segment is refused with 401 at OIDC login
    ok 5 - a sub that is not a safe path segment is refused with 401 at OIDC login
      ---
      duration_ms: 96.739125
      ...
    # Subtest: a sub that is not a safe path segment is refused with 401 from the proxy header
    ok 6 - a sub that is not a safe path segment is refused with 401 from the proxy header
      ---
      duration_ms: 16.128983
      ...
    1..6
ok 1 - Issue \#144 — the OIDC sub is the storage identity (NODE_ENV=production)
  ---
  duration_ms: 1273.8032
  ...
1..1
# tests 7
# suites 0
# pass 7
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 1414.829403

..
----------------------------------------------------------------------
Ran 2 tests in 0.125s

OK

🤖 Generated with Claude Code

In AUTH_METHOD=oidc the OIDC sub is now the storage identity everywhere: the internal Radicale account URL and login, booking accounts, calendar access (owner and shares matched only by user id, no login-name lookup), share invitations and the Radicale auth plugin (exact user id match first); a sub that is not one safe path segment is refused with 401 at the OIDC callback and the proxy header, never rewritten. This closes the account/rights mismatch that hid OIDC users' calendars and the leak that let a member whose login name equals another sub act as that member; two obsolete login-name test cases were updated and CONCEPTS.md now records the decision.

Refs #144

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant