From 8ae877f3f9abf2aa0d6caf3557e654da0398ec27 Mon Sep 17 00:00:00 2001 From: shockrah Date: Tue, 10 Mar 2020 16:48:21 -0700 Subject: [PATCH] updated the response when creating new users --- server/src/invites.rs | 63 ++++++++++++++++++++++--------------------- server/src/payload.rs | 12 ++++----- server/src/users.rs | 19 +++++++++++++ 3 files changed, 57 insertions(+), 37 deletions(-) diff --git a/server/src/invites.rs b/server/src/invites.rs index b15bc7b..edf966d 100644 --- a/server/src/invites.rs +++ b/server/src/invites.rs @@ -3,20 +3,13 @@ use diesel::{self, prelude::*}; use rocket_contrib::json::Json; use rand::random; use crate::DBConn; -use crate::models::{User, Invite}; +use crate::models::Invite; use crate::schema; +use crate::users::new_user_response; +use crate::payload; use chrono::{Duration, Utc}; -macro_rules! blankNewUser { - () => { - User { - userid: 0, - username: "".into(), - key: "".into(), - date: 0, - } - } -} + /* TODO: both the generation and usage endpoints for invites need the following * meaningful responses @@ -26,9 +19,10 @@ TODO: both the generation and usage endpoints for invites need the following #[get("/generate")] pub fn generate_invite(conn: DBConn) -> Json { let dt = Utc::now() + Duration::minutes(30); + // TODO:[maybe] ensure no collisions by doing a quick database check here let mut new_invite = Invite { id: random::(), // hopefully there won't ever be collision with this size of pool - uses: Some(1), // default/hardcorded for now + uses: 1, // default/hardcorded for now expires: dt.timestamp() as u64 }; // Next we cache this invite @@ -36,6 +30,7 @@ pub fn generate_invite(conn: DBConn) -> Json { .values(&new_invite) .execute(&conn.0); + // Finally we attempt to return _something_ match result { Ok(_val) => { Json(new_invite) @@ -43,34 +38,42 @@ pub fn generate_invite(conn: DBConn) -> Json { Err(_e) => { new_invite.id = 0; new_invite.expires = 0; - new_invite.uses = Some(0); + new_invite.uses = 0; Json(new_invite) } } } #[get("/")] -pub fn use_invite(hash: u64, conn: DBConn) -> Json { +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 schema::users::dsl::*; let diesel_result: Result = invites.filter(id.eq(hash)).first(&conn.0); // TODO: this is getting moved elsewhere to clean up so ignore this for now - match diesel_result { - Ok(_data) => { - // we may have an unnecssary struct here but its not that big a deal raelly - let user = crate::users::create_new_user(); - if let Ok(_v) = diesel::insert_into(users).values(&user).execute(&conn.0) { - Json(user) + if let Ok(data) = diesel_result { + match data.uses { + 1 ... std::i32::MAX => { + let user = crate::users::create_new_user(); + match diesel::insert_into(users).values(&user).execute(&conn.0) { + Ok(_v) => Json(new_user_response(&Some(user), None)), + // an issue on our end gets a 500 response + Err(_e) => Json(new_user_response(&None, Some("Unable to create user"))) + } } - else { - Json(blankNewUser!()) + // The invite has been used up and thus should be removed + std::i32::MIN ... 0 => { + // bruh + let _ = diesel::delete(invites.filter(id.eq(data.id))) + .execute(&conn.0) + .expect("Could not delete invite"); + Json(new_user_response(&None, Some("Invalid invite"))) } } - Err(_e) => { - Json(blankNewUser!()) - } + } + else { + Json(new_user_response(&None, Some("Could not create user"))) } } @@ -121,12 +124,10 @@ mod invite_tests { let mut r = client.get("/invite/generate").dispatch(); let invite: Invite = serde_json::from_str(&r.body_string().unwrap()).unwrap(); - // request a user account using the new invite data + // TODO: for some reason we can't use a regular struct so figure that out at some point let mut response = client.get(format!("/invite/{}", invite.id)).dispatch(); - let data: User = serde_json::from_str(&response.body_string().unwrap()).unwrap(); - // make sure the user object isn't fugged - assert_ne!(0, data.userid); - assert_ne!(0, data.date); - println!("{:#?}", data); + let body: String = response.body_string().unwrap(); + println!("{}", body); } + } diff --git a/server/src/payload.rs b/server/src/payload.rs index 4cb967d..79470fe 100644 --- a/server/src/payload.rs +++ b/server/src/payload.rs @@ -5,10 +5,10 @@ // This structure allows us to provide some critical data for the client to reconnect to // the server without having to go through a sign in process everytime -#[derive(Serialize)] -pub struct NewUserInfo { - pub userid: u64, // userid which later will be discoverable via the - pub username: String, - pub key: String, - pub valid: bool +#[derive(Serialize, Deserialize, Debug)] +pub struct NewUserResponse { + pub userid: Option, + pub username: Option, + pub key: Option, + pub err: Option<&'static str>, } \ No newline at end of file diff --git a/server/src/users.rs b/server/src/users.rs index 69e6882..ba8d840 100644 --- a/server/src/users.rs +++ b/server/src/users.rs @@ -1,6 +1,7 @@ use chrono::Utc; use crate::rand_utils::{new_user_id, new_key}; use crate::models::User; +use crate::payload::NewUserResponse; // Returns a struct of payload::NewUserInfo pub fn create_new_user() -> User { @@ -15,6 +16,24 @@ pub fn create_new_user() -> User { } } +pub fn new_user_response(user: &Option, msg: Option<&'static str>) -> NewUserResponse { + if let Some(u) = user { + NewUserResponse { + userid: Some(u.userid), + username: Some(u.username.clone()), + key: Some(u.key.clone()), + err: None + } + } + else{ + NewUserResponse { + userid: None, + username: None, + key: None, + err: Some(msg.unwrap()) + } + } +} #[cfg(test)] mod user_tests { use super::create_new_user;