diff --git a/json-api/db/Cargo.toml b/json-api/db/Cargo.toml index 7b2e498..d211df5 100644 --- a/json-api/db/Cargo.toml +++ b/json-api/db/Cargo.toml @@ -11,3 +11,4 @@ mysql_async = "0.23.1" serde = { version = "1.0.117", features = [ "derive" ] } tokio = { version = "1", features = ["fs", "io-util"] } +rand = "0.8.3" diff --git a/json-api/db/Makefile b/json-api/db/Makefile new file mode 100644 index 0000000..4fea6cd --- /dev/null +++ b/json-api/db/Makefile @@ -0,0 +1,3 @@ +default: + cargo build --release + diff --git a/json-api/db/src/channels.rs b/json-api/db/src/channels.rs index 4f7d5d7..1081210 100644 --- a/json-api/db/src/channels.rs +++ b/json-api/db/src/channels.rs @@ -5,7 +5,7 @@ use mysql_async::error::Error as SqlError; use crate::{VarChar, UBigInt, Integer}; use crate::{sql_err, no_conn, Response}; - +use rand::RngCore; pub const VOICE_CHANNEL: Integer = 1; pub const TEXT_CHANNEL: Integer = 2; @@ -58,19 +58,15 @@ impl crate::Channel { // bounds are literally [1, 2] if kind == TEXT_CHANNEL || kind == VOICE_CHANNEL { let conn = p.get_conn().await?; - let q = "INSERT INTO channels (name, description, kind) VALUES (:n, :d, :k)"; - let conn = conn.drop_exec(q, params!{ + let q = "INSERT INTO channels (id, name, description, kind) VALUES (:i, :n, :d, :k)"; + let id = rand::rngs::OsRng.next_u64(); // generate id's randomly for channels + conn.drop_exec(q, params!{ + "i" => id, "n" => name, "d" => description, "k" => kind }).await?; - let q = "SELECT id FROM channels WHERE name = :name"; - let (_, id): (_, Option) = - conn.first_exec(q, params!{"name" => name}).await?; - - // probably safe but honestly could fail if the net goes down right here - let id = id.unwrap(); Ok(Response::Row(Self { id, name: name.to_string(), diff --git a/json-api/db/src/member.rs b/json-api/db/src/member.rs index 2655a1c..22b12d1 100644 --- a/json-api/db/src/member.rs +++ b/json-api/db/src/member.rs @@ -7,7 +7,7 @@ use crate::{Response, no_conn, sql_err}; use crate::{UBigInt, Integer, VarChar}; use crate::{PublicMember, Member}; - +use rand::RngCore; pub const STATUS_ONLINE: Integer = 0; @@ -95,34 +95,25 @@ impl Member { //! @returns : on_failure => Err(SomeBS) let conn = p.get_conn().await?; - - let conn = conn.drop_exec( + let id: u64 = rand::rngs::OsRng.next_u64(); + conn.drop_exec( "INSERT INTO members(secret, name, status, permissions) - VALUES(:secret, :name, :status, :permissions)", + VALUES(:id, :secret, :name, :status, :permissions)", mysql_async::params!{ + "id" => id, "secret" => secret.clone(), "name" => name.clone(), "status" => STATUS_ONLINE, "permissions" => perms }).await?; - let (_, opt_id): (Conn, Option) = conn.first_exec( - "SELECT id FROM members WHERE secret = :secret", - params!{ - "secret" => secret.clone() - }).await?; - - if let Some(id) = opt_id { - return Ok(Response::Row(Self { - id, - secret: secret.into(), - name: name.into(), - status: STATUS_ONLINE, - permissions: perms - })) - } - - return Ok(Response::Empty); + return Ok(Response::Row(Self { + id, + secret: secret.into(), + name: name.into(), + status: STATUS_ONLINE, + permissions: perms + })) } pub async fn update_perms(p: &Pool, uid: UBigInt, permissions: UBigInt) -> Result { diff --git a/json-api/db/src/messages.rs b/json-api/db/src/messages.rs index 5b7151e..c67c634 100644 --- a/json-api/db/src/messages.rs +++ b/json-api/db/src/messages.rs @@ -15,6 +15,8 @@ use crate::{Response, sql_err}; use crate::{UBigInt, BigInt, VarChar}; use crate::{Message, UserMessage}; +use rand::RngCore; + const MAX_MESSAGES: u64 = 1000; @@ -46,9 +48,10 @@ impl Message { let conn = p.get_conn().await?; let q = "INSERT INTO messages - (time, content, content_type, author_id, channel_id) - VALUES (:time, :content, :ctype, :author, :channel)"; + (id, time, content, content_type, author_id, channel_id) + VALUES (id, :time, :content, :ctype, :author, :channel)"; + let id: u64 = rand::rngs::OsRng.next_u64(); let now: i64 = SystemTime::now() .duration_since(UNIX_EPOCH) .expect("System time `NOW` failed") @@ -60,6 +63,7 @@ impl Message { Ok(Response::RestrictedInput("Large text not allowed".into())) } else { let res = conn.prep_exec(q, params!{ + "id" => id, "time" => now, "content" => content, "ctype" => content_type, @@ -84,6 +88,7 @@ impl Message { let content_ref = format!("{cid}-{time}.{ext}", cid=cid, time=now, ext=extension); let res = conn.prep_exec(q, params!{ + "id" => id, "time" => now, "content" => &content_ref, // store a ref to a file instead of the actual payload "ctype" => content_type, diff --git a/json-api/migrations/2020-03-11-005217_channels/up.sql b/json-api/migrations/2020-03-11-005217_channels/up.sql index fffcabf..e37c630 100644 --- a/json-api/migrations/2020-03-11-005217_channels/up.sql +++ b/json-api/migrations/2020-03-11-005217_channels/up.sql @@ -1,6 +1,6 @@ -- TODO: somehow make the name colum unique CREATE TABLE IF NOT EXISTS `channels` ( - `id` BIGINT UNSIGNED NOT NULL auto_increment, + `id` BIGINT UNSIGNED NOT NULL, `name` VARCHAR(255) NOT NULL, `description` VARCHAR(2048), `kind` INTEGER NOT NULL, diff --git a/json-api/migrations/2020-07-05-215114_members/up.sql b/json-api/migrations/2020-07-05-215114_members/up.sql index 2c8c22c..1309164 100644 --- a/json-api/migrations/2020-07-05-215114_members/up.sql +++ b/json-api/migrations/2020-07-05-215114_members/up.sql @@ -1,7 +1,7 @@ -- TODO: add rate limiter in some form -- PERMISSIONS start at 0 and full perms => all F's CREATE TABLE IF NOT EXISTS `members`( - `id` BIGINT UNSIGNED NOT NULL auto_increment, + `id` BIGINT UNSIGNED NOT NULL, `secret` varchar(256) NOT NULL, `name` varchar(256) NOT NULL, `status` integer NOT NULL, diff --git a/json-api/migrations/2020-07-06-022319_messages/up.sql b/json-api/migrations/2020-07-06-022319_messages/up.sql index 9017353..68cad5d 100644 --- a/json-api/migrations/2020-07-06-022319_messages/up.sql +++ b/json-api/migrations/2020-07-06-022319_messages/up.sql @@ -1,7 +1,8 @@ -- Time stamp is _not_ in ms CREATE TABLE IF NOT EXISTS `messages`( - `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + `id` BIGINT UNSIGNED NOT NULL, `time` BIGINT NOT NULL, + -- Assuming content-type is `not` text/plain this will be a reference to some auto-named file `content` VARCHAR(4096) NOT NULL, `content_type` VARCHAR(10) NOT NULL, `author_id` BIGINT UNSIGNED NOT NULL,