core_crypto/e2e_identity/
refresh_token.rs

1use super::error::{Error, Result};
2use crate::KeystoreError;
3use core_crypto_keystore::connection::FetchFromDatabase;
4use core_crypto_keystore::entities::E2eiRefreshToken;
5use mls_crypto_provider::MlsCryptoProvider;
6use zeroize::Zeroize;
7
8/// An OIDC refresh token managed by CoreCrypto to benefit from encryption-at-rest
9#[derive(Debug, serde::Serialize, serde::Deserialize, Zeroize, derive_more::From, derive_more::Deref)]
10#[zeroize(drop)]
11pub struct RefreshToken(String);
12
13impl RefreshToken {
14    pub(crate) async fn find(key_store: &impl FetchFromDatabase) -> Result<RefreshToken> {
15        key_store
16            .find_unique::<E2eiRefreshToken>()
17            .await
18            .map_err(KeystoreError::wrap("finding refresh token"))?
19            .try_into()
20    }
21
22    pub(crate) async fn replace(self, backend: &MlsCryptoProvider) -> Result<()> {
23        let keystore = backend.keystore();
24        let rt = E2eiRefreshToken::from(self);
25        keystore
26            .save(rt)
27            .await
28            .map_err(KeystoreError::wrap("replacing refresh token"))?;
29        Ok(())
30    }
31}
32
33impl TryFrom<E2eiRefreshToken> for RefreshToken {
34    type Error = Error;
35
36    fn try_from(mut entity: E2eiRefreshToken) -> Result<Self> {
37        let content = std::mem::take(&mut entity.content);
38        let content = String::from_utf8(content).map_err(|_| Error::InvalidRefreshToken)?;
39        Ok(Self(content))
40    }
41}
42
43impl From<RefreshToken> for E2eiRefreshToken {
44    fn from(mut rt: RefreshToken) -> Self {
45        let content = std::mem::take(&mut rt.0);
46        Self {
47            content: content.into_bytes(),
48        }
49    }
50}