use std::sync::Arc;
use jsonwebtoken::{decode, DecodingKey, Validation};
use crate::error::InternalError;
use crate::rest_api::{
auth::{AuthorizationHeader, BearerToken},
secrets::SecretManager,
sessions::Claims,
};
use super::{Identity, IdentityProvider};
#[derive(Clone)]
pub struct BiomeUserIdentityProvider {
token_secret_manager: Arc<dyn SecretManager>,
validation: Validation,
}
impl BiomeUserIdentityProvider {
pub fn new(token_secret_manager: Arc<dyn SecretManager>, validation: Validation) -> Self {
Self {
token_secret_manager,
validation,
}
}
}
impl IdentityProvider for BiomeUserIdentityProvider {
fn get_identity(
&self,
authorization: &AuthorizationHeader,
) -> Result<Option<Identity>, InternalError> {
let token = match authorization {
AuthorizationHeader::Bearer(BearerToken::Biome(token)) => token,
_ => return Ok(None),
};
let secret = self
.token_secret_manager
.secret()
.map_err(|err| InternalError::from_source(err.into()))?;
Ok(decode::<Claims>(
token,
&DecodingKey::from_secret(secret.as_ref()),
&self.validation,
)
.map(|token_data| Identity::User(token_data.claims.user_id()))
.ok())
}
fn clone_box(&self) -> Box<dyn IdentityProvider> {
Box::new(self.clone())
}
}