From b8c4cee57f22e0ec6bfaeb1fb268e02453835ae2 Mon Sep 17 00:00:00 2001 From: shockrah Date: Thu, 30 Jul 2020 23:31:20 -0700 Subject: [PATCH] send message now build properly w/ no warns --- .../2020-07-06-022319_messages/up.sql | 6 +- server/src/messages.rs | 110 +++++++----------- 2 files changed, 43 insertions(+), 73 deletions(-) diff --git a/server/migrations/2020-07-06-022319_messages/up.sql b/server/migrations/2020-07-06-022319_messages/up.sql index 1488872..d97f62f 100644 --- a/server/migrations/2020-07-06-022319_messages/up.sql +++ b/server/migrations/2020-07-06-022319_messages/up.sql @@ -1,6 +1,8 @@ +-- Time stamp is _not_ in ms CREATE TABLE IF NOT EXISTS `messages`( - `id` BIGINT UNSIGNED NOT NULL, - `content` VARCHAR(2048), + `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + `time` BIGINT NOT NULL, + `content` VARCHAR(2048) NOT NULL, `author_id` BIGINT UNSIGNED NOT NULL, `channel_id` BIGINT UNSIGNED NOT NULL, PRIMARY KEY (`id`), diff --git a/server/src/messages.rs b/server/src/messages.rs index cce3b14..943707a 100644 --- a/server/src/messages.rs +++ b/server/src/messages.rs @@ -1,83 +1,43 @@ use std::borrow::Cow; -use mysql_async::{Conn, Pool, params}; +use mysql_async::{Pool, params}; use mysql_async::prelude::{Queryable}; use mysql_async::error::Error; use hyper::{Response, Body, StatusCode}; use serde_json::Value; use chrono::Utc; -use crate::members::Member; -use crate::channels::{Channel, ChannelID, ChannelType}; +use crate::db_types::{UBigInt, VarChar}; struct Message { - author: Member, - date: u64, // used as thr primary key in our table - content: String, - channel: Channel + id: UBigInt, + content: Option, // some messages later might only have file attachments and not text content + author_id: UBigInt, + channel_id: UBigInt, + permissions: UBigInt, } -fn validate_params(p: &Value, keys: Vec<&str>) -> bool { - let mut fail = false; - for key in keys.iter() { - if let None = p.get(key) { - fail = true; - break; - } - } - return fail == false; -} - - -async fn update_messages_table(pool: &Pool, secret: &str, content: Option<&str>, id: Option) - -> Result<(), mysql_async::error::Error> { - match (content, id) { - (Some(content), Some(id)) => { - let conn = pool.get_conn().await?; - // get the user data first since we kinda need it - // make sure the channel exists - const CID_QUERY: &'static str = "SELECT kind from `channels` WHERE id = :id"; - let (conn, row): (Conn, Option) = conn - .first_exec(CID_QUERY, params!{"id"=>id}) - .await?; - - let channel_exists = match row { - Some(r) => r == ChannelType::Text.as_i32(), - None => false - }; - // may as well grab the user id now since the fail case is going to be rare (hopefully) - const UID_QUERY : &'static str = "SELECT userid FROM `keys` WHERE `secret` = :secret"; - let (conn, row): (Conn, Option) = conn - .first_exec(UID_QUERY, params!{"secret"=>secret}) - .await?; - // for a message entry we need: (DATE, CONTENT, AUTHOR_ID, Channel_id) - if channel_exists { - // NOTE: not checking if the user exists as our auth model does that - // for us already - conn.batch_exec( - "INSERT INTO `messages` (id, content, author_id, channel_id) \ - VALUES (:mid, :content, :aid, :cid)", - params!{ - "mid" => Utc::now().timestamp() as u64, - "content" => content, - "aid" => row.expect("uid is None when it should have come back as Some(u64):\ - Occurence in "), - "cid" => id - }).await?; +pub async fn insert_message_table(pool: &Pool, content: &Value, channel_id: &Value, author_id: UBigInt) + -> Result<(), Error>{ + match (content.as_str(), channel_id.as_u64()) { + (Some(content), Some(channel)) => { + let conn = pool.get_conn().await?; + let time = Utc::now().timestamp(); + conn.prep_exec(r"", params!{ + "time" => time, + "content" => content, + "author" => author_id, + "channel" => channel + }).await?; Ok(()) } - else { - let x = Cow::from("Channel does not exist"); - Err(Error::Other(x)) + _ => { + let e = Cow::from("Required parameter missing"); + Err(Error::Other(e)) } } - _ => { - let x = Cow::from("Missing required parameters to create message"); - Err(Error::Other(x)) - } - } } pub async fn send_message(pool: &Pool, response: &mut Response, params: Value) { @@ -85,14 +45,22 @@ pub async fn send_message(pool: &Pool, response: &mut Response, params: Va * @content: expecting string type * @id: expecting the channel id that we're posting data to */ - if validate_params(¶ms, vec!["content", "id"]) { - // now we prepare some arguments for our db and send them down the wire - let content = params.get("content").unwrap().as_str(); - let id = params.get("id").unwrap().as_u64(); - let secret: &str = params.get("secret").unwrap().as_str().unwrap(); //auth sucess guarantees this param is fine - match update_messages_table(pool, secret, content, id).await { - Ok(_) => *response.status_mut() = StatusCode::OK, - Err(_err) => *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR + let content_r = params.get("content"); + let channel_id_r = params.get("channel"); + // auth module guarantees this will be there in the correct form + let author = params.get("userid") + .unwrap().as_u64().unwrap(); + + match (content_r, channel_id_r) { + (Some(content), Some(channel_id)) => { + // insert the new message into our db + if let Ok(_db_result) = insert_message_table(pool, content, channel_id, author).await { + *response.status_mut() = StatusCode::OK; + } + }, + _ => { + *response.status_mut() = StatusCode::BAD_REQUEST; + *response.body_mut() = Body::from("content/channel missing from json parameters"); } } -} \ No newline at end of file +}