switchgear_service/offer/
auth.rs

1use crate::axum::auth::BearerTokenValidator;
2use jsonwebtoken::{decode, Algorithm, DecodingKey, Validation};
3use serde::{Deserialize, Serialize, Serializer};
4use std::fmt::Display;
5
6#[derive(Debug, Serialize, Deserialize)]
7#[serde(rename_all = "camelCase")]
8pub struct OfferClaims {
9    pub aud: OfferAudience,
10    pub exp: usize,
11}
12
13#[derive(Debug, Deserialize, Eq, PartialOrd, PartialEq)]
14#[serde(rename_all = "kebab-case")]
15pub enum OfferAudience {
16    Offer,
17}
18
19impl Serialize for OfferAudience {
20    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
21    where
22        S: Serializer,
23    {
24        serializer.serialize_str(&self.to_string())
25    }
26}
27
28impl Display for OfferAudience {
29    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30        match self {
31            OfferAudience::Offer => f.write_str("offer"),
32        }
33    }
34}
35
36#[derive(Clone)]
37pub struct OfferBearerTokenValidator {
38    decoding_key: DecodingKey,
39    validation: Validation,
40}
41
42impl OfferBearerTokenValidator {
43    pub fn new(decoding_key: DecodingKey) -> Self {
44        let mut validation = Validation::new(Algorithm::ES256);
45        validation.set_audience(&[OfferAudience::Offer]);
46        Self {
47            decoding_key,
48            validation,
49        }
50    }
51
52    pub fn validate_token(&self, token: &str) -> jsonwebtoken::errors::Result<OfferClaims> {
53        let token = decode::<OfferClaims>(token, &self.decoding_key, &self.validation)?;
54        if token.claims.aud == OfferAudience::Offer {
55            Ok(token.claims)
56        } else {
57            Err(jsonwebtoken::errors::Error::from(
58                jsonwebtoken::errors::ErrorKind::InvalidToken,
59            ))
60        }
61    }
62}
63
64impl BearerTokenValidator for OfferBearerTokenValidator {
65    fn validate(&self, token: &str) -> bool {
66        self.validate_token(token).is_ok()
67    }
68}