Fix token parsing and require Auth for list files

This commit is contained in:
Cameron Cordes
2020-07-07 22:37:20 -04:00
parent 2aa1b61429
commit e3bb607d95
6 changed files with 148 additions and 24 deletions

View File

@@ -2,31 +2,42 @@ 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;
use serde::{Deserialize, Serialize};
use std::str::FromStr;
#[derive(Deserialize)]
#[derive(Serialize)]
pub struct Token<'a> {
pub token: &'a str,
}
#[derive(Deserialize, Serialize)]
pub struct Claims {
pub sub: String,
pub exp: u32,
pub exp: i64,
}
impl FromStr for Claims {
type Err = jsonwebtoken::errors::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
println!("Parsing token: {}", s);
let token = *(s
.split("Bearer ")
.collect::<Vec<_>>()
.last()
.unwrap_or(&""));
println!("Parsing token: '{}'", token);
let claims = match decode::<Claims>(
s,
match decode::<Claims>(
&token,
&DecodingKey::from_secret("secret_token".as_ref()),
&Validation::new(Algorithm::HS256),
) {
Ok(data) => Ok(data.claims),
Err(other) => Err(other),
};
return claims;
Err(other) => {
println!("DecodeError: {}", other);
Err(other)
}
}
}
}

View File

@@ -50,7 +50,7 @@ pub fn get_user(user: &str, pass: &str) -> Option<User> {
match users
.filter(username.eq(user))
.load::<User>(&connect())
.unwrap_or(Vec::<User>::new())
.unwrap_or_default()
.first()
{
Some(u) if verify(pass, &u.password).unwrap_or(false) => Some(u.clone()),

View File

@@ -25,9 +25,9 @@ fn is_image_or_video(path: &Path) -> bool {
.unwrap_or_else(|| "")
.to_lowercase();
return extension == &"png"
|| extension == &"jpg"
|| extension == &"jpeg"
|| extension == &"rs"
|| extension == &"mp4";
extension == "png"
|| extension == "jpg"
|| extension == "jpeg"
|| extension == "rs"
|| extension == "mp4"
}

View File

@@ -3,11 +3,14 @@ extern crate diesel;
use actix_web::web::{HttpResponse, Json};
use actix_web::{get, post, App, HttpServer, Responder};
use chrono::{Duration, Utc};
use data::{LoginRequest, ThumbnailRequest};
use jsonwebtoken::{encode, EncodingKey, Header};
use std::path::PathBuf;
use crate::files::list_files;
use crate::data::{Claims, Token};
use crate::database::{create_user, get_user};
use crate::files::list_files;
mod data;
mod database;
@@ -23,14 +26,24 @@ async fn register() -> impl Responder {
#[post("/login")]
async fn login(creds: Json<LoginRequest>) -> impl Responder {
if let Some(user) = get_user(&creds.username, &creds.password) {
HttpResponse::Ok().json(user)
let claims = Claims {
sub: user.id.to_string(),
exp: (Utc::now() + Duration::seconds(30)).timestamp(),
};
let token = encode(
&Header::default(),
&claims,
&EncodingKey::from_secret("secret_token".as_ref()),
)
.unwrap();
HttpResponse::Ok().json(Token { token: &token })
} else {
HttpResponse::NotFound().finish()
}
}
#[get("/photos")]
async fn list_photos(req: Json<ThumbnailRequest>) -> impl Responder {
async fn list_photos(_claims: Claims, req: Json<ThumbnailRequest>) -> impl Responder {
println!("{}", req.path);
let path = &req.path;
@@ -54,8 +67,13 @@ async fn list_photos(req: Json<ThumbnailRequest>) -> impl Responder {
#[actix_rt::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| App::new().service(login).service(list_photos).service(register))
.bind("127.0.0.1:8088")?
.run()
.await
HttpServer::new(|| {
App::new()
.service(login)
.service(list_photos)
.service(register)
})
.bind("127.0.0.1:8088")?
.run()
.await
}