feat(connectors): Microsoft checks share their sign-in row and Graph error rows
Description
Tenth backend PR for the connector checks redesign, stacked on #16200. It adds what the SharePoint, OneDrive and Outlook checks share. The three connector PRs that follow use it for their own rows.
Sign in to Microsoft (all three connectors)
- One row for a failed sign-in. Every probe signs in first. Before, a bad secret made every check fail with the same error. Now every check after sign-in depends on it, so it shows "Not run: Sign in to Microsoft failed".
- Name and lines. The sign-in check is "Sign in to Microsoft". Each sign-in refusal gives the design's line and description: "A required account field is empty", "Certificate file does not open", "Directory ID not found", "Secret or certificate was rejected", "App registration not found", "Microsoft did not issue a token", "Microsoft refused the sign-in request", "Microsoft sign-in is unavailable" and "Unexpected answer from Microsoft sign-in".
- The fields to fix. A description names the account's fields with the connector's labels ("SharePoint Client ID", "OneDrive Certificate", "Microsoft Outlook Client Secret"). It names the fields of the account's sign-in method: the secret for a secret account, the certificate and its password for a certificate account.
- Expiry. An expired client secret (AADSTS7000222) says so. A certificate account reads the certificate's end date from the .pfx, with no call to Microsoft. An expired certificate gives its end date. A passing sign-in gives "Certificate valid until YYYY/MM/DD", and a caveat when the certificate ends in 30 days or less.
- Pass line. "Signed in as {app name}", from the access token's
app_displaynameclaim. The claims are read without a signature check: they only name the app. Without the claim, the line names the app id. - Form run policy. On a form run, a sign-in that cannot reach Microsoft fails (
fails_when_unreachable=True). Other runs keep it Incomplete. - Form unlock. OneDrive and Outlook sign-in now set
validates_binding, as SharePoint does. Their authority host and Graph API host are bound to the credential (MicrosoftCloudBinding), and sign-in proves the credential works with them.
Graph errors (all Microsoft callers)
- Rate limit. A 429 raises
RateLimitedValidationError("Microsoft is throttling requests"), which stops the run. Before, it was a generic unexpected error. - Unreachable. A request that gets no answer after retries raises
UnreachableValidationError("Cannot reach Microsoft"). - Rejected token. A 401 gives "Microsoft rejected the app's token".
- Unexpected answer. A 5xx or another status gives "Unexpected answer from Microsoft", with the name of the request.
- Rows from the caller.
raise_for_graph_errortakes the row of a 403 (denied_row) and of a 404 or 423 (not_found_row). The connector PRs use them. - Error Details.
MicrosoftGraphErroris aSourceApiError. It carries the request method, the URL and the response body, so Error Details show them (redacted as in #16160).
Gateways. The three check_token operations return one shared MicrosoftTokenInfo (lifetime, app name, app id, certificate end date). The three connector token models are removed.
Deviations from the design
- "Directory ID not found" and "Cannot reach Microsoft sign-in": the design's descriptions end with "(HTTP 429)". A missing directory is not a 429, and a 429 at sign-in is the shared rate-limit row. I left the status out of both.
- "Secret or certificate was rejected" and "A required account field is empty": the design's text names only the secret fields. A certificate account gets the certificate fields.
- "Sign-in timed out": not done. The runner owns the timeout text for every source, so this row keeps the runner's "Timed out" line.
How Has This Been Tested?
- New unit tests (
test_microsoft_check_rows.py): every sign-in refusal line, the expired secret and certificate, the token request statuses (429, no answer, 5xx, 4xx, a body that is not JSON), the Graph rate limit, unreachable, 401 and caller rows, Error Details from a Graph refusal, the certificate end date from a real .pfx, the app name from the token, and the expiry caveat. For each of the three connectors: a failed sign-in stops the other checks, an unreachable sign-in fails only a form run, and a throttled sign-in stops the run. - Existing SharePoint, OneDrive and Outlook tests updated to the shared token model.
- Connector, server and EE unit tests: 5527 passed, 1 failed (
web/test_browser_lifecycle.py, a web connector test that also fails without this change).tyand pre-commit are clean. - The live SharePoint test (
test_sharepoint_capability_checks_live.py) checks the new sign-in line and the stopped checks. I did not run it: the test tenant's secrets are in AWS Secrets Manager, and this session has no AWS access.
Additional Options
- [Optional] Please cherry-pick this PR to the latest release version.
- [Optional] Override Linear Check
Generated by Claude Code
Summary by cubic
Unifies the SharePoint, OneDrive, and Outlook capability checks around one shared sign-in probe and shared Graph error rows. A failed sign-in now shows a single "Sign in to Microsoft" row, and every check after it reports "Not run" instead of failing with the same error.
Sign-in row
- Sign-in refusals map to the design's lines and descriptions, naming the account's fields with the connector's labels.
- An expired client secret or certificate says so; a certificate account reads the certificate's end date from the .pfx, with a caveat in the last 30 days.
- A passing sign-in shows "Signed in as {app name}" from the token's claims, or the app id when the claim is missing. A name too long for the summary is cut there and given in full in the description.
- An unreachable sign-in fails on a form run and stays Incomplete otherwise. OneDrive and Outlook sign-in now validate the credential binding, as SharePoint already did.
Graph errors and Error Details
- A 429 stops the run as
RateLimitedValidationError; no answer becomesUnreachableValidationError; a 401 and unexpected answers have their own rows. - Callers pass the rows for a 403 and a 404 or 423.
MicrosoftGraphErroris now aSourceApiErrorcarrying the request method, URL, and response body, so Error Details show them.- The three connector token models are replaced by one
MicrosoftTokenInfo.
Summary by CodeRabbit
-
New Features
- Improved SharePoint, OneDrive, and Outlook connection checks with consistent sign-in status, account details, and actionable guidance.
- Added app identity and certificate information to successful sign-in results.
- Added certificate expiration warnings and clearer credential validation messages.
- Capability checks now run in the correct order and stop when authentication fails.
-
Bug Fixes
- Improved handling and reporting for throttling, unreachable services, permission issues, and Microsoft Graph errors.
- Error details now provide more useful request and response context.
-
Documentation
- Documented shared Microsoft connector sign-in and capability-check behavior.