feat: Replace whitelist
& blacklist
tables with users_status
table
Signed-off-by: Awiteb <a@4rs.nl>
This commit is contained in:
parent
a894089b19
commit
3d086e511c
15 changed files with 383 additions and 443 deletions
|
@ -1,135 +0,0 @@
|
||||||
// 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 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<bool>;
|
|
||||||
|
|
||||||
/// 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<Vec<BlacklistModel>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BlackListExt for DatabaseConnection {
|
|
||||||
#[logcall::logcall]
|
|
||||||
async fn is_blacklisted(
|
|
||||||
&self,
|
|
||||||
blacklister: &UserModel,
|
|
||||||
target_public_key: &PublicKey,
|
|
||||||
) -> ServerResult<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)
|
|
||||||
}
|
|
||||||
|
|
||||||
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<Vec<BlacklistModel>> {
|
|
||||||
blacklister
|
|
||||||
.find_related(BlacklistEntity)
|
|
||||||
.select()
|
|
||||||
.paginate(self, u64::from(page_size.get()))
|
|
||||||
.fetch_page(u64::from(page.get() - 1))
|
|
||||||
.await
|
|
||||||
.map_err(Into::into)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -16,14 +16,12 @@
|
||||||
|
|
||||||
//! Database utilities for the OxideTalis homeserver.
|
//! Database utilities for the OxideTalis homeserver.
|
||||||
|
|
||||||
mod blacklist;
|
|
||||||
mod in_chat_requests;
|
mod in_chat_requests;
|
||||||
mod out_chat_requests;
|
mod out_chat_requests;
|
||||||
mod user;
|
mod user;
|
||||||
mod whitelist;
|
mod user_status;
|
||||||
|
|
||||||
pub use blacklist::*;
|
|
||||||
pub use in_chat_requests::*;
|
pub use in_chat_requests::*;
|
||||||
pub use out_chat_requests::*;
|
pub use out_chat_requests::*;
|
||||||
pub use user::*;
|
pub use user::*;
|
||||||
pub use whitelist::*;
|
pub use user_status::*;
|
||||||
|
|
287
crates/oxidetalis/src/database/user_status.rs
Normal file
287
crates/oxidetalis/src/database/user_status.rs
Normal file
|
@ -0,0 +1,287 @@
|
||||||
|
// 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 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<bool>;
|
||||||
|
|
||||||
|
/// Returns ture if the `blacklister` are blacklisted the
|
||||||
|
/// `target_public_key`
|
||||||
|
async fn is_blacklisted(
|
||||||
|
&self,
|
||||||
|
blacklister: &UserModel,
|
||||||
|
target_public_key: &PublicKey,
|
||||||
|
) -> ServerResult<bool>;
|
||||||
|
|
||||||
|
/// 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<Vec<UsersStatusModel>>;
|
||||||
|
|
||||||
|
/// Returns the blacklist of the user
|
||||||
|
async fn user_blacklist(
|
||||||
|
&self,
|
||||||
|
blacklister: &UserModel,
|
||||||
|
page: NonZeroU32,
|
||||||
|
page_size: NonZeroU8,
|
||||||
|
) -> ServerResult<Vec<UsersStatusModel>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UsersStatusExt for DatabaseConnection {
|
||||||
|
async fn is_whitelisted(
|
||||||
|
&self,
|
||||||
|
whitelister: &UserModel,
|
||||||
|
target_public_key: &PublicKey,
|
||||||
|
) -> ServerResult<bool> {
|
||||||
|
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<bool> {
|
||||||
|
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<Vec<UsersStatusModel>> {
|
||||||
|
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<Vec<UsersStatusModel>> {
|
||||||
|
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<Option<UsersStatusModel>> {
|
||||||
|
user.find_related(UsersStatusEntity)
|
||||||
|
.filter(UsersStatusColumn::Target.eq(target_public_key.to_string()))
|
||||||
|
.one(conn)
|
||||||
|
.await
|
||||||
|
.map_err(Into::into)
|
||||||
|
}
|
|
@ -1,134 +0,0 @@
|
||||||
// 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 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<bool>;
|
|
||||||
|
|
||||||
/// 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<Vec<WhitelistModel>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WhiteListExt for DatabaseConnection {
|
|
||||||
async fn is_whitelisted(
|
|
||||||
&self,
|
|
||||||
whitelister: &UserModel,
|
|
||||||
target_public_key: &PublicKey,
|
|
||||||
) -> ServerResult<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,
|
|
||||||
) -> 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<Vec<WhitelistModel>> {
|
|
||||||
whitelister
|
|
||||||
.find_related(WhitelistEntity)
|
|
||||||
.select()
|
|
||||||
.paginate(self, u64::from(page_size.get()))
|
|
||||||
.fetch_page(u64::from(page.get() - 1))
|
|
||||||
.await
|
|
||||||
.map_err(Into::into)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -30,7 +30,7 @@ use salvo::{
|
||||||
|
|
||||||
use super::{ApiError, ApiResult};
|
use super::{ApiError, ApiResult};
|
||||||
use crate::{
|
use crate::{
|
||||||
database::{BlackListExt, UserTableExt, WhiteListExt},
|
database::{UserTableExt, UsersStatusExt},
|
||||||
extensions::DepotExt,
|
extensions::DepotExt,
|
||||||
middlewares,
|
middlewares,
|
||||||
parameters::Pagination,
|
parameters::Pagination,
|
||||||
|
|
|
@ -57,11 +57,11 @@ impl Default for WhiteListedUser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<WhitelistModel> for WhiteListedUser {
|
impl From<UsersStatusModel> for WhiteListedUser {
|
||||||
fn from(user: WhitelistModel) -> Self {
|
fn from(user: UsersStatusModel) -> Self {
|
||||||
Self {
|
Self {
|
||||||
public_key: PublicKey::from_str(&user.target).expect("Is valid public key"),
|
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<BlacklistModel> for BlackListedUser {
|
impl From<UsersStatusModel> for BlackListedUser {
|
||||||
fn from(user: BlacklistModel) -> Self {
|
fn from(user: UsersStatusModel) -> Self {
|
||||||
Self {
|
Self {
|
||||||
public_key: PublicKey::from_str(&user.target).expect("Is valid public key"),
|
public_key: PublicKey::from_str(&user.target).expect("Is valid public key"),
|
||||||
blacklisted_at: user.blacklisted_at,
|
blacklisted_at: user.updated_at,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ use sea_orm::DatabaseConnection;
|
||||||
use crate::database::InChatRequestsExt;
|
use crate::database::InChatRequestsExt;
|
||||||
use crate::extensions::OnlineUsersExt;
|
use crate::extensions::OnlineUsersExt;
|
||||||
use crate::{
|
use crate::{
|
||||||
database::{BlackListExt, OutChatRequestsExt, UserTableExt, WhiteListExt},
|
database::{OutChatRequestsExt, UserTableExt, UsersStatusExt},
|
||||||
try_ws,
|
try_ws,
|
||||||
websocket::{errors::WsError, ServerEvent, Unsigned, ONLINE_USERS},
|
websocket::{errors::WsError, ServerEvent, Unsigned, ONLINE_USERS},
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,9 +19,8 @@
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
|
|
||||||
pub mod blacklist;
|
|
||||||
pub mod incoming_chat_requests;
|
pub mod incoming_chat_requests;
|
||||||
pub mod outgoing_chat_requests;
|
pub mod outgoing_chat_requests;
|
||||||
pub mod prelude;
|
pub mod prelude;
|
||||||
pub mod users;
|
pub mod users;
|
||||||
pub mod whitelist;
|
pub mod users_status;
|
||||||
|
|
|
@ -38,12 +38,6 @@ pub use sea_orm::{
|
||||||
/// User ID type
|
/// User ID type
|
||||||
pub type UserId = i64;
|
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::{
|
pub use super::incoming_chat_requests::{
|
||||||
ActiveModel as InChatRequestsActiveModel,
|
ActiveModel as InChatRequestsActiveModel,
|
||||||
Column as InChatRequestsColumn,
|
Column as InChatRequestsColumn,
|
||||||
|
@ -62,9 +56,10 @@ pub use super::users::{
|
||||||
Entity as UserEntity,
|
Entity as UserEntity,
|
||||||
Model as UserModel,
|
Model as UserModel,
|
||||||
};
|
};
|
||||||
pub use super::whitelist::{
|
pub use super::users_status::{
|
||||||
ActiveModel as WhitelistActiveModel,
|
AccessStatus,
|
||||||
Column as WhitelistColumn,
|
ActiveModel as UsersStatusActiveModel,
|
||||||
Entity as WhitelistEntity,
|
Column as UsersStatusColumn,
|
||||||
Model as WhitelistModel,
|
Entity as UsersStatusEntity,
|
||||||
|
Model as UsersStatusModel,
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,10 +38,8 @@ pub enum Relation {
|
||||||
InChatRequests,
|
InChatRequests,
|
||||||
#[sea_orm(has_many = "OutChatRequestsEntity")]
|
#[sea_orm(has_many = "OutChatRequestsEntity")]
|
||||||
OutChatRequests,
|
OutChatRequests,
|
||||||
#[sea_orm(has_many = "BlacklistEntity")]
|
#[sea_orm(has_many = "UsersStatusEntity")]
|
||||||
Blacklist,
|
UsersStatus,
|
||||||
#[sea_orm(has_many = "WhitelistEntity")]
|
|
||||||
Whitelist,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Related<InChatRequestsEntity> for Entity {
|
impl Related<InChatRequestsEntity> for Entity {
|
||||||
|
@ -56,15 +54,9 @@ impl Related<OutChatRequestsEntity> for Entity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Related<BlacklistEntity> for Entity {
|
impl Related<UsersStatusEntity> for Entity {
|
||||||
fn to() -> RelationDef {
|
fn to() -> RelationDef {
|
||||||
Relation::Blacklist.def()
|
Relation::UsersStatus.def()
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Related<WhitelistEntity> for Entity {
|
|
||||||
fn to() -> RelationDef {
|
|
||||||
Relation::Whitelist.def()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,15 +24,25 @@ use sea_orm::entity::prelude::*;
|
||||||
|
|
||||||
use crate::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)]
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
|
||||||
#[sea_orm(table_name = "blacklist")]
|
#[sea_orm(table_name = "users_status")]
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
#[sea_orm(primary_key)]
|
#[sea_orm(primary_key)]
|
||||||
pub id: UserId,
|
pub id: UserId,
|
||||||
pub user_id: UserId,
|
pub user_id: UserId,
|
||||||
/// Public key of the target
|
/// Public key of the target
|
||||||
pub target: String,
|
pub target: String,
|
||||||
pub blacklisted_at: chrono::DateTime<Utc>,
|
pub status: AccessStatus,
|
||||||
|
pub updated_at: chrono::DateTime<Utc>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
|
@ -1,56 +0,0 @@
|
||||||
// OxideTalis Messaging Protocol homeserver core implementation
|
|
||||||
// Copyright (c) 2024 OxideTalis Developers <otmp@4rs.nl>
|
|
||||||
//
|
|
||||||
// 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<Utc>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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<UserEntity> for Entity {
|
|
||||||
fn to() -> RelationDef {
|
|
||||||
Relation::UserId.def()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ActiveModelBehavior for ActiveModel {}
|
|
|
@ -19,31 +19,59 @@
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
use sea_orm::sea_query::extension::postgres::Type;
|
||||||
use sea_orm_migration::prelude::*;
|
use sea_orm_migration::prelude::*;
|
||||||
|
|
||||||
|
use super::create_users_table::Users;
|
||||||
|
|
||||||
#[derive(DeriveMigrationName)]
|
#[derive(DeriveMigrationName)]
|
||||||
pub struct Migration;
|
pub struct Migration;
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl MigrationTrait for Migration {
|
impl MigrationTrait for Migration {
|
||||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
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
|
manager
|
||||||
.create_table(
|
.create_table(
|
||||||
Table::create()
|
Table::create()
|
||||||
.table(Blacklist::Table)
|
.table(UsersStatus::Table)
|
||||||
.if_not_exists()
|
.if_not_exists()
|
||||||
.col(
|
.col(
|
||||||
ColumnDef::new(Blacklist::Id)
|
ColumnDef::new(UsersStatus::Id)
|
||||||
.big_integer()
|
.big_integer()
|
||||||
.not_null()
|
.not_null()
|
||||||
.auto_increment()
|
.auto_increment()
|
||||||
.primary_key(),
|
.primary_key(),
|
||||||
)
|
)
|
||||||
.col(ColumnDef::new(Blacklist::UserId).big_integer().not_null())
|
.foreign_key(
|
||||||
.col(ColumnDef::new(Blacklist::Target).string().not_null())
|
ForeignKey::create()
|
||||||
.col(ColumnDef::new(Blacklist::Reason).string_len(400))
|
.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(
|
.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()
|
.timestamp_with_time_zone()
|
||||||
.not_null(),
|
.not_null(),
|
||||||
)
|
)
|
||||||
|
@ -53,13 +81,34 @@ impl MigrationTrait for Migration {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum AccessStatus {
|
||||||
|
Name,
|
||||||
|
Whitelisted,
|
||||||
|
Blacklisted,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(DeriveIden)]
|
#[derive(DeriveIden)]
|
||||||
enum Blacklist {
|
enum UsersStatus {
|
||||||
Table,
|
Table,
|
||||||
Id,
|
Id,
|
||||||
UserId,
|
UserId,
|
||||||
/// Public key of the target
|
/// Public key of the target
|
||||||
Target,
|
Target,
|
||||||
Reason,
|
Status,
|
||||||
BlacklistedAt,
|
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")
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,63 +0,0 @@
|
||||||
// OxideTalis Messaging Protocol homeserver core implementation
|
|
||||||
// Copyright (c) 2024 OxideTalis Developers <otmp@4rs.nl>
|
|
||||||
//
|
|
||||||
// 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,
|
|
||||||
}
|
|
|
@ -21,11 +21,10 @@
|
||||||
|
|
||||||
pub use sea_orm_migration::prelude::*;
|
pub use sea_orm_migration::prelude::*;
|
||||||
|
|
||||||
mod create_blacklist_table;
|
|
||||||
mod create_incoming_chat_requests_table;
|
mod create_incoming_chat_requests_table;
|
||||||
mod create_outgoing_chat_requests_table;
|
mod create_outgoing_chat_requests_table;
|
||||||
|
mod create_users_status;
|
||||||
mod create_users_table;
|
mod create_users_table;
|
||||||
mod create_whitelist_table;
|
|
||||||
|
|
||||||
pub struct Migrator;
|
pub struct Migrator;
|
||||||
|
|
||||||
|
@ -36,8 +35,7 @@ impl MigratorTrait for Migrator {
|
||||||
Box::new(create_users_table::Migration),
|
Box::new(create_users_table::Migration),
|
||||||
Box::new(create_incoming_chat_requests_table::Migration),
|
Box::new(create_incoming_chat_requests_table::Migration),
|
||||||
Box::new(create_outgoing_chat_requests_table::Migration),
|
Box::new(create_outgoing_chat_requests_table::Migration),
|
||||||
Box::new(create_blacklist_table::Migration),
|
Box::new(create_users_status::Migration),
|
||||||
Box::new(create_whitelist_table::Migration),
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue