mirror of
https://github.com/actix/examples
synced 2025-02-03 01:49:05 +01:00
69 lines
1.9 KiB
Rust
69 lines
1.9 KiB
Rust
|
use bcrypt::{hash, DEFAULT_COST};
|
||
|
use chrono::{Duration, Local};
|
||
|
use errors::ServiceError;
|
||
|
use jwt::{decode, encode, Header, Validation};
|
||
|
use models::SlimUser;
|
||
|
use std::convert::From;
|
||
|
use std::env;
|
||
|
|
||
|
pub fn hash_password(plain: &str) -> Result<String, ServiceError> {
|
||
|
// get the hashing cost from the env variable or use default
|
||
|
let hashing_cost: u32 = match 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 {
|
||
|
env::var("JWT_SECRET").unwrap_or_else(|_| "my secret".into())
|
||
|
}
|