common_access_token/cat_claims.rs
1//! # CAT-specific Claims
2//!
3//! This module provides helper functions and structures for working with
4//! Common Access Token (CAT) specific claims as defined in the CAT specification.
5//!
6//! ## Available CAT Claims
7//!
8//! - **CATU** (Common Access Token URI) - limits the URI to which the token can provide access
9//! - **CATR** (Common Access Token Renewal) - instructions for token renewal
10//! - **CATM** (Common Access Token Methods) - limits HTTP methods
11//! - **CATREPLAY** - controls token replay behavior
12//! - **CATV** (Common Access Token Version) - CAT specification version
13//! - **CATPOR** (Common Access Token Probability of Rejection) - probabilistic rate limiting
14//! - **CATNIP** (Common Access Token Network IP) - IP address restrictions
15//! - **CATALPN** (Common Access Token ALPN) - TLS ALPN protocol restrictions
16//! - **CATH** (Common Access Token Header) - HTTP header requirements
17//! - **CATGEOISO3166** - geographic country/region restrictions
18//! - **CATGEOCOORD** - geographic coordinate restrictions
19//! - **CATGEOALT** - altitude restrictions
20//! - **CATTPK** (Common Access Token TLS Public Key) - TLS public key pinning
21//! - **CATDPOP** (Common Access Token DPoP Settings) - DPoP configuration
22//! - **CATIF** (Common Access Token If) - conditional logic
23//! - **CATIFDATA** (Common Access Token If Data) - data for conditional evaluation
24//!
25//! ## CATU Claim (URI Validation)
26//!
27//! The CATU claim allows you to specify URI component restrictions. For example:
28//!
29//! ```rust
30//! use common_access_token::{catu, uri_components, cat_keys};
31//! use std::collections::BTreeMap;
32//!
33//! // Create a CATU claim for URI validation
34//! let mut catu_components = BTreeMap::new();
35//!
36//! // Restrict to https scheme
37//! catu_components.insert(uri_components::SCHEME, catu::exact_match("https"));
38//!
39//! // Restrict to example.com host
40//! catu_components.insert(uri_components::HOST, catu::suffix_match(".example.com"));
41//!
42//! // Restrict to paths starting with /api
43//! catu_components.insert(uri_components::PATH, catu::prefix_match("/api"));
44//!
45//! // Create the CATU claim
46//! let catu_claim = catu::create(catu_components);
47//! ```
48//!
49//! ## CATM Claim (HTTP Methods)
50//!
51//! The CATM claim restricts which HTTP methods are allowed:
52//!
53//! ```rust
54//! use common_access_token::{catm, cat_keys};
55//!
56//! // Create a CATM claim allowing only GET and HEAD methods
57//! let allowed_methods = vec!["GET", "HEAD"];
58//! let catm_claim = catm::create(allowed_methods);
59//! ```
60//!
61//! ## CATREPLAY Claim (Replay Protection)
62//!
63//! The CATREPLAY claim controls token replay behavior:
64//!
65//! ```rust
66//! use common_access_token::{catreplay, cat_keys};
67//!
68//! // Create a CATREPLAY claim that prohibits token reuse
69//! let catreplay_claim = catreplay::prohibited();
70//!
71//! // Or allow token reuse
72//! let catreplay_permitted = catreplay::permitted();
73//!
74//! // Or enable reuse detection
75//! let catreplay_detect = catreplay::reuse_detection();
76//! ```
77//!
78//! ## CATR Claim (Token Renewal)
79//!
80//! The CATR claim provides instructions for token renewal:
81//!
82//! ```rust
83//! use common_access_token::{catr, cat_keys};
84//! use common_access_token::current_timestamp;
85//!
86//! let now = current_timestamp();
87//!
88//! // Create an automatic renewal claim
89//! // This extends expiration by 3600 seconds with a deadline 3000 seconds from now
90//! let renewal_params = catr::automatic_renewal(3600, Some((now + 3000) as i64));
91//! let catr_claim = catr::create(renewal_params);
92//!
93//! // Or create a cookie-based renewal claim
94//! let cookie_renewal = catr::cookie_renewal(
95//! 3600,
96//! Some((now + 3000) as i64),
97//! Some("session"),
98//! Some(vec!["Secure", "HttpOnly"])
99//! );
100//! ```
101
102use crate::header::CborValue;
103use std::collections::BTreeMap;
104
105/// CAT-specific claim keys
106pub mod keys {
107 use crate::constants::cat_keys;
108
109 /// Common Access Token Replay (catreplay) claim key
110 pub const CATREPLAY: i32 = cat_keys::CATREPLAY;
111 /// Common Access Token Probability of Rejection (catpor) claim key
112 pub const CATPOR: i32 = cat_keys::CATPOR;
113 /// Common Access Token Version (catv) claim key
114 pub const CATV: i32 = cat_keys::CATV;
115 /// Common Access Token Network IP (catnip) claim key
116 pub const CATNIP: i32 = cat_keys::CATNIP;
117 /// Common Access Token URI (catu) claim key
118 pub const CATU: i32 = cat_keys::CATU;
119 /// Common Access Token Methods (catm) claim key
120 pub const CATM: i32 = cat_keys::CATM;
121 /// Common Access Token ALPN (catalpn) claim key
122 pub const CATALPN: i32 = cat_keys::CATALPN;
123 /// Common Access Token Header (cath) claim key
124 pub const CATH: i32 = cat_keys::CATH;
125 /// Common Access Token Geographic ISO3166 (catgeoiso3166) claim key
126 pub const CATGEOISO3166: i32 = cat_keys::CATGEOISO3166;
127 /// Common Access Token Geographic Coordinate (catgeocoord) claim key
128 pub const CATGEOCOORD: i32 = cat_keys::CATGEOCOORD;
129 /// Common Access Token Altitude (catgeoalt) claim key
130 pub const CATGEOALT: i32 = cat_keys::CATGEOALT;
131 /// Common Access Token TLS Public Key (cattpk) claim key
132 pub const CATTPK: i32 = cat_keys::CATTPK;
133 /// Common Access Token If Data (catifdata) claim key
134 pub const CATIFDATA: i32 = cat_keys::CATIFDATA;
135 /// Common Access Token DPoP Settings (catdpop) claim key
136 pub const CATDPOP: i32 = cat_keys::CATDPOP;
137 /// Common Access Token If (catif) claim key
138 pub const CATIF: i32 = cat_keys::CATIF;
139 /// Common Access Token Renewal (catr) claim key
140 pub const CATR: i32 = cat_keys::CATR;
141}
142
143/// Helper functions for creating CATU (Common Access Token URI) claims
144pub mod catu {
145 use super::*;
146 use crate::constants::match_types;
147
148 /// Creates a CATU claim with the specified URI component restrictions
149 pub fn create(components: BTreeMap<i32, BTreeMap<i32, CborValue>>) -> CborValue {
150 let mut map = BTreeMap::new();
151 for (component_key, match_map) in components {
152 let mut inner_map = BTreeMap::new();
153 for (match_type, match_value) in match_map {
154 inner_map.insert(match_type, match_value);
155 }
156 map.insert(component_key, CborValue::Map(inner_map));
157 }
158 CborValue::Map(map)
159 }
160
161 /// Creates a match condition for exact text matching
162 pub fn exact_match(text: &str) -> BTreeMap<i32, CborValue> {
163 let mut map = BTreeMap::new();
164 map.insert(match_types::EXACT, CborValue::Text(text.to_string()));
165 map
166 }
167
168 /// Creates a match condition for prefix matching
169 pub fn prefix_match(prefix: &str) -> BTreeMap<i32, CborValue> {
170 let mut map = BTreeMap::new();
171 map.insert(match_types::PREFIX, CborValue::Text(prefix.to_string()));
172 map
173 }
174
175 /// Creates a match condition for suffix matching
176 pub fn suffix_match(suffix: &str) -> BTreeMap<i32, CborValue> {
177 let mut map = BTreeMap::new();
178 map.insert(match_types::SUFFIX, CborValue::Text(suffix.to_string()));
179 map
180 }
181
182 /// Creates a match condition for contains matching
183 pub fn contains_match(text: &str) -> BTreeMap<i32, CborValue> {
184 let mut map = BTreeMap::new();
185 map.insert(match_types::CONTAINS, CborValue::Text(text.to_string()));
186 map
187 }
188
189 /// Creates a match condition for regex matching
190 pub fn regex_match(pattern: &str, groups: Vec<Option<String>>) -> BTreeMap<i32, CborValue> {
191 let mut map = BTreeMap::new();
192
193 let mut array = vec![CborValue::Text(pattern.to_string())];
194 for group in groups {
195 match group {
196 Some(text) => array.push(CborValue::Text(text)),
197 None => array.push(CborValue::Null),
198 }
199 }
200
201 map.insert(match_types::REGEX, CborValue::Array(array));
202 map
203 }
204
205 /// Creates a match condition for SHA-256 matching
206 pub fn sha256_match(hash: Vec<u8>) -> BTreeMap<i32, CborValue> {
207 let mut map = BTreeMap::new();
208 map.insert(match_types::SHA256, CborValue::Bytes(hash));
209 map
210 }
211
212 /// Creates a match condition for SHA-512/256 matching
213 pub fn sha512_256_match(hash: Vec<u8>) -> BTreeMap<i32, CborValue> {
214 let mut map = BTreeMap::new();
215 map.insert(match_types::SHA512_256, CborValue::Bytes(hash));
216 map
217 }
218}
219
220/// Helper functions for creating CATR (Common Access Token Renewal) claims
221pub mod catr {
222 use super::*;
223 use crate::constants::{renewal_params, renewal_types};
224
225 /// Creates a CATR claim with the specified renewal parameters
226 pub fn create(params: BTreeMap<i32, CborValue>) -> CborValue {
227 CborValue::Map(params)
228 }
229
230 /// Creates an automatic renewal claim
231 pub fn automatic_renewal(exp_add: i64, deadline: Option<i64>) -> BTreeMap<i32, CborValue> {
232 let mut map = BTreeMap::new();
233 map.insert(
234 renewal_params::TYPE,
235 CborValue::Integer(renewal_types::AUTOMATIC as i64),
236 );
237 map.insert(renewal_params::EXPADD, CborValue::Integer(exp_add));
238
239 if let Some(deadline_value) = deadline {
240 map.insert(renewal_params::DEADLINE, CborValue::Integer(deadline_value));
241 }
242
243 map
244 }
245
246 /// Creates a cookie renewal claim
247 pub fn cookie_renewal(
248 exp_add: i64,
249 deadline: Option<i64>,
250 cookie_name: Option<&str>,
251 additional_params: Option<Vec<&str>>,
252 ) -> BTreeMap<i32, CborValue> {
253 let mut map = BTreeMap::new();
254 map.insert(
255 renewal_params::TYPE,
256 CborValue::Integer(renewal_types::COOKIE as i64),
257 );
258 map.insert(renewal_params::EXPADD, CborValue::Integer(exp_add));
259
260 if let Some(deadline_value) = deadline {
261 map.insert(renewal_params::DEADLINE, CborValue::Integer(deadline_value));
262 }
263
264 if let Some(name) = cookie_name {
265 map.insert(
266 renewal_params::COOKIE_NAME,
267 CborValue::Text(name.to_string()),
268 );
269 }
270
271 if let Some(params) = additional_params {
272 let params_array: Vec<CborValue> = params
273 .into_iter()
274 .map(|s| CborValue::Text(s.to_string()))
275 .collect();
276 map.insert(
277 renewal_params::COOKIE_PARAMS,
278 CborValue::Array(params_array),
279 );
280 }
281
282 map
283 }
284
285 /// Creates a header renewal claim
286 pub fn header_renewal(
287 exp_add: i64,
288 deadline: Option<i64>,
289 header_name: Option<&str>,
290 additional_params: Option<Vec<&str>>,
291 ) -> BTreeMap<i32, CborValue> {
292 let mut map = BTreeMap::new();
293 map.insert(
294 renewal_params::TYPE,
295 CborValue::Integer(renewal_types::HEADER as i64),
296 );
297 map.insert(renewal_params::EXPADD, CborValue::Integer(exp_add));
298
299 if let Some(deadline_value) = deadline {
300 map.insert(renewal_params::DEADLINE, CborValue::Integer(deadline_value));
301 }
302
303 if let Some(name) = header_name {
304 map.insert(
305 renewal_params::HEADER_NAME,
306 CborValue::Text(name.to_string()),
307 );
308 }
309
310 if let Some(params) = additional_params {
311 let params_array: Vec<CborValue> = params
312 .into_iter()
313 .map(|s| CborValue::Text(s.to_string()))
314 .collect();
315 map.insert(
316 renewal_params::HEADER_PARAMS,
317 CborValue::Array(params_array),
318 );
319 }
320
321 map
322 }
323
324 /// Creates a redirect renewal claim
325 pub fn redirect_renewal(
326 exp_add: i64,
327 deadline: Option<i64>,
328 status_code: Option<i64>,
329 ) -> BTreeMap<i32, CborValue> {
330 let mut map = BTreeMap::new();
331 map.insert(
332 renewal_params::TYPE,
333 CborValue::Integer(renewal_types::REDIRECT as i64),
334 );
335 map.insert(renewal_params::EXPADD, CborValue::Integer(exp_add));
336
337 if let Some(deadline_value) = deadline {
338 map.insert(renewal_params::DEADLINE, CborValue::Integer(deadline_value));
339 }
340
341 if let Some(code) = status_code {
342 map.insert(renewal_params::STATUS_CODE, CborValue::Integer(code));
343 }
344
345 map
346 }
347}
348
349/// Helper functions for creating CATM (Common Access Token Methods) claims
350pub mod catm {
351 use super::*;
352
353 /// Creates a CATM claim with the specified HTTP methods
354 pub fn create(methods: Vec<&str>) -> Vec<CborValue> {
355 methods
356 .into_iter()
357 .map(|s| CborValue::Text(s.to_string()))
358 .collect()
359 }
360}
361
362/// Helper functions for creating CATREPLAY claims
363pub mod catreplay {
364 use super::*;
365 use crate::constants::replay_values;
366
367 /// Creates a CATREPLAY claim with the specified value
368 pub fn create(value: i32) -> CborValue {
369 CborValue::Integer(value as i64)
370 }
371
372 /// Creates a CATREPLAY claim with "permitted" value
373 pub fn permitted() -> CborValue {
374 CborValue::Integer(replay_values::PERMITTED as i64)
375 }
376
377 /// Creates a CATREPLAY claim with "prohibited" value
378 pub fn prohibited() -> CborValue {
379 CborValue::Integer(replay_values::PROHIBITED as i64)
380 }
381
382 /// Creates a CATREPLAY claim with "reuse detection" value
383 pub fn reuse_detection() -> CborValue {
384 CborValue::Integer(replay_values::REUSE_DETECTION as i64)
385 }
386}
387
388/// Helper functions for creating CATV (Common Access Token Version) claims
389pub mod catv {
390 use super::*;
391
392 /// Creates a CATV claim with version 1
393 pub fn create() -> CborValue {
394 CborValue::Integer(1)
395 }
396
397 /// Creates a CATV claim with a specific version number
398 pub fn with_version(version: i64) -> CborValue {
399 CborValue::Integer(version)
400 }
401}
402
403/// Helper functions for creating CATPOR (Common Access Token Probability of Rejection) claims
404///
405/// CATPOR specifies the probability that a token might be rejected, used for probabilistic
406/// rate limiting or load shedding.
407pub mod catpor {
408 use super::*;
409
410 /// Creates a CATPOR claim with a probability value (0.0 to 1.0)
411 ///
412 /// The probability is encoded as an integer representing the percentage (0-100).
413 ///
414 /// # Example
415 ///
416 /// ```
417 /// use common_access_token::cat_claims::catpor;
418 ///
419 /// // 25% probability of rejection
420 /// let catpor_claim = catpor::create(25);
421 /// ```
422 pub fn create(probability_percent: i64) -> CborValue {
423 CborValue::Integer(probability_percent)
424 }
425}
426
427/// Helper functions for creating CATNIP (Common Access Token Network IP) claims
428///
429/// CATNIP restricts the IP addresses from which the token can be used.
430pub mod catnip {
431 use super::*;
432
433 /// Creates a CATNIP claim with a list of allowed IP addresses or ranges
434 ///
435 /// # Example
436 ///
437 /// ```
438 /// use common_access_token::cat_claims::catnip;
439 ///
440 /// // Allow specific IP addresses
441 /// let catnip_claim = catnip::create(vec!["192.168.1.100", "10.0.0.0/8"]);
442 /// ```
443 pub fn create(ip_addresses: Vec<&str>) -> Vec<CborValue> {
444 ip_addresses
445 .into_iter()
446 .map(|ip| CborValue::Text(ip.to_string()))
447 .collect()
448 }
449
450 /// Creates a CATNIP claim with a single IP address
451 pub fn single(ip_address: &str) -> Vec<CborValue> {
452 vec![CborValue::Text(ip_address.to_string())]
453 }
454}
455
456/// Helper functions for creating CATALPN (Common Access Token ALPN) claims
457///
458/// CATALPN restricts the TLS Application-Layer Protocol Negotiation values.
459pub mod catalpn {
460 use super::*;
461
462 /// Creates a CATALPN claim with a list of allowed ALPN protocols
463 ///
464 /// # Example
465 ///
466 /// ```
467 /// use common_access_token::cat_claims::catalpn;
468 ///
469 /// // Allow HTTP/2 and HTTP/1.1
470 /// let catalpn_claim = catalpn::create(vec!["h2", "http/1.1"]);
471 /// ```
472 pub fn create(protocols: Vec<&str>) -> Vec<CborValue> {
473 protocols
474 .into_iter()
475 .map(|proto| CborValue::Text(proto.to_string()))
476 .collect()
477 }
478
479 /// Creates a CATALPN claim for HTTP/2 only
480 pub fn http2_only() -> Vec<CborValue> {
481 vec![CborValue::Text("h2".to_string())]
482 }
483
484 /// Creates a CATALPN claim for HTTP/1.1 only
485 pub fn http1_only() -> Vec<CborValue> {
486 vec![CborValue::Text("http/1.1".to_string())]
487 }
488}
489
490/// Helper functions for creating CATH (Common Access Token Header) claims
491///
492/// CATH specifies HTTP header requirements or restrictions.
493pub mod cath {
494 use super::*;
495
496 /// Creates a CATH claim with header name-value pairs
497 ///
498 /// # Example
499 ///
500 /// ```
501 /// use common_access_token::cat_claims::cath;
502 /// use std::collections::BTreeMap;
503 ///
504 /// let mut headers = BTreeMap::new();
505 /// headers.insert("X-Custom-Header", "required-value");
506 /// headers.insert("User-Agent", "MyApp/1.0");
507 /// let cath_claim = cath::create(headers);
508 /// ```
509 pub fn create(headers: BTreeMap<&str, &str>) -> CborValue {
510 let mut map = BTreeMap::new();
511 for (i, (key, value)) in headers.iter().enumerate() {
512 let mut header_map = BTreeMap::new();
513 header_map.insert(0, CborValue::Text(key.to_string()));
514 header_map.insert(1, CborValue::Text(value.to_string()));
515 map.insert(i as i32, CborValue::Map(header_map));
516 }
517 CborValue::Map(map)
518 }
519}
520
521/// Helper functions for creating CATGEOISO3166 (Common Access Token Geographic ISO3166) claims
522///
523/// CATGEOISO3166 restricts token usage to specific countries or regions.
524pub mod catgeoiso3166 {
525 use super::*;
526
527 /// Creates a CATGEOISO3166 claim with ISO 3166 country codes
528 ///
529 /// # Example
530 ///
531 /// ```
532 /// use common_access_token::cat_claims::catgeoiso3166;
533 ///
534 /// // Allow usage in US and Canada
535 /// let catgeoiso3166_claim = catgeoiso3166::create(vec!["US", "CA"]);
536 /// ```
537 pub fn create(country_codes: Vec<&str>) -> Vec<CborValue> {
538 country_codes
539 .into_iter()
540 .map(|code| CborValue::Text(code.to_string()))
541 .collect()
542 }
543}
544
545/// Helper functions for creating CATGEOCOORD (Common Access Token Geographic Coordinate) claims
546///
547/// CATGEOCOORD restricts token usage based on geographic coordinates.
548pub mod catgeocoord {
549 use super::*;
550
551 /// Creates a CATGEOCOORD claim with latitude and longitude
552 ///
553 /// # Example
554 ///
555 /// ```
556 /// use common_access_token::cat_claims::catgeocoord;
557 ///
558 /// // Center of New York City
559 /// let catgeocoord_claim = catgeocoord::create(40.7128, -74.0060);
560 /// ```
561 pub fn create(latitude: f64, longitude: f64) -> CborValue {
562 let mut map = BTreeMap::new();
563 // Using i64 representation of coordinates (multiply by 1e7 for precision)
564 map.insert(0, CborValue::Integer((latitude * 10_000_000.0) as i64));
565 map.insert(1, CborValue::Integer((longitude * 10_000_000.0) as i64));
566 CborValue::Map(map)
567 }
568
569 /// Creates a CATGEOCOORD claim with latitude, longitude, and radius in meters
570 pub fn with_radius(latitude: f64, longitude: f64, radius_meters: i64) -> CborValue {
571 let mut map = BTreeMap::new();
572 map.insert(0, CborValue::Integer((latitude * 10_000_000.0) as i64));
573 map.insert(1, CborValue::Integer((longitude * 10_000_000.0) as i64));
574 map.insert(2, CborValue::Integer(radius_meters));
575 CborValue::Map(map)
576 }
577}
578
579/// Helper functions for creating CATGEOALT (Common Access Token Geographic Altitude) claims
580///
581/// CATGEOALT restricts token usage based on altitude.
582pub mod catgeoalt {
583 use super::*;
584
585 /// Creates a CATGEOALT claim with altitude in meters
586 ///
587 /// # Example
588 ///
589 /// ```
590 /// use common_access_token::cat_claims::catgeoalt;
591 ///
592 /// // Sea level
593 /// let catgeoalt_claim = catgeoalt::create(0);
594 /// ```
595 pub fn create(altitude_meters: i64) -> CborValue {
596 CborValue::Integer(altitude_meters)
597 }
598
599 /// Creates a CATGEOALT claim with altitude range (min and max in meters)
600 pub fn range(min_meters: i64, max_meters: i64) -> CborValue {
601 let mut map = BTreeMap::new();
602 map.insert(0, CborValue::Integer(min_meters));
603 map.insert(1, CborValue::Integer(max_meters));
604 CborValue::Map(map)
605 }
606}
607
608/// Helper functions for creating CATTPK (Common Access Token TLS Public Key) claims
609///
610/// CATTPK pins the token to a specific TLS public key or certificate.
611pub mod cattpk {
612 use super::*;
613
614 /// Creates a CATTPK claim with a public key hash
615 ///
616 /// # Example
617 ///
618 /// ```
619 /// use common_access_token::cat_claims::cattpk;
620 ///
621 /// // SHA-256 hash of the public key
622 /// let key_hash = vec![0x01, 0x02, 0x03]; // truncated for example
623 /// let cattpk_claim = cattpk::create(key_hash);
624 /// ```
625 pub fn create(public_key_hash: Vec<u8>) -> CborValue {
626 CborValue::Bytes(public_key_hash)
627 }
628
629 /// Creates a CATTPK claim with multiple public key hashes
630 pub fn multiple(public_key_hashes: Vec<Vec<u8>>) -> Vec<CborValue> {
631 public_key_hashes
632 .into_iter()
633 .map(CborValue::Bytes)
634 .collect()
635 }
636}
637
638/// Helper functions for creating CATDPOP (Common Access Token DPoP Settings) claims
639///
640/// CATDPOP provides settings for Demonstrating Proof-of-Possession.
641pub mod catdpop {
642 use super::*;
643
644 /// Creates a CATDPOP claim with DPoP configuration
645 ///
646 /// # Example
647 ///
648 /// ```
649 /// use common_access_token::cat_claims::catdpop;
650 /// use std::collections::BTreeMap;
651 ///
652 /// let mut dpop_config = BTreeMap::new();
653 /// dpop_config.insert(0, common_access_token::CborValue::Integer(1)); // version
654 /// dpop_config.insert(1, common_access_token::CborValue::Text("RS256".to_string())); // algorithm
655 /// let catdpop_claim = catdpop::create(dpop_config);
656 /// ```
657 pub fn create(config: BTreeMap<i32, CborValue>) -> CborValue {
658 CborValue::Map(config)
659 }
660
661 /// Creates a basic CATDPOP claim requiring DPoP
662 pub fn required() -> CborValue {
663 let mut map = BTreeMap::new();
664 map.insert(0, CborValue::Integer(1)); // required
665 CborValue::Map(map)
666 }
667}
668
669/// Helper functions for creating CATIF (Common Access Token If) claims
670///
671/// CATIF provides conditional logic for token handling.
672pub mod catif {
673 use super::*;
674
675 /// Creates a CATIF claim with conditional expressions
676 ///
677 /// # Example
678 ///
679 /// ```
680 /// use common_access_token::cat_claims::catif;
681 /// use std::collections::BTreeMap;
682 ///
683 /// let mut condition = BTreeMap::new();
684 /// condition.insert(0, common_access_token::CborValue::Text("status".to_string()));
685 /// condition.insert(1, common_access_token::CborValue::Text("eq".to_string()));
686 /// condition.insert(2, common_access_token::CborValue::Integer(200));
687 /// let catif_claim = catif::create(condition);
688 /// ```
689 pub fn create(condition: BTreeMap<i32, CborValue>) -> CborValue {
690 CborValue::Map(condition)
691 }
692}
693
694/// Helper functions for creating CATIFDATA (Common Access Token If Data) claims
695///
696/// CATIFDATA provides data for conditional evaluation in CATIF.
697pub mod catifdata {
698 use super::*;
699
700 /// Creates a CATIFDATA claim with data values
701 ///
702 /// # Example
703 ///
704 /// ```
705 /// use common_access_token::cat_claims::catifdata;
706 /// use std::collections::BTreeMap;
707 ///
708 /// let mut data = BTreeMap::new();
709 /// data.insert(0, common_access_token::CborValue::Text("user_role".to_string()));
710 /// data.insert(1, common_access_token::CborValue::Text("admin".to_string()));
711 /// let catifdata_claim = catifdata::create(data);
712 /// ```
713 pub fn create(data: BTreeMap<i32, CborValue>) -> CborValue {
714 CborValue::Map(data)
715 }
716}