jwt_service/impl.rs
1use super::*;
2
3impl JwtConfig {
4 /// Creates a new JwtConfig instance.
5 ///
6 /// # Arguments
7 ///
8 /// - `secret` - The secret key for signing tokens.
9 /// - `expiration_seconds` - Token validity duration in seconds.
10 /// - `AsRef<str>` - The issuer identifier for the token.
11 ///
12 /// # Returns
13 ///
14 /// - `JwtConfig` - The configured JwtConfig instance.
15 pub fn new<S>(secret: S, expiration_seconds: u64, issuer: S) -> Self
16 where
17 S: AsRef<str>,
18 {
19 Self {
20 secret: secret.as_ref().to_string(),
21 expiration_seconds,
22 issuer: issuer.as_ref().to_string(),
23 }
24 }
25
26 /// Returns a reference to the secret key.
27 ///
28 /// # Returns
29 ///
30 /// - `&String` - The secret key.
31 pub fn get_secret(&self) -> &String {
32 &self.secret
33 }
34
35 /// Sets the secret key.
36 ///
37 /// # Arguments
38 ///
39 /// - `AsRef<str>` - The secret key to set.
40 ///
41 /// # Returns
42 ///
43 /// - `&mut Self` - The modified instance for chaining.
44 pub fn set_secret<S>(&mut self, secret: S) -> &mut Self
45 where
46 S: AsRef<str>,
47 {
48 self.secret = secret.as_ref().to_string();
49 self
50 }
51
52 /// Returns the expiration time in seconds.
53 ///
54 /// # Returns
55 ///
56 /// - `u64` - The expiration time.
57 pub fn get_expiration_seconds(&self) -> u64 {
58 self.expiration_seconds
59 }
60
61 /// Sets the expiration time in seconds.
62 ///
63 /// # Arguments
64 ///
65 /// - `u64` - The expiration time to set.
66 ///
67 /// # Returns
68 ///
69 /// - `&mut Self` - The modified instance for chaining.
70 pub fn set_expiration_seconds(&mut self, expiration_seconds: u64) -> &mut Self {
71 self.expiration_seconds = expiration_seconds;
72 self
73 }
74
75 /// Returns a reference to the issuer.
76 ///
77 /// # Returns
78 ///
79 /// - `&String` - The issuer.
80 pub fn get_issuer(&self) -> &String {
81 &self.issuer
82 }
83
84 /// Sets the issuer.
85 ///
86 /// # Arguments
87 ///
88 /// - `AsRef<str>` - The issuer to set.
89 ///
90 /// # Returns
91 ///
92 /// - `&mut Self` - The modified instance for chaining.
93 pub fn set_issuer<S>(&mut self, issuer: S) -> &mut Self
94 where
95 S: AsRef<str>,
96 {
97 self.issuer = issuer.as_ref().to_string();
98 self
99 }
100}
101
102impl JwtExtraJwtClaims {
103 /// Creates a new JwtExtraJwtClaims instance.
104 ///
105 /// # Arguments
106 ///
107 /// - `AsRef<str>` - The subject (user identifier).
108 /// - `AsRef<str>` - The issuer.
109 /// - `usize` - Expiration time as a Unix timestamp.
110 /// - `usize` - Issued at time as a Unix timestamp.
111 /// - `usize` - Not before time as a Unix timestamp.
112 ///
113 /// # Returns
114 ///
115 /// - `JwtExtraJwtClaims` - The created claims instance.
116 pub fn new<S>(sub: S, iss: S, exp: usize, iat: usize, nbf: usize) -> Self
117 where
118 S: AsRef<str>,
119 {
120 Self {
121 sub: sub.as_ref().to_string(),
122 iss: iss.as_ref().to_string(),
123 exp,
124 iat,
125 nbf,
126 }
127 }
128
129 /// Returns a reference to the subject.
130 ///
131 /// # Returns
132 ///
133 /// - `&String` - The subject.
134 pub fn get_sub(&self) -> &String {
135 &self.sub
136 }
137
138 /// Sets the subject.
139 ///
140 /// # Arguments
141 ///
142 /// - `AsRef<str>` - The subject to set.
143 ///
144 /// # Returns
145 ///
146 /// - `&mut Self` - The modified instance for chaining.
147 pub fn set_sub<S>(&mut self, sub: S) -> &mut Self
148 where
149 S: AsRef<str>,
150 {
151 self.sub = sub.as_ref().to_string();
152 self
153 }
154
155 /// Returns a reference to the issuer.
156 ///
157 /// # Returns
158 ///
159 /// - `&String` - The issuer.
160 pub fn get_iss(&self) -> &String {
161 &self.iss
162 }
163
164 /// Sets the issuer.
165 ///
166 /// # Arguments
167 ///
168 /// - `AsRef<str>` - The issuer to set.
169 ///
170 /// # Returns
171 ///
172 /// - `&mut Self` - The modified instance for chaining.
173 pub fn set_iss<S>(&mut self, iss: S) -> &mut Self
174 where
175 S: AsRef<str>,
176 {
177 self.iss = iss.as_ref().to_string();
178 self
179 }
180
181 /// Returns the expiration time.
182 ///
183 /// # Returns
184 ///
185 /// - `usize` - The expiration timestamp.
186 pub fn get_exp(&self) -> usize {
187 self.exp
188 }
189
190 /// Sets the expiration time.
191 ///
192 /// # Arguments
193 ///
194 /// - `exp` - The expiration timestamp to set.
195 ///
196 /// # Returns
197 ///
198 /// - `&mut Self` - The modified instance for chaining.
199 pub fn set_exp(&mut self, exp: usize) -> &mut Self {
200 self.exp = exp;
201 self
202 }
203
204 /// Returns the issued at time.
205 ///
206 /// # Returns
207 ///
208 /// - `usize` - The issued at timestamp.
209 pub fn get_iat(&self) -> usize {
210 self.iat
211 }
212
213 /// Sets the issued at time.
214 ///
215 /// # Arguments
216 ///
217 /// - `usize` - The issued at timestamp to set.
218 ///
219 /// # Returns
220 ///
221 /// - `&mut Self` - The modified instance for chaining.
222 pub fn set_iat(&mut self, iat: usize) -> &mut Self {
223 self.iat = iat;
224 self
225 }
226
227 /// Returns the not before time.
228 ///
229 /// # Returns
230 ///
231 /// - `usize` - The not before timestamp.
232 pub fn get_nbf(&self) -> usize {
233 self.nbf
234 }
235
236 /// Sets the not before time.
237 ///
238 /// # Arguments
239 ///
240 /// - `usize` - The not before timestamp to set.
241 ///
242 /// # Returns
243 ///
244 /// - `&mut Self` - The modified instance for chaining.
245 pub fn set_nbf(&mut self, nbf: usize) -> &mut Self {
246 self.nbf = nbf;
247 self
248 }
249}
250
251impl JwtToken {
252 /// Returns a reference to the token.
253 ///
254 /// # Returns
255 ///
256 /// - `&String` - The token.
257 pub fn get_token(&self) -> &String {
258 &self.token
259 }
260
261 /// Sets the token.
262 ///
263 /// # Arguments
264 ///
265 /// - `AsRef<str>` - The token to set.
266 ///
267 /// # Returns
268 ///
269 /// - `&mut Self` - The modified instance for chaining.
270 pub fn set_token<S>(&mut self, token: S) -> &mut Self
271 where
272 S: AsRef<str>,
273 {
274 self.token = token.as_ref().to_string();
275 self
276 }
277
278 /// Returns a reference to the token type.
279 ///
280 /// # Returns
281 ///
282 /// - `&String` - The token type.
283 pub fn get_token_type(&self) -> &String {
284 &self.token_type
285 }
286
287 /// Sets the token type.
288 ///
289 /// # Arguments
290 ///
291 /// - `token_type` - The token type to set.
292 ///
293 /// # Returns
294 ///
295 /// - `&mut Self` - The modified instance for chaining.
296 pub fn set_token_type<S>(&mut self, token_type: S) -> &mut Self
297 where
298 S: AsRef<str>,
299 {
300 self.token_type = token_type.as_ref().to_string();
301 self
302 }
303
304 /// Returns the expires in value.
305 ///
306 /// # Returns
307 ///
308 /// - `u64` - The expires in value.
309 pub fn get_expires_in(&self) -> u64 {
310 self.expires_in
311 }
312
313 /// Sets the expires in value.
314 ///
315 /// # Arguments
316 ///
317 /// - `u64` - The expires in value to set.
318 ///
319 /// # Returns
320 ///
321 /// - `&mut Self` - The modified instance for chaining.
322 pub fn set_expires_in(&mut self, expires_in: u64) -> &mut Self {
323 self.expires_in = expires_in;
324 self
325 }
326}
327
328impl JwtService {
329 /// Creates a new JwtService instance.
330 ///
331 /// # Arguments
332 ///
333 /// - `JwtConfig` - The JWT configuration.
334 /// - `EncodingKey` - The encoding key for signing tokens.
335 /// - `DecodingKey` - The decoding key for verifying tokens.
336 /// - `Validation` - The validation settings for token verification.
337 ///
338 /// # Returns
339 ///
340 /// - `JwtService` - The created service instance.
341 pub fn new(
342 config: JwtConfig,
343 encoding_key: EncodingKey,
344 decoding_key: DecodingKey,
345 validation: Validation,
346 ) -> Self {
347 Self {
348 config,
349 encoding_key,
350 decoding_key,
351 validation,
352 }
353 }
354
355 /// Returns a reference to the JWT configuration.
356 ///
357 /// # Returns
358 ///
359 /// - `&JwtConfig` - The configuration.
360 pub fn get_config(&self) -> &JwtConfig {
361 &self.config
362 }
363
364 /// Returns a reference to the encoding key.
365 ///
366 /// # Returns
367 ///
368 /// - `&EncodingKey` - The encoding key.
369 pub fn get_encoding_key(&self) -> &EncodingKey {
370 &self.encoding_key
371 }
372
373 /// Returns a reference to the decoding key.
374 ///
375 /// # Returns
376 ///
377 /// - `&DecodingKey` - The decoding key.
378 pub fn get_decoding_key(&self) -> &DecodingKey {
379 &self.decoding_key
380 }
381
382 /// Returns a reference to the validation settings.
383 ///
384 /// # Returns
385 ///
386 /// - `&Validation` - The validation settings.
387 pub fn get_validation(&self) -> &Validation {
388 &self.validation
389 }
390}
391
392impl<T: Default> CustomExtraJwtClaims<T> {
393 /// Returns a reference to the custom payload data.
394 ///
395 /// # Returns
396 ///
397 /// - `&T` - The custom payload data.
398 pub fn get_custom(&self) -> &T {
399 &self.custom
400 }
401
402 /// Sets the custom payload data.
403 ///
404 /// # Arguments
405 ///
406 /// - `T` - The custom payload data to set.
407 ///
408 /// # Returns
409 ///
410 /// - `&mut Self` - The modified instance for chaining.
411 pub fn set_custom(&mut self, custom: T) -> &mut Self {
412 self.custom = custom;
413 self
414 }
415
416 /// Returns a reference to the subject.
417 ///
418 /// # Returns
419 ///
420 /// - `&String` - The subject.
421 pub fn get_sub(&self) -> &String {
422 &self.sub
423 }
424
425 /// Sets the subject.
426 ///
427 /// # Arguments
428 ///
429 /// - `AsRef<str>` - The subject to set.
430 ///
431 /// # Returns
432 ///
433 /// - `&mut Self` - The modified instance for chaining.
434 pub fn set_sub<S>(&mut self, sub: S) -> &mut Self
435 where
436 S: AsRef<str>,
437 {
438 self.sub = sub.as_ref().to_string();
439 self
440 }
441
442 /// Returns a reference to the issuer.
443 ///
444 /// # Returns
445 ///
446 /// - `&String` - The issuer.
447 pub fn get_iss(&self) -> &String {
448 &self.iss
449 }
450
451 /// Sets the issuer.
452 ///
453 /// # Arguments
454 ///
455 /// - `AsRef<str>` - The issuer to set.
456 ///
457 /// # Returns
458 ///
459 /// - `&mut Self` - The modified instance for chaining.
460 pub fn set_iss<S>(&mut self, iss: S) -> &mut Self
461 where
462 S: AsRef<str>,
463 {
464 self.iss = iss.as_ref().to_string();
465 self
466 }
467
468 /// Returns the expiration time.
469 ///
470 /// # Returns
471 ///
472 /// - `usize` - The expiration timestamp.
473 pub fn get_exp(&self) -> usize {
474 self.exp
475 }
476
477 /// Sets the expiration time.
478 ///
479 /// # Arguments
480 ///
481 /// - `exp` - The expiration timestamp to set.
482 ///
483 /// # Returns
484 ///
485 /// - `&mut Self` - The modified instance for chaining.
486 pub fn set_exp(&mut self, exp: usize) -> &mut Self {
487 self.exp = exp;
488 self
489 }
490
491 /// Returns the issued at time.
492 ///
493 /// # Returns
494 ///
495 /// - `usize` - The issued at timestamp.
496 pub fn get_iat(&self) -> usize {
497 self.iat
498 }
499
500 /// Sets the issued at time.
501 ///
502 /// # Arguments
503 ///
504 /// - `usize` - The issued at timestamp to set.
505 ///
506 /// # Returns
507 ///
508 /// - `&mut Self` - The modified instance for chaining.
509 pub fn set_iat(&mut self, iat: usize) -> &mut Self {
510 self.iat = iat;
511 self
512 }
513}
514
515impl ExtraJwtClaims {
516 /// Creates a new ExtraJwtClaims instance.
517 ///
518 /// # Arguments
519 ///
520 /// - `AsRef<str>` - The subject (user identifier).
521 /// - `AsRef<str>` - The issuer.
522 /// - `usize` - Expiration time as a Unix timestamp.
523 ///
524 /// # Returns
525 ///
526 /// - `ExtraJwtClaims` - The created claims instance.
527 pub fn new<S>(sub: S, iss: S, exp: usize) -> Self
528 where
529 S: AsRef<str>,
530 {
531 let now: usize = SystemTime::now()
532 .duration_since(UNIX_EPOCH)
533 .unwrap_or_default()
534 .as_secs() as usize;
535 Self {
536 sub: sub.as_ref().to_string(),
537 iss: iss.as_ref().to_string(),
538 exp,
539 iat: now,
540 extra: HashMap::new(),
541 }
542 }
543
544 /// Returns a reference to the subject.
545 ///
546 /// # Returns
547 ///
548 /// - `&String` - The subject.
549 pub fn get_sub(&self) -> &String {
550 &self.sub
551 }
552
553 /// Sets the subject.
554 ///
555 /// # Arguments
556 ///
557 /// - `AsRef<str>` - The subject to set.
558 ///
559 /// # Returns
560 ///
561 /// - `&mut Self` - The modified instance for chaining.
562 pub fn set_sub<S>(&mut self, sub: S) -> &mut Self
563 where
564 S: AsRef<str>,
565 {
566 self.sub = sub.as_ref().to_string();
567 self
568 }
569
570 /// Returns a reference to the issuer.
571 ///
572 /// # Returns
573 ///
574 /// - `&String` - The issuer.
575 pub fn get_iss(&self) -> &String {
576 &self.iss
577 }
578
579 /// Sets the issuer.
580 ///
581 /// # Arguments
582 ///
583 /// - `AsRef<str>` - The issuer to set.
584 ///
585 /// # Returns
586 ///
587 /// - `&mut Self` - The modified instance for chaining.
588 pub fn set_iss<S>(&mut self, iss: S) -> &mut Self
589 where
590 S: AsRef<str>,
591 {
592 self.iss = iss.as_ref().to_string();
593 self
594 }
595
596 /// Returns the expiration time.
597 ///
598 /// # Returns
599 ///
600 /// - `usize` - The expiration timestamp.
601 pub fn get_exp(&self) -> usize {
602 self.exp
603 }
604
605 /// Sets the expiration time.
606 ///
607 /// # Arguments
608 ///
609 /// - `exp` - The expiration timestamp to set.
610 ///
611 /// # Returns
612 ///
613 /// - `&mut Self` - The modified instance for chaining.
614 pub fn set_exp(&mut self, exp: usize) -> &mut Self {
615 self.exp = exp;
616 self
617 }
618
619 /// Returns the issued at time.
620 ///
621 /// # Returns
622 ///
623 /// - `usize` - The issued at timestamp.
624 pub fn get_iat(&self) -> usize {
625 self.iat
626 }
627
628 /// Sets the issued at time.
629 ///
630 /// # Arguments
631 ///
632 /// - `usize` - The issued at timestamp to set.
633 ///
634 /// # Returns
635 ///
636 /// - `&mut Self` - The modified instance for chaining.
637 pub fn set_iat(&mut self, iat: usize) -> &mut Self {
638 self.iat = iat;
639 self
640 }
641
642 /// Returns a reference to the extra claims.
643 ///
644 /// # Returns
645 ///
646 /// - `&HashMap<String, Value>` - The extra claims.
647 pub fn get_extra(&self) -> &HashMap<String, Value> {
648 &self.extra
649 }
650
651 /// Returns a mutable reference to the extra claims.
652 ///
653 /// # Returns
654 ///
655 /// - `&mut HashMap<String, Value>` - The mutable extra claims.
656 pub fn get_mut_extra(&mut self) -> &mut HashMap<String, Value> {
657 &mut self.extra
658 }
659
660 /// Sets the extra claims.
661 ///
662 /// # Arguments
663 ///
664 /// - `HashMap<String, Value>` - The extra claims to set.
665 ///
666 /// # Returns
667 ///
668 /// - `&mut Self` - The modified instance for chaining.
669 pub fn set_extra(&mut self, extra: HashMap<String, Value>) -> &mut Self {
670 self.extra = extra;
671 self
672 }
673}
674
675/// Display implementation for JwtValidationError.
676impl std::fmt::Display for JwtValidationError {
677 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
678 match self {
679 Self::Expired => write!(f, "Token has expired"),
680 Self::InvalidSignature => write!(f, "Invalid token signature"),
681 Self::InvalidIssuer => write!(f, "Invalid token issuer"),
682 Self::InvalidSubject => write!(f, "Invalid token subject"),
683 Self::NotYetValid => write!(f, "Token is not yet valid"),
684 Self::Malformed => write!(f, "Malformed token"),
685 Self::Other(msg) => write!(f, "{msg}"),
686 }
687 }
688}
689
690/// Error trait implementation for JwtValidationError.
691impl std::error::Error for JwtValidationError {}
692
693/// Conversion from jsonwebtoken errors to JwtValidationError.
694///
695/// # Arguments
696///
697/// - `jsonwebtoken::errors::Error` - The jsonwebtoken error to convert.
698///
699/// # Returns
700///
701/// - `JwtValidationError` - The corresponding validation error.
702impl From<jsonwebtoken::errors::Error> for JwtValidationError {
703 fn from(error: jsonwebtoken::errors::Error) -> Self {
704 match error.kind() {
705 jsonwebtoken::errors::ErrorKind::ExpiredSignature => Self::Expired,
706 jsonwebtoken::errors::ErrorKind::InvalidSignature => Self::InvalidSignature,
707 jsonwebtoken::errors::ErrorKind::InvalidIssuer => Self::InvalidIssuer,
708 jsonwebtoken::errors::ErrorKind::InvalidSubject => Self::InvalidSubject,
709 jsonwebtoken::errors::ErrorKind::ImmatureSignature => Self::NotYetValid,
710 _ => Self::Other(error.to_string()),
711 }
712 }
713}
714
715/// Implementation block for JwtConfig.
716impl JwtConfig {
717 /// Creates a new JwtConfig instance with the specified settings.
718 ///
719 /// # Arguments
720 ///
721 /// - `String` - The secret key for signing tokens.
722 /// - `u64` - Token validity duration in seconds.
723 /// - `String` - The issuer identifier for the token.
724 ///
725 /// # Returns
726 ///
727 /// - `JwtConfig` - The configured JwtConfig instance.
728 pub fn with_settings(secret: String, expiration_seconds: u64, issuer: String) -> Self {
729 let mut instance: JwtConfig = Self::default();
730 instance
731 .set_secret(secret)
732 .set_expiration_seconds(expiration_seconds)
733 .set_issuer(issuer);
734 instance
735 }
736}
737
738/// Conversion from JwtConfig to JwtService.
739///
740/// # Arguments
741///
742/// - `JwtConfig` - The JWT configuration to convert.
743///
744/// # Returns
745///
746/// - `JwtService` - The initialized JWT service.
747impl From<JwtConfig> for JwtService {
748 fn from(config: JwtConfig) -> Self {
749 let encoding_key: EncodingKey = EncodingKey::from_secret(config.get_secret().as_bytes());
750 let decoding_key: DecodingKey = DecodingKey::from_secret(config.get_secret().as_bytes());
751 let mut validation: Validation = Validation::new(Algorithm::HS256);
752 validation.set_issuer(&[config.get_issuer()]);
753 Self::new(config, encoding_key, decoding_key, validation)
754 }
755}
756
757/// Implementation block for JwtService core functionality.
758impl JwtService {
759 /// Generates a JWT token for the given subject.
760 ///
761 /// # Arguments
762 ///
763 /// - `AsRef<str>` - The subject (user identifier) to include in the token.
764 ///
765 /// # Returns
766 ///
767 /// - `Result<JwtToken, String>` - The generated token on success, or an error message on failure.
768 pub fn generate_token<S>(&self, subject: S) -> Result<JwtToken, String>
769 where
770 S: AsRef<str>,
771 {
772 let now: usize = SystemTime::now()
773 .duration_since(UNIX_EPOCH)
774 .unwrap_or_default()
775 .as_secs() as usize;
776 let exp: usize = now + self.get_config().get_expiration_seconds() as usize;
777 let claims: JwtExtraJwtClaims = JwtExtraJwtClaims::new(
778 subject.as_ref().to_string(),
779 self.get_config().get_issuer().clone(),
780 exp,
781 now,
782 now,
783 );
784 let token: String = encode(
785 &Header::new(Algorithm::HS256),
786 &claims,
787 self.get_encoding_key(),
788 )
789 .map_err(|error| error.to_string())?;
790 let mut jwt_token: JwtToken = JwtToken::default();
791 jwt_token
792 .set_token(token)
793 .set_token_type(BEARER)
794 .set_expires_in(self.get_config().get_expiration_seconds());
795 Ok(jwt_token)
796 }
797
798 /// Validates a JWT token and returns its claims.
799 ///
800 /// # Arguments
801 ///
802 /// - `AsRef<str>` - The JWT token to validate.
803 ///
804 /// # Returns
805 ///
806 /// - `Result<JwtExtraJwtClaims, JwtValidationError>` - The claims on success, or a validation error on failure.
807 pub fn validate_token<T>(&self, token: T) -> Result<JwtExtraJwtClaims, JwtValidationError>
808 where
809 T: AsRef<str>,
810 {
811 let token_data = decode::<JwtExtraJwtClaims>(
812 token.as_ref(),
813 self.get_decoding_key(),
814 self.get_validation(),
815 )?;
816 Ok(token_data.claims)
817 }
818
819 /// Extracts the subject from a JWT token.
820 ///
821 /// # Arguments
822 ///
823 /// - `AsRef<str>` - The JWT token to extract the subject from.
824 ///
825 /// # Returns
826 ///
827 /// - `Result<String, String>` - The subject on success, or an error message on failure.
828 pub fn get_subject_from_token<T>(&self, token: T) -> Result<String, String>
829 where
830 T: AsRef<str>,
831 {
832 let claims: JwtExtraJwtClaims = self.validate_token(token).map_err(|e| e.to_string())?;
833 Ok(claims.get_sub().clone())
834 }
835
836 /// Checks if a JWT token is expired.
837 ///
838 /// # Arguments
839 ///
840 /// - `AsRef<str>` - The JWT token to check.
841 ///
842 /// # Returns
843 ///
844 /// - `Result<bool, String>` - True if expired, false otherwise, or an error message on failure.
845 pub fn is_token_expired<T>(&self, token: T) -> Result<bool, String>
846 where
847 T: AsRef<str>,
848 {
849 match decode::<JwtExtraJwtClaims>(
850 token.as_ref(),
851 self.get_decoding_key(),
852 &Validation::new(Algorithm::HS256),
853 ) {
854 Ok(token_data) => {
855 let now: usize = SystemTime::now()
856 .duration_since(UNIX_EPOCH)
857 .unwrap_or_default()
858 .as_secs() as usize;
859 Ok(token_data.claims.get_exp() < now)
860 }
861 Err(error) => Err(error.to_string()),
862 }
863 }
864}
865
866/// Implementation block for JwtService with custom claims support.
867impl JwtService {
868 /// Generates a JWT token with custom claims.
869 ///
870 /// # Arguments
871 ///
872 /// - `AsRef<str>` - The subject (user identifier) to include in the token.
873 /// - `Clone + Default + Serialize + for<'de> Deserialize<'de>` - The custom claims to include in the token payload.
874 ///
875 /// # Returns
876 ///
877 /// - `Result<JwtToken, String>` - The generated token on success, or an error message on failure.
878 pub fn generate_token_with_claims<U, S>(
879 &self,
880 subject: S,
881 claims: U,
882 ) -> Result<JwtToken, String>
883 where
884 U: Clone + Default + Serialize + for<'de> Deserialize<'de>,
885 S: AsRef<str>,
886 {
887 let now: usize = SystemTime::now()
888 .duration_since(UNIX_EPOCH)
889 .unwrap_or_default()
890 .as_secs() as usize;
891 let mut res_claims: CustomExtraJwtClaims<U> = CustomExtraJwtClaims::default();
892 res_claims
893 .set_custom(claims)
894 .set_sub(subject.as_ref())
895 .set_iss(self.get_config().get_issuer().clone())
896 .set_exp(now + self.get_config().get_expiration_seconds() as usize)
897 .set_iat(now);
898 let token: String = encode(
899 &Header::new(Algorithm::HS256),
900 &res_claims,
901 self.get_encoding_key(),
902 )
903 .map_err(|error| error.to_string())?;
904 let mut jwt_token: JwtToken = JwtToken::default();
905 jwt_token.set_token(token);
906 jwt_token.set_token_type(BEARER);
907 jwt_token.set_expires_in(self.get_config().get_expiration_seconds());
908 Ok(jwt_token)
909 }
910
911 /// Validates a JWT token and returns its custom claims.
912 ///
913 /// # Arguments
914 ///
915 /// - `AsRef<str>` - The JWT token to validate.
916 ///
917 /// # Returns
918 ///
919 /// - `Result<CustomExtraJwtClaims<U>, JwtValidationError>` - The custom claims on success, or a validation error on failure.
920 pub fn validate_token_with_claims<U, T>(
921 &self,
922 token: T,
923 ) -> Result<CustomExtraJwtClaims<U>, JwtValidationError>
924 where
925 U: Clone + Default + Serialize + for<'de> Deserialize<'de>,
926 T: AsRef<str>,
927 {
928 let token_data: TokenData<CustomExtraJwtClaims<U>> = decode::<CustomExtraJwtClaims<U>>(
929 token.as_ref(),
930 self.get_decoding_key(),
931 self.get_validation(),
932 )?;
933 Ok(token_data.claims)
934 }
935
936 /// Generates a JWT token with extra custom fields.
937 ///
938 /// # Arguments
939 ///
940 /// - `AsRef<str>` - The subject (user identifier) to include in the token.
941 /// - `HashMap<String, Value>` - Additional key-value pairs to include in the token payload.
942 ///
943 /// # Returns
944 ///
945 /// - `Result<JwtToken, String>` - The generated token on success, or an error message on failure.
946 pub fn generate_token_with_extra_claims<S>(
947 &self,
948 subject: S,
949 extra: HashMap<String, Value>,
950 ) -> Result<JwtToken, String>
951 where
952 S: AsRef<str>,
953 {
954 let now: usize = SystemTime::now()
955 .duration_since(UNIX_EPOCH)
956 .unwrap_or_default()
957 .as_secs() as usize;
958 let mut claims: ExtraJwtClaims = ExtraJwtClaims::new(
959 subject.as_ref().to_string(),
960 self.get_config().get_issuer().clone(),
961 now + self.get_config().get_expiration_seconds() as usize,
962 );
963 claims.set_extra(extra);
964 let token: String = encode(
965 &Header::new(Algorithm::HS256),
966 &claims,
967 self.get_encoding_key(),
968 )
969 .map_err(|error| error.to_string())?;
970 let mut jwt_token: JwtToken = JwtToken::default();
971 jwt_token.set_token(token);
972 jwt_token.set_token_type(BEARER);
973 jwt_token.set_expires_in(self.get_config().get_expiration_seconds());
974 Ok(jwt_token)
975 }
976
977 /// Validates a JWT token and returns its claims with extra fields.
978 ///
979 /// # Arguments
980 ///
981 /// - `AsRef<str>` - The JWT token to validate.
982 ///
983 /// # Returns
984 ///
985 /// - `Result<ExtraJwtClaims, JwtValidationError>` - The claims with extra fields on success, or a validation error on failure.
986 pub fn validate_token_with_extra_claims<T>(
987 &self,
988 token: T,
989 ) -> Result<ExtraJwtClaims, JwtValidationError>
990 where
991 T: AsRef<str>,
992 {
993 let token_data: TokenData<ExtraJwtClaims> = decode::<ExtraJwtClaims>(
994 token.as_ref(),
995 self.get_decoding_key(),
996 self.get_validation(),
997 )?;
998 Ok(token_data.claims)
999 }
1000
1001 /// Extracts a specific field value from a JWT token's extra claims.
1002 ///
1003 /// # Arguments
1004 ///
1005 /// - `AsRef<str>` - The JWT AsRef<str token to extract the field from.
1006 /// - `AsRef<str>` - The key of the field to retrieve.
1007 ///
1008 /// # Returns
1009 ///
1010 /// - `Result<Option<Value>, JwtValidationError>` - The field value if found, or None, or a validation error.
1011 pub fn get_from_token<T, K>(
1012 &self,
1013 token: T,
1014 field_key: K,
1015 ) -> Result<Option<Value>, JwtValidationError>
1016 where
1017 T: AsRef<str>,
1018 K: AsRef<str>,
1019 {
1020 let claims: ExtraJwtClaims = self.validate_token_with_extra_claims(token)?;
1021 Ok(claims.get(field_key.as_ref()).cloned())
1022 }
1023}
1024
1025/// Implementation block for ExtraJwtClaims helper methods.
1026impl ExtraJwtClaims {
1027 /// Inserts a key-value pair into the extra claims.
1028 ///
1029 /// # Arguments
1030 ///
1031 /// - `String` - The key to insert.
1032 /// - `Value` - The value to associate with the key.
1033 ///
1034 /// # Returns
1035 ///
1036 /// - `Self` - The modified ExtraJwtClaims instance for chaining.
1037 pub fn insert(mut self, key: String, value: Value) -> Self {
1038 self.get_mut_extra().insert(key, value);
1039 self
1040 }
1041
1042 /// Extends the extra claims with additional key-value pairs.
1043 ///
1044 /// # Arguments
1045 ///
1046 /// - `HashMap<String, Value>` - A HashMap of key-value pairs to add.
1047 ///
1048 /// # Returns
1049 ///
1050 /// - `Self` - The modified ExtraJwtClaims instance for chaining.
1051 pub fn extend_extra(mut self, extra: HashMap<String, Value>) -> Self {
1052 self.get_mut_extra().extend(extra);
1053 self
1054 }
1055
1056 /// Retrieves a value from the extra claims by key.
1057 ///
1058 /// # Arguments
1059 ///
1060 /// - `AsRef<str>` - The key to look up.
1061 ///
1062 /// # Returns
1063 ///
1064 /// - `Option<&Value>` - The value if found, or None.
1065 pub fn get<K>(&self, key: K) -> Option<&Value>
1066 where
1067 K: AsRef<str>,
1068 {
1069 self.get_extra().get(key.as_ref())
1070 }
1071
1072 /// Checks if a key exists in the extra claims.
1073 ///
1074 /// # Arguments
1075 ///
1076 /// - `AsRef<str>` - The key to check.
1077 ///
1078 /// # Returns
1079 ///
1080 /// - `bool` - True if the key exists, false otherwise.
1081 pub fn contains_key<K>(&self, key: K) -> bool
1082 where
1083 K: AsRef<str>,
1084 {
1085 self.get_extra().contains_key(key.as_ref())
1086 }
1087
1088 /// Removes a key from the extra claims and returns its value.
1089 ///
1090 /// # Arguments
1091 ///
1092 /// - `AsRef<str>` - The key to remove.
1093 ///
1094 /// # Returns
1095 ///
1096 /// - `Option<Value>` - The removed value if found, or None.
1097 pub fn remove<K>(&mut self, key: K) -> Option<Value>
1098 where
1099 K: AsRef<str>,
1100 {
1101 self.get_mut_extra().remove(key.as_ref())
1102 }
1103}