alibi_plugins/oauth_provider/
token_storage.rs1use alibi_core::AuthResult;
3use alibi_core::store::OAuthTokenKind;
4use async_trait::async_trait;
5use base64::{Engine as _, engine::general_purpose::URL_SAFE_NO_PAD};
6use sha2::{Digest as _, Sha256};
7
8#[async_trait]
11pub trait OAuthTokenHasher: Send + Sync + std::fmt::Debug {
12 async fn hash(&self, token: &str, kind: &str) -> AuthResult<String>;
13}
14impl super::OAuthProviderPlugin {
15 fn token_prefix(&self, kind: OAuthTokenKind) -> &str {
16 match kind {
17 OAuthTokenKind::Access => self.config.opaque_access_token_prefix.as_deref(),
18 OAuthTokenKind::Refresh => self.config.refresh_token_prefix.as_deref(),
19 }
20 .unwrap_or_default()
21 }
22
23 pub(super) fn encode_token_prefix(&self, token: &str, kind: OAuthTokenKind) -> String {
24 format!("{}{token}", self.token_prefix(kind))
25 }
26
27 pub(super) fn decode_token_prefix<'a>(
30 &self,
31 token: &'a str,
32 kind: OAuthTokenKind,
33 ) -> Option<&'a str> {
34 let prefix = self.token_prefix(kind);
35 if prefix.is_empty() {
36 Some(token)
37 } else {
38 token.strip_prefix(prefix)
39 }
40 }
41
42 pub async fn hash_token(&self, token: &str, kind: &str) -> AuthResult<String> {
44 if let Some(hasher) = &self.config.token_hasher {
45 hasher.hash(token, kind).await
46 } else {
47 Ok(URL_SAFE_NO_PAD.encode(Sha256::digest(token)))
48 }
49 }
50}