1use serde::{Deserialize, Serialize};
6
7use crate::common::{GrantId, Provider};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
11#[serde(rename_all = "lowercase")]
12pub enum GrantStatus {
13 Valid,
15 Invalid,
17}
18
19#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
45pub struct Grant {
46 pub id: GrantId,
48
49 pub provider: Provider,
51
52 #[serde(skip_serializing_if = "Option::is_none")]
54 pub grant_status: Option<GrantStatus>,
55
56 #[serde(skip_serializing_if = "Option::is_none")]
58 pub email: Option<String>,
59
60 #[serde(skip_serializing_if = "Option::is_none")]
62 pub scope: Option<Vec<String>>,
63
64 #[serde(skip_serializing_if = "Option::is_none")]
66 pub user_timezone: Option<String>,
67
68 #[serde(skip_serializing_if = "Option::is_none")]
70 pub created_at: Option<i64>,
71
72 #[serde(skip_serializing_if = "Option::is_none")]
74 pub updated_at: Option<i64>,
75
76 #[serde(skip_serializing_if = "Option::is_none")]
78 pub provider_user_id: Option<String>,
79
80 #[serde(skip_serializing_if = "Option::is_none")]
82 pub ip: Option<String>,
83
84 #[serde(skip_serializing_if = "Option::is_none")]
86 pub state: Option<String>,
87
88 #[serde(skip_serializing_if = "Option::is_none")]
90 pub user_agent: Option<String>,
91
92 #[serde(skip_serializing_if = "Option::is_none")]
94 pub settings: Option<serde_json::Value>,
95
96 #[serde(skip_serializing_if = "Option::is_none")]
98 pub metadata: Option<serde_json::Value>,
99}
100
101#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
106pub struct CreateGrantRequest {
107 pub provider: Provider,
109
110 #[serde(skip_serializing_if = "Option::is_none")]
112 pub settings: Option<serde_json::Value>,
113
114 #[serde(skip_serializing_if = "Option::is_none")]
116 pub scope: Option<Vec<String>>,
117
118 #[serde(skip_serializing_if = "Option::is_none")]
120 pub state: Option<String>,
121
122 #[serde(skip_serializing_if = "Option::is_none")]
124 pub metadata: Option<serde_json::Value>,
125}
126
127impl CreateGrantRequest {
128 pub fn builder(provider: Provider) -> CreateGrantRequestBuilder {
130 CreateGrantRequestBuilder::new(provider)
131 }
132}
133
134#[derive(Debug, Clone)]
136pub struct CreateGrantRequestBuilder {
137 provider: Provider,
138 settings: Option<serde_json::Value>,
139 scope: Option<Vec<String>>,
140 state: Option<String>,
141 metadata: Option<serde_json::Value>,
142}
143
144impl CreateGrantRequestBuilder {
145 pub fn new(provider: Provider) -> Self {
147 Self {
148 provider,
149 settings: None,
150 scope: None,
151 state: None,
152 metadata: None,
153 }
154 }
155
156 pub fn settings(mut self, settings: serde_json::Value) -> Self {
158 self.settings = Some(settings);
159 self
160 }
161
162 pub fn scope(mut self, scope: Vec<String>) -> Self {
164 self.scope = Some(scope);
165 self
166 }
167
168 pub fn state(mut self, state: impl Into<String>) -> Self {
170 self.state = Some(state.into());
171 self
172 }
173
174 pub fn metadata(mut self, metadata: serde_json::Value) -> Self {
176 self.metadata = Some(metadata);
177 self
178 }
179
180 pub fn build(self) -> CreateGrantRequest {
182 CreateGrantRequest {
183 provider: self.provider,
184 settings: self.settings,
185 scope: self.scope,
186 state: self.state,
187 metadata: self.metadata,
188 }
189 }
190}
191
192#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
194pub struct UpdateGrantRequest {
195 #[serde(skip_serializing_if = "Option::is_none")]
197 pub settings: Option<serde_json::Value>,
198
199 #[serde(skip_serializing_if = "Option::is_none")]
201 pub scope: Option<Vec<String>>,
202
203 #[serde(skip_serializing_if = "Option::is_none")]
205 pub metadata: Option<serde_json::Value>,
206}
207
208impl UpdateGrantRequest {
209 pub fn builder() -> UpdateGrantRequestBuilder {
211 UpdateGrantRequestBuilder::default()
212 }
213}
214
215#[derive(Debug, Clone, Default)]
217pub struct UpdateGrantRequestBuilder {
218 settings: Option<serde_json::Value>,
219 scope: Option<Vec<String>>,
220 metadata: Option<serde_json::Value>,
221}
222
223impl UpdateGrantRequestBuilder {
224 pub fn settings(mut self, settings: serde_json::Value) -> Self {
226 self.settings = Some(settings);
227 self
228 }
229
230 pub fn scope(mut self, scope: Vec<String>) -> Self {
232 self.scope = Some(scope);
233 self
234 }
235
236 pub fn metadata(mut self, metadata: serde_json::Value) -> Self {
238 self.metadata = Some(metadata);
239 self
240 }
241
242 pub fn build(self) -> UpdateGrantRequest {
244 UpdateGrantRequest {
245 settings: self.settings,
246 scope: self.scope,
247 metadata: self.metadata,
248 }
249 }
250}
251
252#[cfg(test)]
253mod tests {
254 use super::*;
255
256 #[test]
257 fn test_grant_serialization() {
258 let grant = Grant {
259 id: GrantId::new("grant_123"),
260 provider: Provider::Google,
261 grant_status: Some(GrantStatus::Valid),
262 email: Some("user@example.com".to_string()),
263 scope: Some(vec![
264 "https://www.googleapis.com/auth/gmail.readonly".to_string()
265 ]),
266 user_timezone: None,
267 created_at: Some(1234567890),
268 updated_at: Some(1234567890),
269 provider_user_id: None,
270 ip: None,
271 state: None,
272 user_agent: None,
273 settings: None,
274 metadata: None,
275 };
276
277 let json = serde_json::to_string(&grant).unwrap();
278 assert!(json.contains("grant_123"));
279 assert!(json.contains("google"));
280 assert!(json.contains("user@example.com"));
281 }
282
283 #[test]
284 fn test_grant_deserialization() {
285 let json = r#"{
286 "id": "grant_123",
287 "provider": "google",
288 "grant_status": "valid",
289 "email": "user@example.com",
290 "scope": ["https://www.googleapis.com/auth/gmail.readonly"],
291 "created_at": 1234567890,
292 "updated_at": 1234567890
293 }"#;
294
295 let grant: Grant = serde_json::from_str(json).unwrap();
296 assert_eq!(grant.id.as_str(), "grant_123");
297 assert_eq!(grant.provider, Provider::Google);
298 assert_eq!(grant.grant_status, Some(GrantStatus::Valid));
299 assert_eq!(grant.email, Some("user@example.com".to_string()));
300 }
301
302 #[test]
303 fn test_grant_status_serialization() {
304 assert_eq!(
305 serde_json::to_string(&GrantStatus::Valid).unwrap(),
306 r#""valid""#
307 );
308 assert_eq!(
309 serde_json::to_string(&GrantStatus::Invalid).unwrap(),
310 r#""invalid""#
311 );
312 }
313
314 #[test]
315 fn test_create_grant_request_builder() {
316 let request = CreateGrantRequest::builder(Provider::Google)
317 .scope(vec![
318 "https://www.googleapis.com/auth/gmail.readonly".to_string()
319 ])
320 .state("test_state")
321 .build();
322
323 assert_eq!(request.provider, Provider::Google);
324 assert!(request.scope.is_some());
325 assert_eq!(request.state, Some("test_state".to_string()));
326 assert!(request.settings.is_none());
327 assert!(request.metadata.is_none());
328 }
329
330 #[test]
331 fn test_create_grant_request_with_metadata() {
332 let metadata = serde_json::json!({"team": "engineering"});
333 let request = CreateGrantRequest::builder(Provider::Microsoft)
334 .metadata(metadata.clone())
335 .build();
336
337 assert_eq!(request.provider, Provider::Microsoft);
338 assert_eq!(request.metadata, Some(metadata));
339 }
340
341 #[test]
342 fn test_update_grant_request_builder() {
343 let metadata = serde_json::json!({"updated": true});
344 let request = UpdateGrantRequest::builder()
345 .metadata(metadata.clone())
346 .scope(vec!["new_scope".to_string()])
347 .build();
348
349 assert_eq!(request.metadata, Some(metadata));
350 assert_eq!(request.scope, Some(vec!["new_scope".to_string()]));
351 assert!(request.settings.is_none());
352 }
353
354 #[test]
355 fn test_update_grant_request_default() {
356 let request = UpdateGrantRequest::default();
357 assert!(request.settings.is_none());
358 assert!(request.scope.is_none());
359 assert!(request.metadata.is_none());
360 }
361}