use alibi_core::{AuthResult, SessionView, UserView};
use async_trait::async_trait;
use std::{collections::HashMap, sync::Arc};
pub struct OAuthInteractionContext<'a> {
pub headers: &'a HashMap<String, String>,
pub user: &'a UserView,
pub session: &'a SessionView,
pub scopes: &'a [String],
}
pub struct OAuthPostLoginContext<'a> {
pub headers: &'a HashMap<String, String>,
pub user: &'a UserView,
pub session: &'a SessionView,
pub scopes: &'a [String],
pub is_continuation: bool,
}
#[async_trait]
pub trait OAuthPostLoginPolicy: Send + Sync + std::fmt::Debug {
async fn should_redirect(&self, input: OAuthPostLoginContext<'_>) -> AuthResult<bool>;
}
pub struct OAuthConsentReferenceContext<'a> {
pub user: &'a UserView,
pub session: &'a SessionView,
pub scopes: &'a [String],
}
#[async_trait]
pub trait OAuthConsentReference: Send + Sync + std::fmt::Debug {
async fn consent_reference_id(
&self,
input: OAuthConsentReferenceContext<'_>,
) -> AuthResult<Option<String>>;
}
#[derive(Debug, Clone)]
pub struct OAuthPostLoginConfig {
pub page: String,
pub should_redirect: Arc<dyn OAuthPostLoginPolicy>,
pub consent_reference_id: Option<Arc<dyn OAuthConsentReference>>,
}
impl super::OAuthProviderPlugin {
pub(super) async fn consent_reference_id(
&self,
user: &UserView,
session: &SessionView,
scopes: &[String],
) -> AuthResult<Option<String>> {
let Some(reference) = self
.config
.post_login
.as_ref()
.and_then(|config| config.consent_reference_id.as_ref())
else {
return Ok(None);
};
reference
.consent_reference_id(OAuthConsentReferenceContext {
user,
session,
scopes,
})
.await
.map(|reference| reference.filter(|reference| !reference.is_empty()))
.map_err(|error| {
if alibi_core::endpoint::is_endpoint_api_error(&error) {
error
} else {
alibi_core::AuthError::CallbackFailure(Box::new(error))
}
})
}
}
pub(super) fn consent_matches_reference(
metadata: &serde_json::Value,
reference: Option<&str>,
) -> bool {
let stored = metadata
.get("referenceId")
.and_then(serde_json::Value::as_str)
.filter(|stored| !stored.is_empty());
stored == reference
}