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