switchgear_service/discovery/
auth.rs1use 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 DiscoveryClaims {
9 pub aud: DiscoveryAudience,
10 pub exp: usize,
11}
12
13#[derive(Debug, Deserialize, Eq, PartialOrd, PartialEq)]
14#[serde(rename_all = "kebab-case")]
15pub enum DiscoveryAudience {
16 Discovery,
17}
18
19impl Serialize for DiscoveryAudience {
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 DiscoveryAudience {
29 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30 match self {
31 DiscoveryAudience::Discovery => f.write_str("discovery"),
32 }
33 }
34}
35
36#[derive(Clone)]
37pub struct DiscoveryBearerTokenValidator {
38 decoding_key: DecodingKey,
39 validation: Validation,
40}
41
42impl DiscoveryBearerTokenValidator {
43 pub fn new(decoding_key: DecodingKey) -> Self {
44 let mut validation = Validation::new(Algorithm::ES256);
45 validation.set_audience(&[DiscoveryAudience::Discovery]);
46 Self {
47 decoding_key,
48 validation,
49 }
50 }
51
52 pub fn validate_token(&self, token: &str) -> jsonwebtoken::errors::Result<DiscoveryClaims> {
53 let token = decode::<DiscoveryClaims>(token, &self.decoding_key, &self.validation)?;
54 if token.claims.aud == DiscoveryAudience::Discovery {
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 DiscoveryBearerTokenValidator {
65 fn validate(&self, token: &str) -> bool {
66 self.validate_token(token).is_ok()
67 }
68}