1
0
mirror of https://github.com/actix/examples synced 2025-02-03 01:49:05 +01:00

68 lines
1.9 KiB
Rust
Raw Normal View History

use bcrypt::{hash, DEFAULT_COST};
use chrono::{Duration, Local};
2019-03-29 13:43:03 -07:00
use jsonwebtoken::{decode, encode, Header, Validation};
use crate::errors::ServiceError;
use crate::models::SlimUser;
pub fn hash_password(plain: &str) -> Result<String, ServiceError> {
// get the hashing cost from the env variable or use default
2019-03-29 13:43:03 -07:00
let hashing_cost: u32 = match std::env::var("HASH_ROUNDS") {
Ok(cost) => cost.parse().unwrap_or(DEFAULT_COST),
_ => DEFAULT_COST,
};
println!("{}", &hashing_cost);
hash(plain, hashing_cost).map_err(|_| ServiceError::InternalServerError)
}
#[derive(Debug, Serialize, Deserialize)]
struct Claims {
// issuer
iss: String,
// subject
sub: String,
//issued at
iat: i64,
// expiry
exp: i64,
// user email
email: String,
}
// struct to get converted to token and back
impl Claims {
fn with_email(email: &str) -> Self {
Claims {
iss: "localhost".into(),
sub: "auth".into(),
email: email.to_owned(),
iat: Local::now().timestamp(),
exp: (Local::now() + Duration::hours(24)).timestamp(),
}
}
}
impl From<Claims> for SlimUser {
fn from(claims: Claims) -> Self {
SlimUser {
email: claims.email,
}
}
}
pub fn create_token(data: &SlimUser) -> Result<String, ServiceError> {
let claims = Claims::with_email(data.email.as_str());
encode(&Header::default(), &claims, get_secret().as_ref())
.map_err(|_err| ServiceError::InternalServerError)
}
pub fn decode_token(token: &str) -> Result<SlimUser, ServiceError> {
decode::<Claims>(token, get_secret().as_ref(), &Validation::default())
.map(|data| Ok(data.claims.into()))
.map_err(|_err| ServiceError::Unauthorized)?
}
fn get_secret() -> String {
2019-03-29 13:43:03 -07:00
std::env::var("JWT_SECRET").unwrap_or_else(|_| "my secret".into())
}