extern crate bcrypt; extern crate jsonwebtoken; use actix_web::HttpResponse; use chrono::{Duration, Local}; use jsonwebtoken::{decode, encode, Header, Validation}; use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize)] struct Claims { sub: i32, name: String, admin: bool, exp: usize, } pub struct UserWithToken { pub id: i32, pub username: String, pub admin: bool, } impl From for UserWithToken { fn from(claims: Claims) -> Self { UserWithToken { id: claims.sub, username: claims.name, admin: claims.admin, } } } impl Claims { fn with_username(id: i32, username: &str, admin: bool) -> Self { Claims { sub: id, name: username.into(), admin, exp: (Local::now() + Duration::hours(24)).timestamp() as usize, } } } fn get_secret() -> [u8] { std::env::var("JWT_SECRET").expect("JWT_SECRET").as_bytes() } pub fn new_token(id: i32, username: &str, admin: &bool) -> Result { let claims = Claims::with_username(username, admin); encode(&Header::default(), &claims, get_secret()) .map_err(|e| HttpResponse::InternalServerError().json(e.to_string())) } pub fn decode_token(token: &str) -> Result { decode::(token, get_secret(), &Validation::default()) .map(|data| data.claims.into()) .map_err(|e| HttpResponse::Unauthorized().json(e.to_string())) }