pub struct UserAccessToken { /* private fields */ }Expand description
A user access token obtained from the device flow.
Non-expiring, and non-renewable. The published App opts out of user-token expiration, so GitHub issues no renewal token alongside this one and there is nothing to renew — see the crate documentation. The token is invalidated only by the user uninstalling the App or revoking the authorization at GitHub.
Debug is written by hand. Deriving it here would put the token into every
tracing field, every unwrap() panic message, and every anyhow chain
that ever carries one, which is the exact leak 07-security.md gates on.
Implementations§
Source§impl UserAccessToken
impl UserAccessToken
pub fn new(token: SecretString) -> Self
Sourcepub fn from_stored(token: SecretString) -> Self
pub fn from_stored(token: SecretString) -> Self
Rebuild the credential d2 handed back, for f1.
Sourcepub fn from_stored_document(stored: &SecretString) -> Self
pub fn from_stored_document(stored: &SecretString) -> Self
Reads whichever of the two stored shapes is there.
§Why the store holds a document now, and why the old shape still loads
A renewable credential is three values – access token, refresh token, and when each stops working – where there used to be one string. The secret store takes one opaque value per host, so the document goes inside it rather than the store growing a schema: no platform change, no migration step, and the same DPAPI blob or keychain item as before.
A value that is not this document is a bare access token, which is what every host stored until now. That is not a fallback for tidiness: upgrading must not log anybody out, and the App’s expiration setting can be turned on – or back off – without stranding hosts that are mid-way through either. A token has no internal structure to confuse with JSON, so the discrimination is unambiguous.
Sourcepub fn to_stored_document(&self) -> SecretString
pub fn to_stored_document(&self) -> SecretString
The value to hand the secret store.
Always the document, even for a credential with no renewal half: one shape written means one shape to reason about, and reading still accepts the bare token that older versions wrote.
Sourcepub fn secret(&self) -> &SecretString
pub fn secret(&self) -> &SecretString
The token itself. Every call site of this is a place a secret can escape,
so there are deliberately few: the Authorization header, and d2’s
store call.
pub fn token_type(&self) -> &str
pub fn scope(&self) -> Option<&str>
Sourcepub fn family(&self) -> &str
pub fn family(&self) -> &str
The token’s four-character family prefix — ghu_ for an App
user-to-server token — and nothing else.
This exists so diagnostics can answer “did the device flow return the kind of token we expected?” without exposing the token. The D17 spike asserted exactly this and no more.
Sourcepub fn is_user_to_server(&self) -> bool
pub fn is_user_to_server(&self) -> bool
true for the ghu_ family the published App issues.
Trait Implementations§
Source§impl Clone for UserAccessToken
impl Clone for UserAccessToken
Source§fn clone(&self) -> UserAccessToken
fn clone(&self) -> UserAccessToken
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for UserAccessToken
impl Debug for UserAccessToken
impl Eq for UserAccessToken
Source§impl PartialEq for UserAccessToken
impl PartialEq for UserAccessToken
Source§fn eq(&self, other: &Self) -> bool
fn eq(&self, other: &Self) -> bool
Equality exists so device_flow::PollOutcome can carry a token and
still be compared in a test. Production code never compares two
credentials, and this is not a constant-time comparison.
Auto Trait Implementations§
impl Freeze for UserAccessToken
impl RefUnwindSafe for UserAccessToken
impl Send for UserAccessToken
impl Sync for UserAccessToken
impl Unpin for UserAccessToken
impl UnsafeUnpin for UserAccessToken
impl UnwindSafe for UserAccessToken
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.