1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//! OpenID Connect support for `boxlite auth login`.
//!
//! Houses the three flows that talk to a Dex / Auth0-style IdP:
//!
//! - [`discovery`] — resolve issuer / client_id / audience and pull the OIDC
//! well-known document so the auth-code and device-code flows know which
//! endpoints to hit.
//! - [`auth_code`] — browser-based Authorization Code with PKCE; spins up a
//! local axum listener for the redirect callback.
//! - [`device_code`] — RFC 8628 device-authorization grant for headless /
//! SSH sessions; relies on the polling helpers in `openidconnect` so we
//! don't reimplement the back-off rules.
//! - [`refresh`] — proactive refresh-token exchange called from
//! `credentials::load_active` before any authenticated request.
//!
//! The credentials file is the authoritative source of truth for OIDC
//! sessions; nothing in this module persists state on its own. Each flow
//! returns an [`OidcTokens`] value that the caller folds back into a
//! [`crate::credentials::Profile`].
use ;
use SecretString;
/// Resolved OIDC parameters needed to start any of the three flows.
///
/// Built by [`discovery::resolve`]; the fields after `issuer` are the
/// configurable surface a user can override with `--issuer`/`--client-id`/
/// `--audience` or with environment variables.
/// Optional overrides the user supplies on the CLI. `None` means "take
/// whatever the server / env tells us"; `Some(...)` wins over every other
/// source. Kept as a separate struct so each flow's arg parsing has a
/// single typed value to plumb through.
/// Tokens returned by any OIDC flow. The caller decides how to fold these
/// into a `Profile` (auth-code and device-code both produce all three; a
/// refresh response only updates `access_token` and `expires_at`).