#![warn(missing_docs)]
use crate::auth::{error::AuthError, state::Identity, CredentialsProvider, UserMapper};
pub use crate::auth::{ErasedOAuthFlow, Session, SessionConfig, SessionStore};
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
pub use chrono;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FlowContext {
pub state: String,
pub params: HashMap<String, String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum FlowResult {
Complete(Identity),
Redirect(String),
Pending,
}
#[async_trait]
pub trait Flow: Send + Sync {
fn id(&self) -> &str;
async fn execute(&self, ctx: FlowContext) -> Result<FlowResult, AuthError>;
}
use std::collections::HashMap;
pub use crate::engine::{Configured, Engine, EngineBuilder, Missing};
pub mod client_credentials_flow;
pub mod device_flow;
pub mod oauth2;
pub use client_credentials_flow::ClientCredentialsFlow;
pub use device_flow::{DeviceAuthorizationResponse, DeviceFlow};
pub use oauth2::OAuth2Flow;
pub struct CredentialsFlow<P: CredentialsProvider, M: UserMapper = ()> {
provider: P,
mapper: Option<M>,
}
impl<P: CredentialsProvider> CredentialsFlow<P, ()> {
pub fn new(provider: P) -> Self {
Self {
provider,
mapper: None,
}
}
}
impl<P: CredentialsProvider, M: UserMapper> CredentialsFlow<P, M> {
pub fn with_mapper(provider: P, mapper: M) -> Self {
Self {
provider,
mapper: Some(mapper),
}
}
pub async fn authenticate(
&self,
creds: P::Credentials,
) -> Result<(Identity, Option<M::LocalUser>), AuthError> {
let identity = self.provider.authenticate(creds).await?;
let local_user = if let Some(mapper) = &self.mapper {
Some(mapper.map_user(&identity).await?)
} else {
None
};
Ok((identity, local_user))
}
}