alibi_plugins/oauth_provider/
refresh_format.rs1use alibi_core::AuthResult;
3use async_trait::async_trait;
4use std::{future::Future, pin::Pin};
5
6pub enum OAuthRefreshTokenEncryption {
14 Immediate(String),
15 Promise(Pin<Box<dyn Future<Output = AuthResult<String>> + Send + 'static>>),
16}
17
18#[derive(Debug, Clone)]
21pub struct OAuthDecodedRefreshToken {
22 pub token: String,
23 pub session_id: Option<String>,
24}
25
26#[async_trait]
29pub trait OAuthRefreshTokenFormatter: Send + Sync + std::fmt::Debug {
30 fn encrypt(
32 &self,
33 token: &str,
34 session_id: Option<&str>,
35 ) -> AuthResult<OAuthRefreshTokenEncryption>;
36
37 async fn decrypt(&self, token: &str) -> AuthResult<OAuthDecodedRefreshToken>;
39}
40
41impl super::OAuthProviderPlugin {
42 pub(super) fn encode_refresh_token(
43 &self,
44 token: &str,
45 session_id: Option<&str>,
46 ) -> AuthResult<String> {
47 let formatted = match &self.config.refresh_token_formatter {
48 None => token.to_owned(),
49 Some(formatter) => match formatter.encrypt(token, session_id)? {
50 OAuthRefreshTokenEncryption::Immediate(value) => value,
51 OAuthRefreshTokenEncryption::Promise(future) => {
52 drop(tokio::spawn(future));
56 "[object Promise]".to_owned()
57 }
58 },
59 };
60 Ok(self.encode_token_prefix(&formatted, alibi_core::store::OAuthTokenKind::Refresh))
61 }
62
63 pub(super) async fn decode_refresh_token(
64 &self,
65 token: &str,
66 ) -> AuthResult<Option<OAuthDecodedRefreshToken>> {
67 let Some(token) =
68 self.decode_token_prefix(token, alibi_core::store::OAuthTokenKind::Refresh)
69 else {
70 return Ok(None);
71 };
72 Ok(Some(match &self.config.refresh_token_formatter {
73 Some(formatter) => formatter.decrypt(token).await?,
74 None => OAuthDecodedRefreshToken {
75 token: token.to_owned(),
76 session_id: None,
77 },
78 }))
79 }
80}