Removal of chrono and async_trait as dependancy in db-lib

Removig chrono from api code as well

Removing chrono as dep in api code
+ Using Content-Type for /message/send content type

Updating cargo lists for removal of fluff deps

Removal of more fluff

Addking makefile to avoid compiling debug builds by accident while developing
This commit is contained in:
shockrah
2021-03-20 13:56:02 -07:00
parent cb5975f235
commit 988aa9f155
21 changed files with 181 additions and 2062 deletions

View File

@@ -9,10 +9,7 @@ use std::collections::HashMap;
use crate::perms::ADMIN_PERMS;
use db::{
self,
member::Member
};
use db::{self, Member};
use crate::qs_param;

View File

@@ -1,15 +1,14 @@
use serde::{Serialize, Deserialize};
use bcrypt::{self, BcryptResult};
use mysql_async::Pool;
use chrono::{Utc, Duration};
use std::collections::HashMap;
use std::time::{SystemTime, UNIX_EPOCH};
use crate::routes;
use crate::qs_param;
use db::{member::Member, common::FromDB};
use db::Response;
use db::{Response, Member};
use jsonwebtoken::EncodingKey;
lazy_static! {
@@ -31,12 +30,14 @@ struct Claim {
impl Claim {
pub fn new(id: db::UBigInt) -> Claim {
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("System time fetch failed")
.as_millis() as i64;
Claim {
sub: id,
exp: Utc::now()
.checked_add_signed(Duration::weeks(1))
.expect("Couldn't generate an expirey date")
.timestamp(),
exp: now,
cookie: generate_cookie()
}
}
@@ -114,10 +115,14 @@ async fn valid_jwt(p: &Pool, token: &str) -> AuthReason {
let algo = Algorithm::HS512;
let dk = DecodingKey::from_secret(&HMAC_SECRET);
if let Ok(decoded) = decode::<Claim>(token, &dk, &Validation::new(algo)) {
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("System time fetch failed")
.as_millis() as i64;
// subject used for querying speed NOT security
let listed = db::auth::listed_jwt(p, decoded.claims.sub, token).await.unwrap();
let active = Utc::now().timestamp() < decoded.claims.exp;
let active = now < decoded.claims.exp;
return match listed && active {
true => AuthReason::Good,

View File

@@ -6,7 +6,7 @@ use serde_json::json;
use std::collections::HashMap;
use db::{ self, common::FromDB, Channel };
use db::{ self, Channel};
use crate::http::set_json_body;
use crate::qs_param;
@@ -80,7 +80,7 @@ pub async fn delete_channel(pool: &Pool, response: &mut Response<Body>, params:
* @channel_id : u64 - required
*/
use crate::perms;
use db::member::Member;
use db::Member;
use db::Response::*;
let uid = qs_param!(params, "id", u64).unwrap();

View File

@@ -1,22 +1,11 @@
use serde_json::json;
use mysql_async;
use mysql_async::Pool;
use hyper::{Response, Body, StatusCode};
use chrono::Utc;
use std::time::{SystemTime, UNIX_EPOCH};
use std::collections::HashMap;
use db::BigInt;
use db::common::FromDB;
use db::member::Member;
use db::invites::Invite;
use crate::qs_param;
use crate::http;
use crate::meta;
use serde_json::json;
use mysql_async::{self, Pool};
use hyper::{Response, Body, StatusCode};
use db::{BigInt, Member, Invite};
use crate::{http, meta, qs_param};
/*
@@ -29,15 +18,23 @@ async fn valid_invite(pool: &Pool, id: BigInt) -> bool {
/*
* Fetches an invite from the database to check for validity
*/
let query: Option<db::invites::Invite> = match db::invites::Invite::get(pool, id as u64).await {
db::Response::Row(invite) => { Some(invite) },
_ => { None }
let query = if let Ok(inv) = Invite::get(pool, id).await {
match inv {
db::Response::Row(data) => Some(data),
_ => None
}
} else {
None
};
if let Some(invite) = query {
// if expires at all
if invite.expires {
let now = Utc::now().timestamp_millis();
let now: i64 = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Systemtime fetch failed")
.as_millis() as i64;
// old?
let mut valid_status = now < invite.id;
// used?
@@ -70,7 +67,7 @@ async fn use_invite(pool: &Pool, code: Option<BigInt>) -> Option<Member>{
if valid_invite(pool, id).await {
let raw_secret = auth::generate_secret();
let secret = auth::encrypt_secret(&raw_secret).unwrap();
return match db::member::Member::add(pool, "Anonymous".into(), &secret, GENERAL_NEW).await {
return match Member::add(pool, "Anonymous".into(), &secret, GENERAL_NEW).await {
Ok(response) => {
match response {
db::Response::Row(member) => Some(member),
@@ -123,7 +120,7 @@ pub async fn join(pool: &Pool, response: &mut Response<Body>, params: HashMap<St
async fn allowed_perm_invite(pool: &Pool, uid: u64) -> bool {
use crate::perms;
return match db::member::Member::get(pool, uid).await {
return match Member::get(pool, uid).await {
db::Response::Row(user) => perms::has_perm(user.permissions, perms::CREATE_PERM_INVITES),
_ => false
};

View File

@@ -1,5 +1,4 @@
extern crate db;
extern crate chrono;
extern crate clap;
extern crate dotenv;
extern crate getrandom;
@@ -20,7 +19,8 @@ use hyper::{
Server,
Response, Request, Body,
Method, StatusCode,
service::{make_service_fn, service_fn}
service::{make_service_fn, service_fn},
HeaderMap
};
use mysql_async::Pool;
@@ -51,11 +51,13 @@ async fn route_dispatcher(
meth: &Method,
path: &str,
body: Body,
params: HashMap<String, String>) {
params: HashMap<String, String>,
headers: HeaderMap) {
const GET: &Method = &Method::GET;
const POST: &Method = &Method::POST;
const DELETE: &Method = &Method::DELETE;
println!("{}: {}", meth, path);
match (meth, path) {
/* INVITES */
(POST, routes::INVITE_CREATE) => invites::create(pool, resp, params).await,
@@ -65,7 +67,7 @@ async fn route_dispatcher(
(POST, routes::CHANNELS_CREATE) => channels::create_channel(pool, resp, params).await,
(DELETE, routes::CHANNELS_DELETE) => channels::delete_channel(pool, resp, params).await,
/* MESSAGING */
(POST, routes::MESSAGE_SEND) => messages::send_message(pool, resp, body, params).await,
(POST, routes::MESSAGE_SEND) => messages::send_message(pool, resp, body, headers, params).await,
(GET, routes::MESSAGE_TIME_RANGE) => messages::get_by_time(pool, resp, params).await,
(GET, routes::MESSAGE_FROM_ID) =>messages::from_id(pool, resp, params).await,
/* ADMIN */
@@ -94,6 +96,7 @@ async fn main_responder(request: Request<Body>) -> Result<Response<Body>, hyper:
let method = parts.method;
let path = parts.uri.path();
let qs = parts.uri.query();
let headers = parts.headers;
let params_opt: Option<HashMap<String, String>> = if let Some(query_string) = qs {
Some(http::parse_query_string(query_string))
} else {
@@ -103,7 +106,7 @@ async fn main_responder(request: Request<Body>) -> Result<Response<Body>, hyper:
if let Some(params) = params_opt {
let mysql_pool = Pool::new(&env::var("DATABASE_URL").unwrap());
match auth::wall_entry(path, &mysql_pool, &params).await {
OpenAuth | Good => route_dispatcher(&mysql_pool, &mut response, &method, path, body, params).await,
OpenAuth | Good => route_dispatcher(&mysql_pool, &mut response, &method, path, body, params, headers).await,
LoginValid => auth::login_get_jwt(&mysql_pool, &mut response, params).await,
NoKey | BadKey => *response.status_mut() = StatusCode::UNAUTHORIZED,
ServerIssue(msg) => {
@@ -155,7 +158,7 @@ async fn attempt_owner_creation(name: &str) {
let p = Pool::new(&env::var("DATABASE_URL").unwrap());
let owner_secret = auth::generate_secret();
if let Ok(enc_secret) = auth::encrypt_secret(&owner_secret) {
if let Ok(response) = db::member::Member::add(&p, name, &enc_secret, perms::OWNER).await {
if let Ok(response) = db::Member::add(&p, name, &enc_secret, perms::OWNER).await {
match response {
db::Response::Row(mut owner) => {
owner.secret = owner_secret; // giving the secret itself back to the user

View File

@@ -4,8 +4,7 @@ use mysql_async::Pool;
use serde_json::json;
use db::member::STATUS_ONLINE;
use db::common::FromDB;
use db::member::Member;
use db::Member;
use db::Response::*;
use crate::http::set_json_body;
@@ -36,7 +35,6 @@ pub async fn get_self(p: &Pool, response: &mut Response<Body>, params: HashMap<S
set_json_body(response, json!({
"id" : user.id,
"name" : user.name,
"joindate" : user.joindate,
"permissions" : user.permissions
}));
},
@@ -82,7 +80,6 @@ pub async fn get_member(p: &Pool, response: &mut Response<Body>, params: HashMap
set_json_body(response, json!({"member": {
"id": member.id,
"name": member.name,
"joindate": member.joindate,
"status": member.status,
"permissions": member.permissions
}}));

View File

@@ -1,5 +1,5 @@
use mysql_async::Pool;
use hyper::{Response, Body, StatusCode};
use hyper::{Response, Body, HeaderMap, StatusCode};
use hyper::body::to_bytes;
use serde_json::json;
@@ -54,19 +54,27 @@ pub async fn get_by_time(pool: &Pool, response: &mut Response<Body>, params: Has
}
}
pub async fn send_message(pool: &Pool, response: &mut Response<Body>, body: Body, params: HashMap<String, String>) {
pub async fn send_message(pool: &Pool, response: &mut Response<Body>, body: Body, headers: HeaderMap, params: HashMap<String, String>) {
/*
* Message content is sent in the message body
* @channel_id: channel id that we're going to send a message to
* @content-type in the headers
* TODO: more features here because send_message is a large handler
*/
use db::Response::*;
use db::member::Member;
use crate::db::common::FromDB;
use db::Member;
// NOTE: auth module guarantees this will be there in the correct form
// NOTE: auth module guarantees that id will be present so the unwrap is safe
let uid = qs_param!(params, "id", u64).unwrap();
let ctype = params.get("type");
let ctype: Option<&str> = match headers.get("Content-Type") {
Some(hval) => {
match hval.to_str() {
Ok(s) => Some(s),
_ => None
}
},
None => None
};
let permissions = match Member::get(pool, uid).await {
Row(user) => user.permissions,
@@ -89,10 +97,11 @@ pub async fn send_message(pool: &Pool, response: &mut Response<Body>, body: Body
} else {
// block away wrong content types
const CONTENT_TYPES: [&'static str;7] = ["text", "png", "jpeg", "jpg", "webm", "mp3", "mp4"];
if CONTENT_TYPES.contains(&ctype.unwrap().as_str()) == false {
if CONTENT_TYPES.contains(&ctype.unwrap()) == false {
*response.status_mut() = StatusCode::BAD_REQUEST;
}
else {
// ctype safe unwrap
match db::Message::send(pool, &content, ctype.unwrap(), channel_id.unwrap(), uid).await {
Ok(Empty) => {/* TODO: put something here to notify the rtc server if its there*/},
Ok(RestrictedInput(_msg)) => *response.status_mut() = StatusCode::BAD_REQUEST,