Skip to content

ogar-az: Graph mailbox and OneDrive reads; ogar-dir-sim: mailbox hosts and locations - #340

Merged
AdaWorldAPI merged 3 commits into
mainfrom
ccr-0455e606-wmtsor
Oct 10, 2026
Merged

AdaWorldAPI merged 3 commits into
mainfrom
ccr-0455e606-wmtsor

Conversation

@AdaWorldAPI

@AdaWorldAPI AdaWorldAPI commented Oct 10, 2026 •

Copy link
Copy Markdown
Owner

What

ogar-az::mailbox. Graph doesn't report a mailbox as a property of user; each piece takes its own read, with its own permission. This module names those reads as Pulls. Every one is a GET against v1.0 with the least-privileged permission Microsoft documents:

pull path permission
MailboxSettings /users/{id}/mailboxSettings MailboxSettings.Read
ExchangeSettings /users/{id}/settings/exchange User.Read.All
MailboxFolders /admin/exchange/mailboxes/{mailboxId}/folders MailboxFolder.Read.All
MailboxItems /admin/exchange/mailboxes/{mailboxId}/folders/{folderId}/items MailboxItem.Read.All
UserDrive /users/{id}/drive Files.Read.All, delegated
  • Pull::grant says how the permission is granted. The mailbox reads take an application permission. Microsoft lists reading a user's drive as delegated only.
  • encode_mailbox turns one user's two settings reads into a DirRecord of kind AzKind::Mailbox. The record is keyed by the Graph user id (the mailbox's ExternalDirectoryObjectId) and holds:
    • userPurpose, as returned by Graph;
    • primaryMailboxId, as returned by Graph;
    • the mailbox GUID decoded from primaryMailboxId.
  • The GUID is decoded only from the full spelling MBX:{guid}@{tenant}. The tenant part must equal the record's tenant. Any other spelling keeps the raw value and decodes nothing.
  • user_drive accepts a drive only when its owner is that user. It returns the drive id, which Spear's drive scope needs to address uploads.

The module performs no HTTP and no writes. examples/mailbox_ingest.rs prints the reads with their permissions and encodes saved response bodies.

ogar-dir-sim::deployment.

  • MailboxHost is where a mailbox lives: ExchangeServer or Stalwart on-premises, or ExchangeOnline.
  • Deployment { on_premises, online } names the on-premises host (or none) and whether Exchange Online is present. Its constants are EXCHANGE_SERVER, ONLINE, EXCHANGE_HYBRID, STALWART and STALWART_WITH_ONLINE.
  • What each deployment reads:
    • With an on-premises host, the AD recipient attributes decide the recipient type.
    • With Exchange Online present, the cloud mailbox decides delivery to cloud-hosted recipients.
    • The ExchangeGuid is compared only for Exchange Server together with Exchange Online, because Stalwart has no ExchangeGuid.
  • host_of(recipient) is where that recipient's mailbox lives. A mail server needs this before it accepts a message as local or relays it.
  • MailboxLocation { host, kind, mailbox_guid } and MailboxLocationType (seven values) carry what Get-MailboxLocation reports. Exchange names a location TenantGUID\MailboxGUID, the same pair Graph spells MBX:{guid}@{tenant}.
  • MailboxPurpose is Graph's userPurpose, mapped onto RemoteKind.

Docs. DIRECTORY-ADAPTERS-POC.md §10 covers the Graph reads. DIRECTORY-SIMULATION-POC.md V15 covers hosts and locations, with these open items:

  • lance-graph doesn't consume the deployment yet; the simulator still behaves as EXCHANGE_HYBRID.
  • Stalwart's DirSim backend currently answers Account even for a mailbox that lives in Exchange Online. Under STALWART_WITH_ONLINE it should answer Account only where host_of is Stalwart.
  • Spear's OneDrive upload isn't built: this PR only resolves the drive id, and the upload itself (Spear's write) is the next step.

Not done here

  • No real tenant. Nothing has run against a real tenant. That the MBX: GUID is the ExchangeGuid should be confirmed against Get-EXOMailbox -Properties ExchangeGuid.
  • No Mailbox.ReadWrite.All. No permission by that name exists. Mailbox content is covered by MailboxFolder.* and MailboxItem.*, and only their read variants are used here.

Tests

  • tests/mailbox.rs has 8 tests and deployment.rs has 4.
  • Disable checks: I disabled 11 guards one at a time, and each turned at least one test red:
    • the tenant check and the length check in the GUID decode;
    • the record-kind gate on the accessors;
    • the ExchangeSettings permission;
    • exact matching of userPurpose;
    • the drive owner check and the drive's delegated grant;
    • the deprovisioned case and the online gate in host_of;
    • comparing the ExchangeGuid only for Exchange Server, and only in the earlier version, comparing it only for the hybrid deployment.
  • fmt and clippy -D warnings are clean on Rust 1.99.0.
  • ogar-from-schema's do_arm/sgo tests fail the same way on main here: they need an OGIT checkout this container doesn't have.

🤖 Generated with Claude Code

https://claude.ai/code/session_01G22yT6htkcdyXsihxxXdrg

…deployment shapes

ogar-az::mailbox names the Graph reads a mailbox takes (mailboxSettings,
settings/exchange, admin/exchange/mailboxes folders and items), each a
GET with its least-privileged application permission, and encodes one
user's results into a DirRecord of kind Mailbox: userPurpose and
primaryMailboxId raw, plus the mailbox GUID decoded strictly from the
observed MBX:{guid}@{tenant} spelling. No HTTP, no writes.

ogar-dir-sim::deployment adds ExchangeDeployment (on-premises, online,
hybrid: which source is authoritative for what) and MailboxPurpose
(Graph's userPurpose, mapped to RemoteKind).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G22yT6htkcdyXsihxxXdrg
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G22yT6htkcdyXsihxxXdrg
…§10) and deployment shapes (plan V15)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G22yT6htkcdyXsihxxXdrg
@coderabbitai

coderabbitai Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption.


Comment @coderabbitai help to get the list of available commands.

@AdaWorldAPI
AdaWorldAPI marked this pull request as ready for review October 10, 2026 12:56
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-10T12:57:38.103145Z fc1c348 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@AdaWorldAPI
AdaWorldAPI merged commit 5ae403d into main Oct 10, 2026
3 of 4 checks passed
@AdaWorldAPI AdaWorldAPI changed the title ogar-az: read Exchange Online mailboxes through Graph; ogar-dir-sim: deployment shapes ogar-az: Graph mailbox and OneDrive reads; ogar-dir-sim: mailbox hosts and locations Oct 10, 2026
@coderabbitai

coderabbitai Bot commented Oct 10, 2026

Copy link
Copy Markdown

Add Carrot credits or activate Agent usage billing to use Autofix

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.

2 participants