From 54f5b1bbe1c1d0d142d134b24ff379bcdb1d295c Mon Sep 17 00:00:00 2001 From: shockrah Date: Sat, 7 Mar 2020 21:51:54 -0800 Subject: [PATCH] new route to create users still requires some kind of auth however --- server/src/invites.rs | 61 +++++++++++++++++++++++++++------------- server/src/main.rs | 1 + server/src/payload.rs | 12 ++++---- server/src/rand_utils.rs | 27 ++++++++++++++++++ 4 files changed, 75 insertions(+), 26 deletions(-) create mode 100644 server/src/rand_utils.rs diff --git a/server/src/invites.rs b/server/src/invites.rs index 1fd4311..b00f3eb 100644 --- a/server/src/invites.rs +++ b/server/src/invites.rs @@ -6,7 +6,18 @@ use chrono::{Duration, Utc}; use crate::DBConn; use crate::models::Invite; use crate::schema; +use crate::payload::NewUserInfo; +use crate::rand_utils::{newUserID, newKeyHash}; +macro_rules! blankNewUser { + () => { + NewUserInfo { + userid: 0, + key_hash: None, + valid: false + } + } +} /* TODO: both the generation and usage endpoints for invites need the following * meaningful responses @@ -27,10 +38,10 @@ pub fn generate_invite(conn: DBConn) -> Json { .execute(&conn.0); match result { - Ok(val) => { + Ok(_val) => { Json(new_invite) } - Err(e) => { + Err(_e) => { new_invite.id = 0; new_invite.uses = Some(0); new_invite.expires = 0; @@ -40,30 +51,42 @@ pub fn generate_invite(conn: DBConn) -> Json { } #[get("/")] -pub fn use_invite(hash: u64, conn: DBConn) -> Result { +pub fn use_invite(hash: u64, conn: DBConn) -> Json { + // Grab the token from our table to make sure it's even there to begin with + use schema::invites::dsl::*; use rand::{thread_rng, Rng}; use rand::distributions::Alphanumeric; // NOTE: collection of 1 item from the table could be done cleaner - use schema::invites::dsl::*; - let data: Vec = invites.select((id, expires, uses)) + let data = invites.select((id, expires, uses)) .filter(id.eq(hash)) - .load(&conn.0) + .first::(&conn.0) .unwrap(); - if data.is_empty() { - Err("invite does not exist".into()) - } - else { - let invite_id = data[0].id; - // generating the field data we need for the random token - let nu_token: String = thread_rng() - .sample_iter(&Alphanumeric) - .take(30) - .collect(); - - let row = diesel::delete(invites.filter(id.eq(hash))).execute(&conn.0); - Ok(format!("Invite used successfully {:?} random fields[{}]", row, nu_token)) + let _data: Result = invites.filter(id.eq(hash)).first(&conn.0); + // We're going to need more secure random numbers but for now this will do + match data { + Ok(d) => { + if d.id == hash { + // create the new user + let new = NewUserInfo { + userid: newUserID(), + key_hash: newKeyHash(), + valid: true + }; + // save the user info and finally return it back to the caller + diesel::insert_into(users) + .values(&new) + .execute(&conn.0); + Json(new) + } + else { + Json(blankNewUser!()) + } + } + Err(_e) => { + Json(blankNewUser!()) + } } } diff --git a/server/src/main.rs b/server/src/main.rs index 9a9f9a0..5f1c945 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -8,6 +8,7 @@ extern crate chrono; extern crate dotenv; extern crate serde; extern crate rand; +extern crate getrandom; use rocket_contrib::serve::StaticFiles; diff --git a/server/src/payload.rs b/server/src/payload.rs index 8995005..6f71938 100644 --- a/server/src/payload.rs +++ b/server/src/payload.rs @@ -6,10 +6,8 @@ // the server without having to go through a sign in process everytime #[derive(Serialize)] -pub struct NewUserResponse { - // passkey-value - // userid-value - pub userid: u64, - pub username: String, - pub email: String, -} +pub struct NewUserInfo { + pub userid: u64, // userid which later will be discoverable via the + pub key_hash: Option, + pub valid: bool +} \ No newline at end of file diff --git a/server/src/rand_utils.rs b/server/src/rand_utils.rs new file mode 100644 index 0000000..2cd49e4 --- /dev/null +++ b/server/src/rand_utils.rs @@ -0,0 +1,27 @@ +// This modules mainly deals with creating various types of random data + +pub fn newUserID() -> u64 { + let mut buf = [0u8; 8]; + match getrandom::getrandom(&mut buf) { // honestly if this fails idk wtf you want + Ok(_val) => {u64::from_ne_bytes(buf)} + Err(_e) => {0} // if this really happens we're fucked anyway + } + +} + +pub fn newKey() -> String { + let mut buf = [0u8; 32]; + getrandom::getrandom(&mut buf)?; + let mut string = String::new(); + for i in buf.iter() { + // if the value isn't in the proper range then we place it in the proper range + // [33-126] + if i < 33 { + i += 33; + } + else if i > 126 { + i %= 126; + } + } + string +} \ No newline at end of file