Data validation on sends, Start of reply chains
This commit is contained in:
@@ -5,14 +5,13 @@ use chrono::{DateTime, Utc};
|
|||||||
use moka::future::Cache;
|
use moka::future::Cache;
|
||||||
use sqlx::{FromRow, Pool, query_as, Sqlite};
|
use sqlx::{FromRow, Pool, query_as, Sqlite};
|
||||||
use sqlx::query;
|
use sqlx::query;
|
||||||
use sqlx::sqlite::SqliteQueryResult;
|
|
||||||
use tarpc::context::Context;
|
use tarpc::context::Context;
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
use realm_auth::types::RealmAuthClient;
|
use realm_auth::types::RealmAuthClient;
|
||||||
use realm_shared::types::ErrorCode::*;
|
use realm_shared::types::ErrorCode::*;
|
||||||
use realm_shared::types::ErrorCode;
|
use realm_shared::types::ErrorCode;
|
||||||
|
|
||||||
use crate::types::{Message, MessageData, RealmChat, Room, User};
|
use crate::types::{Attachment, Edit, Message, MessageData, Reaction, RealmChat, Redaction, Reply, Room, User};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct RealmChatServer {
|
pub struct RealmChatServer {
|
||||||
@@ -65,13 +64,7 @@ impl RealmChatServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(cached_username) => {
|
Some(cached_username) => cached_username.eq(userid),
|
||||||
if cached_username.eq(userid) {
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,20 +90,23 @@ impl RealmChat for RealmChatServer {
|
|||||||
format!("Hello, {name}!")
|
format!("Hello, {name}!")
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_message(self, _: Context, stoken: String, message: Message) -> Result<Message, ErrorCode> {
|
async fn send_message(self, ctx: Context, stoken: String, mut message: Message) -> Result<Message, ErrorCode> {
|
||||||
if !self.is_stoken_valid(&message.user.userid, &stoken).await {
|
if !self.is_stoken_valid(&message.user.userid, &stoken).await { // Check sender userid
|
||||||
return Err(Unauthorized)
|
return Err(Unauthorized)
|
||||||
}
|
}
|
||||||
|
|
||||||
match &message.data {
|
// Assert all the data in message is correct
|
||||||
|
message.user = self.clone().get_user(ctx, message.user.userid).await.unwrap();
|
||||||
|
|
||||||
|
match &message.data { // Check that the sender is the owner of the referencing msg
|
||||||
MessageData::Edit(e) => {
|
MessageData::Edit(e) => {
|
||||||
let ref_msg = self.get_message_from_id(tarpc::context::current(), stoken.clone(), e.referencing_id).await?;
|
let ref_msg = self.clone().get_message_from_id(ctx, stoken.clone(), e.referencing_id).await?;
|
||||||
if !ref_msg.user.userid.eq(&message.user.userid) {
|
if !ref_msg.user.userid.eq(&message.user.userid) {
|
||||||
return Err(Unauthorized)
|
return Err(Unauthorized)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MessageData::Redaction(r)=> {
|
MessageData::Redaction(r)=> {
|
||||||
let ref_msg = self.get_message_from_id(tarpc::context::current(), stoken.clone(), r.referencing_id).await?;
|
let ref_msg = self.clone().get_message_from_id(ctx, stoken.clone(), r.referencing_id).await?;
|
||||||
if !ref_msg.user.userid.eq(&message.user.userid) {
|
if !ref_msg.user.userid.eq(&message.user.userid) {
|
||||||
return Err(Unauthorized)
|
return Err(Unauthorized)
|
||||||
}
|
}
|
||||||
@@ -119,7 +115,8 @@ impl RealmChat for RealmChatServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let is_admin = self.is_user_admin(&stoken).await;
|
let is_admin = self.is_user_admin(&stoken).await;
|
||||||
let admin_only_send = query!("SELECT admin_only_send FROM room WHERE roomid = ?",
|
let admin_only_send = query!(
|
||||||
|
"SELECT admin_only_send FROM room WHERE roomid = ?",
|
||||||
message.room.roomid).fetch_one(&self.db_pool).await;
|
message.room.roomid).fetch_one(&self.db_pool).await;
|
||||||
if let Ok(record) = admin_only_send {
|
if let Ok(record) = admin_only_send {
|
||||||
if record.admin_only_send && !is_admin {
|
if record.admin_only_send && !is_admin {
|
||||||
@@ -129,6 +126,8 @@ impl RealmChat for RealmChatServer {
|
|||||||
return Err(RoomNotFound)
|
return Err(RoomNotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message.room = self.clone().get_room(ctx, stoken.clone(), message.room.roomid).await.unwrap();
|
||||||
|
|
||||||
let result = match &message.data {
|
let result = match &message.data {
|
||||||
MessageData::Text(text) => {
|
MessageData::Text(text) => {
|
||||||
query!("INSERT INTO message (timestamp, user, room, msg_type, msg_text) VALUES (?, ?, ?, 'text', ?)",
|
query!("INSERT INTO message (timestamp, user, room, msg_type, msg_text) VALUES (?, ?, ?, 'text', ?)",
|
||||||
@@ -205,6 +204,32 @@ impl RealmChat for RealmChatServer {
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn get_all_direct_replies(self, _: Context, stoken: String, head: i64) -> Result<Vec<Message>, ErrorCode> {
|
||||||
|
let mut messages: Vec<Message> = Vec::new();
|
||||||
|
|
||||||
|
let is_admin = self.is_user_admin(&stoken).await;
|
||||||
|
let result = sqlx::query("SELECT message.*,
|
||||||
|
room.id AS 'room_id', room.roomid AS 'room_roomid', room.name AS 'room_name', room.admin_only_send AS 'room_admin_only_send', room.admin_only_view AS 'room_admin_only_view',
|
||||||
|
user.id AS 'user_id', user.userid AS 'user_userid', user.name AS 'user_name', user.online AS 'user_online', user.admin AS 'user_admin'
|
||||||
|
FROM message INNER JOIN room ON message.room = room.id INNER JOIN user ON message.user = user.id WHERE message.referencing_id = ? AND room.admin_only_view = ? OR false")
|
||||||
|
.bind(head)
|
||||||
|
.bind(is_admin)
|
||||||
|
.fetch_all(&self.db_pool).await;
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(rows) => {
|
||||||
|
for row in rows {
|
||||||
|
messages.push(Message::from_row(&row).unwrap())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(_) => {
|
||||||
|
return Err(MessageNotFound)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(messages)
|
||||||
|
}
|
||||||
|
|
||||||
async fn get_rooms(self, _: Context, stoken: String) -> Result<Vec<Room>, ErrorCode> {
|
async fn get_rooms(self, _: Context, stoken: String) -> Result<Vec<Room>, ErrorCode> {
|
||||||
let is_admin = self.is_user_admin(&stoken).await;
|
let is_admin = self.is_user_admin(&stoken).await;
|
||||||
let result = query_as!(
|
let result = query_as!(
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ pub trait RealmChat {
|
|||||||
//NOTE: Any user can call, if they are in the server
|
//NOTE: Any user can call, if they are in the server
|
||||||
async fn get_message_from_id(stoken: String, id: i64) -> Result<Message, ErrorCode>;
|
async fn get_message_from_id(stoken: String, id: i64) -> Result<Message, ErrorCode>;
|
||||||
async fn get_messages_since(stoken: String, time: DateTime<Utc>) -> Result<Vec<Message>, ErrorCode>;
|
async fn get_messages_since(stoken: String, time: DateTime<Utc>) -> Result<Vec<Message>, ErrorCode>;
|
||||||
|
async fn get_all_direct_replies(stoken: String, head: i64) -> Result<Vec<Message>, ErrorCode>;
|
||||||
async fn get_rooms(stoken: String) -> Result<Vec<Room>, ErrorCode>;
|
async fn get_rooms(stoken: String) -> Result<Vec<Room>, ErrorCode>;
|
||||||
async fn get_room(stoken: String, roomid: String) -> Result<Room, ErrorCode>;
|
async fn get_room(stoken: String, roomid: String) -> Result<Room, ErrorCode>;
|
||||||
async fn get_user(userid: String) -> Result<User, ErrorCode>;
|
async fn get_user(userid: String) -> Result<User, ErrorCode>;
|
||||||
@@ -89,7 +90,7 @@ impl FromRow<'_, SqliteRow> for Message {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Maybe have multipart messages
|
//TODO: Maybe have multipart messages
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||||
pub enum MessageData {
|
pub enum MessageData {
|
||||||
Text(String),
|
Text(String),
|
||||||
Attachment(Attachment),
|
Attachment(Attachment),
|
||||||
@@ -99,35 +100,35 @@ pub enum MessageData {
|
|||||||
Redaction(Redaction), //NOTE: Have to be the owner of the referencing_guid
|
Redaction(Redaction), //NOTE: Have to be the owner of the referencing_guid
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct Attachment {
|
pub struct Attachment {
|
||||||
//TODO
|
//TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct Reply {
|
pub struct Reply {
|
||||||
pub referencing_id: i64,
|
pub referencing_id: i64,
|
||||||
pub text: String,
|
pub text: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct Edit {
|
pub struct Edit {
|
||||||
pub referencing_id: i64,
|
pub referencing_id: i64,
|
||||||
pub text: String,
|
pub text: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct Reaction {
|
pub struct Reaction {
|
||||||
pub referencing_id: i64,
|
pub referencing_id: i64,
|
||||||
pub emoji: String
|
pub emoji: String
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct Redaction {
|
pub struct Redaction {
|
||||||
pub referencing_id: i64,
|
pub referencing_id: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
|
#[derive(Debug, Clone, Serialize, Deserialize, FromRow, PartialEq)]
|
||||||
pub struct User {
|
pub struct User {
|
||||||
pub id: i64,
|
pub id: i64,
|
||||||
pub userid: String,
|
pub userid: String,
|
||||||
@@ -136,7 +137,7 @@ pub struct User {
|
|||||||
pub admin: bool,
|
pub admin: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
|
#[derive(Debug, Clone, Serialize, Deserialize, FromRow, PartialEq)]
|
||||||
pub struct Room {
|
pub struct Room {
|
||||||
pub id: i64,
|
pub id: i64,
|
||||||
pub roomid: String,
|
pub roomid: String,
|
||||||
|
|||||||
Reference in New Issue
Block a user