systemprompt_api/routes/oauth/endpoints/token/
mod.rs1pub mod generation;
12mod handler;
13pub mod validation;
14
15pub use handler::handle_token;
16
17use serde::{Deserialize, Serialize};
18
19use crate::routes::oauth::OAuthHttpError;
20
21pub type TokenResult<T> = Result<T, TokenError>;
22
23#[derive(Debug, Deserialize)]
24pub struct TokenRequest {
25 pub grant_type: String,
26 pub code: Option<String>,
27 pub redirect_uri: Option<String>,
28 pub client_id: Option<String>,
29 pub client_secret: Option<String>,
30 pub refresh_token: Option<String>,
31 pub scope: Option<String>,
32 pub code_verifier: Option<String>,
33 pub resource: Option<String>,
34 pub plugin_id: Option<String>,
35 pub audience: Option<String>,
36 pub subject_token: Option<String>,
37 pub subject_token_type: Option<String>,
38 pub actor_token: Option<String>,
39 pub actor_token_type: Option<String>,
40 pub requested_token_type: Option<String>,
41}
42
43#[derive(Debug, Serialize)]
44pub struct TokenResponse {
45 pub access_token: String,
46 pub token_type: String,
47 pub expires_in: i64,
48 #[serde(skip_serializing_if = "Option::is_none")]
49 pub refresh_token: Option<String>,
50 #[serde(skip_serializing_if = "Option::is_none")]
51 pub scope: Option<String>,
52 #[serde(skip_serializing_if = "Option::is_none")]
55 pub issued_token_type: Option<String>,
56}
57
58#[derive(Debug, thiserror::Error)]
59pub enum TokenError {
60 #[error("Invalid request: {field} {message}")]
61 InvalidRequest { field: String, message: String },
62
63 #[error("Unsupported grant type: {grant_type}")]
64 UnsupportedGrantType { grant_type: String },
65
66 #[error("Invalid client credentials")]
67 InvalidClient,
68
69 #[error("Invalid authorization code: {reason}")]
70 InvalidGrant { reason: String },
71
72 #[error("Invalid refresh token: {reason}")]
73 InvalidRefreshToken { reason: String },
74
75 #[error("Invalid credentials")]
76 InvalidCredentials,
77
78 #[error("Invalid client secret")]
79 InvalidClientSecret,
80
81 #[error("Authorization code expired")]
82 ExpiredCode,
83
84 #[error("Server error: {message}")]
85 ServerError { message: String },
86
87 #[error("Invalid target resource: {message}")]
88 InvalidTarget { message: String },
89
90 #[error("Invalid scope: {message}")]
91 InvalidScope { message: String },
92}
93
94impl From<TokenError> for OAuthHttpError {
95 fn from(error: TokenError) -> Self {
96 match error {
97 TokenError::InvalidRequest { field, message } => {
98 Self::invalid_request(format!("{field}: {message}"))
99 },
100 TokenError::UnsupportedGrantType { grant_type } => {
101 Self::unsupported_grant_type(format!("Grant type '{grant_type}' is not supported"))
102 },
103 TokenError::InvalidClient => Self::invalid_client("Client authentication failed"),
104 TokenError::InvalidGrant { reason } => Self::invalid_grant(reason),
105 TokenError::InvalidRefreshToken { reason } => {
106 Self::invalid_grant(format!("Refresh token invalid: {reason}"))
107 },
108 TokenError::InvalidCredentials => Self::invalid_grant("Invalid credentials"),
109 TokenError::InvalidClientSecret => Self::invalid_client("Invalid client secret"),
110 TokenError::ExpiredCode => Self::invalid_grant("Authorization code expired"),
111 TokenError::ServerError { message } => Self::server_error(message),
112 TokenError::InvalidTarget { message } => Self::invalid_target(message),
113 TokenError::InvalidScope { message } => Self::invalid_scope(message),
114 }
115 }
116}