Fix token parsing and require Auth for list files
This commit is contained in:
94
Cargo.lock
generated
94
Cargo.lock
generated
@@ -379,13 +379,34 @@ version = "1.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "block-buffer"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
|
||||||
|
dependencies = [
|
||||||
|
"block-padding",
|
||||||
|
"byte-tools",
|
||||||
|
"byteorder",
|
||||||
|
"generic-array 0.12.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block-cipher"
|
name = "block-cipher"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fa136449e765dc7faa244561ccae839c394048667929af599b5d931ebe7b7f10"
|
checksum = "fa136449e765dc7faa244561ccae839c394048667929af599b5d931ebe7b7f10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array",
|
"generic-array 0.14.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "block-padding"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
|
||||||
|
dependencies = [
|
||||||
|
"byte-tools",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -425,6 +446,12 @@ version = "3.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
|
checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byte-tools"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
version = "1.3.4"
|
version = "1.3.4"
|
||||||
@@ -496,6 +523,16 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crypto-mac"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array 0.12.3",
|
||||||
|
"subtle",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "derive_more"
|
name = "derive_more"
|
||||||
version = "0.99.9"
|
version = "0.99.9"
|
||||||
@@ -529,6 +566,15 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "digest"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array 0.12.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dotenv"
|
name = "dotenv"
|
||||||
version = "0.15.0"
|
version = "0.15.0"
|
||||||
@@ -590,6 +636,12 @@ dependencies = [
|
|||||||
"synstructure",
|
"synstructure",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fake-simd"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flate2"
|
name = "flate2"
|
||||||
version = "1.0.16"
|
version = "1.0.16"
|
||||||
@@ -741,6 +793,15 @@ dependencies = [
|
|||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "generic-array"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
|
||||||
|
dependencies = [
|
||||||
|
"typenum",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "generic-array"
|
name = "generic-array"
|
||||||
version = "0.14.2"
|
version = "0.14.2"
|
||||||
@@ -805,6 +866,16 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hmac"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695"
|
||||||
|
dependencies = [
|
||||||
|
"crypto-mac",
|
||||||
|
"digest",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hostname"
|
name = "hostname"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@@ -851,12 +922,15 @@ dependencies = [
|
|||||||
"actix-rt",
|
"actix-rt",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
"bcrypt",
|
"bcrypt",
|
||||||
|
"chrono",
|
||||||
"diesel",
|
"diesel",
|
||||||
"dotenv",
|
"dotenv",
|
||||||
"futures",
|
"futures",
|
||||||
|
"hmac",
|
||||||
"jsonwebtoken",
|
"jsonwebtoken",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"sha2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1461,6 +1535,18 @@ version = "0.6.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
|
checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sha2"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69"
|
||||||
|
dependencies = [
|
||||||
|
"block-buffer",
|
||||||
|
"digest",
|
||||||
|
"fake-simd",
|
||||||
|
"opaque-debug",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signal-hook-registry"
|
name = "signal-hook-registry"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
@@ -1512,6 +1598,12 @@ version = "0.5.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "subtle"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.33"
|
version = "1.0.33"
|
||||||
|
|||||||
@@ -14,5 +14,8 @@ jsonwebtoken = "7.2.0"
|
|||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
diesel = { version = "1.4.4", features = ["sqlite"] }
|
diesel = { version = "1.4.4", features = ["sqlite"] }
|
||||||
|
hmac = "0.7.1"
|
||||||
|
sha2 = "0.8.2"
|
||||||
|
chrono = "0.4.11"
|
||||||
dotenv = "0.15"
|
dotenv = "0.15"
|
||||||
bcrypt = "0.8.1"
|
bcrypt = "0.8.1"
|
||||||
|
|||||||
@@ -2,31 +2,42 @@ use actix_web::error::ErrorUnauthorized;
|
|||||||
use actix_web::{dev, http::header, Error, FromRequest, HttpRequest};
|
use actix_web::{dev, http::header, Error, FromRequest, HttpRequest};
|
||||||
use futures::future::{err, ok, Ready};
|
use futures::future::{err, ok, Ready};
|
||||||
use jsonwebtoken::{decode, Algorithm, DecodingKey, Validation};
|
use jsonwebtoken::{decode, Algorithm, DecodingKey, Validation};
|
||||||
use serde::Deserialize;
|
use serde::{Deserialize, Serialize};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Serialize)]
|
||||||
|
pub struct Token<'a> {
|
||||||
|
pub token: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
pub struct Claims {
|
pub struct Claims {
|
||||||
pub sub: String,
|
pub sub: String,
|
||||||
pub exp: u32,
|
pub exp: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for Claims {
|
impl FromStr for Claims {
|
||||||
type Err = jsonwebtoken::errors::Error;
|
type Err = jsonwebtoken::errors::Error;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
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>(
|
match decode::<Claims>(
|
||||||
s,
|
&token,
|
||||||
&DecodingKey::from_secret("secret_token".as_ref()),
|
&DecodingKey::from_secret("secret_token".as_ref()),
|
||||||
&Validation::new(Algorithm::HS256),
|
&Validation::new(Algorithm::HS256),
|
||||||
) {
|
) {
|
||||||
Ok(data) => Ok(data.claims),
|
Ok(data) => Ok(data.claims),
|
||||||
Err(other) => Err(other),
|
Err(other) => {
|
||||||
};
|
println!("DecodeError: {}", other);
|
||||||
|
Err(other)
|
||||||
return claims;
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ pub fn get_user(user: &str, pass: &str) -> Option<User> {
|
|||||||
match users
|
match users
|
||||||
.filter(username.eq(user))
|
.filter(username.eq(user))
|
||||||
.load::<User>(&connect())
|
.load::<User>(&connect())
|
||||||
.unwrap_or(Vec::<User>::new())
|
.unwrap_or_default()
|
||||||
.first()
|
.first()
|
||||||
{
|
{
|
||||||
Some(u) if verify(pass, &u.password).unwrap_or(false) => Some(u.clone()),
|
Some(u) if verify(pass, &u.password).unwrap_or(false) => Some(u.clone()),
|
||||||
|
|||||||
10
src/files.rs
10
src/files.rs
@@ -25,9 +25,9 @@ fn is_image_or_video(path: &Path) -> bool {
|
|||||||
.unwrap_or_else(|| "")
|
.unwrap_or_else(|| "")
|
||||||
.to_lowercase();
|
.to_lowercase();
|
||||||
|
|
||||||
return extension == &"png"
|
extension == "png"
|
||||||
|| extension == &"jpg"
|
|| extension == "jpg"
|
||||||
|| extension == &"jpeg"
|
|| extension == "jpeg"
|
||||||
|| extension == &"rs"
|
|| extension == "rs"
|
||||||
|| extension == &"mp4";
|
|| extension == "mp4"
|
||||||
}
|
}
|
||||||
|
|||||||
32
src/main.rs
32
src/main.rs
@@ -3,11 +3,14 @@ extern crate diesel;
|
|||||||
|
|
||||||
use actix_web::web::{HttpResponse, Json};
|
use actix_web::web::{HttpResponse, Json};
|
||||||
use actix_web::{get, post, App, HttpServer, Responder};
|
use actix_web::{get, post, App, HttpServer, Responder};
|
||||||
|
use chrono::{Duration, Utc};
|
||||||
use data::{LoginRequest, ThumbnailRequest};
|
use data::{LoginRequest, ThumbnailRequest};
|
||||||
|
use jsonwebtoken::{encode, EncodingKey, Header};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use crate::files::list_files;
|
use crate::data::{Claims, Token};
|
||||||
use crate::database::{create_user, get_user};
|
use crate::database::{create_user, get_user};
|
||||||
|
use crate::files::list_files;
|
||||||
|
|
||||||
mod data;
|
mod data;
|
||||||
mod database;
|
mod database;
|
||||||
@@ -23,14 +26,24 @@ async fn register() -> impl Responder {
|
|||||||
#[post("/login")]
|
#[post("/login")]
|
||||||
async fn login(creds: Json<LoginRequest>) -> impl Responder {
|
async fn login(creds: Json<LoginRequest>) -> impl Responder {
|
||||||
if let Some(user) = get_user(&creds.username, &creds.password) {
|
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 {
|
} else {
|
||||||
HttpResponse::NotFound().finish()
|
HttpResponse::NotFound().finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/photos")]
|
#[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);
|
println!("{}", req.path);
|
||||||
|
|
||||||
let path = &req.path;
|
let path = &req.path;
|
||||||
@@ -54,8 +67,13 @@ async fn list_photos(req: Json<ThumbnailRequest>) -> impl Responder {
|
|||||||
|
|
||||||
#[actix_rt::main]
|
#[actix_rt::main]
|
||||||
async fn main() -> std::io::Result<()> {
|
async fn main() -> std::io::Result<()> {
|
||||||
HttpServer::new(|| App::new().service(login).service(list_photos).service(register))
|
HttpServer::new(|| {
|
||||||
.bind("127.0.0.1:8088")?
|
App::new()
|
||||||
.run()
|
.service(login)
|
||||||
.await
|
.service(list_photos)
|
||||||
|
.service(register)
|
||||||
|
})
|
||||||
|
.bind("127.0.0.1:8088")?
|
||||||
|
.run()
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user