ezidam/crates/jwt/src/claims.rs

58 lines
1.6 KiB
Rust

use crate::{Error, PrivateKey};
use chrono::Duration;
use jwt_compact::{Claims, Header, TimeOptions};
use serde::{Deserialize, Serialize};
use users::User;
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct JwtClaims {
// Standard JWT claims
#[serde(rename = "iss")]
pub issuer: String,
#[serde(rename = "sub")]
pub subject: String,
#[serde(rename = "aud")]
pub audience: String,
// Custom claims
pub username: String,
pub email: Option<String>,
pub is_admin: bool,
pub roles: Vec<String>,
}
impl JwtClaims {
pub fn new(
issuer: impl Into<String>,
audience: impl Into<String>,
user: &User,
roles: Vec<String>,
) -> Self {
Self {
// Standard JWT claims
issuer: issuer.into(),
subject: user.id().to_string(),
audience: audience.into(),
// Custom claims
username: user.username().to_string(),
email: user.email().map(String::from),
is_admin: user.is_admin(),
roles,
}
}
pub fn sign_serialize(self, key: &PrivateKey, duration_minutes: i64) -> Result<String, Error> {
let header = Header::default().with_key_id(key.id());
let claims = Claims::<Self>::new(self);
// Set duration
let duration = Duration::minutes(duration_minutes);
let time_options = TimeOptions::default();
let claims = claims.set_duration_and_issuance(&time_options, duration);
key.sign_serialize_jwt(header, claims)
}
}