• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

getdozer / dozer / 5709656380

pending completion
5709656380

push

github

web-flow
Version bump (#1808)

45512 of 59772 relevant lines covered (76.14%)

39312.43 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

72.29
/dozer-api/src/auth/authorizer.rs
1
use dozer_types::models::api_security::ApiSecurity;
2
use jsonwebtoken::{decode, encode, Algorithm, DecodingKey, EncodingKey, Header, Validation};
3
use std::time::{Duration, SystemTime, UNIX_EPOCH};
4

5
use crate::errors::AuthError;
6

7
use super::{Access, Claims};
8

9
pub struct Authorizer<'a> {
10
    secret: &'a [u8],
11
    aud: &'a str,
12
    sub: &'a str,
13
}
14

15
impl<'a> Authorizer<'a> {
16
    pub fn new(secret: &'a str, aud: Option<&'a str>, sub: Option<&'a str>) -> Self {
10✔
17
        Self {
10✔
18
            secret: secret.as_bytes(),
10✔
19
            aud: aud.unwrap_or("cache_user"),
10✔
20
            sub: sub.unwrap_or("api@dozer.com"),
10✔
21
        }
10✔
22
    }
10✔
23

×
24
    /// Creates exp based on duration provided with a default of 300 seconds
×
25
    pub fn get_expiry(dur: Option<Duration>) -> u64 {
5✔
26
        let start = SystemTime::now();
5✔
27
        let since_the_epoch = start
5✔
28
            .duration_since(UNIX_EPOCH)
5✔
29
            .expect("Time went backwards");
5✔
30

×
31
        let dur = match dur {
5✔
32
            Some(dur) => dur + since_the_epoch,
×
33
            // 300 seconds
×
34
            None => Duration::new(300, 0) + since_the_epoch,
5✔
35
        };
36

×
37
        dur.as_secs() * 1000 + dur.subsec_nanos() as u64 / 1_000_000
5✔
38
    }
5✔
39

×
40
    pub fn generate_token(
5✔
41
        &self,
5✔
42
        access: Access,
5✔
43
        dur: Option<Duration>,
5✔
44
    ) -> Result<String, AuthError> {
5✔
45
        let exp = Self::get_expiry(dur);
5✔
46

5✔
47
        let my_claims = Claims {
5✔
48
            exp: exp as usize,
5✔
49
            access,
5✔
50
            aud: self.aud.to_owned(),
5✔
51
            sub: self.sub.to_owned(),
5✔
52
        };
5✔
53

5✔
54
        encode(
5✔
55
            &Header::default(),
5✔
56
            &my_claims,
5✔
57
            &EncodingKey::from_secret(self.secret),
5✔
58
        )
5✔
59
        .map_err(Into::into)
5✔
60
    }
5✔
61

×
62
    pub fn validate_token(&self, token: &str) -> Result<Claims, AuthError> {
6✔
63
        let mut validation = Validation::new(Algorithm::HS256);
6✔
64
        validation.sub = Some(self.sub.to_owned());
6✔
65
        validation.set_audience(&[self.aud.to_owned()]);
6✔
66

6✔
67
        match decode::<Claims>(token, &DecodingKey::from_secret(self.secret), &validation) {
6✔
68
            Ok(c) => Ok(c.claims),
5✔
69
            Err(err) => Err(err.into()),
1✔
70
        }
×
71
    }
6✔
72
}
×
73

×
74
impl<'a> From<&'a ApiSecurity> for Authorizer<'a> {
×
75
    fn from(value: &'a ApiSecurity) -> Self {
4✔
76
        match value {
4✔
77
            ApiSecurity::Jwt(secret) => Authorizer::new(secret, None, None),
4✔
78
        }
4✔
79
    }
4✔
80
}
81
#[cfg(test)]
×
82
mod tests {
×
83
    use super::Access;
×
84
    use super::Authorizer;
×
85

×
86
    #[test]
1✔
87
    fn generate_and_verify_claim() {
1✔
88
        let auth_utils = Authorizer::new("secret", None, None);
1✔
89

1✔
90
        let token = auth_utils.generate_token(Access::All, None).unwrap();
1✔
91

1✔
92
        let token_data = auth_utils.validate_token(&token).unwrap();
1✔
93
        assert_eq!(token_data.access, Access::All, "must be equal");
1✔
94
    }
1✔
95
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc