feat: New tables utils

The tables is:
- `blacklist`
- `incoming_chat_requests`
- `whitelist`
- `outgoing_chat_requests`

Signed-off-by: Awiteb <a@4rs.nl>
This commit is contained in:
Awiteb 2024-07-12 22:51:57 +03:00
parent 4de83b02cd
commit 90cd947e71
Signed by: awiteb
GPG key ID: 3F6B55640AA6682F
5 changed files with 301 additions and 0 deletions

View 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,
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)
}
}

View 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()))
.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(())
}
}

View file

@ -16,6 +16,14 @@
//! Database utilities for the OxideTalis homeserver. //! Database utilities for the OxideTalis homeserver.
mod blacklist;
mod in_chat_requests;
mod out_chat_requests;
mod user; mod user;
mod whitelist;
pub use blacklist::*;
pub use in_chat_requests::*;
pub use out_chat_requests::*;
pub use user::*; pub use user::*;
pub use whitelist::*;

View 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,
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(())
}
}

View 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
/// `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(())
}
}