From 747e27c4af3144db069ad214a128de4ba38c41fb Mon Sep 17 00:00:00 2001
From: Awiteb
Date: Tue, 16 Jul 2024 17:03:54 +0300
Subject: [PATCH] feat: Endpoint to returns user blacklisted users
Signed-off-by: Awiteb
---
crates/oxidetalis/src/database/blacklist.rs | 25 ++++++++++++
crates/oxidetalis/src/routes/user.rs | 44 ++++++++++++++++++++-
crates/oxidetalis/src/schemas/user.rs | 27 +++++++++++++
3 files changed, 94 insertions(+), 2 deletions(-)
diff --git a/crates/oxidetalis/src/database/blacklist.rs b/crates/oxidetalis/src/database/blacklist.rs
index 2215ad2..f2f9229 100644
--- a/crates/oxidetalis/src/database/blacklist.rs
+++ b/crates/oxidetalis/src/database/blacklist.rs
@@ -16,6 +16,8 @@
//! 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::*;
@@ -39,6 +41,14 @@ pub trait BlackListExt {
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 {
@@ -78,4 +88,19 @@ impl BlackListExt for DatabaseConnection {
.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/routes/user.rs b/crates/oxidetalis/src/routes/user.rs
index febdc14..abd384d 100644
--- a/crates/oxidetalis/src/routes/user.rs
+++ b/crates/oxidetalis/src/routes/user.rs
@@ -30,11 +30,11 @@ use salvo::{
use super::{ApiError, ApiResult};
use crate::{
- database::{UserTableExt, WhiteListExt},
+ database::{BlackListExt, UserTableExt, WhiteListExt},
extensions::DepotExt,
middlewares,
parameters::Pagination,
- schemas::{EmptySchema, MessageSchema, RegisterUserBody, WhiteListedUser},
+ schemas::{BlackListedUser, EmptySchema, MessageSchema, RegisterUserBody, WhiteListedUser},
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),
+ (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>> {
+ 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
pub fn route() -> Router {
Router::new()
.push(Router::with_path("register").post(register))
.push(Router::with_path("whitelist").get(user_whitelist))
+ .push(Router::with_path("blacklist").get(user_blacklist))
.hoop(middlewares::public_key_check)
.hoop(middlewares::signature_check)
}
diff --git a/crates/oxidetalis/src/schemas/user.rs b/crates/oxidetalis/src/schemas/user.rs
index dd90f09..c853ebd 100644
--- a/crates/oxidetalis/src/schemas/user.rs
+++ b/crates/oxidetalis/src/schemas/user.rs
@@ -39,6 +39,15 @@ pub struct WhiteListedUser {
pub whitelisted_at: DateTime,
}
+#[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,
+}
+
impl Default for WhiteListedUser {
fn default() -> Self {
WhiteListedUser::new(
@@ -56,3 +65,21 @@ impl From for WhiteListedUser {
}
}
}
+
+impl Default for BlackListedUser {
+ fn default() -> Self {
+ BlackListedUser::new(
+ PublicKey::from_str("bYhbrm61ov8GLZfskUYbsCLJTfaacMsuTBYgBABEH9dy").expect("is valid"),
+ Utc::now(),
+ )
+ }
+}
+
+impl From 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,
+ }
+ }
+}