1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
use serde::{Deserialize, Serialize};
/// API DTOs for OAuth2 endpoints - these define the wire format
/// Separate from domain models to allow API versioning without affecting business logic
#[derive(Debug, Serialize, Deserialize)]
pub struct AuthorizeRequestDto {
pub client_id: String,
pub redirect_uri: String,
pub response_type: String,
pub scope: Option<String>,
pub state: Option<String>,
pub code_challenge: Option<String>,
pub code_challenge_method: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct TokenRequestDto {
pub grant_type: String,
pub code: Option<String>,
pub refresh_token: Option<String>,
pub redirect_uri: Option<String>,
pub client_id: Option<String>,
pub client_secret: Option<String>,
pub code_verifier: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct TokenResponseDto {
pub access_token: String,
pub token_type: String,
pub expires_in: u64,
#[serde(skip_serializing_if = "Option::is_none")]
pub refresh_token: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub scope: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ErrorResponseDto {
pub error: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub error_description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error_uri: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct IntrospectionRequestDto {
pub token: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub token_type_hint: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct IntrospectionResponseDto {
pub active: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub client_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub username: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub scope: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub exp: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub iat: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sub: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub aud: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub iss: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub jti: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct RevocationRequestDto {
pub token: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub token_type_hint: Option<String>,
}
// Conversion traits between DTOs and domain models
impl From<crate::domain::AuthorizationRequest> for AuthorizeRequestDto {
fn from(req: crate::domain::AuthorizationRequest) -> Self {
Self {
client_id: req.client_id,
redirect_uri: req.redirect_uri,
response_type: req.response_type,
scope: req.scope,
state: req.state,
code_challenge: req.code_challenge,
code_challenge_method: req.code_challenge_method,
}
}
}
impl From<AuthorizeRequestDto> for crate::domain::AuthorizationRequest {
fn from(dto: AuthorizeRequestDto) -> Self {
Self {
client_id: dto.client_id,
redirect_uri: dto.redirect_uri,
response_type: dto.response_type,
scope: dto.scope,
state: dto.state,
code_challenge: dto.code_challenge,
code_challenge_method: dto.code_challenge_method,
}
}
}
impl From<crate::domain::TokenResult> for TokenResponseDto {
fn from(result: crate::domain::TokenResult) -> Self {
Self {
access_token: result.access_token,
token_type: result.token_type,
expires_in: result.expires_in,
refresh_token: result.refresh_token,
scope: result.scope,
}
}
}
impl From<crate::domain::OAuthError> for ErrorResponseDto {
fn from(error: crate::domain::OAuthError) -> Self {
Self {
error: error.error_code,
error_description: error.description,
error_uri: error.uri,
}
}
}
|