Skip to content

Commit

Permalink
Change to rust rocket
Browse files Browse the repository at this point in the history
  • Loading branch information
dasbaumwolltier committed Feb 10, 2022
1 parent dcc355f commit fcfbd65
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 121 deletions.
17 changes: 11 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
actix-rt = "2.6"
actix-web = "4.0.0-beta.21"
actix-cors = "0.6.0-beta.8"
actix-files = "0.6.0-beta.16"
actix-multipart = "0.4.0-beta.13"
actix-web-httpauth = "0.6.0-beta.7"
#actix-rt = "2.6"
#actix-web = "4.0.0-beta.21"
#actix-cors = "0.6.0-beta.8"
#actix-files = "0.6.0-beta.16"
#actix-multipart = "0.4.0-beta.13"
#actix-web-httpauth = "0.6.0-beta.7"

async-trait = "0.1"

Expand All @@ -30,8 +30,13 @@ once_cell = "1.9.0"

path-clean = "0.1"

rocket = "0.5.0-rc.1"
rocket-basicauth = "2"

rust-argon2 = "1.0"

sanitize-filename = "0.3"

serde = "1.0"
serde_derive = "1.0"
serde_yaml = "0.8"
81 changes: 35 additions & 46 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
use std::collections::HashMap;
use std::fs::File;
use std::io;
use std::io::{BufReader, ErrorKind};
use std::process::exit;
use std::str::FromStr;
use std::sync::Arc;
use actix_cors::Cors;
use actix_web::{App, HttpServer};
use actix_web::web::Data;
use clap::Arg;
use log::{error};
use simplelog::{ColorChoice, Config, TerminalMode, TermLogger};
use rocket::{launch, routes};
use simplelog::{ColorChoice, TerminalMode, TermLogger};
use crate::config::RepositoryConfig;
use crate::repository::file::FileRepository;
use crate::repository::RepositoryProvider;
Expand All @@ -19,8 +17,8 @@ mod repository;
mod rest;
mod utils;

#[actix_web::main]
async fn main() -> Result<(), std::io::Error> {
#[launch]
fn launch() -> _ {
let matches = clap::App::new("Simple Repository Manager")
.version("0.1")
.author("Gabriel Guldner <[email protected]>")
Expand All @@ -32,22 +30,22 @@ async fn main() -> Result<(), std::io::Error> {
.required(true)
.takes_value(true)
).arg(Arg::new("host")
.short('h')
.long("host")
.value_name("HOST")
.default_missing_value("127.0.0.1")
).arg(Arg::new("port")
.short('p')
.long("port")
.value_name("PORT")
.default_missing_value("8080")
).arg(Arg::new("verbose")
.short('v')
.multiple_occurrences(true)
.long("verbose")
.required(false)
.takes_value(false)
).get_matches();
.short('h')
.long("host")
.value_name("HOST")
.default_missing_value("127.0.0.1")
).arg(Arg::new("port")
.short('p')
.long("port")
.value_name("PORT")
.default_missing_value("8080")
).arg(Arg::new("verbose")
.short('v')
.multiple_occurrences(true)
.long("verbose")
.required(false)
.takes_value(false)
).get_matches();

let level = match matches.occurrences_of("verbose") {
0 => log::LevelFilter::Info,
Expand All @@ -57,24 +55,26 @@ async fn main() -> Result<(), std::io::Error> {

TermLogger::init(
level,
Config::default(),
simplelog::Config::default(),
TerminalMode::Stdout,
ColorChoice::Auto,
).map_err(|e| std::io::Error::new(ErrorKind::Other, e))?;
).map_err(|e| std::io::Error::new(ErrorKind::Other, e));

let port = match u16::from_str(matches.value_of("port").unwrap()) {
Ok(port) => port,
Err(e) => {
error!("Could not parse port: {}!", e);
return Err(io::Error::new(ErrorKind::Other, e));
exit(1);
}
};

let host = matches.value_of("host").unwrap_or("127.0.0.1");

let config_file = match File::open(matches.value_of("config").unwrap()) {
Ok(config_file) => config_file,
Err(e) => {
log::error!("Could not open config.yaml: {}", e);
return Err(e);
exit(1);
}
};

Expand All @@ -83,7 +83,7 @@ async fn main() -> Result<(), std::io::Error> {
Ok(config) => config,
Err(e) => {
error!("Could not deserialize config: {}", e);
return Err(std::io::Error::new(ErrorKind::Other, e));
exit(1);
}
};

Expand All @@ -98,22 +98,11 @@ async fn main() -> Result<(), std::io::Error> {
}
}

let provider_data = Data::new(providers);

HttpServer::new(move || {
let cors = Cors::default()
.allow_any_origin()
.allowed_methods(vec!["GET", "PUT"]);

App::new()
.wrap(cors)
.app_data(Data::clone(&provider_data))
.service(rest::retrieve)
.service(rest::upload)
})
.bind((matches.value_of("host").unwrap(), port))?
.run()
.await?;
let figment = rocket::Config::figment()
.merge(("port", port))
.merge(("address", host));

Ok(())
}
rocket::custom(figment)
.manage(providers)
.mount("/", routes![rest::retrieve, rest::upload])
}
26 changes: 13 additions & 13 deletions src/repository/file.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use std::collections::HashMap;
use std::path::{PathBuf};
use std::path::PathBuf;
use std::str::FromStr;
use actix_rt::task;
use actix_web::{Error};
use actix_web::error::{ErrorForbidden, ErrorInternalServerError, ErrorUnauthorized};
use async_trait::async_trait;
use log::error;
use path_clean::PathClean;
use rocket::http::Status;
use rocket::response::status::Custom;
use rocket::tokio::task;
use crate::config::{PasswordType, Permission, PermissionConfig, UserConfig};
use crate::enclose;
use crate::repository::RepositoryProvider;
Expand Down Expand Up @@ -35,30 +35,30 @@ impl RepositoryProvider for FileRepository {
return Ok(full_path);
}

