use std::str::FromStr; use actix_web::error::ErrorUnauthorized; use actix_web::{dev, http::header, Error, FromRequest, HttpRequest}; use futures::future::{err, ok, Ready}; use jsonwebtoken::{decode, Algorithm, DecodingKey, Validation}; use serde::{Deserialize, Serialize}; #[derive(Serialize)] pub struct Token<'a> { pub token: &'a str, } #[derive(Deserialize, Serialize)] pub struct Claims { pub sub: String, pub exp: i64, } pub fn secret_key() -> String { dotenv::var("SECRET_KEY").expect("SECRET_KEY env not set!") } impl FromStr for Claims { type Err = jsonwebtoken::errors::Error; fn from_str(s: &str) -> Result { let token = *(s.split("Bearer ").collect::>().last().unwrap_or(&"")); match decode::( &token, &DecodingKey::from_secret(secret_key().as_bytes()), &Validation::new(Algorithm::HS256), ) { Ok(data) => Ok(data.claims), Err(other) => { println!("DecodeError: {}", other); Err(other) } } } } impl FromRequest for Claims { type Error = Error; type Future = Ready>; type Config = (); fn from_request(req: &HttpRequest, _payload: &mut dev::Payload) -> Self::Future { let claims = match req.headers().get(header::AUTHORIZATION) { Some(header) => Claims::from_str(header.to_str().unwrap_or("")), None => Err(jsonwebtoken::errors::Error::from( jsonwebtoken::errors::ErrorKind::InvalidToken, )), }; if let Ok(claims) = claims { ok(claims) } else { err(ErrorUnauthorized("Bad token")) } } } #[derive(Deserialize)] pub struct ThumbnailRequest { pub path: String, pub size: Option, } #[derive(Deserialize)] pub struct LoginRequest { pub username: String, pub password: String, } #[derive(Deserialize)] pub struct CreateAccountRequest { pub username: String, pub password: String, pub confirmation: String, } #[derive(Deserialize)] pub struct AddFavoriteRequest { pub path: String, }