- Removed joindate from members schema

+ Auth module now uses std::time for time based calculations
! All time notations are i64 and rounded to the Millisecond

* Moving db pool to a lazy static to avoid constructing a whole pool on every request

+ Adding more logging per request, even if its lazy logging
* Content-Types are now correctly written per type
This commit is contained in:
shockrah 2021-03-20 19:47:59 -07:00
parent 8812ff7198
commit 03c41b6833
5 changed files with 41 additions and 22 deletions

View File

@ -4,5 +4,8 @@ default:
dep: dep:
cargo update cargo update
run:
cargo run --release -- -s
clean: clean:
cargo clean cargo clean

View File

@ -4,7 +4,6 @@ CREATE TABLE IF NOT EXISTS `members`(
`id` BIGINT UNSIGNED NOT NULL auto_increment, `id` BIGINT UNSIGNED NOT NULL auto_increment,
`secret` varchar(256) NOT NULL, `secret` varchar(256) NOT NULL,
`name` varchar(256) NOT NULL, `name` varchar(256) NOT NULL,
`joindate` bigint NOT NULL,
`status` integer NOT NULL, `status` integer NOT NULL,
`permissions` bigint UNSIGNED NOT NULL, `permissions` bigint UNSIGNED NOT NULL,
PRIMARY KEY( `id` , `secret` ) PRIMARY KEY( `id` , `secret` )

View File

@ -3,7 +3,7 @@ use bcrypt::{self, BcryptResult};
use mysql_async::Pool; use mysql_async::Pool;
use std::collections::HashMap; use std::collections::HashMap;
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{Duration, SystemTime, UNIX_EPOCH};
use crate::routes; use crate::routes;
use crate::qs_param; use crate::qs_param;
@ -30,7 +30,9 @@ struct Claim {
impl Claim { impl Claim {
pub fn new(id: db::UBigInt) -> Claim { pub fn new(id: db::UBigInt) -> Claim {
let now = SystemTime::now()
// JWT's expire every 48 hours
let now = (SystemTime::now() + Duration::from_secs(60 * 60 * 48))
.duration_since(UNIX_EPOCH) .duration_since(UNIX_EPOCH)
.expect("System time fetch failed") .expect("System time fetch failed")
.as_millis() as i64; .as_millis() as i64;

View File

@ -45,6 +45,12 @@ const NO_ERR: u16 = 0;
const CONFIG_ERR: u16 = 1; const CONFIG_ERR: u16 = 1;
const SHUTDOWN_ERR: u16 = 2; const SHUTDOWN_ERR: u16 = 2;
lazy_static! {
static ref DB_POOL: Pool = {
Pool::new(&env::var("DATABASE_URL").unwrap())
};
}
async fn route_dispatcher( async fn route_dispatcher(
pool: &Pool, pool: &Pool,
resp: &mut Response<Body>, resp: &mut Response<Body>,
@ -82,7 +88,7 @@ async fn route_dispatcher(
/* META ROUTE */ /* META ROUTE */
(GET, routes::META) => meta::server_meta(resp).await, (GET, routes::META) => meta::server_meta(resp).await,
_ => { _ => {
eprintln!("\tNOT FOUND: {}: {}", meth, path); println!("\tNOT FOUND: {}: {}", meth, path);
*resp.status_mut() = StatusCode::NOT_FOUND *resp.status_mut() = StatusCode::NOT_FOUND
} }
} }
@ -104,13 +110,21 @@ async fn main_responder(request: Request<Body>) -> Result<Response<Body>, hyper:
}; };
if let Some(params) = params_opt { if let Some(params) = params_opt {
let mysql_pool = Pool::new(&env::var("DATABASE_URL").unwrap()); match auth::wall_entry(path, &DB_POOL, &params).await {
match auth::wall_entry(path, &mysql_pool, &params).await { OpenAuth | Good => {
OpenAuth | Good => route_dispatcher(&mysql_pool, &mut response, &method, path, body, params, headers).await, // route dispatch has its own more comprehensive logging
LoginValid => auth::login_get_jwt(&mysql_pool, &mut response, params).await, route_dispatcher(&DB_POOL, &mut response, &method, path, body, params, headers).await;
NoKey | BadKey => *response.status_mut() = StatusCode::UNAUTHORIZED, },
LoginValid => {
println!("LoginValid");
auth::login_get_jwt(&DB_POOL, &mut response, params).await;
},
NoKey | BadKey => {
println!("NoKey | BadKey");
*response.status_mut() = StatusCode::UNAUTHORIZED;
},
ServerIssue(msg) => { ServerIssue(msg) => {
println!("\tAUTH : 500 [{}]", msg); eprintln!("{}", msg);
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
} }
} }
@ -158,8 +172,8 @@ async fn attempt_owner_creation(name: &str) {
let p = Pool::new(&env::var("DATABASE_URL").unwrap()); let p = Pool::new(&env::var("DATABASE_URL").unwrap());
let owner_secret = auth::generate_secret(); let owner_secret = auth::generate_secret();
if let Ok(enc_secret) = auth::encrypt_secret(&owner_secret) { if let Ok(enc_secret) = auth::encrypt_secret(&owner_secret) {
if let Ok(response) = db::Member::add(&p, name, &enc_secret, perms::OWNER).await { match db::Member::add(&p, name, &enc_secret, perms::OWNER).await {
match response { Ok(response) => match response {
db::Response::Row(mut owner) => { db::Response::Row(mut owner) => {
owner.secret = owner_secret; // giving the secret itself back to the user owner.secret = owner_secret; // giving the secret itself back to the user
let server_config = serde_json::json!({ let server_config = serde_json::json!({
@ -168,16 +182,11 @@ async fn attempt_owner_creation(name: &str) {
}); });
println!("{}", serde_json::to_string_pretty(&server_config).unwrap()); println!("{}", serde_json::to_string_pretty(&server_config).unwrap());
}, },
db::Response::Empty => { _ => eprintln!("SQL server failed to return owner data, check configs and also the members table to make sure there's nothing there by accident")
eprintln!("SQL server failed to return owner data, check configs and also the members table to make sure there's nothing there by accident");
}, },
_ => {} Err(e) => eprintln!("Error communicating with database : {}", e)
}; };
} }
else {
eprintln!("Could not communicate with the SQL server, check your configs!");
}
}
else { else {
eprintln!("Could not generate a proper secret"); eprintln!("Could not generate a proper secret");
} }

View File

@ -68,6 +68,7 @@ pub async fn send_message(pool: &Pool, response: &mut Response<Body>, body: Body
let uid = qs_param!(params, "id", u64).unwrap(); let uid = qs_param!(params, "id", u64).unwrap();
let ctype: Option<&str> = match headers.get("Content-Type") { let ctype: Option<&str> = match headers.get("Content-Type") {
Some(hval) => { Some(hval) => {
println!("{:?}", hval);
match hval.to_str() { match hval.to_str() {
Ok(s) => Some(s), Ok(s) => Some(s),
_ => None _ => None
@ -96,7 +97,12 @@ pub async fn send_message(pool: &Pool, response: &mut Response<Body>, body: Body
*response.status_mut() = StatusCode::BAD_REQUEST; *response.status_mut() = StatusCode::BAD_REQUEST;
} else { } else {
// block away wrong content types // block away wrong content types
const CONTENT_TYPES: [&'static str;7] = ["text", "png", "jpeg", "jpg", "webm", "mp3", "mp4"]; const CONTENT_TYPES: [&'static str;7] = [
"text/plain",
"image/png", "image/jpeg", "image/jpg",
"application/webm", "application/mp4",
"application/mp3"
];
if CONTENT_TYPES.contains(&ctype.unwrap()) == false { if CONTENT_TYPES.contains(&ctype.unwrap()) == false {
*response.status_mut() = StatusCode::BAD_REQUEST; *response.status_mut() = StatusCode::BAD_REQUEST;
} }