summaryrefslogtreecommitdiffstats
path: root/src/jwt.rs
blob: 6382a0193c64252194a6ca9fe374baf7f1b24a57 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
use std::sync::Arc;

use axum::extract::{Request, State};
use axum_extra::{
    headers::{authorization::Bearer, Authorization},
    TypedHeader,
};
use jsonwebtoken::{DecodingKey, Validation};
use serde::{Deserialize, Serialize};
use uuid::Uuid;

use crate::{error::AuthError, state::AppState};

#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct Claims {
    pub sub: Uuid,
    pub iat: i64,
    pub exp: i64,
}

impl Claims {
    pub fn new(sub: Uuid, max_age: time::Duration) -> Self {
        let iat = time::OffsetDateTime::now_utc().unix_timestamp();
        let exp = iat + max_age.whole_seconds();
        Self { sub, iat, exp }
    }

    pub fn encode(&self, secret: &[u8]) -> Result<String, jsonwebtoken::errors::Error> {
        jsonwebtoken::encode(
            &jsonwebtoken::Header::default(),
            self,
            &jsonwebtoken::EncodingKey::from_secret(secret),
        )
    }
}

pub async fn authenticate(
    State(state): State<Arc<AppState>>,
    TypedHeader(Authorization(bearer)): TypedHeader<Authorization<Bearer>>,
    mut req: Request,
) -> Result<Request, AuthError> {
    let claims = jsonwebtoken::decode::<Claims>(
        bearer.token(),
        &DecodingKey::from_secret(state.jwt_secret.as_ref()),
        &Validation::default(),
    )?
    .claims;

    req.extensions_mut().insert(claims);
    Ok(req)
}