From 3d086e511cd6ac1a3254de278e39b42c8a2811ca Mon Sep 17 00:00:00 2001 From: Awiteb Date: Wed, 17 Jul 2024 18:34:39 +0300 Subject: [PATCH] feat: Replace `whitelist` & `blacklist` tables with `users_status` table Signed-off-by: Awiteb --- crates/oxidetalis/src/database/blacklist.rs | 135 -------- crates/oxidetalis/src/database/mod.rs | 6 +- crates/oxidetalis/src/database/user_status.rs | 287 ++++++++++++++++++ crates/oxidetalis/src/database/whitelist.rs | 134 -------- crates/oxidetalis/src/routes/user.rs | 2 +- crates/oxidetalis/src/schemas/user.rs | 12 +- .../src/websocket/handlers/chat_request.rs | 2 +- crates/oxidetalis_entities/src/lib.rs | 3 +- crates/oxidetalis_entities/src/prelude.rs | 17 +- crates/oxidetalis_entities/src/users.rs | 16 +- .../src/{blacklist.rs => users_status.rs} | 20 +- crates/oxidetalis_entities/src/whitelist.rs | 56 ---- ...cklist_table.rs => create_users_status.rs} | 67 +++- .../src/create_whitelist_table.rs | 63 ---- crates/oxidetalis_migrations/src/lib.rs | 6 +- 15 files changed, 383 insertions(+), 443 deletions(-) delete mode 100644 crates/oxidetalis/src/database/blacklist.rs create mode 100644 crates/oxidetalis/src/database/user_status.rs delete mode 100644 crates/oxidetalis/src/database/whitelist.rs rename crates/oxidetalis_entities/src/{blacklist.rs => users_status.rs} (78%) delete mode 100644 crates/oxidetalis_entities/src/whitelist.rs rename crates/oxidetalis_migrations/src/{create_blacklist_table.rs => create_users_status.rs} (52%) delete mode 100644 crates/oxidetalis_migrations/src/create_whitelist_table.rs diff --git a/crates/oxidetalis/src/database/blacklist.rs b/crates/oxidetalis/src/database/blacklist.rs deleted file mode 100644 index 1749b96..0000000 --- a/crates/oxidetalis/src/database/blacklist.rs +++ /dev/null @@ -1,135 +0,0 @@ -// OxideTalis Messaging Protocol homeserver implementation -// Copyright (C) 2024 OxideTalis Developers -// -// 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 . - -//! Database extension to work with the blacklist table - -use std::num::{NonZeroU32, NonZeroU8}; - -use chrono::Utc; -use oxidetalis_core::types::PublicKey; -use oxidetalis_entities::prelude::*; -use sea_orm::DatabaseConnection; - -use super::WhiteListExt; -use crate::{errors::ServerResult, websocket::errors::WsError}; - -/// 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, - ) -> ServerResult; - - /// Add the `target_public_key` to the blacklist of the `blacklister` and - /// remove it from the whitelist table (if it's there) - async fn add_to_blacklist( - &self, - blacklister: &UserModel, - target_public_key: &PublicKey, - ) -> ServerResult<()>; - - /// Remove the target from blacklist table - async fn remove_from_blacklist( - &self, - blacklister: &UserModel, - target_public_key: &PublicKey, - ) -> ServerResult<()>; - - /// Returns the blacklist of the user - async fn user_blacklist( - &self, - blacklister: &UserModel, - page: NonZeroU32, - page_size: NonZeroU8, - ) -> ServerResult>; -} - -impl BlackListExt for DatabaseConnection { - #[logcall::logcall] - async fn is_blacklisted( - &self, - blacklister: &UserModel, - target_public_key: &PublicKey, - ) -> ServerResult { - 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) - } - - async fn add_to_blacklist( - &self, - blacklister: &UserModel, - target_public_key: &PublicKey, - ) -> ServerResult<()> { - if self.is_blacklisted(blacklister, target_public_key).await? { - return Err(WsError::AlreadyOnTheblacklist.into()); - } - if blacklister.public_key == target_public_key.to_string() { - return Err(WsError::CannotAddSelfToBlacklist.into()); - } - self.remove_from_whitelist(blacklister, target_public_key) - .await?; - - BlacklistActiveModel { - user_id: Set(blacklister.id), - target: Set(target_public_key.to_string()), - blacklisted_at: Set(Utc::now()), - ..Default::default() - } - .save(self) - .await?; - Ok(()) - } - - async fn remove_from_blacklist( - &self, - blacklister: &UserModel, - target_public_key: &PublicKey, - ) -> ServerResult<()> { - if let Some(target_user) = blacklister - .find_related(BlacklistEntity) - .filter(BlacklistColumn::Target.eq(target_public_key.to_string())) - .one(self) - .await? - { - target_user.delete(self).await?; - } - Ok(()) - } - - async fn user_blacklist( - &self, - blacklister: &UserModel, - page: NonZeroU32, - page_size: NonZeroU8, - ) -> ServerResult> { - blacklister - .find_related(BlacklistEntity) - .select() - .paginate(self, u64::from(page_size.get())) - .fetch_page(u64::from(page.get() - 1)) - .await - .map_err(Into::into) - } -} diff --git a/crates/oxidetalis/src/database/mod.rs b/crates/oxidetalis/src/database/mod.rs index dc03f6a..c4011ac 100644 --- a/crates/oxidetalis/src/database/mod.rs +++ b/crates/oxidetalis/src/database/mod.rs @@ -16,14 +16,12 @@ //! Database utilities for the OxideTalis homeserver. -mod blacklist; mod in_chat_requests; mod out_chat_requests; mod user; -mod whitelist; +mod user_status; -pub use blacklist::*; pub use in_chat_requests::*; pub use out_chat_requests::*; pub use user::*; -pub use whitelist::*; +pub use user_status::*; diff --git a/crates/oxidetalis/src/database/user_status.rs b/crates/oxidetalis/src/database/user_status.rs new file mode 100644 index 0000000..152e1c8 --- /dev/null +++ b/crates/oxidetalis/src/database/user_status.rs @@ -0,0 +1,287 @@ +// OxideTalis Messaging Protocol homeserver implementation +// Copyright (C) 2024 OxideTalis Developers +// +// 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 . + +//! Database extension to work with the whitelist table + +use std::num::{NonZeroU32, NonZeroU8}; + +use chrono::Utc; +use oxidetalis_core::types::PublicKey; +use oxidetalis_entities::prelude::*; +use sea_orm::DatabaseConnection; + +use crate::{errors::ServerResult, websocket::errors::WsError}; + +/// Extension trait for the `DatabaseConnection` to work with the whitelist +/// table +pub trait UsersStatusExt { + /// Returns ture if the `whitelister` are whitelisted the + /// `target_public_key` + async fn is_whitelisted( + &self, + whitelister: &UserModel, + target_public_key: &PublicKey, + ) -> ServerResult; + + /// Returns ture if the `blacklister` are blacklisted the + /// `target_public_key` + async fn is_blacklisted( + &self, + blacklister: &UserModel, + target_public_key: &PublicKey, + ) -> ServerResult; + + /// Add the `target_public_key` to the whitelist of the `whitelister` and + /// remove it from the blacklist table (if it's there) + async fn add_to_whitelist( + &self, + whitelister: &UserModel, + target_public_key: &PublicKey, + ) -> ServerResult<()>; + + /// Add the `target_public_key` to the blacklist of the `blacklister` and + /// remove it from the whitelist table (if it's there) + async fn add_to_blacklist( + &self, + blacklister: &UserModel, + target_public_key: &PublicKey, + ) -> ServerResult<()>; + + /// Remove the target from whitelist table + // FIXME(awiteb): This method will be used when I work on decentralization, So, I'm keeping it + // for now + #[allow(dead_code)] + async fn remove_from_whitelist( + &self, + whitelister: &UserModel, + target_public_key: &PublicKey, + ) -> ServerResult<()>; + + /// Remove the target from blacklist table + // FIXME(awiteb): This method will be used when I work on decentralization, So, I'm keeping it + // for now + #[allow(dead_code)] + async fn remove_from_blacklist( + &self, + blacklister: &UserModel, + target_public_key: &PublicKey, + ) -> ServerResult<()>; + + /// Returns the whitelist of the user + async fn user_whitelist( + &self, + whitelister: &UserModel, + page: NonZeroU32, + page_size: NonZeroU8, + ) -> ServerResult>; + + /// Returns the blacklist of the user + async fn user_blacklist( + &self, + blacklister: &UserModel, + page: NonZeroU32, + page_size: NonZeroU8, + ) -> ServerResult>; +} + +impl UsersStatusExt for DatabaseConnection { + async fn is_whitelisted( + &self, + whitelister: &UserModel, + target_public_key: &PublicKey, + ) -> ServerResult { + whitelister + .find_related(UsersStatusEntity) + .filter( + UsersStatusColumn::Target + .eq(target_public_key.to_string()) + .and(UsersStatusColumn::Status.eq(AccessStatus::Whitelisted)), + ) + .one(self) + .await + .map(|u| u.is_some()) + .map_err(Into::into) + } + + async fn is_blacklisted( + &self, + blacklister: &UserModel, + target_public_key: &PublicKey, + ) -> ServerResult { + blacklister + .find_related(UsersStatusEntity) + .filter( + UsersStatusColumn::Target + .eq(target_public_key.to_string()) + .and(UsersStatusColumn::Status.eq(AccessStatus::Blacklisted)), + ) + .one(self) + .await + .map(|u| u.is_some()) + .map_err(Into::into) + } + + async fn add_to_whitelist( + &self, + whitelister: &UserModel, + target_public_key: &PublicKey, + ) -> ServerResult<()> { + if self.is_whitelisted(whitelister, target_public_key).await? { + return Err(WsError::AlreadyOnTheWhitelist.into()); + } + if whitelister.public_key == target_public_key.to_string() { + return Err(WsError::CannotAddSelfToWhitelist.into()); + } + + if let Some(mut user) = get_user_status(self, whitelister, target_public_key) + .await? + .map(IntoActiveModel::into_active_model) + { + user.status = Set(AccessStatus::Whitelisted); + user.updated_at = Set(Utc::now()); + user.update(self).await?; + } else { + UsersStatusActiveModel { + user_id: Set(whitelister.id), + target: Set(target_public_key.to_string()), + status: Set(AccessStatus::Whitelisted), + updated_at: Set(Utc::now()), + ..Default::default() + } + .save(self) + .await?; + } + + Ok(()) + } + + async fn add_to_blacklist( + &self, + blacklister: &UserModel, + target_public_key: &PublicKey, + ) -> ServerResult<()> { + if self.is_blacklisted(blacklister, target_public_key).await? { + return Err(WsError::AlreadyOnTheBlacklist.into()); + } + if blacklister.public_key == target_public_key.to_string() { + return Err(WsError::CannotAddSelfToBlacklist.into()); + } + + if let Some(mut user) = get_user_status(self, blacklister, target_public_key) + .await? + .map(IntoActiveModel::into_active_model) + { + user.status = Set(AccessStatus::Blacklisted); + user.updated_at = Set(Utc::now()); + user.update(self).await?; + } else { + UsersStatusActiveModel { + user_id: Set(blacklister.id), + target: Set(target_public_key.to_string()), + status: Set(AccessStatus::Blacklisted), + updated_at: Set(Utc::now()), + ..Default::default() + } + .save(self) + .await?; + } + + Ok(()) + } + + async fn remove_from_whitelist( + &self, + whitelister: &UserModel, + target_public_key: &PublicKey, + ) -> ServerResult<()> { + if let Some(target_user) = whitelister + .find_related(UsersStatusEntity) + .filter( + UsersStatusColumn::Target + .eq(target_public_key.to_string()) + .and(UsersStatusColumn::Status.eq(AccessStatus::Whitelisted)), + ) + .one(self) + .await? + { + target_user.delete(self).await?; + } + Ok(()) + } + + async fn remove_from_blacklist( + &self, + blacklister: &UserModel, + target_public_key: &PublicKey, + ) -> ServerResult<()> { + if let Some(target_user) = blacklister + .find_related(UsersStatusEntity) + .filter( + UsersStatusColumn::Target + .eq(target_public_key.to_string()) + .and(UsersStatusColumn::Status.eq(AccessStatus::Blacklisted)), + ) + .one(self) + .await? + { + target_user.delete(self).await?; + } + Ok(()) + } + + async fn user_whitelist( + &self, + whitelister: &UserModel, + page: NonZeroU32, + page_size: NonZeroU8, + ) -> ServerResult> { + whitelister + .find_related(UsersStatusEntity) + .filter(UsersStatusColumn::Status.eq(AccessStatus::Whitelisted)) + .paginate(self, u64::from(page_size.get())) + .fetch_page(u64::from(page.get() - 1)) + .await + .map_err(Into::into) + } + + async fn user_blacklist( + &self, + blacklister: &UserModel, + page: NonZeroU32, + page_size: NonZeroU8, + ) -> ServerResult> { + blacklister + .find_related(UsersStatusEntity) + .filter(UsersStatusColumn::Status.eq(AccessStatus::Blacklisted)) + .paginate(self, u64::from(page_size.get())) + .fetch_page(u64::from(page.get() - 1)) + .await + .map_err(Into::into) + } +} + +/// Returns user from user_status table by the entered and target public key +async fn get_user_status( + conn: &DatabaseConnection, + user: &UserModel, + target_public_key: &PublicKey, +) -> ServerResult> { + user.find_related(UsersStatusEntity) + .filter(UsersStatusColumn::Target.eq(target_public_key.to_string())) + .one(conn) + .await + .map_err(Into::into) +} diff --git a/crates/oxidetalis/src/database/whitelist.rs b/crates/oxidetalis/src/database/whitelist.rs deleted file mode 100644 index 7cb74ba..0000000 --- a/crates/oxidetalis/src/database/whitelist.rs +++ /dev/null @@ -1,134 +0,0 @@ -// OxideTalis Messaging Protocol homeserver implementation -// Copyright (C) 2024 OxideTalis Developers -// -// 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 . - -//! Database extension to work with the whitelist table - -use std::num::{NonZeroU32, NonZeroU8}; - -use chrono::Utc; -use oxidetalis_core::types::PublicKey; -use oxidetalis_entities::prelude::*; -use sea_orm::DatabaseConnection; - -use super::BlackListExt; -use crate::{errors::ServerResult, websocket::errors::WsError}; - -/// 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, - ) -> ServerResult; - - /// Add the `target_public_key` to the whitelist of the `whitelister` and - /// remove it from the blacklist table (if it's there) - async fn add_to_whitelist( - &self, - whitelister: &UserModel, - target_public_key: &PublicKey, - ) -> ServerResult<()>; - - /// Remove the target from whitelist table - async fn remove_from_whitelist( - &self, - whitelister: &UserModel, - target_public_key: &PublicKey, - ) -> ServerResult<()>; - - /// Returns the whitelist of the user - async fn user_whitelist( - &self, - whitelister: &UserModel, - page: NonZeroU32, - page_size: NonZeroU8, - ) -> ServerResult>; -} - -impl WhiteListExt for DatabaseConnection { - async fn is_whitelisted( - &self, - whitelister: &UserModel, - target_public_key: &PublicKey, - ) -> ServerResult { - 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, - ) -> ServerResult<()> { - if self.is_whitelisted(whitelister, target_public_key).await? { - return Err(WsError::AlreadyOnTheWhitelist.into()); - } - if whitelister.public_key == target_public_key.to_string() { - return Err(WsError::CannotAddSelfToWhitelist.into()); - } - self.remove_from_blacklist(whitelister, target_public_key) - .await?; - - WhitelistActiveModel { - user_id: Set(whitelister.id), - target: Set(target_public_key.to_string()), - whitelisted_at: Set(Utc::now()), - ..Default::default() - } - .save(self) - .await?; - Ok(()) - } - - async fn remove_from_whitelist( - &self, - whitelister: &UserModel, - target_public_key: &PublicKey, - ) -> ServerResult<()> { - if let Some(target_user) = whitelister - .find_related(WhitelistEntity) - .filter(WhitelistColumn::Target.eq(target_public_key.to_string())) - .one(self) - .await? - { - target_user.delete(self).await?; - } - Ok(()) - } - - async fn user_whitelist( - &self, - whitelister: &UserModel, - page: NonZeroU32, - page_size: NonZeroU8, - ) -> ServerResult> { - whitelister - .find_related(WhitelistEntity) - .select() - .paginate(self, u64::from(page_size.get())) - .fetch_page(u64::from(page.get() - 1)) - .await - .map_err(Into::into) - } -} diff --git a/crates/oxidetalis/src/routes/user.rs b/crates/oxidetalis/src/routes/user.rs index abd384d..7a0f423 100644 --- a/crates/oxidetalis/src/routes/user.rs +++ b/crates/oxidetalis/src/routes/user.rs @@ -30,7 +30,7 @@ use salvo::{ use super::{ApiError, ApiResult}; use crate::{ - database::{BlackListExt, UserTableExt, WhiteListExt}, + database::{UserTableExt, UsersStatusExt}, extensions::DepotExt, middlewares, parameters::Pagination, diff --git a/crates/oxidetalis/src/schemas/user.rs b/crates/oxidetalis/src/schemas/user.rs index c853ebd..4351d77 100644 --- a/crates/oxidetalis/src/schemas/user.rs +++ b/crates/oxidetalis/src/schemas/user.rs @@ -57,11 +57,11 @@ impl Default for WhiteListedUser { } } -impl From for WhiteListedUser { - fn from(user: WhitelistModel) -> Self { +impl From for WhiteListedUser { + fn from(user: UsersStatusModel) -> Self { Self { public_key: PublicKey::from_str(&user.target).expect("Is valid public key"), - whitelisted_at: user.whitelisted_at, + whitelisted_at: user.updated_at, } } } @@ -75,11 +75,11 @@ impl Default for BlackListedUser { } } -impl From for BlackListedUser { - fn from(user: BlacklistModel) -> Self { +impl From for BlackListedUser { + fn from(user: UsersStatusModel) -> Self { Self { public_key: PublicKey::from_str(&user.target).expect("Is valid public key"), - blacklisted_at: user.blacklisted_at, + blacklisted_at: user.updated_at, } } } diff --git a/crates/oxidetalis/src/websocket/handlers/chat_request.rs b/crates/oxidetalis/src/websocket/handlers/chat_request.rs index 9519347..c3c31e3 100644 --- a/crates/oxidetalis/src/websocket/handlers/chat_request.rs +++ b/crates/oxidetalis/src/websocket/handlers/chat_request.rs @@ -25,7 +25,7 @@ use sea_orm::DatabaseConnection; use crate::database::InChatRequestsExt; use crate::extensions::OnlineUsersExt; use crate::{ - database::{BlackListExt, OutChatRequestsExt, UserTableExt, WhiteListExt}, + database::{OutChatRequestsExt, UserTableExt, UsersStatusExt}, try_ws, websocket::{errors::WsError, ServerEvent, Unsigned, ONLINE_USERS}, }; diff --git a/crates/oxidetalis_entities/src/lib.rs b/crates/oxidetalis_entities/src/lib.rs index 3c72884..7ed4e2c 100644 --- a/crates/oxidetalis_entities/src/lib.rs +++ b/crates/oxidetalis_entities/src/lib.rs @@ -19,9 +19,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -pub mod blacklist; pub mod incoming_chat_requests; pub mod outgoing_chat_requests; pub mod prelude; pub mod users; -pub mod whitelist; +pub mod users_status; diff --git a/crates/oxidetalis_entities/src/prelude.rs b/crates/oxidetalis_entities/src/prelude.rs index 44eb108..5adcf81 100644 --- a/crates/oxidetalis_entities/src/prelude.rs +++ b/crates/oxidetalis_entities/src/prelude.rs @@ -38,12 +38,6 @@ pub use sea_orm::{ /// User ID type pub type UserId = i64; -pub use super::blacklist::{ - ActiveModel as BlacklistActiveModel, - Column as BlacklistColumn, - Entity as BlacklistEntity, - Model as BlacklistModel, -}; pub use super::incoming_chat_requests::{ ActiveModel as InChatRequestsActiveModel, Column as InChatRequestsColumn, @@ -62,9 +56,10 @@ pub use super::users::{ Entity as UserEntity, Model as UserModel, }; -pub use super::whitelist::{ - ActiveModel as WhitelistActiveModel, - Column as WhitelistColumn, - Entity as WhitelistEntity, - Model as WhitelistModel, +pub use super::users_status::{ + AccessStatus, + ActiveModel as UsersStatusActiveModel, + Column as UsersStatusColumn, + Entity as UsersStatusEntity, + Model as UsersStatusModel, }; diff --git a/crates/oxidetalis_entities/src/users.rs b/crates/oxidetalis_entities/src/users.rs index cd6b172..675e589 100644 --- a/crates/oxidetalis_entities/src/users.rs +++ b/crates/oxidetalis_entities/src/users.rs @@ -38,10 +38,8 @@ pub enum Relation { InChatRequests, #[sea_orm(has_many = "OutChatRequestsEntity")] OutChatRequests, - #[sea_orm(has_many = "BlacklistEntity")] - Blacklist, - #[sea_orm(has_many = "WhitelistEntity")] - Whitelist, + #[sea_orm(has_many = "UsersStatusEntity")] + UsersStatus, } impl Related for Entity { @@ -56,15 +54,9 @@ impl Related for Entity { } } -impl Related for Entity { +impl Related for Entity { fn to() -> RelationDef { - Relation::Blacklist.def() - } -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Whitelist.def() + Relation::UsersStatus.def() } } diff --git a/crates/oxidetalis_entities/src/blacklist.rs b/crates/oxidetalis_entities/src/users_status.rs similarity index 78% rename from crates/oxidetalis_entities/src/blacklist.rs rename to crates/oxidetalis_entities/src/users_status.rs index 848432d..3459192 100644 --- a/crates/oxidetalis_entities/src/blacklist.rs +++ b/crates/oxidetalis_entities/src/users_status.rs @@ -24,15 +24,25 @@ use sea_orm::entity::prelude::*; use crate::prelude::*; +#[derive(Debug, Clone, Eq, PartialEq, EnumIter, DeriveActiveEnum)] +#[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "access_status")] +pub enum AccessStatus { + #[sea_orm(string_value = "whitelisted")] + Whitelisted, + #[sea_orm(string_value = "blacklisted")] + Blacklisted, +} + #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] -#[sea_orm(table_name = "blacklist")] +#[sea_orm(table_name = "users_status")] pub struct Model { #[sea_orm(primary_key)] - pub id: UserId, - pub user_id: UserId, + pub id: UserId, + pub user_id: UserId, /// Public key of the target - pub target: String, - pub blacklisted_at: chrono::DateTime, + pub target: String, + pub status: AccessStatus, + pub updated_at: chrono::DateTime, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] diff --git a/crates/oxidetalis_entities/src/whitelist.rs b/crates/oxidetalis_entities/src/whitelist.rs deleted file mode 100644 index b1bee22..0000000 --- a/crates/oxidetalis_entities/src/whitelist.rs +++ /dev/null @@ -1,56 +0,0 @@ -// OxideTalis Messaging Protocol homeserver core implementation -// Copyright (c) 2024 OxideTalis Developers -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -use chrono::Utc; -use sea_orm::entity::prelude::*; - -use crate::prelude::*; - -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] -#[sea_orm(table_name = "whitelist")] -pub struct Model { - #[sea_orm(primary_key)] - pub id: UserId, - pub user_id: UserId, - /// Public key of the target - pub target: String, - pub whitelisted_at: chrono::DateTime, -} - -#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] -pub enum Relation { - #[sea_orm( - belongs_to = "UserEntity", - from = "Column::UserId", - to = "super::users::Column::Id" - on_update = "NoAction", - on_delete = "Cascade" - )] - UserId, -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::UserId.def() - } -} - -impl ActiveModelBehavior for ActiveModel {} diff --git a/crates/oxidetalis_migrations/src/create_blacklist_table.rs b/crates/oxidetalis_migrations/src/create_users_status.rs similarity index 52% rename from crates/oxidetalis_migrations/src/create_blacklist_table.rs rename to crates/oxidetalis_migrations/src/create_users_status.rs index 2eaf805..ad57d00 100644 --- a/crates/oxidetalis_migrations/src/create_blacklist_table.rs +++ b/crates/oxidetalis_migrations/src/create_users_status.rs @@ -19,31 +19,59 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. +use std::fmt; + +use sea_orm::sea_query::extension::postgres::Type; use sea_orm_migration::prelude::*; +use super::create_users_table::Users; + #[derive(DeriveMigrationName)] pub struct Migration; #[async_trait::async_trait] impl MigrationTrait for Migration { async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .create_type( + Type::create() + .as_enum(AccessStatus::Name) + .values(vec![AccessStatus::Whitelisted, AccessStatus::Blacklisted]) + .to_owned(), + ) + .await?; + manager .create_table( Table::create() - .table(Blacklist::Table) + .table(UsersStatus::Table) .if_not_exists() .col( - ColumnDef::new(Blacklist::Id) + ColumnDef::new(UsersStatus::Id) .big_integer() .not_null() .auto_increment() .primary_key(), ) - .col(ColumnDef::new(Blacklist::UserId).big_integer().not_null()) - .col(ColumnDef::new(Blacklist::Target).string().not_null()) - .col(ColumnDef::new(Blacklist::Reason).string_len(400)) + .foreign_key( + ForeignKey::create() + .name("fk-users_status-users") + .from(UsersStatus::Table, UsersStatus::UserId) + .to(Users::Table, Users::Id) + .on_update(ForeignKeyAction::NoAction) + .on_delete(ForeignKeyAction::Cascade), + ) + .col(ColumnDef::new(UsersStatus::Target).string().not_null()) .col( - ColumnDef::new(Blacklist::BlacklistedAt) + ColumnDef::new(UsersStatus::Status) + .enumeration( + AccessStatus::Name, + [AccessStatus::Whitelisted, AccessStatus::Blacklisted], + ) + .not_null(), + ) + .col( + ColumnDef::new(UsersStatus::UpdatedAt) .timestamp_with_time_zone() .not_null(), ) @@ -53,13 +81,34 @@ impl MigrationTrait for Migration { } } +enum AccessStatus { + Name, + Whitelisted, + Blacklisted, +} + #[derive(DeriveIden)] -enum Blacklist { +enum UsersStatus { Table, Id, UserId, /// Public key of the target Target, - Reason, - BlacklistedAt, + Status, + UpdatedAt, +} + +impl Iden for AccessStatus { + fn unquoted(&self, s: &mut dyn fmt::Write) { + write!( + s, + "{}", + match self { + Self::Name => "access_status", + Self::Whitelisted => "whitelisted", + Self::Blacklisted => "blacklisted", + } + ) + .expect("is a string") + } } diff --git a/crates/oxidetalis_migrations/src/create_whitelist_table.rs b/crates/oxidetalis_migrations/src/create_whitelist_table.rs deleted file mode 100644 index d29f837..0000000 --- a/crates/oxidetalis_migrations/src/create_whitelist_table.rs +++ /dev/null @@ -1,63 +0,0 @@ -// OxideTalis Messaging Protocol homeserver core implementation -// Copyright (c) 2024 OxideTalis Developers -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -use sea_orm_migration::prelude::*; - -#[derive(DeriveMigrationName)] -pub struct Migration; - -#[async_trait::async_trait] -impl MigrationTrait for Migration { - async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { - manager - .create_table( - Table::create() - .table(Whitelist::Table) - .if_not_exists() - .col( - ColumnDef::new(Whitelist::Id) - .big_integer() - .not_null() - .auto_increment() - .primary_key(), - ) - .col(ColumnDef::new(Whitelist::UserId).big_integer().not_null()) - .col(ColumnDef::new(Whitelist::Target).string().not_null()) - .col( - ColumnDef::new(Whitelist::WhitelistedAt) - .timestamp_with_time_zone() - .not_null(), - ) - .to_owned(), - ) - .await - } -} - -#[derive(DeriveIden)] -enum Whitelist { - Table, - Id, - UserId, - /// Public key of the target - Target, - WhitelistedAt, -} diff --git a/crates/oxidetalis_migrations/src/lib.rs b/crates/oxidetalis_migrations/src/lib.rs index 0108570..e94142e 100644 --- a/crates/oxidetalis_migrations/src/lib.rs +++ b/crates/oxidetalis_migrations/src/lib.rs @@ -21,11 +21,10 @@ pub use sea_orm_migration::prelude::*; -mod create_blacklist_table; mod create_incoming_chat_requests_table; mod create_outgoing_chat_requests_table; +mod create_users_status; mod create_users_table; -mod create_whitelist_table; pub struct Migrator; @@ -36,8 +35,7 @@ impl MigratorTrait for Migrator { Box::new(create_users_table::Migration), Box::new(create_incoming_chat_requests_table::Migration), Box::new(create_outgoing_chat_requests_table::Migration), - Box::new(create_blacklist_table::Migration), - Box::new(create_whitelist_table::Migration), + Box::new(create_users_status::Migration), ] } }