feat: Chat request implementation #14
3 changed files with 94 additions and 2 deletions
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
//! Database extension to work with the blacklist table
|
//! Database extension to work with the blacklist table
|
||||||
|
|
||||||
|
use std::num::{NonZeroU32, NonZeroU8};
|
||||||
|
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use oxidetalis_core::types::PublicKey;
|
use oxidetalis_core::types::PublicKey;
|
||||||
use oxidetalis_entities::prelude::*;
|
use oxidetalis_entities::prelude::*;
|
||||||
|
@ -39,6 +41,14 @@ pub trait BlackListExt {
|
||||||
blacklister: &UserModel,
|
blacklister: &UserModel,
|
||||||
target_public_key: &PublicKey,
|
target_public_key: &PublicKey,
|
||||||
) -> ServerResult<()>;
|
) -> 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 {
|
impl BlackListExt for DatabaseConnection {
|
||||||
|
@ -78,4 +88,19 @@ impl BlackListExt for DatabaseConnection {
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,11 +30,11 @@ use salvo::{
|
||||||
|
|
||||||
use super::{ApiError, ApiResult};
|
use super::{ApiError, ApiResult};
|
||||||
use crate::{
|
use crate::{
|
||||||
database::{UserTableExt, WhiteListExt},
|
database::{BlackListExt, UserTableExt, WhiteListExt},
|
||||||
extensions::DepotExt,
|
extensions::DepotExt,
|
||||||
middlewares,
|
middlewares,
|
||||||
parameters::Pagination,
|
parameters::Pagination,
|
||||||
schemas::{EmptySchema, MessageSchema, RegisterUserBody, WhiteListedUser},
|
schemas::{BlackListedUser, EmptySchema, MessageSchema, RegisterUserBody, WhiteListedUser},
|
||||||
utils,
|
utils,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -121,11 +121,51 @@ async fn user_whitelist(
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// (🔐) Get blacklisted users
|
||||||
|
#[endpoint(
|
||||||
|
operation_id = "blacklist",
|
||||||
|
tags("User"),
|
||||||
|
responses(
|
||||||
|
(status_code = 200, description = "Returns blacklisted users", content_type = "application/json", body = Vec<BlackListedUser>),
|
||||||
|
(status_code = 403, description = "Not registered user, must register first", content_type = "application/json", body = MessageSchema),
|
||||||
|
(status_code = 401, description = "The entered signature or public key is invalid", content_type = "application/json", body = MessageSchema),
|
||||||
|
(status_code = 429, description = "Too many requests", content_type = "application/json", body = MessageSchema),
|
||||||
|
(status_code = 500, description = "Internal server error", content_type = "application/json", body = MessageSchema),
|
||||||
|
),
|
||||||
|
parameters(
|
||||||
|
Pagination,
|
||||||
|
("X-OTMP-PUBLIC" = PublicKey, Header, description = "Public key of the sender"),
|
||||||
|
("X-OTMP-SIGNATURE" = Signature, Header, description = "Signature of the request"),
|
||||||
|
),
|
||||||
|
)]
|
||||||
|
async fn user_blacklist(
|
||||||
|
req: &mut Request,
|
||||||
|
depot: &mut Depot,
|
||||||
|
) -> ApiResult<Json<Vec<BlackListedUser>>> {
|
||||||
|
let pagination = Pagination::extract(req).await?;
|
||||||
|
let conn = depot.db_conn();
|
||||||
|
let user = conn
|
||||||
|
.get_user_by_pubk(
|
||||||
|
&utils::extract_public_key(req)
|
||||||
|
.expect("Public key should be checked in the middleware"),
|
||||||
|
)
|
||||||
|
.await?
|
||||||
|
.ok_or(ApiError::NotRegisteredUser)?;
|
||||||
|
Ok(Json(
|
||||||
|
conn.user_blacklist(&user, pagination.page, pagination.page_size)
|
||||||
|
.await?
|
||||||
|
.into_iter()
|
||||||
|
.map(Into::into)
|
||||||
|
.collect(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
/// The route of the endpoints of this module
|
/// The route of the endpoints of this module
|
||||||
pub fn route() -> Router {
|
pub fn route() -> Router {
|
||||||
Router::new()
|
Router::new()
|
||||||
.push(Router::with_path("register").post(register))
|
.push(Router::with_path("register").post(register))
|
||||||
.push(Router::with_path("whitelist").get(user_whitelist))
|
.push(Router::with_path("whitelist").get(user_whitelist))
|
||||||
|
.push(Router::with_path("blacklist").get(user_blacklist))
|
||||||
.hoop(middlewares::public_key_check)
|
.hoop(middlewares::public_key_check)
|
||||||
.hoop(middlewares::signature_check)
|
.hoop(middlewares::signature_check)
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,15 @@ pub struct WhiteListedUser {
|
||||||
pub whitelisted_at: DateTime<Utc>,
|
pub whitelisted_at: DateTime<Utc>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Debug, ToSchema, derive_new::new)]
|
||||||
|
#[salvo(schema(name = BlackListedUser, example = json!(BlackListedUser::default())))]
|
||||||
|
pub struct BlackListedUser {
|
||||||
|
/// User's public key
|
||||||
|
pub public_key: PublicKey,
|
||||||
|
/// When the user was blacklisted
|
||||||
|
pub blacklisted_at: DateTime<Utc>,
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for WhiteListedUser {
|
impl Default for WhiteListedUser {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
WhiteListedUser::new(
|
WhiteListedUser::new(
|
||||||
|
@ -56,3 +65,21 @@ impl From<WhitelistModel> for WhiteListedUser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for BlackListedUser {
|
||||||
|
fn default() -> Self {
|
||||||
|
BlackListedUser::new(
|
||||||
|
PublicKey::from_str("bYhbrm61ov8GLZfskUYbsCLJTfaacMsuTBYgBABEH9dy").expect("is valid"),
|
||||||
|
Utc::now(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<BlacklistModel> for BlackListedUser {
|
||||||
|
fn from(user: BlacklistModel) -> Self {
|
||||||
|
Self {
|
||||||
|
public_key: PublicKey::from_str(&user.target).expect("Is valid public key"),
|
||||||
|
blacklisted_at: user.blacklisted_at,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue