paseto_core/
validation.rs

1//! Common PASETO claims validations.
2//!
3//! <https://github.com/paseto-standard/paseto-spec/blob/master/docs/02-Implementation-Guide/04-Claims.md>
4
5use alloc::boxed::Box;
6use alloc::rc::Rc;
7use alloc::sync::Arc;
8use alloc::vec::Vec;
9use core::marker::PhantomData;
10
11use crate::PasetoError;
12
13/// Validation rules for the claims in a PASETO
14pub trait Validate {
15    /// The type of claim that can be validated
16    type Claims;
17
18    /// The validation to perform on the claims
19    fn validate(&self, claims: &Self::Claims) -> Result<(), PasetoError>;
20
21    /// Extend the validation with another validation.
22    fn and_then<V>(self, other: V) -> impl Validate<Claims = Self::Claims>
23    where
24        Self: Sized,
25        V: Validate<Claims = Self::Claims>,
26    {
27        ValidateThen(self, other)
28    }
29
30    /// Convert this validator into a validator of another type
31    fn map<T>(self, f: impl for<'a> Fn(&'a T) -> &'a Self::Claims) -> impl Validate<Claims = T>
32    where
33        Self: Sized,
34    {
35        Map(PhantomData::<T>, f, self)
36    }
37}
38
39/// Perform no validation on the claims.
40pub struct NoValidation<Claims>(PhantomData<Claims>);
41
42impl<Claims> NoValidation<Claims> {
43    /// Accept responsibility that the claims will be unvalidated.
44    pub fn dangerous_no_validation() -> Self {
45        NoValidation(PhantomData)
46    }
47}
48
49impl<Claims> Validate for NoValidation<Claims> {
50    type Claims = Claims;
51    fn validate(&self, _: &Self::Claims) -> Result<(), PasetoError> {
52        Ok(())
53    }
54}
55
56struct Map<Claims, F, T>(PhantomData<Claims>, F, T);
57
58impl<Claims, F, T> Validate for Map<Claims, F, T>
59where
60    F: for<'a> Fn(&'a Claims) -> &'a T::Claims,
61    T: Validate,
62{
63    type Claims = Claims;
64
65    fn validate(&self, claims: &Self::Claims) -> Result<(), PasetoError> {
66        self.2.validate((self.1)(claims))
67    }
68}
69struct ValidateThen<T, U>(T, U);
70
71impl<T: Validate, U: Validate<Claims = T::Claims>> Validate for ValidateThen<T, U> {
72    type Claims = T::Claims;
73
74    fn validate(&self, claims: &Self::Claims) -> Result<(), PasetoError> {
75        self.0.validate(claims)?;
76        self.1.validate(claims)
77    }
78}
79
80impl<T: Validate> Validate for Vec<T> {
81    type Claims = T::Claims;
82
83    fn validate(&self, claims: &Self::Claims) -> Result<(), PasetoError> {
84        <[T]>::validate(self, claims)
85    }
86}
87
88impl<T: Validate> Validate for [T] {
89    type Claims = T::Claims;
90
91    fn validate(&self, claims: &Self::Claims) -> Result<(), PasetoError> {
92        for v in self {
93            T::validate(v, claims)?;
94        }
95        Ok(())
96    }
97}
98
99impl<T: Validate + ?Sized> Validate for Box<T> {
100    type Claims = T::Claims;
101
102    fn validate(&self, claims: &Self::Claims) -> Result<(), PasetoError> {
103        T::validate(self, claims)
104    }
105}
106
107impl<T: Validate + ?Sized> Validate for Arc<T> {
108    type Claims = T::Claims;
109
110    fn validate(&self, claims: &Self::Claims) -> Result<(), PasetoError> {
111        T::validate(self, claims)
112    }
113}
114
115impl<T: Validate + ?Sized> Validate for Rc<T> {
116    type Claims = T::Claims;
117
118    fn validate(&self, claims: &Self::Claims) -> Result<(), PasetoError> {
119        T::validate(self, claims)
120    }
121}