1use serde::{Deserialize, Serialize};
2
3fn default_oauth2_request_encoding() -> String {
5 OAuth2RequestEncoding::FORM_URL.to_string()
6}
7
8fn default_token_endpoint() -> String {
10 "/oauth2/token".to_string()
11}
12
13fn default_revocation_endpoint() -> String {
15 "/oauth2/revoke".to_string()
16}
17
18fn default_introspection_endpoint() -> String {
20 "/oauth2/introspect".to_string()
21}
22
23string_constants! {
24 AuthenticationScheme {
26 BASIC => "Basic",
27 BEARER => "Bearer",
28 CERTIFICATE => "Certificate",
29 DIGEST => "Digest",
30 OAUTH2 => "OAuth2",
31 OIDC => "OpenIDConnect",
32 }
33}
34
35string_constants! {
36 OAuth2ClientAuthenticationMethod {
38 BASIC => "client_secret_basic",
39 POST => "client_secret_post",
40 JWT => "client_secret_jwt",
41 PRIVATE_KEY => "private_key_jwt",
42 NONE => "none",
43 }
44}
45
46string_constants! {
47 OAuth2RequestEncoding {
49 FORM_URL => "application/x-www-form-urlencoded",
50 JSON => "application/json",
51 }
52}
53
54#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
56pub struct AuthenticationPolicyDefinition {
57 #[serde(rename = "use", skip_serializing_if = "Option::is_none")]
59 pub use_: Option<String>,
60
61 #[serde(skip_serializing_if = "Option::is_none")]
63 pub basic: Option<BasicAuthenticationSchemeDefinition>,
64
65 #[serde(skip_serializing_if = "Option::is_none")]
67 pub bearer: Option<BearerAuthenticationSchemeDefinition>,
68
69 #[serde(skip_serializing_if = "Option::is_none")]
71 pub certificate: Option<CertificateAuthenticationSchemeDefinition>,
72
73 #[serde(skip_serializing_if = "Option::is_none")]
75 pub digest: Option<DigestAuthenticationSchemeDefinition>,
76
77 #[serde(skip_serializing_if = "Option::is_none")]
79 pub oauth2: Option<OAuth2AuthenticationSchemeDefinition>,
80
81 #[serde(skip_serializing_if = "Option::is_none")]
83 pub oidc: Option<OpenIDConnectSchemeDefinition>,
84}
85
86#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
88#[serde(untagged)]
89pub enum ReferenceableAuthenticationPolicy {
90 Reference(AuthenticationPolicyReference),
92 Policy(Box<AuthenticationPolicyDefinition>),
94}
95
96#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
98pub struct AuthenticationPolicyReference {
99 #[serde(rename = "use")]
101 pub use_: String,
102}
103
104macro_rules! credential_auth_scheme {
107 ($(#[$meta:meta])* $name:ident) => {
108 $(#[$meta])*
109 #[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
110 pub struct $name {
111 #[serde(rename = "use", skip_serializing_if = "Option::is_none")]
113 pub use_: Option<String>,
114
115 #[serde(skip_serializing_if = "Option::is_none")]
117 pub username: Option<String>,
118
119 #[serde(skip_serializing_if = "Option::is_none")]
121 pub password: Option<String>,
122 }
123 };
124}
125
126credential_auth_scheme!(
127 BasicAuthenticationSchemeDefinition
129);
130
131#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
133pub struct BearerAuthenticationSchemeDefinition {
134 #[serde(rename = "use", skip_serializing_if = "Option::is_none")]
136 pub use_: Option<String>,
137
138 #[serde(skip_serializing_if = "Option::is_none")]
140 pub token: Option<String>,
141}
142
143#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
145pub struct CertificateAuthenticationSchemeDefinition {
146 #[serde(rename = "use", skip_serializing_if = "Option::is_none")]
148 pub use_: Option<String>,
149}
150
151credential_auth_scheme!(
152 DigestAuthenticationSchemeDefinition
154);
155
156#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
158pub struct OAuth2AuthenticationClientDefinition {
159 #[serde(skip_serializing_if = "Option::is_none")]
161 pub id: Option<String>,
162
163 #[serde(skip_serializing_if = "Option::is_none")]
165 pub secret: Option<String>,
166
167 #[serde(skip_serializing_if = "Option::is_none")]
169 pub assertion: Option<String>,
170
171 #[serde(skip_serializing_if = "Option::is_none")]
173 pub authentication: Option<String>,
174}
175
176#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
178pub struct OAuth2AuthenticationRequestDefinition {
179 #[serde(default = "default_oauth2_request_encoding")]
181 pub encoding: String,
182}
183
184#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
186pub struct OAuth2TokenDefinition {
187 pub token: String,
189
190 #[serde(rename = "type")]
192 pub type_: String,
193}
194
195#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
197pub struct OAuth2AuthenticationEndpointsDefinition {
198 #[serde(default = "default_token_endpoint")]
200 pub token: String,
201
202 #[serde(default = "default_revocation_endpoint")]
204 pub revocation: String,
205
206 #[serde(default = "default_introspection_endpoint")]
208 pub introspection: String,
209}
210
211macro_rules! oauth2_like_auth_scheme {
214 ($( #[$meta:meta] )* $name:ident { $($extra_field:tt)* }) => {
215 $( #[$meta] )*
216 #[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
217 pub struct $name {
218 #[serde(rename = "use", skip_serializing_if = "Option::is_none")]
220 pub use_: Option<String>,
221
222 $($extra_field)*
223
224 #[serde(skip_serializing_if = "Option::is_none")]
226 pub authority: Option<String>,
227
228 #[serde(skip_serializing_if = "Option::is_none")]
230 pub grant: Option<String>,
231
232 #[serde(skip_serializing_if = "Option::is_none")]
234 pub client: Option<OAuth2AuthenticationClientDefinition>,
235
236 #[serde(skip_serializing_if = "Option::is_none")]
238 pub request: Option<OAuth2AuthenticationRequestDefinition>,
239
240 #[serde(skip_serializing_if = "Option::is_none")]
242 pub issuers: Option<Vec<String>>,
243
244 #[serde(skip_serializing_if = "Option::is_none")]
246 pub scopes: Option<Vec<String>>,
247
248 #[serde(skip_serializing_if = "Option::is_none")]
250 pub audiences: Option<Vec<String>>,
251
252 #[serde(skip_serializing_if = "Option::is_none")]
254 pub resources: Option<Vec<String>>,
255
256 #[serde(skip_serializing_if = "Option::is_none")]
258 pub username: Option<String>,
259
260 #[serde(skip_serializing_if = "Option::is_none")]
262 pub password: Option<String>,
263
264 #[serde(skip_serializing_if = "Option::is_none")]
266 pub subject: Option<OAuth2TokenDefinition>,
267
268 #[serde(skip_serializing_if = "Option::is_none")]
270 pub actor: Option<OAuth2TokenDefinition>,
271 }
272 };
273}
274
275oauth2_like_auth_scheme!(
276 OAuth2AuthenticationSchemeDefinition {
278 #[serde(skip_serializing_if = "Option::is_none")]
280 pub endpoints: Option<OAuth2AuthenticationEndpointsDefinition>,
281 }
282);
283
284oauth2_like_auth_scheme!(
285 OpenIDConnectSchemeDefinition {
287 #[serde(skip_serializing_if = "Option::is_none")]
289 pub endpoints: Option<OAuth2AuthenticationEndpointsDefinition>,
290 }
291);
292
293#[cfg(test)]
294mod tests {
295 use super::*;
296
297 #[test]
298 fn test_basic_auth_serialize() {
299 let basic = BasicAuthenticationSchemeDefinition {
300 use_: None,
301 username: Some("john".to_string()),
302 password: Some("12345".to_string()),
303 };
304 let json = serde_json::to_string(&basic).unwrap();
305 assert!(json.contains("\"username\":\"john\""));
306 assert!(json.contains("\"password\":\"12345\""));
307 assert!(!json.contains("\"use\""));
308 }
309
310 #[test]
311 fn test_basic_auth_deserialize() {
312 let json = r#"{"username": "admin", "password": "secret"}"#;
313 let basic: BasicAuthenticationSchemeDefinition = serde_json::from_str(json).unwrap();
314 assert_eq!(basic.username, Some("admin".to_string()));
315 assert_eq!(basic.password, Some("secret".to_string()));
316 }
317
318 #[test]
319 fn test_basic_auth_with_use_secret() {
320 let json = r#"{"use": "mySecret"}"#;
321 let basic: BasicAuthenticationSchemeDefinition = serde_json::from_str(json).unwrap();
322 assert_eq!(basic.use_, Some("mySecret".to_string()));
323 assert!(basic.username.is_none());
324 }
325
326 #[test]
327 fn test_bearer_auth_serialize() {
328 let bearer = BearerAuthenticationSchemeDefinition {
329 use_: None,
330 token: Some("mytoken123".to_string()),
331 };
332 let json = serde_json::to_string(&bearer).unwrap();
333 assert!(json.contains("\"token\":\"mytoken123\""));
334 }
335
336 #[test]
337 fn test_bearer_auth_with_use_secret() {
338 let json = r#"{"use": "bearerSecret"}"#;
339 let bearer: BearerAuthenticationSchemeDefinition = serde_json::from_str(json).unwrap();
340 assert_eq!(bearer.use_, Some("bearerSecret".to_string()));
341 }
342
343 #[test]
344 fn test_digest_auth_serialize() {
345 let digest = DigestAuthenticationSchemeDefinition {
346 use_: None,
347 username: Some("digestUser".to_string()),
348 password: Some("digestPass".to_string()),
349 };
350 let json = serde_json::to_string(&digest).unwrap();
351 assert!(json.contains("\"username\":\"digestUser\""));
352 assert!(json.contains("\"password\":\"digestPass\""));
353 }
354
355 #[test]
356 fn test_auth_policy_basic() {
357 let policy = AuthenticationPolicyDefinition {
358 use_: None,
359 basic: Some(BasicAuthenticationSchemeDefinition {
360 use_: None,
361 username: Some("john".to_string()),
362 password: Some("12345".to_string()),
363 }),
364 bearer: None,
365 certificate: None,
366 digest: None,
367 oauth2: None,
368 oidc: None,
369 };
370 let json = serde_json::to_string(&policy).unwrap();
371 assert!(json.contains("\"basic\""));
372 assert!(json.contains("\"username\":\"john\""));
373 assert!(!json.contains("\"bearer\""));
374 }
375
376 #[test]
377 fn test_auth_policy_digest_deserialize() {
378 let json = r#"{
379 "digest": {
380 "username": "digestUser",
381 "password": "digestPass"
382 }
383 }"#;
384 let policy: AuthenticationPolicyDefinition = serde_json::from_str(json).unwrap();
385 assert!(policy.digest.is_some());
386 assert!(policy.basic.is_none());
387 let digest = policy.digest.unwrap();
388 assert_eq!(digest.username, Some("digestUser".to_string()));
389 assert_eq!(digest.password, Some("digestPass".to_string()));
390 }
391
392 #[test]
393 fn test_auth_policy_oauth2_inline() {
394 let json = r#"{
395 "oauth2": {
396 "authority": "https://auth.example.com",
397 "grant": "client_credentials",
398 "scopes": ["scope1", "scope2"]
399 }
400 }"#;
401 let policy: AuthenticationPolicyDefinition = serde_json::from_str(json).unwrap();
402 assert!(policy.oauth2.is_some());
403 let oauth2 = policy.oauth2.unwrap();
404 assert_eq!(
405 oauth2.authority,
406 Some("https://auth.example.com".to_string())
407 );
408 assert_eq!(oauth2.grant, Some("client_credentials".to_string()));
409 assert_eq!(
410 oauth2.scopes,
411 Some(vec!["scope1".to_string(), "scope2".to_string()])
412 );
413 }
414
415 #[test]
416 fn test_auth_policy_oauth2_use() {
417 let json = r#"{
418 "oauth2": {
419 "use": "mysecret"
420 }
421 }"#;
422 let policy: AuthenticationPolicyDefinition = serde_json::from_str(json).unwrap();
423 assert!(policy.oauth2.is_some());
424 let oauth2 = policy.oauth2.unwrap();
425 assert_eq!(oauth2.use_, Some("mysecret".to_string()));
426 }
427
428 #[test]
429 fn test_referenceable_auth_policy_reference() {
430 let json = r#"{"use": "myAuthPolicy"}"#;
431 let ref_policy: ReferenceableAuthenticationPolicy = serde_json::from_str(json).unwrap();
432 match ref_policy {
433 ReferenceableAuthenticationPolicy::Reference(r) => {
434 assert_eq!(r.use_, "myAuthPolicy");
435 }
436 _ => panic!("Expected Reference variant"),
437 }
438 }
439
440 #[test]
441 fn test_referenceable_auth_policy_inline() {
442 let json = r#"{
443 "basic": {
444 "username": "john",
445 "password": "secret"
446 }
447 }"#;
448 let ref_policy: ReferenceableAuthenticationPolicy = serde_json::from_str(json).unwrap();
449 match ref_policy {
450 ReferenceableAuthenticationPolicy::Policy(p) => {
451 assert!(p.basic.is_some());
452 }
453 _ => panic!("Expected Policy variant"),
454 }
455 }
456
457 #[test]
458 fn test_oauth2_scheme_roundtrip() {
459 let json = r#"{
460 "authority": "https://auth.example.com",
461 "grant": "client_credentials",
462 "scopes": ["scope1", "scope2"]
463 }"#;
464 let oauth2: OAuth2AuthenticationSchemeDefinition = serde_json::from_str(json).unwrap();
465 let serialized = serde_json::to_string(&oauth2).unwrap();
466 let deserialized: OAuth2AuthenticationSchemeDefinition =
467 serde_json::from_str(&serialized).unwrap();
468 assert_eq!(oauth2, deserialized);
469 }
470
471 #[test]
474 fn test_auth_policy_basic_roundtrip() {
475 let json = r#"{"basic":{"username":"john","password":"12345"}}"#;
477 let policy: AuthenticationPolicyDefinition = serde_json::from_str(json).unwrap();
478 assert!(policy.basic.is_some());
479 let basic = policy.basic.as_ref().unwrap();
480 assert_eq!(basic.username, Some("john".to_string()));
481 assert_eq!(basic.password, Some("12345".to_string()));
482 let serialized = serde_json::to_string(&policy).unwrap();
483 let deserialized: AuthenticationPolicyDefinition =
484 serde_json::from_str(&serialized).unwrap();
485 assert_eq!(policy, deserialized);
486 }
487
488 #[test]
489 fn test_auth_policy_digest_roundtrip() {
490 let json = r#"{"digest":{"username":"digestUser","password":"digestPass"}}"#;
492 let policy: AuthenticationPolicyDefinition = serde_json::from_str(json).unwrap();
493 assert!(policy.digest.is_some());
494 let digest = policy.digest.as_ref().unwrap();
495 assert_eq!(digest.username, Some("digestUser".to_string()));
496 assert_eq!(digest.password, Some("digestPass".to_string()));
497 let serialized = serde_json::to_string(&policy).unwrap();
498 let deserialized: AuthenticationPolicyDefinition =
499 serde_json::from_str(&serialized).unwrap();
500 assert_eq!(policy, deserialized);
501 }
502
503 #[test]
504 fn test_oauth2_use_secret() {
505 let json = r#"{"oauth2":{"use":"mysecret"}}"#;
507 let policy: AuthenticationPolicyDefinition = serde_json::from_str(json).unwrap();
508 assert!(policy.oauth2.is_some());
509 let oauth2 = policy.oauth2.as_ref().unwrap();
510 assert_eq!(oauth2.use_, Some("mysecret".to_string()));
511 }
512
513 #[test]
514 fn test_oauth2_inline_properties() {
515 let json = r#"{"oauth2":{"authority":"https://auth.example.com","grant":"client_credentials","scopes":["scope1","scope2"]}}"#;
517 let policy: AuthenticationPolicyDefinition = serde_json::from_str(json).unwrap();
518 assert!(policy.oauth2.is_some());
519 let oauth2 = policy.oauth2.as_ref().unwrap();
520 assert_eq!(
521 oauth2.authority,
522 Some("https://auth.example.com".to_string())
523 );
524 assert_eq!(oauth2.grant, Some("client_credentials".to_string()));
525 assert_eq!(
526 oauth2.scopes,
527 Some(vec!["scope1".to_string(), "scope2".to_string()])
528 );
529 }
530
531 #[test]
532 fn test_bearer_auth_roundtrip() {
533 let bearer = BearerAuthenticationSchemeDefinition {
534 use_: None,
535 token: Some("mytoken123".to_string()),
536 };
537 let serialized = serde_json::to_string(&bearer).unwrap();
538 let deserialized: BearerAuthenticationSchemeDefinition =
539 serde_json::from_str(&serialized).unwrap();
540 assert_eq!(bearer, deserialized);
541 }
542
543 #[test]
544 fn test_referenceable_auth_policy_roundtrip() {
545 let json = r#"{"basic":{"username":"admin","password":"admin"}}"#;
547 let ref_policy: ReferenceableAuthenticationPolicy = serde_json::from_str(json).unwrap();
548 let serialized = serde_json::to_string(&ref_policy).unwrap();
549 let deserialized: ReferenceableAuthenticationPolicy =
550 serde_json::from_str(&serialized).unwrap();
551 assert_eq!(ref_policy, deserialized);
552 }
553
554 #[test]
555 fn test_basic_auth_use_vs_credentials() {
556 let use_json = r#"{"use":"mySecret"}"#;
558 let basic_use: BasicAuthenticationSchemeDefinition =
559 serde_json::from_str(use_json).unwrap();
560 assert_eq!(basic_use.use_, Some("mySecret".to_string()));
561 assert!(basic_use.username.is_none());
562
563 let cred_json = r#"{"username":"admin","password":"secret"}"#;
564 let basic_cred: BasicAuthenticationSchemeDefinition =
565 serde_json::from_str(cred_json).unwrap();
566 assert!(basic_cred.use_.is_none());
567 assert_eq!(basic_cred.username, Some("admin".to_string()));
568 assert_eq!(basic_cred.password, Some("secret".to_string()));
569 }
570
571 #[test]
572 fn test_digest_auth_use_secret() {
573 let json = r#"{"use":"digestSecret"}"#;
574 let digest: DigestAuthenticationSchemeDefinition = serde_json::from_str(json).unwrap();
575 assert_eq!(digest.use_, Some("digestSecret".to_string()));
576 assert!(digest.username.is_none());
577 }
578
579 #[test]
582 fn test_oauth2_full_properties() {
583 let json = r#"{
585 "authority": "https://auth.example.com",
586 "grant": "client_credentials",
587 "scopes": ["scope1", "scope2"],
588 "client": {
589 "id": "my-client-id",
590 "secret": "my-client-secret",
591 "authentication": "client_secret_post"
592 },
593 "request": {
594 "encoding": "application/x-www-form-urlencoded"
595 },
596 "issuers": ["https://issuer1.example.com", "https://issuer2.example.com"],
597 "audiences": ["api1", "api2"],
598 "endpoints": {
599 "token": "/oauth2/token",
600 "revocation": "/oauth2/revoke",
601 "introspection": "/oauth2/introspect"
602 }
603 }"#;
604 let oauth2: OAuth2AuthenticationSchemeDefinition = serde_json::from_str(json).unwrap();
605 assert_eq!(
606 oauth2.authority,
607 Some("https://auth.example.com".to_string())
608 );
609 assert_eq!(oauth2.grant, Some("client_credentials".to_string()));
610 assert_eq!(
611 oauth2.scopes,
612 Some(vec!["scope1".to_string(), "scope2".to_string()])
613 );
614 assert!(oauth2.client.is_some());
615 let client = oauth2.client.as_ref().unwrap();
616 assert_eq!(client.id, Some("my-client-id".to_string()));
617 assert_eq!(client.secret, Some("my-client-secret".to_string()));
618 assert_eq!(
619 client.authentication,
620 Some("client_secret_post".to_string())
621 );
622 assert!(oauth2.request.is_some());
623 let req = oauth2.request.as_ref().unwrap();
624 assert_eq!(req.encoding, "application/x-www-form-urlencoded");
625 assert_eq!(
626 oauth2.issuers,
627 Some(vec![
628 "https://issuer1.example.com".to_string(),
629 "https://issuer2.example.com".to_string()
630 ])
631 );
632 assert_eq!(
633 oauth2.audiences,
634 Some(vec!["api1".to_string(), "api2".to_string()])
635 );
636 assert!(oauth2.endpoints.is_some());
637 let endpoints = oauth2.endpoints.as_ref().unwrap();
638 assert_eq!(endpoints.token, "/oauth2/token");
639 assert_eq!(endpoints.revocation, "/oauth2/revoke");
640 assert_eq!(endpoints.introspection, "/oauth2/introspect");
641 }
642
643 #[test]
644 fn test_oauth2_full_properties_roundtrip() {
645 let json = r#"{
646 "authority": "https://auth.example.com",
647 "grant": "client_credentials",
648 "scopes": ["scope1"],
649 "client": {"id": "client1", "secret": "secret1"}
650 }"#;
651 let oauth2: OAuth2AuthenticationSchemeDefinition = serde_json::from_str(json).unwrap();
652 let serialized = serde_json::to_string(&oauth2).unwrap();
653 let deserialized: OAuth2AuthenticationSchemeDefinition =
654 serde_json::from_str(&serialized).unwrap();
655 assert_eq!(oauth2, deserialized);
656 }
657
658 #[test]
659 fn test_oauth2_password_grant() {
660 let json = r#"{
662 "authority": "https://auth.example.com",
663 "grant": "password",
664 "username": "user1",
665 "password": "pass1",
666 "scopes": ["read", "write"]
667 }"#;
668 let oauth2: OAuth2AuthenticationSchemeDefinition = serde_json::from_str(json).unwrap();
669 assert_eq!(oauth2.grant, Some("password".to_string()));
670 assert_eq!(oauth2.username, Some("user1".to_string()));
671 assert_eq!(oauth2.password, Some("pass1".to_string()));
672 }
673
674 #[test]
675 fn test_oauth2_token_exchange_grant() {
676 let json = r#"{
678 "authority": "https://auth.example.com",
679 "grant": "urn:ietf:params:oauth:grant-type:token-exchange",
680 "subject": {"token": "subject-token", "type": "urn:ietf:params:oauth:token-type:access_token"},
681 "actor": {"token": "actor-token", "type": "urn:ietf:params:oauth:token-type:access_token"}
682 }"#;
683 let oauth2: OAuth2AuthenticationSchemeDefinition = serde_json::from_str(json).unwrap();
684 assert_eq!(
685 oauth2.grant,
686 Some("urn:ietf:params:oauth:grant-type:token-exchange".to_string())
687 );
688 assert!(oauth2.subject.is_some());
689 let subject = oauth2.subject.as_ref().unwrap();
690 assert_eq!(subject.token, "subject-token");
691 assert_eq!(
692 subject.type_,
693 "urn:ietf:params:oauth:token-type:access_token"
694 );
695 assert!(oauth2.actor.is_some());
696 let actor = oauth2.actor.as_ref().unwrap();
697 assert_eq!(actor.token, "actor-token");
698 }
699
700 #[test]
701 fn test_oauth2_endpoints_defaults() {
702 let json = r#"{}"#;
704 let endpoints: OAuth2AuthenticationEndpointsDefinition =
705 serde_json::from_str(json).unwrap();
706 assert_eq!(endpoints.token, "/oauth2/token");
707 assert_eq!(endpoints.revocation, "/oauth2/revoke");
708 assert_eq!(endpoints.introspection, "/oauth2/introspect");
709 }
710
711 #[test]
712 fn test_oauth2_request_encoding_defaults() {
713 let json = r#"{}"#;
715 let request: OAuth2AuthenticationRequestDefinition = serde_json::from_str(json).unwrap();
716 assert_eq!(request.encoding, "application/x-www-form-urlencoded");
717 }
718
719 #[test]
720 fn test_oauth2_request_encoding_json() {
721 let json = r#"{"encoding": "application/json"}"#;
722 let request: OAuth2AuthenticationRequestDefinition = serde_json::from_str(json).unwrap();
723 assert_eq!(request.encoding, "application/json");
724 }
725
726 #[test]
727 fn test_oidc_full_properties() {
728 let json = r#"{
730 "authority": "https://oidc.example.com",
731 "grant": "authorization_code",
732 "scopes": ["openid", "profile"],
733 "client": {"id": "oidc-client"}
734 }"#;
735 let oidc: OpenIDConnectSchemeDefinition = serde_json::from_str(json).unwrap();
736 assert_eq!(oidc.authority, Some("https://oidc.example.com".to_string()));
737 assert_eq!(oidc.grant, Some("authorization_code".to_string()));
738 assert_eq!(
739 oidc.scopes,
740 Some(vec!["openid".to_string(), "profile".to_string()])
741 );
742 assert!(oidc.client.is_some());
743 }
744
745 #[test]
746 fn test_oidc_roundtrip() {
747 let json = r#"{
748 "authority": "https://oidc.example.com",
749 "grant": "authorization_code",
750 "scopes": ["openid"]
751 }"#;
752 let oidc: OpenIDConnectSchemeDefinition = serde_json::from_str(json).unwrap();
753 let serialized = serde_json::to_string(&oidc).unwrap();
754 let deserialized: OpenIDConnectSchemeDefinition =
755 serde_json::from_str(&serialized).unwrap();
756 assert_eq!(oidc, deserialized);
757 }
758
759 #[test]
760 fn test_certificate_auth() {
761 let json = r#"{"use": "certSecret"}"#;
762 let cert: CertificateAuthenticationSchemeDefinition = serde_json::from_str(json).unwrap();
763 assert_eq!(cert.use_, Some("certSecret".to_string()));
764 assert_eq!(AuthenticationScheme::CERTIFICATE, "Certificate");
765 }
766
767 #[test]
768 fn test_auth_policy_bearer_inline() {
769 let json = r#"{
771 "bearer": {
772 "token": "my-bearer-token"
773 }
774 }"#;
775 let policy: AuthenticationPolicyDefinition = serde_json::from_str(json).unwrap();
776 assert!(policy.bearer.is_some());
777 let bearer = policy.bearer.as_ref().unwrap();
778 assert_eq!(bearer.token, Some("my-bearer-token".to_string()));
779 assert!(bearer.use_.is_none());
780 }
781
782 #[test]
783 fn test_auth_policy_certificate_inline() {
784 let json = r#"{
785 "certificate": {
786 "use": "myCertSecret"
787 }
788 }"#;
789 let policy: AuthenticationPolicyDefinition = serde_json::from_str(json).unwrap();
790 assert!(policy.certificate.is_some());
791 let cert = policy.certificate.as_ref().unwrap();
792 assert_eq!(cert.use_, Some("myCertSecret".to_string()));
793 }
794
795 #[test]
796 fn test_oauth2_client_assertion() {
797 let json = r#"{
799 "id": "client-id",
800 "assertion": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
801 "authentication": "private_key_jwt"
802 }"#;
803 let client: OAuth2AuthenticationClientDefinition = serde_json::from_str(json).unwrap();
804 assert_eq!(client.id, Some("client-id".to_string()));
805 assert_eq!(
806 client.assertion,
807 Some("eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...".to_string())
808 );
809 assert_eq!(client.authentication, Some("private_key_jwt".to_string()));
810 }
811
812 #[test]
813 fn test_oauth2_token_definition() {
814 let json = r#"{
815 "token": "my-token-value",
816 "type": "urn:ietf:params:oauth:token-type:access_token"
817 }"#;
818 let token: OAuth2TokenDefinition = serde_json::from_str(json).unwrap();
819 assert_eq!(token.token, "my-token-value");
820 assert_eq!(token.type_, "urn:ietf:params:oauth:token-type:access_token");
821 }
822}