Skip to main content

wae_authentication/oauth2/
types.rs

1//! OAuth2 类型定义
2
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6/// OAuth2 访问令牌响应
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct TokenResponse {
9    /// 访问令牌
10    pub access_token: String,
11
12    /// 令牌类型
13    pub token_type: String,
14
15    /// 过期时间(秒)
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub expires_in: Option<u64>,
18
19    /// 刷新令牌
20    #[serde(skip_serializing_if = "Option::is_none")]
21    pub refresh_token: Option<String>,
22
23    /// 授权范围
24    #[serde(skip_serializing_if = "Option::is_none")]
25    pub scope: Option<String>,
26
27    /// ID 令牌 (OpenID Connect)
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub id_token: Option<String>,
30}
31
32impl TokenResponse {
33    /// 创建新的令牌响应
34    pub fn new(access_token: impl Into<String>, token_type: impl Into<String>) -> Self {
35        Self {
36            access_token: access_token.into(),
37            token_type: token_type.into(),
38            expires_in: None,
39            refresh_token: None,
40            scope: None,
41            id_token: None,
42        }
43    }
44
45    /// 设置过期时间
46    pub fn with_expires_in(mut self, expires_in: u64) -> Self {
47        self.expires_in = Some(expires_in);
48        self
49    }
50
51    /// 设置刷新令牌
52    pub fn with_refresh_token(mut self, refresh_token: impl Into<String>) -> Self {
53        self.refresh_token = Some(refresh_token.into());
54        self
55    }
56
57    /// 设置授权范围
58    pub fn with_scope(mut self, scope: impl Into<String>) -> Self {
59        self.scope = Some(scope.into());
60        self
61    }
62
63    /// 设置 ID 令牌
64    pub fn with_id_token(mut self, id_token: impl Into<String>) -> Self {
65        self.id_token = Some(id_token.into());
66        self
67    }
68}
69
70/// OAuth2 授权码响应
71#[derive(Debug, Clone, Serialize, Deserialize)]
72pub struct AuthorizationCodeResponse {
73    /// 授权码
74    pub code: String,
75
76    /// 状态参数
77    pub state: Option<String>,
78}
79
80/// OAuth2 用户信息
81#[derive(Debug, Clone, Serialize, Deserialize)]
82pub struct UserInfo {
83    /// 用户唯一标识
84    #[serde(skip_serializing_if = "Option::is_none")]
85    pub sub: Option<String>,
86
87    /// 用户名
88    #[serde(skip_serializing_if = "Option::is_none")]
89    pub username: Option<String>,
90
91    /// 昵称
92    #[serde(skip_serializing_if = "Option::is_none")]
93    pub nickname: Option<String>,
94
95    /// 姓名
96    #[serde(skip_serializing_if = "Option::is_none")]
97    pub name: Option<String>,
98
99    /// 名
100    #[serde(skip_serializing_if = "Option::is_none")]
101    pub given_name: Option<String>,
102
103    /// 姓
104    #[serde(skip_serializing_if = "Option::is_none")]
105    pub family_name: Option<String>,
106
107    /// 头像 URL
108    #[serde(skip_serializing_if = "Option::is_none")]
109    pub picture: Option<String>,
110
111    /// 邮箱
112    #[serde(skip_serializing_if = "Option::is_none")]
113    pub email: Option<String>,
114
115    /// 邮箱是否已验证
116    #[serde(skip_serializing_if = "Option::is_none")]
117    pub email_verified: Option<bool>,
118
119    /// 手机号
120    #[serde(skip_serializing_if = "Option::is_none")]
121    pub phone_number: Option<String>,
122
123    /// 手机号是否已验证
124    #[serde(skip_serializing_if = "Option::is_none")]
125    pub phone_number_verified: Option<bool>,
126
127    /// 地区/语言
128    #[serde(skip_serializing_if = "Option::is_none")]
129    pub locale: Option<String>,
130
131    /// 时区
132    #[serde(skip_serializing_if = "Option::is_none")]
133    pub zoneinfo: Option<String>,
134
135    /// 其他字段
136    #[serde(flatten)]
137    pub extra: HashMap<String, serde_json::Value>,
138}
139
140impl UserInfo {
141    /// 创建新的用户信息
142    pub fn new() -> Self {
143        Self {
144            sub: None,
145            username: None,
146            nickname: None,
147            name: None,
148            given_name: None,
149            family_name: None,
150            picture: None,
151            email: None,
152            email_verified: None,
153            phone_number: None,
154            phone_number_verified: None,
155            locale: None,
156            zoneinfo: None,
157            extra: HashMap::new(),
158        }
159    }
160
161    /// 获取用户 ID
162    pub fn user_id(&self) -> Option<&str> {
163        self.sub.as_deref()
164    }
165
166    /// 获取显示名称
167    pub fn display_name(&self) -> Option<&str> {
168        self.nickname.as_deref().or(self.name.as_deref()).or(self.username.as_deref())
169    }
170}
171
172impl Default for UserInfo {
173    fn default() -> Self {
174        Self::new()
175    }
176}
177
178/// OAuth2 授权 URL 构建结果
179#[derive(Debug, Clone)]
180pub struct AuthorizationUrl {
181    /// 授权 URL
182    pub url: String,
183
184    /// 状态参数
185    pub state: String,
186
187    /// PKCE code verifier
188    pub code_verifier: Option<String>,
189}
190
191/// OAuth2 令牌刷新请求
192#[derive(Debug, Clone, Serialize, Deserialize)]
193pub struct RefreshTokenRequest {
194    /// 刷新令牌
195    pub refresh_token: String,
196
197    /// 授权范围
198    #[serde(skip_serializing_if = "Option::is_none")]
199    pub scope: Option<String>,
200}
201
202impl RefreshTokenRequest {
203    /// 创建新的刷新请求
204    pub fn new(refresh_token: impl Into<String>) -> Self {
205        Self { refresh_token: refresh_token.into(), scope: None }
206    }
207
208    /// 设置授权范围
209    pub fn with_scope(mut self, scope: impl Into<String>) -> Self {
210        self.scope = Some(scope.into());
211        self
212    }
213}
214
215/// OAuth2 错误响应
216#[derive(Debug, Clone, Serialize, Deserialize)]
217pub struct ErrorResponse {
218    /// 错误代码
219    pub error: String,
220
221    /// 错误描述
222    #[serde(skip_serializing_if = "Option::is_none")]
223    pub error_description: Option<String>,
224
225    /// 错误 URI
226    #[serde(skip_serializing_if = "Option::is_none")]
227    pub error_uri: Option<String>,
228}
229
230impl ErrorResponse {
231    /// 创建新的错误响应
232    pub fn new(error: impl Into<String>) -> Self {
233        Self { error: error.into(), error_description: None, error_uri: None }
234    }
235
236    /// 设置错误描述
237    pub fn with_description(mut self, description: impl Into<String>) -> Self {
238        self.error_description = Some(description.into());
239        self
240    }
241
242    /// 设置错误 URI
243    pub fn with_uri(mut self, uri: impl Into<String>) -> Self {
244        self.error_uri = Some(uri.into());
245        self
246    }
247}