pub struct Auth {
pub token_store: TokenStore,
/* private fields */
}Expand description
Manages authentication for X API requests.
Holds the credential matrix (env-supplied vs store-derived client_id /
client_secret), the active app name, and the TokenStore that
persists tokens to disk. Constructed via Auth::new (legacy
~/.xurl path) or Auth::new_with_store_path (test-friendly explicit
path).
Fields§
§token_store: TokenStoreToken store backing this Auth instance.
Implementations§
Source§impl Auth
impl Auth
Sourcepub fn new(cfg: &Config) -> Self
pub fn new(cfg: &Config) -> Self
Creates a new Auth object using the legacy ~/.xurl token-store path.
Shim over Auth::new_with_store_path resolving to
Config::default_store_path. Credentials are resolved: env vars -> active app.
Sourcepub fn new_with_store_path(cfg: &Config, store_path: &Path) -> Self
pub fn new_with_store_path(cfg: &Config, store_path: &Path) -> Self
Creates a new Auth object backed by an explicit token-store path.
The canonical constructor. Tests pass a TempDir-rooted path to avoid
touching the real ~/.xurl; the binary calls Auth::new which
resolves to Config::default_store_path. Credentials are resolved:
env vars -> active app at store_path.
Runs the three-level redirect URI resolver (env > app-stored >
built-in default) against the constructed token store and writes the
result back into the owned Config, satisfying KTD2’s single source
of truth invariant.
Sourcepub fn with_app_name(&mut self, app_name: &str)
pub fn with_app_name(&mut self, app_name: &str)
Sets the explicit app name override and re-resolves the redirect URI.
Credentials honor env precedence per the internal
client_id_from_env / client_secret_from_env flags:
env-supplied values survive the switch; store-derived values
get re-resolved from the new app’s
entry, even when the previous app’s stored value was non-empty.
The redirect URI is always re-resolved (env-precedence is enforced
inside the resolver itself, so re-running unconditionally produces
the right value per KTD3).
Sourcepub fn get_oauth1_header(
&self,
method: &str,
url_str: &str,
additional_params: Option<&BTreeMap<String, String>>,
) -> Result<String>
pub fn get_oauth1_header( &self, method: &str, url_str: &str, additional_params: Option<&BTreeMap<String, String>>, ) -> Result<String>
Gets the OAuth1 Authorization header for a request.
§Errors
Returns an error if no OAuth1 token is found or signature generation fails.
Sourcepub fn get_oauth2_header(&mut self, username: &str) -> Result<String>
pub fn get_oauth2_header(&mut self, username: &str) -> Result<String>
Gets or refreshes an OAuth2 token and returns the Authorization header.
Lookup precedence is intent-split per KTD5:
- non-empty
username(named caller): try the username’s own token first; on miss, fall through toTokenStore::get_first_oauth2_token_for_app(which itself prefersdefault_user, then arbitrary-first); on total miss, trigger the full OAuth2 flow. The unnamed (/me-failed salvage) slot is never consulted on this branch — a caller who supplies a username has explicit identity intent and must not silently receive a salvage-state token under their name. - empty
username: tryget_first_oauth2_token_for_app(which prefersdefault_user, then arbitrary-first); on miss, fall through to the unnamed slot viaTokenStore::get_oauth2_token_unnamed_for_app; on total miss, trigger the OAuth2 flow.
In both branches the cached-token path delegates to
Auth::refresh_oauth2_token, which is a no-op if the token is still
valid.
§Errors
Returns an error if the OAuth2 flow fails or token refresh fails.
Sourcepub fn oauth2_flow(
&mut self,
username: &str,
out: &OutputConfig,
stdout: &mut dyn Write,
) -> Result<String>
pub fn oauth2_flow( &mut self, username: &str, out: &OutputConfig, stdout: &mut dyn Write, ) -> Result<String>
Starts the OAuth2 PKCE flow with the default open::that browser opener.
Browser-failure prompts are written to stdout via out’s
print_message, so callers can capture them in tests. Library
consumers needing a custom opener (recording / headless / tests for
the listener-before-browser ordering) call
oauth2::run_oauth2_flow directly with their own fn(&str) -> io::Result<()> opener.
§Errors
Returns an error if the authorization flow, token exchange, or username resolution fails.
Sourcepub fn refresh_oauth2_token(&mut self, username: &str) -> Result<String>
pub fn refresh_oauth2_token(&mut self, username: &str) -> Result<String>
Validates and refreshes an OAuth2 token if needed.
§Errors
Returns an error if no token is found or the refresh request fails.
Sourcepub fn remote_oauth2_step1(&self, pending_path: &Path) -> Result<String>
pub fn remote_oauth2_step1(&self, pending_path: &Path) -> Result<String>
Runs step 1 of the remote OAuth2 PKCE flow.
Returns the authorization URL that the user should open in a browser on another machine.
§Errors
Returns an error if the authorization URL is invalid or the pending state file cannot be written.
Sourcepub fn remote_oauth2_step2(
&mut self,
redirect_url: &str,
username: &str,
pending_path: &Path,
) -> Result<String>
pub fn remote_oauth2_step2( &mut self, redirect_url: &str, username: &str, pending_path: &Path, ) -> Result<String>
Runs step 2 of the remote OAuth2 PKCE flow.
Takes the redirect URL from the browser, extracts the authorization code, exchanges it for an access token, and saves the token.
§Errors
Returns an error if the pending state is missing/expired/invalid, the token exchange fails, or the username cannot be resolved.
Sourcepub fn get_bearer_token_header(&self) -> Result<String>
pub fn get_bearer_token_header(&self) -> Result<String>
Gets the bearer token Authorization header.
Resolution order: XURL_BEARER_TOKEN env var first (one-shot agent
flows that pipe a secret without persisting it to disk), then the
token store entry on the resolved app. Empty env values fall through
to the store. The env var matches the precedence shape used by every
other agentic flag (XURL_VERBOSE, XURL_OUTPUT, XURL_NO_BROWSER,
etc.) and pairs with XURL_OUTPUT=json xr ... --auth app for stateless
container invocations.
Production code reads XURL_BEARER_TOKEN from the process environment.
The resolution logic is factored into resolve_bearer_token so unit
tests can exercise every precedence path without mutating the global
environment (the project policy in MEMORY: no env mutation in tests,
no #[serial]).
§Errors
Returns an error if XURL_BEARER_TOKEN is unset (or empty) AND no
bearer token is stored for the resolved app.
Sourcepub fn with_token_store(self, token_store: TokenStore) -> Self
pub fn with_token_store(self, token_store: TokenStore) -> Self
Replaces the token store (used in integration tests).
Honors the internal env-precedence flags
(client_id_from_env / client_secret_from_env):
env-supplied values survive the swap; store-derived values get
re-resolved from the new store’s
active app. Replaces the older equality-based heuristic
(self.client_id == old_app.client_id) which produced false
negatives when the old and new stores happened to share a value.
Sourcepub fn token_store(&self) -> &TokenStore
pub fn token_store(&self) -> &TokenStore
Returns a reference to the token store.
Sourcepub fn client_id(&self) -> &str
pub fn client_id(&self) -> &str
Returns the active OAuth2 client ID (env-supplied or store-derived).
Sourcepub fn client_secret(&self) -> &str
pub fn client_secret(&self) -> &str
Returns the active OAuth2 client secret (env-supplied or store-derived).
Sourcepub fn redirect_uri(&self) -> &str
pub fn redirect_uri(&self) -> &str
Returns the resolved OAuth2 redirect URI.
The value already reflects the three-level precedence (env >
app-stored > built-in default) applied at construction by
Auth::new_with_store_path.
Sourcepub fn http_timeout_secs(&self) -> u64
pub fn http_timeout_secs(&self) -> u64
Per-request HTTP timeout in seconds for OAuth2 token exchange,
refresh, and /2/users/me lookups. Mirrors the --timeout flag.