Skip to main content

CredentialStore

Struct CredentialStore 

Source
pub struct CredentialStore {
    using_keyring: bool,
    credentials_path: PathBuf,
    encryption_key: [u8; 32],
    legacy_key: [u8; 32],
}
Expand description

Credential storage manager

Fields§

§using_keyring: bool

Whether we’re using keyring (true) or encrypted file (false)

§credentials_path: PathBuf

Path to the encrypted credentials file (fallback)

§encryption_key: [u8; 32]

Encryption key for the file fallback. Random and persisted, so it does not change when the machine is renamed.

§legacy_key: [u8; 32]

The pre-existing derivation, retained only to read a file written before the key was persisted. Anything decrypted with it is rewritten under encryption_key.

Implementations§

Source§

impl CredentialStore

Source

pub fn new() -> Self

Create a new credential store, detecting the best available backend

Source

pub fn is_using_keyring(&self) -> bool

Check if we’re using the secure keyring backend

Source

pub fn save_token( &self, user_id: &str, token: &str, ) -> Result<CredentialResult, CredentialError>

Save an access token for a user

Source

pub fn get_token(&self, user_id: &str) -> Result<String, CredentialError>

Get an access token for a user

Source

pub fn delete_token(&self, user_id: &str) -> Result<(), CredentialError>

Delete an access token for a user

Source

fn test_keyring_available() -> bool

Source

fn test_keyring_inner() -> bool

Source

fn save_to_keyring( &self, user_id: &str, token: &str, ) -> Result<(), CredentialError>

Source

fn get_from_keyring(&self, user_id: &str) -> Result<String, CredentialError>

Source

fn delete_from_keyring(&self, user_id: &str) -> Result<(), CredentialError>

Source

fn get_key_path() -> PathBuf

Where the fallback key lives: beside the credentials file, so the two travel together and a restore that brings one brings the other.

Source

fn get_credentials_path() -> PathBuf

Source

fn derive_legacy_encryption_key() -> [u8; 32]

The key derivation used before keys were persisted.

Kept only so a credentials file written by an older build can still be read once and rewritten under the persisted key. Never used to encrypt. See the module docs for why it was replaced.

TRACES: UR-012 | IR-014

Source

fn load_credentials_file(&self) -> Result<Value, CredentialError>

Load and decrypt the credential map.

A file that is present but undecryptable is deliberately reported as an empty credential set rather than as an error. The key never leaves the device it was derived on (Android Keystore keys are never backed up, and the file fallback’s key is derived from machine identifiers), so a restored/transferred install gets ciphertext with no key and every read would fail permanently. Surfacing that as an error made session restore throw instead of falling back to the login screen: an unrecoverable app rather than a clean logged-out one. The next successful login re-encrypts the file with the current key, so the state self-heals.

TRACES: UR-012 | IR-014

Source

fn save_credentials_file(&self, data: &Value) -> Result<(), CredentialError>

Source

fn encrypt(&self, plaintext: &str) -> Result<String, CredentialError>

Source

fn decrypt_migrating( &self, encrypted: &str, ) -> Result<(String, bool), CredentialError>

Decrypt with the current key, falling back to the legacy derivation.

Returns the plaintext and whether the legacy key was what opened it, so the caller can rewrite the file under the current key and stop depending on a derivation that changes when the machine is renamed.

TRACES: UR-012 | IR-014 | UT-014

Source

fn save_to_file( &self, user_id: &str, token: &str, ) -> Result<(), CredentialError>

Source

fn get_from_file(&self, user_id: &str) -> Result<String, CredentialError>

Source

fn delete_from_file(&self, user_id: &str) -> Result<(), CredentialError>

Trait Implementations§

Source§

impl Default for CredentialStore

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> NoneValue for T
where T: Default,

§

type NoneType = T

§

fn null_value() -> T

The none-equivalent value.
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more