feat: Chat request implementation #14
5 changed files with 301 additions and 0 deletions
52
crates/oxidetalis/src/database/blacklist.rs
Normal file
52
crates/oxidetalis/src/database/blacklist.rs
Normal file
|
@ -0,0 +1,52 @@
|
|||
// OxideTalis Messaging Protocol homeserver implementation
|
||||
// Copyright (C) 2024 OxideTalis Developers <otmp@4rs.nl>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://gnu.org/licenses/agpl-3.0>.
|
||||
|
||||
//! Database extension to work with the balcklist table
|
||||
|
||||
use oxidetalis_core::types::PublicKey;
|
||||
use oxidetalis_entities::prelude::*;
|
||||
use sea_orm::DatabaseConnection;
|
||||
|
||||
use crate::errors::ApiResult;
|
||||
|
||||
/// Extension trait for the `DatabaseConnection` to work with the blacklist
|
||||
/// table
|
||||
pub trait BlackListExt {
|
||||
/// Returns ture if the `blacklister` are blacklisted the
|
||||
/// `target_public_key`
|
||||
async fn is_blacklisted(
|
||||
&self,
|
||||
blacklister: &UserModel,
|
||||
awiteb marked this conversation as resolved
|
||||
target_public_key: &PublicKey,
|
||||
) -> ApiResult<bool>;
|
||||
}
|
||||
|
||||
impl BlackListExt for DatabaseConnection {
|
||||
#[logcall::logcall]
|
||||
async fn is_blacklisted(
|
||||
&self,
|
||||
blacklister: &UserModel,
|
||||
target_public_key: &PublicKey,
|
||||
) -> ApiResult<bool> {
|
||||
blacklister
|
||||
.find_related(BlacklistEntity)
|
||||
.filter(BlacklistColumn::Target.eq(target_public_key.to_string()))
|
||||
.one(self)
|
||||
.await
|
||||
.map(|u| u.is_some())
|
||||
.map_err(Into::into)
|
||||
}
|
||||
}
|
66
crates/oxidetalis/src/database/in_chat_requests.rs
Normal file
66
crates/oxidetalis/src/database/in_chat_requests.rs
Normal file
|
@ -0,0 +1,66 @@
|
|||
// OxideTalis Messaging Protocol homeserver implementation
|
||||
// Copyright (C) 2024 OxideTalis Developers <otmp@4rs.nl>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://gnu.org/licenses/agpl-3.0>.
|
||||
|
||||
//! Database extension for the `in_chat_requests` table.
|
||||
|
||||
use chrono::Utc;
|
||||
use oxidetalis_core::types::PublicKey;
|
||||
use oxidetalis_entities::prelude::*;
|
||||
use sea_orm::DatabaseConnection;
|
||||
|
||||
use crate::websocket::errors::{WsError, WsResult};
|
||||
|
||||
/// Extension trait for the `in_chat_requests` table.
|
||||
pub trait InChatRequestsExt {
|
||||
/// Save the chat request in the recipient table
|
||||
async fn save_in_chat_request(
|
||||
&self,
|
||||
requester: &PublicKey,
|
||||
recipient: &UserModel,
|
||||
) -> WsResult<()>;
|
||||
}
|
||||
|
||||
impl InChatRequestsExt for DatabaseConnection {
|
||||
#[logcall::logcall]
|
||||
async fn save_in_chat_request(
|
||||
&self,
|
||||
sender: &PublicKey,
|
||||
recipient: &UserModel,
|
||||
) -> WsResult<()> {
|
||||
if sender.to_string() == recipient.public_key {
|
||||
return Err(WsError::CannotSendChatRequestToSelf);
|
||||
}
|
||||
if recipient
|
||||
.find_related(InChatRequestsEntity)
|
||||
.filter(InChatRequestsColumn::Sender.eq(sender.to_string()))
|
||||
awiteb marked this conversation as resolved
Amjad50
commented
since we are not dealing with the result. maybe a one statement approach to do
here i'm updating since we are not dealing with the result. maybe a one statement approach to do
```rust
InChatRequestsEntity::insert(InChatRequestsActiveModel {
recipient_id: Set(recipient.id),
sender: Set(sender.to_string()),
in_on: Set(Utc::now()),
..Default::default()
})
.on_conflict(
OnConflict::columns([
InChatRequestsColumn::RecipientId,
InChatRequestsColumn::Sender,
])
.update_column(InChatRequestsColumn::InOn)
.to_owned(),
)
.exec(self)
```
here i'm updating `InOn` if needed, but can also be changed to `do_nothing()`
|
||||
.one(self)
|
||||
.await
|
||||
.map_err(|_| WsError::InternalServerError)?
|
||||
.is_none()
|
||||
{
|
||||
InChatRequestsActiveModel {
|
||||
recipient_id: Set(recipient.id),
|
||||
sender: Set(sender.to_string()),
|
||||
in_on: Set(Utc::now()),
|
||||
..Default::default()
|
||||
}
|
||||
.save(self)
|
||||
.await
|
||||
.map_err(|_| WsError::InternalServerError)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -16,6 +16,14 @@
|
|||
|
||||
//! Database utilities for the OxideTalis homeserver.
|
||||
|
||||
mod blacklist;
|
||||
mod in_chat_requests;
|
||||
mod out_chat_requests;
|
||||
mod user;
|
||||
mod whitelist;
|
||||
|
||||
pub use blacklist::*;
|
||||
pub use in_chat_requests::*;
|
||||
pub use out_chat_requests::*;
|
||||
pub use user::*;
|
||||
pub use whitelist::*;
|
||||
|
|
86
crates/oxidetalis/src/database/out_chat_requests.rs
Normal file
86
crates/oxidetalis/src/database/out_chat_requests.rs
Normal file
|
@ -0,0 +1,86 @@
|
|||
// OxideTalis Messaging Protocol homeserver implementation
|
||||
// Copyright (C) 2024 OxideTalis Developers <otmp@4rs.nl>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://gnu.org/licenses/agpl-3.0>.
|
||||
|
||||
//! Database extension for the `out_chat_requests` table.
|
||||
|
||||
use chrono::Utc;
|
||||
use oxidetalis_core::types::PublicKey;
|
||||
use oxidetalis_entities::prelude::*;
|
||||
use sea_orm::DatabaseConnection;
|
||||
|
||||
use crate::{
|
||||
errors::ApiResult,
|
||||
websocket::errors::{WsError, WsResult},
|
||||
};
|
||||
|
||||
/// Extension trait for the `out_chat_requests` table.
|
||||
pub trait OutChatRequestsExt {
|
||||
/// Returns true if the `user` have a sended chat request to the `recipient`
|
||||
async fn have_chat_request_to(
|
||||
&self,
|
||||
awiteb marked this conversation as resolved
Amjad50
commented
should return should return `true` based on the name and description of the func
Amjad50
commented
small nitpick (also applies to small nitpick (also applies to `have_chat_request_to` below)
I would name it `get_chat_request_to`, as `have` seems that it would be boolean
|
||||
requester: &UserModel,
|
||||
recipient: &PublicKey,
|
||||
) -> ApiResult<bool>;
|
||||
|
||||
/// Save the chat request in the requester table
|
||||
async fn save_out_chat_request(
|
||||
&self,
|
||||
requester: &UserModel,
|
||||
recipient: &PublicKey,
|
||||
) -> WsResult<()>;
|
||||
}
|
||||
|
||||
impl OutChatRequestsExt for DatabaseConnection {
|
||||
#[logcall::logcall]
|
||||
async fn have_chat_request_to(
|
||||
&self,
|
||||
requester: &UserModel,
|
||||
recipient: &PublicKey,
|
||||
) -> ApiResult<bool> {
|
||||
requester
|
||||
.find_related(OutChatRequestsEntity)
|
||||
.filter(OutChatRequestsColumn::Recipient.eq(recipient.to_string()))
|
||||
.one(self)
|
||||
.await
|
||||
.map(|user| user.is_some())
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
#[logcall::logcall]
|
||||
async fn save_out_chat_request(
|
||||
&self,
|
||||
requester: &UserModel,
|
||||
recipient: &PublicKey,
|
||||
) -> WsResult<()> {
|
||||
if self
|
||||
.have_chat_request_to(requester, recipient)
|
||||
.await
|
||||
.map_err(|_| WsError::InternalServerError)?
|
||||
{
|
||||
return Err(WsError::AlreadySendChatRequest);
|
||||
}
|
||||
OutChatRequestsActiveModel {
|
||||
sender_id: Set(requester.id),
|
||||
recipient: Set(recipient.to_string()),
|
||||
out_on: Set(Utc::now()),
|
||||
..Default::default()
|
||||
}
|
||||
.save(self)
|
||||
.await
|
||||
.map_err(|_| WsError::InternalServerError)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
89
crates/oxidetalis/src/database/whitelist.rs
Normal file
89
crates/oxidetalis/src/database/whitelist.rs
Normal file
|
@ -0,0 +1,89 @@
|
|||
// OxideTalis Messaging Protocol homeserver implementation
|
||||
// Copyright (C) 2024 OxideTalis Developers <otmp@4rs.nl>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://gnu.org/licenses/agpl-3.0>.
|
||||
|
||||
//! Database extension to work with the balcklist table
|
||||
|
||||
use chrono::Utc;
|
||||
use oxidetalis_core::types::PublicKey;
|
||||
use oxidetalis_entities::prelude::*;
|
||||
use sea_orm::DatabaseConnection;
|
||||
|
||||
use crate::{
|
||||
errors::ApiResult,
|
||||
websocket::errors::{WsError, WsResult},
|
||||
};
|
||||
|
||||
/// Extension trait for the `DatabaseConnection` to work with the whitelist
|
||||
/// table
|
||||
pub trait WhiteListExt {
|
||||
/// Returns ture if the `whitelister` are whitelisted the
|
||||
awiteb marked this conversation as resolved
Amjad50
commented
ture ture
The whitelister has whitelisted
|
||||
/// `target_public_key`
|
||||
async fn is_whitelisted(
|
||||
&self,
|
||||
whitelister: &UserModel,
|
||||
target_public_key: &PublicKey,
|
||||
) -> ApiResult<bool>;
|
||||
|
||||
/// Add the `target_public_key` to the whitelist of the `whitelister`
|
||||
async fn add_to_whitelist(
|
||||
&self,
|
||||
whitelister: &UserModel,
|
||||
target_public_key: &PublicKey,
|
||||
) -> WsResult<()>;
|
||||
}
|
||||
|
||||
impl WhiteListExt for DatabaseConnection {
|
||||
async fn is_whitelisted(
|
||||
&self,
|
||||
whitelister: &UserModel,
|
||||
target_public_key: &PublicKey,
|
||||
) -> ApiResult<bool> {
|
||||
whitelister
|
||||
.find_related(WhitelistEntity)
|
||||
.filter(WhitelistColumn::Target.eq(target_public_key.to_string()))
|
||||
.one(self)
|
||||
.await
|
||||
.map(|u| u.is_some())
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
async fn add_to_whitelist(
|
||||
&self,
|
||||
whitelister: &UserModel,
|
||||
target_public_key: &PublicKey,
|
||||
) -> WsResult<()> {
|
||||
if self
|
||||
.is_whitelisted(whitelister, target_public_key)
|
||||
.await
|
||||
.map_err(|_| WsError::InternalServerError)?
|
||||
{
|
||||
return Err(WsError::AlreadyOnTheWhitelist);
|
||||
}
|
||||
if whitelister.public_key == target_public_key.to_string() {
|
||||
return Err(WsError::CannotAddSelfToWhitelist);
|
||||
}
|
||||
WhitelistActiveModel {
|
||||
user_id: Set(whitelister.id),
|
||||
target: Set(target_public_key.to_string()),
|
||||
whitelisted_at: Set(Utc::now()),
|
||||
..Default::default()
|
||||
}
|
||||
.save(self)
|
||||
.await
|
||||
.map_err(|_| WsError::InternalServerError)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue
ture
->true
(use find and replace all, there are multiple of these)blacklister has blacklisted