Repository navigation
fix: use an OU's handle as its mail domain - #308
Merged
Merged
Conversation
[High impact] Rebuilds mail domain resolution to use OU handles instead of hierarchy. The PR does not yet appear safe to merge because cached positive results can outlive the index-age cutoff.
|
maneesha-xyz
marked this pull request as draft
September 29, 2026 05:07
Thunder can only find an OU by its full handle path, and a domain no longer says where its OU sits, so socketmap reads the whole OU tree into a domain index. The index is built alongside startup and rebuilt every CACHE_TTL_SECONDS, with the wait starting when a walk ends. Lookups only read it; they wait for a walk only while no index exists, and share a failed first build's error for a few seconds. A domain claimed by two OUs is left out. Each page of a walk uses the current token.
maneesha-xyz
force-pushed
the
ou-handle-as-mail-domain
branch
from
November 12, 2026 06:45
299dd98 to
0b5c17e
Compare
maneesha-xyz
marked this pull request as ready for review
November 12, 2026 08:26
Aravinda-HWK
approved these changes
Nov 12, 2026
…nswered - TEMP instead of NOTFOUND for a domain several OUs claim - TEMP when a Thunder lookup fails, instead of bouncing the recipient - Stop serving the domain index after 12 failed refresh intervals - Lowercase the domain in normalizeEmail
- Lowercase the domain in GetUserDB, which login and delivery both use - Docs: cached answers can outlast the index age cutoff by one cache interval
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📌 Description
An OU's handle is now its mail domain. Raven no longer works out the domain from where the OU sits in the Thunder tree, so a domain can have any number of labels, a child OU's domain doesn't have to be a subdomain of its parent's, and a grouping OU (such as
foundations) can sit above OUs that receive mail.🔍 Changes Made
internal/maildomain: newFromHandle, which returns an OU handle as a lowercased domain, or reports that the handle isn't a domain (foundations,default).internal/socketmap/thunder:buildOUPathand the never-expiringouCacheare removed.ValidateDomainandGetOrgUnitIDForDomainnow look the domain up in a domain → OU ID index built by walkingGET /organization-unitsandGET /organization-units/{id}/ous(paged at 100, followingnextlinks).CACHE_TTL_SECONDS. If a rebuild fails, the previous index stays in use.internal/server/authandinternal/delivery/groupresolver: the parent-walk inresolveOrganizationUnitDomainis replaced with a singleGET /organization-units/{id}andFromHandle. The callers (IMAP LOGIN domain check, OAUTHBEARER, group expansion) are unchanged.docs/THUNDER_CONSUMER_CONTRACT_GUIDE.md: endpoint [TASK] Write Test for "LOGIN" Command #3 is now the list/children endpoints, and [BUG] Copy of the send mail was not saved on the sqlite database. #9 no longer describes a parent walk.✅ Checklist (Email System)
LOGIN,CAPABILITY,LIST,SELECT,FETCH,LOGOUT).🧪 Testing Instructions
To test the server, use the instructions in the README in the
testdirectory.go test ./...passes. The new and updated tests:internal/maildomain: handle parsing, including deep domains,co.uk, mixed case, trailing dot, non-domain handles and path-traversal characters.internal/socketmap/thunder/index_test.go: a child OUsilver.x.yunderfoundationsresolves with nox.yOU present; duplicate handles resolve to nothing; pagination; index reuse within the TTL; the previous index is served when a rebuild fails; an error when no index was ever built.internal/server/authandinternal/delivery/groupresolver: fixtures use full-domain handles and fail the test if a parent OU is fetched.Against a real Thunder, with raven's own
IDP_CLIENT_ID/IDP_CLIENT_SECRET, run the socketmap service and check thatvirtual-domains <child OU domain>returnsOK 1andvirtual-domains <grouping OU handle>returnsNOTFOUND. This also confirms raven's token may call the list endpoints; so far they have only been checked with an admin token.silverunderx.ybecomessilver.x.y. Otherwise mail for that OU stops resolving and its users can't log in.CACHE_TTL_SECONDS(default 300) to take effect. Socketmap answers from the domain index, and a stale index is refreshed in the background, so Postfix rejects mail for a newly created domain until the next refresh lands. A renamed OU's old domain is accepted for the same window.mailDomainswould enforce this.mailDomainsattribute on OUs in Thunder.