use actix_web::{HttpResponse, ResponseError};
use failure::Fail;
use jsonwebtoken::{decode, encode, Header, Validation};
use serde::{Deserialize, Serialize};
use time::get_time;
use uuid::Uuid;
mod test;
const SECRET: &[u8] = b"my_secret";
#[derive(Debug, Fail)]
pub enum TokenError {
#[fail(display = "unable to create session token")]
Create,
#[fail(display = "unable to verify session token")]
Verify,
}
impl ResponseError for TokenError {
fn error_response(&self) -> HttpResponse {
match self {
TokenError::Create => HttpResponse::InternalServerError().into(),
TokenError::Verify => HttpResponse::Unauthorized().into(),
}
}
}
#[derive(Deserialize, Serialize)]
pub struct Token {
sub: String,
exp: i64,
iat: i64,
jti: String,
}
impl Token {
pub fn create(username: &str) -> Result<String, TokenError> {
const DEFAULT_TOKEN_VALIDITY: i64 = 3600;
let claim = Token {
sub: username.to_owned(),
exp: get_time().sec + DEFAULT_TOKEN_VALIDITY,
iat: get_time().sec,
jti: Uuid::new_v4().to_string(),
};
encode(&Header::default(), &claim, SECRET).map_err(|_| TokenError::Create)
}
pub fn verify(token: &str) -> Result<String, TokenError> {
let data = decode::<Token>(token, SECRET, &Validation::default())
.map_err(|_| TokenError::Verify)?;
Self::create(&data.claims.sub)
}
}