Skip to main content

doido_auth/controllers/
oauth.rs

1//! Default OAuth redirect/callback controller.
2
3use crate::error::AuthError;
4use crate::oauth::get_provider;
5use crate::state::global;
6use doido_auth_macros::auth_controller;
7use doido_controller::axum::http::StatusCode;
8use doido_controller::axum::response::{IntoResponse, Redirect, Response};
9use doido_core::Result;
10use serde::Deserialize;
11
12/// Default OAuth controller for [`auth_routes!`](crate::auth_routes).
13pub struct AuthOauth;
14
15#[derive(Debug, Deserialize)]
16struct OAuthCallbackQuery {
17    code: String,
18    #[allow(dead_code)]
19    state: Option<String>,
20}
21
22#[auth_controller]
23impl AuthOauth {
24    /// GET `/auth/{provider}` — start the OAuth authorization flow.
25    pub async fn authorize(ctx: doido_controller::Context) -> Result<Response> {
26        let provider = ctx.param("provider").unwrap_or("unknown");
27        let state = global();
28        let oauth = state
29            .oauth
30            .get(provider)
31            .cloned()
32            .or_else(|| get_provider(provider))
33            .ok_or_else(|| AuthError::OAuth(format!("unknown provider {provider}")))?;
34        let url = oauth.authorize_url(&uuid::Uuid::new_v4().to_string())?;
35        Ok(Redirect::temporary(&url).into_response())
36    }
37
38    /// GET `/auth/{provider}/callback` — OAuth provider callback.
39    pub async fn callback(ctx: doido_controller::Context) -> Result<Response> {
40        let provider = ctx.param("provider").unwrap_or("unknown").to_string();
41        let query: OAuthCallbackQuery = ctx.params()?;
42        let state = global();
43        let oauth = state
44            .oauth
45            .get(&provider)
46            .cloned()
47            .or_else(|| get_provider(&provider))
48            .ok_or_else(|| AuthError::OAuth(format!("unknown provider {provider}")))?;
49        let tokens = oauth.exchange_code(&query.code)?;
50        Ok((StatusCode::OK, doido_controller::axum::Json(tokens)).into_response())
51    }
52}