feat: Chat request implementation #14

Manually merged
awiteb merged 55 commits from awiteb/chat-request-and-response into master 2024-07-18 14:21:39 +02:00 AGit
3 changed files with 94 additions and 2 deletions
Showing only changes of commit 747e27c4af - Show all commits

View file

@ -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)
}
} }

View file

@ -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)
} }

View file

@ -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,
}
}
}