async fn is_permitted(&self, user_id: Option<String>, password: Option<String>, required: &Permission) -> Result<(), Error> {
async fn is_permitted(&self, user_id: Option<String>, password: Option<String>, required: &Permission) -> Result<(), Custom<String>> {
if user_id.is_none() {
return if self.anonymous.is_permitted(&required) {
Ok(())
} else {
Err(ErrorForbidden("Anonymous user not permitted!"))
Err(Custom(Status::Forbidden, String::from("Anonymous user not permitted!")))
};
}

if password.is_none() {
return Err(ErrorUnauthorized("No password given!"));
return Err(Custom(Status::Unauthorized, String::from("No password given!")));
}

let user_id = user_id.unwrap();
let password = password.unwrap();

let permission = match self.permissions.get(&user_id) {
Some(permission) => permission,
None => return Err(ErrorUnauthorized("Username or password mismatch!"))
None => return Err(Custom(Status::Unauthorized, String::from("Username or password mismatch!")))
};

let (hash, password_type) = match self.users.get(&user_id) {
Some(hash) => hash.clone(),
None => return Err(ErrorUnauthorized("Username or password mismatch!"))
None => return Err(Custom(Status::Unauthorized, String::from("Username or password mismatch!")))
};

let blake3_hash = self.blake3_hashes.get(&user_id).cloned();
Expand All @@ -67,18 +67,18 @@ impl RepositoryProvider for FileRepository {
PasswordType::BCrypt => to_io_error(bcrypt::verify(password, &hash)),
PasswordType::Argon2 => to_io_error(argon2::verify_encoded(&hash, password.as_bytes())),
PasswordType::Blake3 => Ok(blake3::hash(password.as_bytes()) == blake3_hash.unwrap())
}}).await.map_err(|e| ErrorInternalServerError(e))?;
}}).await.map_err(|e| Custom(Status::InternalServerError, format!("{}", e)))?;

match res {
Ok(r) =>
if r {
Ok(())
} else {
Err(ErrorUnauthorized("Username or password mismatch!"))
Err(Custom(Status::Unauthorized, String::from("Username or password mismatch!")))
},
Err(e) => {
error!("Could not verify password! {}", e);
return Err(ErrorUnauthorized("Username or password mismatch!"));
return Err(Custom(Status::Unauthorized, String::from("Username or password mismatch!")));
}
}
}
Expand Down Expand Up @@ -121,4 +121,4 @@ impl FileRepository {
users,
}
}
}
}
4 changes: 2 additions & 2 deletions src/repository/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use std::path::{PathBuf};
use actix_web::Error;
use async_trait::async_trait;
use rocket::response::status::Custom;
use crate::config::Permission;

pub mod file;

#[async_trait]
pub trait RepositoryProvider {
async fn get_file(&self, path: &PathBuf) -> Result<PathBuf, ()>;
async fn is_permitted(&self, user_id: Option<String>, password: Option<String>, required: &Permission) -> Result<(), Error>;
async fn is_permitted(&self, user_id: Option<String>, password: Option<String>, required: &Permission) -> Result<(), Custom<String>>;
}
Loading

0 comments on commit fcfbd65

Please sign in to comment.