Skip to main content

systemprompt_api/routes/oauth/endpoints/token/
mod.rs

1mod generation;
2mod handler;
3mod validation;
4
5pub use handler::handle_token;
6
7use serde::{Deserialize, Serialize};
8
9pub type TokenResult<T> = Result<T, TokenError>;
10
11#[derive(Debug, Deserialize)]
12pub struct TokenRequest {
13    pub grant_type: String,
14    pub code: Option<String>,
15    pub redirect_uri: Option<String>,
16    pub client_id: Option<String>,
17    pub client_secret: Option<String>,
18    pub refresh_token: Option<String>,
19    pub scope: Option<String>,
20    pub code_verifier: Option<String>,
21    pub resource: Option<String>,
22}
23
24#[derive(Debug, Serialize)]
25
26pub struct TokenResponse {
27    pub access_token: String,
28    pub token_type: String,
29    pub expires_in: i64,
30    pub refresh_token: Option<String>,
31    pub scope: Option<String>,
32}
33
34#[derive(Debug, thiserror::Error)]
35pub enum TokenError {
36    #[error("Invalid request: {field} {message}")]
37    InvalidRequest { field: String, message: String },
38
39    #[error("Unsupported grant type: {grant_type}")]
40    UnsupportedGrantType { grant_type: String },
41
42    #[error("Invalid client credentials")]
43    InvalidClient,
44
45    #[error("Invalid authorization code: {reason}")]
46    InvalidGrant { reason: String },
47
48    #[error("Invalid refresh token: {reason}")]
49    InvalidRefreshToken { reason: String },
50
51    #[error("Invalid credentials")]
52    InvalidCredentials,
53
54    #[error("Invalid client secret")]
55    InvalidClientSecret,
56
57    #[error("Authorization code expired")]
58    ExpiredCode,
59
60    #[error("Server error: {message}")]
61    ServerError { message: String },
62}
63
64#[derive(Debug, Serialize)]
65
66pub struct TokenErrorResponse {
67    pub error: String,
68    pub error_description: Option<String>,
69}
70
71impl From<TokenError> for TokenErrorResponse {
72    fn from(error: TokenError) -> Self {
73        let (error_type, description) = match &error {
74            TokenError::InvalidRequest { field, message } => {
75                ("invalid_request", Some(format!("{field}: {message}")))
76            },
77            TokenError::UnsupportedGrantType { grant_type } => (
78                "unsupported_grant_type",
79                Some(format!("Grant type '{grant_type}' is not supported")),
80            ),
81            TokenError::InvalidClient => (
82                "invalid_client",
83                Some("Client authentication failed".to_string()),
84            ),
85            TokenError::InvalidGrant { reason } => ("invalid_grant", Some(reason.clone())),
86            TokenError::InvalidRefreshToken { reason } => (
87                "invalid_grant",
88                Some(format!("Refresh token invalid: {reason}")),
89            ),
90            TokenError::InvalidCredentials => {
91                ("invalid_grant", Some("Invalid credentials".to_string()))
92            },
93            TokenError::InvalidClientSecret => {
94                ("invalid_client", Some("Invalid client secret".to_string()))
95            },
96            TokenError::ExpiredCode => (
97                "invalid_grant",
98                Some("Authorization code expired".to_string()),
99            ),
100            TokenError::ServerError { message } => ("server_error", Some(message.clone())),
101        };
102
103        Self {
104            error: error_type.to_string(),
105            error_description: description,
106        }
107    }
108}