Query string parameter 'type' is now enforced by the api

+ Flag is literally called 'type'
This commit is contained in:
shockrah 2021-03-12 02:17:06 -08:00
parent dc117ba02f
commit 9ce04e96a7
4 changed files with 35 additions and 32 deletions

View File

@ -171,10 +171,10 @@ def run(worker: Worker):
message_tests = [
# bs message spam
{'init': ['post', '/message/send', {'channel_id': chan_d['id'], 'content': 'bs content'}], 'auth': jwt, 'hope': 200, 'body': True},
{'init': ['post', '/message/send', {'channel_id': chan_d['id'], 'content': 'bs content'}], 'auth': jwt, 'hope': 200},
{'init': ['post', '/message/send', {'channel_id': chan_d['id'], 'content': 'bs content'}], 'auth': jwt, 'hope': 200},
{'init': ['post', '/message/send', {'channel_id': chan_d['id'], 'content': 'bs content'}], 'auth': jwt, 'hope': 200},
{'init': ['post', '/message/send', {'type': 'text', 'channel_id': chan_d['id'], 'content': 'bs content'}], 'auth': jwt, 'hope': 200, 'body': True},
{'init': ['post', '/message/send', {'type': 'text', 'channel_id': chan_d['id'], 'content': 'bs content'}], 'auth': jwt, 'hope': 200},
{'init': ['post', '/message/send', {'type': 'text', 'channel_id': chan_d['id'], 'content': 'bs content'}], 'auth': jwt, 'hope': 200},
{'init': ['post', '/message/send', {'type': 'text', 'channel_id': chan_d['id'], 'content': 'bs content'}], 'auth': jwt, 'hope': 200},
# can we get them back tho?
{
@ -214,19 +214,14 @@ def run(worker: Worker):
],
'auth': jwt, 'hope': 200, 'body': True
},
# tests that don't follow the api's rules
{
# channel doesn't exist so a 404 seems to be inorder
'init': [
'get', '/message/from_id', {'start': 1, 'channel_id':9}
],
# Channel doesn't exist so empty vector is result
'init': [ 'get', '/message/from_id', {'start': 1, 'channel_id':9} ],
'auth': jwt, 'hope': 404
},
{
'init': [
# good channel but id is tooo high
'get', '/message/from_id', {'start': 5, 'channel_id':3}
],
# Channel id doesn't refer to a real channel
'init': [ 'get', '/message/from_id', {'start': 5, 'channel_id':3} ],
'auth': jwt, 'hope': 404
},
]

View File

@ -11,20 +11,21 @@ const MAX_MESSAGES: u64 = 1000;
impl crate::Message {
pub async fn send(p: &Pool, content: &str, cid: UBigInt, uid: UBigInt) -> Result<Response<Self>, SqlError> {
pub async fn send(p: &Pool, content: &str, content_type: &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)";
(time, content, content_type, author_id, channel_id)
VALUES (:time, :content, :ctype, :author, :channel)";
let now = Utc::now().timestamp();
let res = conn.prep_exec(q, params!{
"time" => now,
"content" => content,
"ctype" => content_type,
"author" => uid,
"channel" => cid
}).await;
@ -102,6 +103,7 @@ impl crate::Message {
pub async fn get_from_id(p: &Pool, channel_id: UBigInt, start: UBigInt, limit: Option<UBigInt>) -> Result<Response<Self>, SqlError> {
//! @returns on success : Set(Vec<Messages>)
//! @returns on user failure : RestrictedInput(String)
//! @returns on failure : Err(SqlError)
let conn = p.get_conn().await?;
let limit = if let Some(limit) = limit{

View File

@ -3,7 +3,7 @@ CREATE TABLE IF NOT EXISTS `messages`(
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`time` BIGINT NOT NULL,
`content` VARCHAR(4096) NOT NULL,
`content_type` VARCHAR NOT NULL,
`content_type` VARCHAR(10) NOT NULL,
`author_id` BIGINT UNSIGNED NOT NULL,
`channel_id` BIGINT UNSIGNED NOT NULL,
PRIMARY KEY (`id`),

View File

@ -66,6 +66,8 @@ pub async fn send_message(pool: &Pool, response: &mut Response<Body>, body: Body
// NOTE: auth module guarantees this will be there in the correct form
let uid = qs_param!(params, "id", u64).unwrap();
let ctype = params.get("type");
let permissions = match Member::get(pool, uid).await {
Row(user) => user.permissions,
_ => 0
@ -82,17 +84,24 @@ pub async fn send_message(pool: &Pool, response: &mut Response<Body>, body: Body
let content = String::from_utf8_lossy(body_bytes);
// 400 on empty bodies or missing channel id's
if content.len() == 0 || channel_id.is_none() {
if content.len() == 0 || channel_id.is_none() || ctype.is_none() {
*response.status_mut() = StatusCode::BAD_REQUEST;
} else {
match db::Message::send(pool, &content, channel_id.unwrap(), uid).await {
Ok(Empty) => {}, // nothing to do hyper defaults to 200
Ok(RestrictedInput(_msg)) => *response.status_mut() = StatusCode::BAD_REQUEST,
Ok(Other(msg)) => {
eprintln!("{}", msg);
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
},
_ => *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR
// block away wrong content types
const CONTENT_TYPES: [&'static str;7] = ["text", "png", "jpeg", "jpg", "webm", "mp3", "mp4"];
if CONTENT_TYPES.contains(&ctype.unwrap().as_str()) == false {
*response.status_mut() = StatusCode::BAD_REQUEST;
}
else {
match db::Message::send(pool, &content, ctype.unwrap(), channel_id.unwrap(), uid).await {
Ok(Empty) => {/* TODO: put something here to notify the rtc server if its there*/},
Ok(RestrictedInput(_msg)) => *response.status_mut() = StatusCode::BAD_REQUEST,
Ok(Other(msg)) => {
eprintln!("{}", msg);
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
},
_ => *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR
}
}
}
}
@ -117,14 +126,11 @@ pub async fn from_id(pool: &Pool, response: &mut Response<Body>, params: HashMap
Ok(db_response) => {
match db_response {
db::Response::Set(messages) => {
// NOTE this check is here because the db's check doesn't
// correctly with async and caching and magic idfk its here
// it works its correct and the cost is the same as putting
// it in the db layer so whatever
// *any* kind of empty response, even those from weird
// parameters get 404's
if messages.len() == 0 {
*response.status_mut() = StatusCode::NOT_FOUND;
}
else {
} else {
set_json_body(response, json!({"messages": messages}));
}
},