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