authkestra_engine/flow/
mod.rs1#![warn(missing_docs)]
15
16use crate::auth::{error::AuthError, state::Identity, CredentialsProvider, UserMapper};
17pub use crate::auth::{ErasedOAuthFlow, Session, SessionConfig, SessionStore};
18use async_trait::async_trait;
19use serde::{Deserialize, Serialize};
20
21pub use chrono;
22
23#[derive(Debug, Clone, Serialize, Deserialize)]
25pub struct FlowContext {
26 pub state: String,
28 pub params: HashMap<String, String>,
30}
31
32#[derive(Debug, Clone, Serialize, Deserialize)]
34pub enum FlowResult {
35 Complete(Identity),
37 Redirect(String),
39 Pending,
41}
42
43#[async_trait]
45pub trait Flow: Send + Sync {
46 fn id(&self) -> &str;
48
49 async fn execute(&self, ctx: FlowContext) -> Result<FlowResult, AuthError>;
51}
52
53use std::collections::HashMap;
54
55pub use crate::engine::{Configured, Engine, EngineBuilder, Missing};
56
57pub mod client_credentials_flow;
59pub mod device_flow;
61pub mod oauth2;
63
64pub use client_credentials_flow::ClientCredentialsFlow;
65pub use device_flow::{DeviceAuthorizationResponse, DeviceFlow};
66pub use oauth2::OAuth2Flow;
67
68pub struct CredentialsFlow<P: CredentialsProvider, M: UserMapper = ()> {
70 provider: P,
71 mapper: Option<M>,
72}
73
74impl<P: CredentialsProvider> CredentialsFlow<P, ()> {
75 pub fn new(provider: P) -> Self {
77 Self {
78 provider,
79 mapper: None,
80 }
81 }
82}
83
84impl<P: CredentialsProvider, M: UserMapper> CredentialsFlow<P, M> {
85 pub fn with_mapper(provider: P, mapper: M) -> Self {
87 Self {
88 provider,
89 mapper: Some(mapper),
90 }
91 }
92
93 pub async fn authenticate(
95 &self,
96 creds: P::Credentials,
97 ) -> Result<(Identity, Option<M::LocalUser>), AuthError> {
98 let identity = self.provider.authenticate(creds).await?;
99
100 let local_user = if let Some(mapper) = &self.mapper {
101 Some(mapper.map_user(&identity).await?)
102 } else {
103 None
104 };
105
106 Ok((identity, local_user))
107 }
108}