aboutsummaryrefslogtreecommitdiff
path: root/src/auth.rs
blob: 418f64e087bda49a6021ef8a2214755179e1fb20 (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
use argon2::password_hash::rand_core::OsRng;
use argon2::password_hash::{PasswordHasher, SaltString};
use argon2::{Argon2, PasswordHash, PasswordVerifier};
use jsonwebtoken::{self as jwt, DecodingKey, EncodingKey, Header, Validation};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
pub struct JwtClaims {
    pub sub: i64,
    pub iat: i64,
    pub exp: i64,
}

pub fn create_password(password: &str) -> argon2::password_hash::Result<String> {
    Ok(Argon2::default()
        .hash_password(password.as_bytes(), &SaltString::generate(&mut OsRng))?
        .to_string())
}

pub fn validate_password(
    password: &str,
    password_hash: &str,
) -> argon2::password_hash::Result<bool> {
    Ok(Argon2::default()
        .verify_password(password.as_bytes(), &PasswordHash::new(password_hash)?)
        .is_ok())
}

pub fn create_jwt(claims: &JwtClaims, secret: &str) -> jwt::errors::Result<String> {
    jwt::encode(
        &Header::default(),
        claims,
        &EncodingKey::from_secret(secret.as_bytes()),
    )
}

pub fn validate_jwt(token: &str, secret: &str) -> jwt::errors::Result<JwtClaims> {
    let mut validation = Validation::default();
    validation.set_required_spec_claims(&["exp"]);
    validation.validate_exp = true;
    validation.leeway = 0;

    Ok(jwt::decode(
        token,
        &DecodingKey::from_secret(secret.as_bytes()),
        &validation,
    )?
    .claims)
}