From 62204e52cab13f341b3d77508a13c83d34fb1175 Mon Sep 17 00:00:00 2001 From: shockrah Date: Tue, 5 May 2020 17:09:18 -0700 Subject: [PATCH] dumy commit as work will continue on new async branch --- server/src/auth.rs | 92 +++++++++++++++++++++++++++++++++++++++++++ server/src/payload.rs | 10 ++--- server/src/users.rs | 33 ++++++++++------ 3 files changed, 118 insertions(+), 17 deletions(-) create mode 100644 server/src/auth.rs diff --git a/server/src/auth.rs b/server/src/auth.rs new file mode 100644 index 0000000..b856d16 --- /dev/null +++ b/server/src/auth.rs @@ -0,0 +1,92 @@ +// Handlers for the base auth routes +use crate::users; +use std::{error, fmt}; + + +#[derive(FromForm)] +struct JoinParams { + code: u64, + name: String, +} + + +pub type AuthResult = std::result::Result; + +#[derive(Clone)] +pub struct AuthErr { + msg: &'static str, + status: u16, +} + +impl fmt::Display for AuthErr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Authentication error") + } +} + +impl error::Error for AuthErr { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + None + } +} + +impl<'r> Responder<'r> for AuthErr { + fn respond_to(self, _:&Request) -> response::Result<'r> { + Response::build() + .status(Status::InternalServerError) + .raw_header("db-error", self.msg) + .ok() + } +} + +#[post("/login")] +pub fn login() { +} + +#[post("/join", data="")] +pub fn join(conn: DBConn, params: JoinParams) -> AuthResult, AuthErr>{ + /* + * Requires -> body + * Requires -> body + */ + const expired: &'static str = "Invite expired"; + const negate: &'static str = "Malformed request"; + let diesel_result: Result = invites + .filter(id.eq(code)) + .first(&conn.0); + + if let Ok(data) = diesel_result { + match data.uses { + 1 ... std::i32::MAX => { + let user = users::new_user(); + // update the uses counter + diesel::update(users.filter(userid.eq(user.userid))) + .set(uses.eq(data.uses - 1)) + .execute(&conn.0) + + AuthResult(Json(user)) + } + // The invite has been used up and thus should be removed + std::i32::MIN ... 0 => { + let _ = diesel::delete(invites.filter(id.eq(data.id))) + .execute(&conn.0) + .expect("Could not delete invite"); + + AuthResult(AuthErr{msg: expired}) + } + } + } + else { + AuthResult(AuthErr{msg:negate}) + } +} + +#[post("/leave", data = "<>")] +pub fn leave() { +} + +#[pust("/close")] +pub fn close() { +} + + diff --git a/server/src/payload.rs b/server/src/payload.rs index abe2bf5..3b06924 100644 --- a/server/src/payload.rs +++ b/server/src/payload.rs @@ -5,13 +5,11 @@ // 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 -// TODO: refactor this so that we don't need any optional fields #[derive(Serialize, Deserialize, Debug)] pub struct NewUserResponse { - pub userid: Option, - pub username: Option, - pub key: Option, - pub err: Option<&'static str>, + pub id: u64, + pub secret: String, + pub discriminator: i32, } // This is basically anyone that's online at the moment @@ -38,4 +36,4 @@ pub struct VoiceChannel { pub struct TextChannel { pub id: i32, pub name: String, -} \ No newline at end of file +} diff --git a/server/src/users.rs b/server/src/users.rs index db86ee5..a69edc9 100644 --- a/server/src/users.rs +++ b/server/src/users.rs @@ -7,19 +7,30 @@ use crate::{DBConn, schema}; use diesel::{self, prelude::*}; use diesel::result::Error; -pub fn create_new_user() -> User { - let uid = new_user_id(); - let uname = format!("User:#{}", uid); - let rstring = new_key(); - User { - userid: uid, - username: uname, - key: rstring, - date: Utc::now().timestamp() as u64, +pub fn create_new_user(conn: DBConn, name: String) -> User { + use schema::users::dsl::*; + use diesel::result::Error; + use crate::models::InsertableUser; + + let ins = InsertableUser { + name: name, + secret: new_key(), + date: time, status: USER_ONLINE, - } + }; + // insert the nwe user data then return usable user data to the client + diesel::insert_into(users::table) + .values(&ins) + .execute(&conn.0); + + let new_user_data : Result = users + .filter(userid.eq(ins.id)) + .first(&conn.0); + + new_user_data.unwrap() } + pub fn new_user_response(user: &Option, msg: Option<&'static str>) -> NewUserResponse { if let Some(u) = user { NewUserResponse { @@ -131,4 +142,4 @@ mod user_tests { println!("{}", body); } //TODO: fail case for removing users -} \ No newline at end of file +}