Merging new db-lib code integration
! I should note that there are two things which are incomplete 1. channel deletion with linked messages 2. Invites module has not been refactored BUT behaves beautifully in all tests so far so i cba
This commit is contained in:
commit
e4fdf4feb7
2
server-api/Cargo.lock
generated
2
server-api/Cargo.lock
generated
@ -308,8 +308,10 @@ name = "db"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"chrono 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mysql_async 0.23.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -16,8 +16,7 @@ while getopts ":htbr" arg; do
|
||||
case ${arg} in
|
||||
h)echo help command;;
|
||||
t)
|
||||
cargo build 1>/dev/null 2>&1
|
||||
cargo test 1>/dev/null 2>&1
|
||||
cargo build
|
||||
cargo run -- -s &
|
||||
server=$!
|
||||
echo Waiting on server to spin up && sleep 2
|
||||
|
@ -21,16 +21,16 @@ class Test:
|
||||
|
||||
self.test_count = 0
|
||||
if create_admin:
|
||||
self.body = Test.__create_admin()
|
||||
self.body = Test.__create_admin() #this was an afterthough for pipelines(later not now)
|
||||
elif admin is not None:
|
||||
self.body = body
|
||||
else:
|
||||
# for now we use this because my dev server has this fake ass acc on it
|
||||
self.body = {
|
||||
'secret': 'utO088fltYrTZg323NZfAGrAkArMkDfwjPmt0ooAYta2oJOYDWcAd1FnrpVVMqZtMeUX4_Hu57-LHCkXy8gedg==',
|
||||
'id': 23,
|
||||
'name': 'admin',
|
||||
'joindate':1602385239,
|
||||
'secret': 'JfW_Icct2P1WEo6PQlGb7l1IMd2QsRXAVarPoPZHZnj7NOMWBMdirnH9JqAKgrO5z3fb54QYsWlPPlRGowwFSA==',
|
||||
'id': 1,
|
||||
'name': 'owner sama uwu',
|
||||
'joindate': 69,
|
||||
'status': 0,
|
||||
'permissions': 18446744073709551615
|
||||
}
|
||||
@ -96,6 +96,7 @@ class Test:
|
||||
if __name__ == '__main__':
|
||||
worker = Test(create_admin=False)
|
||||
|
||||
|
||||
# First the invites api gets some basic tests
|
||||
worker.get('/invite/create')
|
||||
|
||||
@ -112,6 +113,10 @@ if __name__ == '__main__':
|
||||
|
||||
# Messaging
|
||||
|
||||
worker.post('/channels/create', name='send-channel', kind=TEXT_CHANNEL)
|
||||
worker.post('/message/send', channel='send-channel', content="some random content")
|
||||
worker.delete('/channels/delete', name='send-channel')
|
||||
msg_chan_id = time.time()
|
||||
msg_chan_raw = worker.post('/channels/create', name=f'{msg_chan_id}', kind=TEXT_CHANNEL)
|
||||
msg_chan = json.loads(msg_chan_raw)
|
||||
print(f'Channel id to be used: {msg_chan["id"]}')
|
||||
|
||||
worker.post('/message/send', channel=msg_chan['id'], content="some random content")
|
||||
worker.delete('/channels/delete', channel_id=msg_chan['id']) # finally clean up the channel we created
|
||||
|
117
server-api/db/Cargo.lock
generated
117
server-api/db/Cargo.lock
generated
@ -63,9 +63,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "base-x"
|
||||
version = "0.2.7"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2734baf8ed08920ccecce1b48a2dfce4ac74a973144add031163bd21a1c5dab"
|
||||
checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
@ -138,9 +138,9 @@ checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.61"
|
||||
version = "1.0.62"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed67cbde08356238e75fc4656be4749481eeffb09e19f320a25237d5221c985d"
|
||||
checksum = "f1770ced377336a88a67c473594ccc14eca6f4559217c34f64aac8f83d641b40"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
@ -176,9 +176,9 @@ checksum = "c478836e029dcef17fb47c89023448c64f781a046e0300e257ad8225ae59afab"
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.7.0"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171"
|
||||
checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
@ -186,9 +186,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.7.0"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac"
|
||||
checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b"
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
@ -276,8 +276,10 @@ name = "db"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"chrono",
|
||||
"mysql_async",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -357,6 +359,16 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ece68d15c92e84fa4f19d3780f1294e5ca82a78a6d515f1efaabcc144688be00"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon"
|
||||
version = "0.3.3"
|
||||
@ -375,15 +387,15 @@ checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.7"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18eaa56102984bed2c88ea39026cff3ce3b4c7f508ca970cedf2450ea10d4e46"
|
||||
checksum = "847ce131b72ffb13b6109a221da9ad97a64cbe48feb1028356b836b47b8f1748"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.7"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e36fccf3fc58563b4a14d265027c627c3b665d7fed489427e88e7cc929559efe"
|
||||
checksum = "77408a692f1f97bcc61dc001d752e00643408fbc922e4d634c655df50d595556"
|
||||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
"proc-macro2",
|
||||
@ -393,24 +405,24 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.7"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e3ca3f17d6e8804ae5d3df7a7d35b2b3a6fe89dac84b31872720fc3060a0b11"
|
||||
checksum = "f878195a49cee50e006b02b93cf7e0a95a38ac7b776b4c4d9cc1207cd20fcb3d"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.7"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96d502af37186c4fef99453df03e374683f8a1eec9dcc1e66b3b82dc8278ce3c"
|
||||
checksum = "7c554eb5bf48b2426c4771ab68c6b14468b6e76cc90996f528c3338d761a4d0d"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.7"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abcb44342f62e6f3e8ac427b8aa815f724fd705dfad060b18ac7866c15bb8e34"
|
||||
checksum = "d304cff4a7b99cfb7986f7d43fbe93d175e72e704a8860787cc95e9ffd85cbd2"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-macro",
|
||||
@ -603,7 +615,7 @@ checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656"
|
||||
dependencies = [
|
||||
"log",
|
||||
"mio",
|
||||
"miow 0.3.5",
|
||||
"miow 0.3.6",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
@ -632,9 +644,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "miow"
|
||||
version = "0.3.5"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07b88fb9795d4d36d62a012dfbf49a8f5cf12751f36d31a9dbe66d528e58979e"
|
||||
checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897"
|
||||
dependencies = [
|
||||
"socket2",
|
||||
"winapi 0.3.9",
|
||||
@ -692,16 +704,16 @@ dependencies = [
|
||||
"serde_json",
|
||||
"sha1",
|
||||
"sha2",
|
||||
"time 0.2.22",
|
||||
"time 0.2.23",
|
||||
"twox-hash",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.4"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b0d88c06fe90d5ee94048ba40409ef1d9315d86f6f38c2efdaad4fb50c58b2d"
|
||||
checksum = "6fcc7939b5edc4e4f86b1b4a04bb1498afaaf871b1a6691838ed06fcb48d3a3f"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"libc",
|
||||
@ -764,9 +776,9 @@ checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.4.1"
|
||||
version = "1.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad"
|
||||
checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
@ -1030,9 +1042,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "0.4.4"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64808902d7d99f78eaddd2b4e2509713babc3dc3c85ad6f4c447680f3c01e535"
|
||||
checksum = "c1759c2e3c8580017a484a7ac56d3abc5a6c1feadf88db2f3633f12ae4268c69"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"core-foundation",
|
||||
@ -1043,9 +1055,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "0.4.3"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17bf11d99252f512695eb468de5516e5cf75455521e69dfe343f3b74e4748405"
|
||||
checksum = "f99b9d5e26d2a71633cc4f2ebae7cc9f874044e0c351a27e17892d76dce5678b"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
@ -1071,6 +1083,9 @@ name = "serde"
|
||||
version = "1.0.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
@ -1120,9 +1135,9 @@ checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.3.15"
|
||||
version = "0.3.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1fa70dc5c8104ec096f4fe7ede7a221d35ae13dcd19ba1ad9a81d2cab9a1c44"
|
||||
checksum = "7fd8b795c389288baa5f355489c65e71fd48a02104600d15c4cfbc561e9e429d"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"libc",
|
||||
@ -1132,9 +1147,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "standback"
|
||||
version = "0.2.11"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4e0831040d2cf2bdfd51b844be71885783d489898a192f254ae25d57cce725c"
|
||||
checksum = "cf906c8b8fc3f6ecd1046e01da1d8ddec83e48c8b08b84dcc02b585a6bedf5a8"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
@ -1273,9 +1288,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.2.22"
|
||||
version = "0.2.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55b7151c9065e80917fbf285d9a5d1432f60db41d170ccafc749a136b41a93af"
|
||||
checksum = "bcdaeea317915d59b2b4cd3b5efcd156c309108664277793f5351700c02ce98b"
|
||||
dependencies = [
|
||||
"const_fn",
|
||||
"libc",
|
||||
@ -1311,15 +1326,24 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "0.3.4"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "238ce071d267c5710f9d31451efec16c5ee22de34df17cc05e56cbc92e967117"
|
||||
checksum = "b78a366903f506d2ad52ca8dc552102ffdd3e937ba8a227f024dc1d1eae28575"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "0.2.22"
|
||||
version = "0.2.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd"
|
||||
checksum = "a6d7ad61edd59bfcc7e80dababf0f4aed2e6d5e0ba1659356ae889752dfc12ff"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
@ -1337,9 +1361,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "0.2.5"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389"
|
||||
checksum = "e44da00bfc73a25f814cd8d7e57a68a5c31b74b3152a0a1d1f590c97ed06265a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -1398,9 +1422,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.13"
|
||||
version = "0.1.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977"
|
||||
checksum = "f1e9a0b71dba18b6fa17c7b3dcf1440bb3522552deb2f84bf47dabd9fb7e5570"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
@ -1413,10 +1437,11 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.1.1"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb"
|
||||
checksum = "5909f2b0817350449ed73e8bcd81c8c3c8d9a7a5d8acba4b27db277f1868976e"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
|
@ -9,4 +9,8 @@ edition = "2018"
|
||||
[dependencies]
|
||||
mysql_async = "0.23.1"
|
||||
async-trait = "0.1.40"
|
||||
serde = "1.0.117"
|
||||
|
||||
serde_json = "1.0"
|
||||
serde = { version = "1.0.117", features = [ "derive" ] }
|
||||
|
||||
chrono = "0.4.0"
|
||||
|
@ -10,7 +10,6 @@ use crate::{sql_err, no_conn, Response};
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Serialize)]
|
||||
pub struct Channel {
|
||||
pub id: UBigInt,
|
||||
@ -185,7 +184,8 @@ impl Channel {
|
||||
Err(_) => Response::Empty
|
||||
};
|
||||
}
|
||||
return Response::Other("Could fetch new channel".into());
|
||||
// TODO: change this to return Result<> which should help with ambiguity
|
||||
return Response::Other("Could not fetch new channel".into());
|
||||
}
|
||||
return Response::Other(no_conn!("db::channels::add"))
|
||||
}
|
||||
|
@ -15,6 +15,11 @@ macro_rules! no_conn {
|
||||
macro_rules! sql_err {
|
||||
($spec:literal) => {
|
||||
format!("[ SQL Error ] : {}", $spec)
|
||||
};
|
||||
|
||||
// Using this mostly to pull in sql err types from lib to outside world for logging
|
||||
($exp:expr) => {
|
||||
format!("[ SQL Error ] : {}", $exp)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,9 @@ impl FromDB<Invite, bool> for Invite {
|
||||
type Row = Option<(BigInt, Option<BigInt>, bool)>;
|
||||
|
||||
async fn get(p: &Pool, id: UBigInt) -> Response<Self> {
|
||||
// NOTE: cast is required for this as `id` is used as unix timestamp
|
||||
let id: BigInt = id as BigInt;
|
||||
|
||||
if id <= 0 {
|
||||
return Response::Empty;
|
||||
}
|
||||
|
@ -4,11 +4,14 @@ use mysql_async::error::Error as SqlError;
|
||||
|
||||
use async_trait::async_trait;
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{Response, no_conn, sql_err};
|
||||
use crate::{UBigInt, BigInt, Integer, VarChar};
|
||||
|
||||
use crate::common::{FromDB};
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Member {
|
||||
pub id: UBigInt,
|
||||
pub secret: VarChar,
|
||||
@ -61,33 +64,22 @@ impl FromDB<Member, Integer> for Member {
|
||||
let q = r#"UPDATE members
|
||||
SET status = :status, permissions = :perms, name = :name
|
||||
WHERE id = :id"#;
|
||||
// TODO: remoev this retarded extra network hit
|
||||
// technically this is really nice for the user but ultimately it either works or it
|
||||
// doesn't so like the fucks the point of doing some bs like this
|
||||
// the next a client queries this they'll get whatever data is in the db
|
||||
// likewise clients are going likely going to re-get this data since its been updated
|
||||
// or at least should
|
||||
|
||||
if let Ok(conn) = p.get_conn().await {
|
||||
match Member::get(p, row.id).await {
|
||||
Response::Row(_) => {
|
||||
let db_result: Result<Conn, SqlError>
|
||||
= conn.drop_exec(q, params!{
|
||||
let query = conn.drop_exec(q, params!{
|
||||
"id" => row.id,
|
||||
"status" => row.status,
|
||||
"name" => row.name,
|
||||
"perms" => row.permissions
|
||||
}).await;
|
||||
match db_result {
|
||||
Ok(_) => return Response::Success,
|
||||
Err(_) => return Response::Other(sql_err!("WARN member found | Member::FromDB::update failed - "))
|
||||
}
|
||||
},
|
||||
Response::Empty => return Response::Empty,
|
||||
Response::Other(msg) => return Response::Other(msg),
|
||||
_ => return Response::Other(sql_err!("Member::FromD::update Bro i dont even"))
|
||||
|
||||
return match query {
|
||||
Ok(_) => Response::Success,
|
||||
Err(err) => Response::Other(sql_err!(err))
|
||||
}
|
||||
}
|
||||
return Response::Other(no_conn!("Member::FromDB::update"));
|
||||
|
||||
return Response::Other(no_conn!("db::Member::update"));
|
||||
}
|
||||
|
||||
async fn delete(p: &Pool, id: UBigInt) -> Response<Self> {
|
||||
@ -151,3 +143,69 @@ impl FromDB<Member, Integer> for Member {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Member {
|
||||
pub async fn add(p: &Pool, name: &str, secret: &str, perms: u64) -> Result<Response<Self>, SqlError> {
|
||||
//! @param {pool}
|
||||
//! @param {&str}
|
||||
//! @param {&str}
|
||||
//! @param {u64}
|
||||
|
||||
//! @returns : on_succes => Ok(Response<Member>)
|
||||
//! @returns : on_partial_succes => Ok(Response<Member>)
|
||||
//! @returns : on_failure => Err(SomeBS)
|
||||
use chrono::Utc;
|
||||
|
||||
let conn = p.get_conn().await?;
|
||||
|
||||
//name
|
||||
//perms
|
||||
//secret
|
||||
let now: BigInt = Utc::now().timestamp();
|
||||
|
||||
|
||||
let conn = conn.drop_exec(
|
||||
"INSERT INTO members(secret, name, joindate, status, permissions)
|
||||
VALUES(:secret, :name, :joindate, :status, :permissions)",
|
||||
mysql_async::params!{
|
||||
"secret" => secret.clone(),
|
||||
"name" => name.clone(),
|
||||
"joindate" => now,
|
||||
"status" => STATUS_ONLINE,
|
||||
"permissions" => perms
|
||||
}).await?;
|
||||
|
||||
let (_, opt_id): (Conn, Option<UBigInt>) = 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: id,
|
||||
secret: secret.into(),
|
||||
name: name.into(),
|
||||
joindate: now,
|
||||
status: STATUS_ONLINE,
|
||||
permissions: perms
|
||||
}))
|
||||
}
|
||||
|
||||
return Ok(Response::Empty);
|
||||
}
|
||||
|
||||
pub async fn update_perms(p: &Pool, uid: UBigInt, permissions: UBigInt) -> Result<UBigInt, SqlError> {
|
||||
//! @return on_sucess Ok(NewPermisionsMask)
|
||||
//!
|
||||
let conn = p.get_conn().await?;
|
||||
conn.drop_exec(
|
||||
"UPDATE members SET permissions = :perms WHERE id = :id",
|
||||
params!{
|
||||
"id" => uid,
|
||||
"perms" => permissions
|
||||
}).await?;
|
||||
|
||||
Ok(permissions)
|
||||
}
|
||||
}
|
||||
|
@ -112,3 +112,27 @@ impl FromDB<Message, (BigInt, UBigInt)> for Message {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Message {
|
||||
pub async fn send(p: &Pool, content: &str, cid: UBigInt, uid: UBigInt) -> Result<Response<Self>, SqlError> {
|
||||
//! @returns on_sucess -> empty
|
||||
//! @returns on_failure Err(SqlErr)
|
||||
|
||||
use chrono::Utc;
|
||||
let conn = p.get_conn().await?;
|
||||
let q = "INSERT INTO messages
|
||||
(time, content, author_id, channel_id)
|
||||
VALUES (:time, :content, :author, :channel)";
|
||||
let now = Utc::now().timestamp();
|
||||
|
||||
conn.prep_exec(q, params!{
|
||||
"time" => now,
|
||||
"content" => content,
|
||||
"author" => uid,
|
||||
"channel" => cid
|
||||
}).await?;
|
||||
|
||||
return Ok(Response::Empty);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 auto_increment,
|
||||
`secret` varchar(256) NOT NULL,
|
||||
`name` varchar(256) NOT NULL,
|
||||
`joindate` bigint NOT NULL,
|
||||
|
@ -4,6 +4,8 @@ CREATE TABLE IF NOT EXISTS `messages`(
|
||||
`time` BIGINT NOT NULL,
|
||||
`content` VARCHAR(2048) NOT NULL,
|
||||
`author_id` BIGINT UNSIGNED NOT NULL,
|
||||
`channel_id` BIGINT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
FOREIGN KEY (`author_id`) REFERENCES members(`id`) ON DELETE CASCADE
|
||||
FOREIGN KEY (`author_id`) REFERENCES members(`id`),
|
||||
FOREIGN KEY (`channel_id`) REFERENCES channels(`id`)
|
||||
);
|
||||
|
@ -4,13 +4,16 @@ use hyper::{Response, Body};
|
||||
use hyper::StatusCode;
|
||||
|
||||
use mysql_async::Pool;
|
||||
use mysql_async::error::Error as SqlError;
|
||||
use mysql_async::prelude::Queryable;
|
||||
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::perms::ADMIN_PERMS;
|
||||
|
||||
use db::{
|
||||
self,
|
||||
member::Member
|
||||
};
|
||||
|
||||
macro_rules! get_target_id {
|
||||
($obj:expr) => {
|
||||
match $obj.get("target-id") {
|
||||
@ -20,24 +23,15 @@ macro_rules! get_target_id {
|
||||
}
|
||||
}
|
||||
|
||||
async fn modify_perms(p: &Pool, uid: u64, new_perms: u64) -> Result<(), SqlError>{
|
||||
use mysql_async::params;
|
||||
let conn = p.get_conn().await?;
|
||||
conn.prep_exec(
|
||||
"UPDATE members SET permissions = :perms WHERE id = :id",
|
||||
params!{
|
||||
"id" => uid,
|
||||
"perms" => new_perms
|
||||
}).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn new_admin(p: &Pool, response: &mut Response<Body>, params: Value) {
|
||||
// @requires: owner level permission as regular admins can have conflict of interests
|
||||
// @user-param: "target-id": Number
|
||||
|
||||
if let Some(uid) = get_target_id!(params) {
|
||||
let _ = modify_perms(p, uid, ADMIN_PERMS).await;
|
||||
|
||||
if let Err(e) = Member::update_perms(p, uid, ADMIN_PERMS).await {
|
||||
eprintln!("{}", e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// this is likely the users fault providing shit ass json
|
||||
@ -46,32 +40,21 @@ pub async fn new_admin(p: &Pool, response: &mut Response<Body>, params: Value) {
|
||||
}
|
||||
}
|
||||
|
||||
async fn update_member_permissions(p: &Pool, uid: u64, perms: u64) -> Result<(), SqlError>{
|
||||
use mysql_async::params;
|
||||
let conn = p.get_conn().await?;
|
||||
conn.prep_exec(
|
||||
"UPDATE members permissions = :perms WHERE id = :id",
|
||||
params!{
|
||||
"id" => uid,
|
||||
"perms" => perms
|
||||
}
|
||||
).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn set_permissions(p: &Pool, response: &mut Response<Body>, params: Value) {
|
||||
// @requiresL: admin level permissions, admins can't touch other admins
|
||||
let tuid = get_target_id!(params);
|
||||
|
||||
let new_perms = match params.get("permissions") {
|
||||
let new_perms_opt = match params.get("permissions") {
|
||||
Some(val) => val.as_u64(),
|
||||
None => None
|
||||
};
|
||||
|
||||
match (tuid, new_perms) {
|
||||
(Some(uid), Some(perms)) => {
|
||||
if let Ok(_) = update_member_permissions(p, uid, perms).await {
|
||||
match (tuid, new_perms_opt) {
|
||||
(Some(uid), Some(new_perms)) => {
|
||||
// Returns Ok(Response::sucess) | Err(log)
|
||||
if let Err(e) = Member::update_perms(p, uid, new_perms).await {
|
||||
eprintln!("{}", e); // wil be some sql error
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
|
@ -9,7 +9,6 @@ use db::{member::Member, common::FromDB};
|
||||
use db::Response;
|
||||
|
||||
// used when we create a new users for the first time
|
||||
pub const BCRYPT_COST: u32 = 14;
|
||||
pub enum AuthReason {
|
||||
Good, //passed regular check
|
||||
OpenAuth, // route does not require auth
|
||||
|
@ -57,9 +57,13 @@ pub async fn create_channel(pool: &Pool, response: &mut Response<Body>, params:
|
||||
|
||||
*response.body_mut() = Body::from(to_string(&row).unwrap_or("{}".into()));
|
||||
},
|
||||
db::Response::Empty => {},
|
||||
db::Response::Other(msg) => {},
|
||||
_ => {*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;}
|
||||
db::Response::Empty => *response.status_mut() = StatusCode::NOT_FOUND,
|
||||
// TODO: loggin
|
||||
db::Response::Other(msg) => {
|
||||
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
|
||||
eprintln!("\t{}", msg);
|
||||
}
|
||||
_ => *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR
|
||||
}
|
||||
},
|
||||
// basically one of the parameter gets failed so we bail on all of this
|
||||
@ -74,8 +78,14 @@ pub async fn delete_channel(pool: &Pool, response: &mut Response<Body>, params:
|
||||
// TODO: something more intelligent with the logging im ngl
|
||||
match Channel::delete(pool, id).await {
|
||||
db::Response::Success => {},
|
||||
db::Response::Other(data) => println!("\t{}", data),
|
||||
_ => {}
|
||||
db::Response::Other(data) => {
|
||||
eprintln!("\t{}", data);
|
||||
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
_ => {
|
||||
eprintln!("\tBro like restart the server");
|
||||
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -87,87 +97,3 @@ pub async fn delete_channel(pool: &Pool, response: &mut Response<Body>, params:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod channels_tests {
|
||||
use crate::testing::{get_pool, hyper_resp};
|
||||
use serde_json::Value;
|
||||
use hyper::StatusCode;
|
||||
const DUMMY_TRANSIENT_CHANNEL: &'static str = "sample channel";
|
||||
|
||||
#[tokio::test]
|
||||
async fn list_all_channels_good() {
|
||||
// Generation of data
|
||||
let p = get_pool();
|
||||
let mut resp = hyper_resp();
|
||||
// @params: none
|
||||
// Collection of data
|
||||
super::list_channels(&p, &mut resp).await;
|
||||
|
||||
// Analysis
|
||||
assert_eq!(StatusCode::OK, resp.status());
|
||||
println!("list_all_channels_good : \t{:?}", resp.body());
|
||||
let _ = p.disconnect().await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn delete_and_create_channel_good() {
|
||||
use chrono::Utc;
|
||||
let p = get_pool();
|
||||
let mut resp = hyper_resp();
|
||||
// @params: name + kind + [description]
|
||||
let cname_id = Utc::now();
|
||||
let params: Value = serde_json::from_str(&format!(r#"
|
||||
{{
|
||||
"name": "{}-{}",
|
||||
"kind": 2,
|
||||
"description": "some random bs"
|
||||
}}
|
||||
"#, DUMMY_TRANSIENT_CHANNEL, cname_id)).unwrap();
|
||||
|
||||
super::create_channel(&p, &mut resp, params).await;
|
||||
|
||||
println!("CREATE CHANNEL: {:?}", resp.body());
|
||||
assert_eq!(StatusCode::OK, resp.status());
|
||||
|
||||
|
||||
// clean up and hopefully delete the channel properly
|
||||
let mut resp_delete = hyper_resp();
|
||||
let params_delete: Value = serde_json::from_str(&format!(r#"
|
||||
{{
|
||||
"name": "{}-{}"
|
||||
}}
|
||||
"#, DUMMY_TRANSIENT_CHANNEL, cname_id)).unwrap();
|
||||
println!("Parameters: {}", params_delete);
|
||||
super::delete_channel(&p, &mut resp_delete, params_delete).await;
|
||||
|
||||
println!("Body: {:?}", resp.body());
|
||||
let _ = p.disconnect().await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn delete_channel_missing_name() {
|
||||
let p = get_pool();
|
||||
let mut resp = hyper_resp();
|
||||
// this endpoint is super lenient for some reason btw
|
||||
let param: Value = serde_json::from_str("{}").expect("JSON is not written correctly");
|
||||
|
||||
super::delete_channel(&p, &mut resp, param).await;
|
||||
|
||||
assert_eq!(StatusCode::BAD_REQUEST, resp.status());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn delet_channel_non_real_channel() {
|
||||
let p = get_pool();
|
||||
let mut resp = hyper_resp();
|
||||
// this endpoint is super lenient for some reason btw
|
||||
let param: Value = serde_json::from_str(r#"{
|
||||
"name": "this channel doesn't exist"
|
||||
}"#).expect("JSON is not written correctly");
|
||||
|
||||
super::delete_channel(&p, &mut resp, param).await;
|
||||
|
||||
assert_eq!(StatusCode::OK, resp.status());
|
||||
}
|
||||
}
|
||||
|
@ -11,11 +11,13 @@ use hyper::{Response, Body, StatusCode};
|
||||
use chrono::Utc;
|
||||
|
||||
use db::{UBigInt, BigInt};
|
||||
use crate::members::{self, Member};
|
||||
use db::common::FromDB;
|
||||
use db::member::Member;
|
||||
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Invite {
|
||||
id: BigInt,
|
||||
id: BigInt, // doubles as the timestamp for when it dies
|
||||
uses: Option<BigInt>, // optional because some links are permanent
|
||||
expires: bool,
|
||||
}
|
||||
@ -25,34 +27,33 @@ struct Invite {
|
||||
* are of the enum mysql_async::error::Error
|
||||
*/
|
||||
|
||||
async fn valid_invite(pool: &Pool, id: BigInt) -> Result<bool, Error>{
|
||||
async fn valid_invite(pool: &Pool, id: BigInt) -> bool {
|
||||
/*
|
||||
* Fetches an invite from the database to check for validity
|
||||
*/
|
||||
let conn = pool.get_conn().await?;
|
||||
let db_fetch_result: (Conn, Option<(Option<BigInt>, bool)>) =
|
||||
conn.first_exec("SELECT uses, expires FROM invites WHERE id = :id",
|
||||
params!{"id" => id}).await?;
|
||||
let query: Option<db::invites::Invite> = match db::invites::Invite::get(pool, id as u64).await {
|
||||
db::Response::Row(invite) => { Some(invite) },
|
||||
_ => { None }
|
||||
};
|
||||
|
||||
if let Some(row) = db_fetch_result.1 {
|
||||
if let Some(invite) = query {
|
||||
// if expires at all
|
||||
if row.1 {
|
||||
if invite.expires {
|
||||
let now = Utc::now().timestamp();
|
||||
// old?
|
||||
let mut status = now > id;
|
||||
let mut valid_status = now > invite.id;
|
||||
// used?
|
||||
if row.0.is_some() && status == false {
|
||||
status = row.0.unwrap() <= 0; // safe unwrap since we know its Some(_)
|
||||
if invite.uses.is_some() && valid_status == false {
|
||||
valid_status = invite.uses.unwrap() <= 0; // safe unwrap since we know its Some(_)
|
||||
}
|
||||
return Ok(status)
|
||||
return valid_status
|
||||
}
|
||||
// no expiry date? no problem
|
||||
return Ok(true);
|
||||
return true
|
||||
}
|
||||
|
||||
// prolly not a real id
|
||||
else {
|
||||
return Ok(false);
|
||||
}
|
||||
return false
|
||||
|
||||
}
|
||||
|
||||
@ -60,26 +61,30 @@ async fn use_invite(pool: &Pool, code: Option<BigInt>) -> Option<Member>{
|
||||
/*
|
||||
* Attempts to change the state of the current invite being provided
|
||||
*/
|
||||
use crate::auth;
|
||||
use crate::perms::GENERAL_NEW;
|
||||
let id = match code {
|
||||
Some(id) => id,
|
||||
None => 0
|
||||
};
|
||||
|
||||
if let Ok(valid) = valid_invite(pool, id).await {
|
||||
if valid {
|
||||
match members::insert_new_member(pool, "Anonymous".into(), GENERAL_NEW).await {
|
||||
Ok(member) => return Some(member),
|
||||
// some random comment
|
||||
if valid_invite(pool, id).await {
|
||||
let secret = auth::generate_secret();
|
||||
return match db::member::Member::add(pool, "Anonymous".into(), &secret, GENERAL_NEW).await {
|
||||
Ok(response) => {
|
||||
match response {
|
||||
db::Response::Row(member) => Some(member),
|
||||
_ => None,
|
||||
}
|
||||
},
|
||||
// TODO: logggin or something idk
|
||||
Err(_) => return None
|
||||
}
|
||||
}
|
||||
else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn join(pool: &Pool, response: &mut Response<Body>, params: Value) {
|
||||
@ -90,7 +95,6 @@ pub async fn join(pool: &Pool, response: &mut Response<Body>, params: Value) {
|
||||
Some(val) => val.as_i64(),
|
||||
None => None
|
||||
};
|
||||
|
||||
match use_invite(&pool, code).await {
|
||||
Some(new_account) => *response.body_mut() = Body::from(serde_json::to_string(&new_account).unwrap()),
|
||||
None => {
|
||||
|
@ -207,9 +207,25 @@ OPTIONS:
|
||||
if let Some(owner_name) = args.value_of("create-owner") {
|
||||
let p = Pool::new(&env::var("DATABASE_URL").unwrap());
|
||||
eprintln!("Creating owner {{ {} }}...", owner_name);
|
||||
if let Ok(owner) = members::insert_new_member(&p, owner_name.to_string(), std::u64::MAX).await {
|
||||
println!("{}", serde_json::to_string(&owner).unwrap());
|
||||
let owner_secret = auth::generate_secret();
|
||||
// creation of owner should just dump straight to stdout since this fires
|
||||
// from a commandline parameter anyway
|
||||
match db::member::Member::add(&p, "owner sama uwu", &owner_secret, perms::OWNER).await {
|
||||
Ok(response) => {
|
||||
match response {
|
||||
db::Response::Row(owner) =>
|
||||
println!("{}", serde_json::to_string(&owner).expect("SQL query passed but serde couldn't parse the data for some reason")),
|
||||
db::Response::Empty => {
|
||||
eprintln!("SQL server failed to return owner data, check configs and also the members table to make sure there's nothing there by accident");
|
||||
},
|
||||
_ => {}
|
||||
};
|
||||
},
|
||||
Err(_) => {
|
||||
eprintln!("Could not communicate with the SQL server, check your configs!");
|
||||
}
|
||||
}
|
||||
//println!("{}", serde_json::to_string(&owner).unwrap());
|
||||
p.disconnect();
|
||||
}
|
||||
|
||||
|
@ -1,86 +1,22 @@
|
||||
use chrono::Utc;
|
||||
use hyper::{Response, Body};
|
||||
use mysql_async::{Conn, Pool, error::Error as SqlError};
|
||||
use mysql_async::prelude::{params, Queryable};
|
||||
use serde::Serialize;
|
||||
use hyper::{Response, Body, StatusCode};
|
||||
use hyper::header::HeaderValue;
|
||||
use mysql_async::Pool;
|
||||
|
||||
use db::{UBigInt, BigInt, Integer, VarChar};
|
||||
use db::member::STATUS_ONLINE;
|
||||
use crate::auth;
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Member {
|
||||
pub id: UBigInt,
|
||||
pub secret: VarChar,
|
||||
pub name: VarChar,
|
||||
pub joindate: BigInt,
|
||||
pub status: Integer,
|
||||
pub permissions: UBigInt,
|
||||
}
|
||||
|
||||
|
||||
pub async fn insert_new_member(p: &Pool, name: VarChar, perms: u64) -> Result<Member, SqlError> {
|
||||
use crate::auth::generate_secret;
|
||||
|
||||
let conn: Conn = p.get_conn().await?;
|
||||
let secret_raw: String = generate_secret();
|
||||
let secret = match bcrypt::hash(&secret_raw, auth::BCRYPT_COST) {
|
||||
Ok(value) => value,
|
||||
Err(e) => panic!("\tCould not insert member due to bcrypt failure:\n\t\t{}",e)
|
||||
};
|
||||
let now: BigInt = Utc::now().timestamp();
|
||||
|
||||
let conn = conn.drop_exec(
|
||||
"INSERT INTO members(secret, name, joindate, status, permissions)
|
||||
VALUES(:secret, :name, :joindate, :status, :permissions)",
|
||||
mysql_async::params!{
|
||||
"secret" => secret.clone(),
|
||||
"name" => name.clone(),
|
||||
"joindate" => now,
|
||||
"status" => STATUS_ONLINE,
|
||||
"permissions" => perms
|
||||
}).await?;
|
||||
|
||||
// now pull back the user from our db and return that row
|
||||
let db_row_result: (Conn, Option<UBigInt>) = conn.first_exec(
|
||||
"SELECT id FROM members WHERE secret = :secret",
|
||||
params!{
|
||||
"secret" => secret.clone()
|
||||
}).await?;
|
||||
|
||||
Ok(Member {
|
||||
id: db_row_result.1.unwrap(), // if we made it this far this shouldn't fail (i hope)
|
||||
secret: secret_raw,
|
||||
name: name,
|
||||
joindate: now,
|
||||
status: 0,
|
||||
permissions: perms
|
||||
})
|
||||
}
|
||||
|
||||
async fn select_online_default(p: &Pool) -> Result<Vec<(UBigInt, VarChar)>, SqlError> {
|
||||
let conn = p.get_conn().await?;
|
||||
let q = format!("SELECT id, name FROM members WHERE status = {} LIMIT 100", STATUS_ONLINE);
|
||||
let data = conn.prep_exec(&q, ()).await?;
|
||||
let (_, users) = data.map_and_drop(|row| {
|
||||
let (id, nickname): (UBigInt, VarChar) = mysql_async::from_row(row);
|
||||
(id, nickname)
|
||||
}).await?;
|
||||
|
||||
return Ok(users);
|
||||
}
|
||||
use db::common::FromDB;
|
||||
|
||||
pub async fn get_online_members(p: &Pool, response: &mut Response<Body>) {
|
||||
/*
|
||||
* Json {
|
||||
* "members": [...],
|
||||
* "start": 0,
|
||||
* "count": 100
|
||||
* }
|
||||
*/
|
||||
if let Ok(list) = select_online_default(p).await {
|
||||
// unwrap_or`ing for serde_json since it shouldn't fail in theory(on paper)
|
||||
*response.body_mut() = Body::from(serde_json::to_string(&list).unwrap_or("[]".into()));
|
||||
// TODO: at some point we should provide a way of not querying literally every user in
|
||||
// existance
|
||||
// TODO: loggin at some point or something idklol
|
||||
return match db::channels::Channel::filter(p, STATUS_ONLINE).await {
|
||||
db::Response::Set(users) => {
|
||||
response.headers_mut().insert("Content-Type",
|
||||
HeaderValue::from_static("application/json"));
|
||||
|
||||
*response.body_mut() = Body::from(serde_json::to_string(&users).unwrap_or("[]".into()));
|
||||
},
|
||||
db::Response::Other(_msg) => *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR,
|
||||
_ => *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR
|
||||
}
|
||||
println!("fuck bro");
|
||||
}
|
||||
|
@ -1,78 +1,35 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use mysql_async::{Pool, params};
|
||||
use mysql_async::prelude::{Queryable};
|
||||
use mysql_async::error::Error;
|
||||
use mysql_async::Pool;
|
||||
use hyper::{Response, Body, StatusCode};
|
||||
use serde_json::Value;
|
||||
use chrono::Utc;
|
||||
|
||||
use db::UBigInt;
|
||||
|
||||
|
||||
pub async fn insert_message(pool: &Pool, content: &Value, channel_name: &Value, author_id: UBigInt)
|
||||
-> Result<(), Error>{
|
||||
match (content.as_str(), channel_name.as_str()) {
|
||||
(Some(content), Some(channel)) => {
|
||||
let conn = pool.get_conn().await?;
|
||||
let time = Utc::now().timestamp();
|
||||
conn.prep_exec(
|
||||
r"INSERT INTO messages
|
||||
(time, content, author_id, channel_name)
|
||||
VALUES(:time, :content, :author, :channel)",
|
||||
params!{
|
||||
"time" => time,
|
||||
"content" => content,
|
||||
"author" => author_id,
|
||||
"channel" => channel
|
||||
}).await?;
|
||||
Ok(())
|
||||
}
|
||||
_ => {
|
||||
let e = Cow::from("Required parameter missing");
|
||||
Err(Error::Other(e))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn send_message(pool: &Pool, response: &mut Response<Body>, params: Value) {
|
||||
/*
|
||||
* @content: expecting string type
|
||||
* @id: expecting the channel id that we're posting data to
|
||||
* @channel: channel id that we're going to send a message to
|
||||
*/
|
||||
let content_r = params.get("content");
|
||||
let channel_name_r = params.get("channel");
|
||||
// auth module guarantees this will be there in the correct form
|
||||
// NOTE: auth module guarantees this will be there in the correct form
|
||||
let author = params.get("id")
|
||||
.unwrap().as_u64().unwrap();
|
||||
|
||||
match (content_r, channel_name_r) {
|
||||
(Some(content), Some(channel_name)) => {
|
||||
match insert_message(pool, content, channel_name, author).await {
|
||||
Ok(_) => *response.status_mut() = StatusCode::OK,
|
||||
Err(err) => {
|
||||
use mysql_async::error::Error::{Server};
|
||||
println!("\tDB Error::send_message: {:?}", err);
|
||||
// doing this to avoid client confusion as some input does cause sql errors
|
||||
if let Server(se) = err {
|
||||
if se.code == 1452 {
|
||||
match (params.get("content") , params.get("channel")) {
|
||||
(Some(content_v), Some(channel_id_v)) => {
|
||||
let (content, channel) = (content_v.as_str(), channel_id_v.as_u64());
|
||||
|
||||
if let (Some(message), Some(cid)) = (content, channel) {
|
||||
// call returns empty on sucess so we don't need to do anything
|
||||
// TODO: loggin
|
||||
if let Err(issue) = db::messages::Message::send(pool, message, cid, author).await {
|
||||
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
|
||||
eprintln!("\t{}", issue);
|
||||
}
|
||||
// if there's no issue then we don't need to do anything at all
|
||||
}
|
||||
else {
|
||||
*response.status_mut() = StatusCode::BAD_REQUEST;
|
||||
*response.body_mut() = Body::from(format!("{} does not exist", channel_name));
|
||||
}
|
||||
else {
|
||||
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
*response.status_mut() = StatusCode::BAD_REQUEST;
|
||||
*response.body_mut() = Body::from("content/channel missing from json parameters");
|
||||
}
|
||||
_ => *response.status_mut() = StatusCode::BAD_REQUEST
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,46 +60,5 @@ mod messaging_tests {
|
||||
assert_ne!(StatusCode::OK, resp.status());
|
||||
}
|
||||
|
||||
#[tokio::test]#[ignore]
|
||||
async fn send_message_good() {
|
||||
use crate::members::insert_new_member;
|
||||
use crate::perms::GENERAL_NEW;
|
||||
use mysql_async::params;
|
||||
use mysql_async::prelude::Queryable;
|
||||
use crate::testing::tmp_channel_params;
|
||||
|
||||
let p = get_pool();
|
||||
let mut resp = hyper_resp();
|
||||
|
||||
let tmp_chan = tmp_channel_params(&p, "sample").await;
|
||||
|
||||
const TMP_NAME: &'static str = "bs user";
|
||||
let temp_member = insert_new_member(&p, TMP_NAME.into(), GENERAL_NEW).await.unwrap();
|
||||
|
||||
|
||||
let params: Value = serde_json::from_str(&format!(r#"
|
||||
{{
|
||||
"id": {},
|
||||
"channel": "{}",
|
||||
"content": "bs message"
|
||||
}}
|
||||
"#, temp_member.id, tmp_chan.name)).unwrap();
|
||||
|
||||
super::send_message(&p, &mut resp, params).await;
|
||||
|
||||
if resp.status() == StatusCode::BAD_REQUEST {
|
||||
panic!("{:?}", resp.body());
|
||||
}
|
||||
|
||||
// Destroy the the message and the user that we created
|
||||
let conn = match p.get_conn().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => panic!("Could not get connection to db during send_message_good:\nIssue:\t{}", e)
|
||||
};
|
||||
|
||||
let conn = conn.drop_exec("DELETE FROM messages WHERE author_id = :id", params!{"id" => temp_member.id}).await.unwrap();
|
||||
let conn = conn.drop_exec("DELETE FROM members WHERE id = :id", params!{"id" => temp_member.id}).await.unwrap();
|
||||
let _ = conn.drop_exec("DELETE FROM channels WHERE name = :name", params!{"name" => tmp_chan.name}).await;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,26 +1,31 @@
|
||||
// TODO: this whole ass module bro i mean c'mon.... just just clean it
|
||||
pub const INVITE_CREATE: &'static str = "/invite/create"; // requires none
|
||||
type Rstr = &'static str;
|
||||
|
||||
pub const CHANNELS_LIST: &'static str = "/channels/list"; // requires none
|
||||
pub const CHANNELS_CREATE: &'static str = "/channels/create"; // requires @name @kind
|
||||
pub const CHANNELS_DELETE: &'static str = "/channels/delete"; // requires @channel_id
|
||||
pub const SERVER_META: Rstr = "/meta"; // @returns server meta document TBD
|
||||
pub const INVITE_CREATE: Rstr = "/invite/create"; // @ perms::CREATE_INVITE
|
||||
|
||||
pub const MESSAGE_SEND: &'static str = "/message/send"; // requires @content
|
||||
pub const CHANNELS_LIST: Rstr = "/channels/list"; // requires none
|
||||
pub const CHANNELS_CREATE: Rstr = "/channels/create"; // requires @name @kind perms::CREATE_CHANNEl
|
||||
pub const CHANNELS_DELETE: Rstr = "/channels/delete"; // requires @name perms::DELETE_CHANNEL
|
||||
|
||||
pub const SERVER_META: &'static str = "/meta"; // open
|
||||
pub const MESSAGE_SEND: Rstr = "/message/send"; // requires @content perms::MESSAGE_SEND
|
||||
|
||||
pub const GET_ONLINE_MEMBERS: &'static str = "/members/get_online";
|
||||
// @requires: admin permissions
|
||||
//
|
||||
pub const SET_PERMS_BY_ADMIN: &'static str = "/admin/setpermisions";
|
||||
pub const SET_NEW_ADMIN: &'static str = "/owner/newadmin"; // @requiers: owner perms
|
||||
pub const GET_ONLINE_MEMBERS: Rstr = "/members/get_online";
|
||||
|
||||
|
||||
// ADMIN ROUTES
|
||||
pub const SET_PERMS_BY_ADMIN: Rstr = "/admin/setpermisions"; // @requires perms::ADMIN
|
||||
pub const SET_NEW_ADMIN: Rstr = "/owner/newadmin"; // @requiers: owner perms
|
||||
|
||||
|
||||
// TODO: here be dragons...
|
||||
// potentially adding more bases later
|
||||
pub const DYNAMIC_ROUTE_BASES: [(&'static str, bool);3] = [
|
||||
pub const DYNAMIC_ROUTE_BASES: [(Rstr, bool);3] = [
|
||||
("/join", true), // open
|
||||
("/public", true), // open : valid sections := neighbors|rules|description
|
||||
("/user", false), // TODO: valid sections := /meta/<name>|/dm/<name>
|
||||
];
|
||||
pub const DYN_JOIN: &'static str = DYNAMIC_ROUTE_BASES[0].0;
|
||||
pub const DYN_JOIN: Rstr = DYNAMIC_ROUTE_BASES[0].0;
|
||||
|
||||
pub struct DynRoute {
|
||||
pub base: String,
|
||||
|
Loading…
Reference in New Issue
Block a user