use std::{convert::Infallible, time::Duration};
use crate::core::crypto::signer::{JwsSigner, JwsSignerSelector};
use crate::{
core::{
jwt::{JwsSerializationError, Jwt},
platform::{MaybeSend, MaybeSendSync},
secrets::SecretString,
},
grant::authorization_code::types::AuthorizationPayloadWithClientId,
};
pub trait Jar: MaybeSendSync {
type Error: crate::core::Error;
fn generate_request_object(
&self,
audience: &str,
authorization_payload: AuthorizationPayloadWithClientId<'_>,
) -> impl Future<Output = Result<Option<SecretString>, Self::Error>> + MaybeSend;
}
#[derive(Debug, Clone, Copy)]
pub struct NoJar;
impl Jar for NoJar {
type Error = Infallible;
async fn generate_request_object(
&self,
_audience: &str,
_authorization_payload: AuthorizationPayloadWithClientId<'_>,
) -> Result<Option<SecretString>, Self::Error> {
Ok(None)
}
}
impl<S: JwsSignerSelector> Jar for S {
type Error = JwsSerializationError<<S::Signer as JwsSigner>::Error>;
async fn generate_request_object(
&self,
audience: &str,
authorization_payload: AuthorizationPayloadWithClientId<'_>,
) -> Result<Option<SecretString>, Self::Error> {
Jwt::builder()
.issuer(authorization_payload.client_id)
.audience(audience)
.issued_now_expires_after(Duration::from_mins(1))
.claims(authorization_payload)
.build()
.to_jws_compact(&self.select_signer())
.await
.map(Some)
}
}