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