summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/models/warning.rs71
-rw-r--r--src/routes/warning.rs65
2 files changed, 126 insertions, 10 deletions
diff --git a/src/models/warning.rs b/src/models/warning.rs
index 200f671..f6a4963 100644
--- a/src/models/warning.rs
+++ b/src/models/warning.rs
@@ -23,6 +23,18 @@ pub struct WarningCreate {
pub note: String,
}
+/// Payload used for warning filtering
+#[derive(Deserialize)]
+pub struct WarningFilterPayload {
+ pub model_id: i32,
+}
+
+/// Struct used as argument for filtering by the backend
+pub struct WarningFilter {
+ pub model_id: i32,
+ pub user_id: Option<i32>,
+}
+
impl Warning {
/// Create a warning means create an object which has an `user_id` (creator of the warning), a
/// `model_id` (suspect model) and a `note`
@@ -119,4 +131,63 @@ impl Warning {
Ok(rec)
}
+
+ /// Filter warnings. Pass a `WarningFilter` argument
+ pub async fn filter(page: i64, args: WarningFilter) -> Result<Vec<Warning>, AppError> {
+ let pool = unsafe { get_client() };
+
+ let query = r#"
+ SELECT * FROM warnings WHERE model_id = $1
+ "#;
+
+ let rows: Vec<Warning> = match args.user_id {
+ Some(id) => {
+ sqlx::query_as(&format!(r#"{} AND user_id = $2 LIMIT $3 OFFSET $4"#, query))
+ .bind(args.model_id)
+ .bind(id)
+ .bind(CONFIG.page_limit)
+ .bind(CONFIG.page_limit * page)
+ .fetch_all(pool)
+ .await?
+ }
+ None => {
+ sqlx::query_as(&format!(r#"{} LIMIT $2 OFFSET $3"#, query))
+ .bind(args.model_id)
+ .bind(CONFIG.page_limit)
+ .bind(CONFIG.page_limit * page)
+ .fetch_all(pool)
+ .await?
+ }
+ };
+
+ Ok(rows)
+ }
+
+ /// Return the number of filtered warnings.
+ pub async fn count_by_model_id(args: WarningFilter) -> Result<i64, AppError> {
+ let pool = unsafe { get_client() };
+
+ let query = r#"
+ SELECT COUNT(id) as count FROM warnings WHERE model_id = $1
+ "#;
+
+ let cursor = match args.user_id {
+ Some(id) => {
+ sqlx::query(&format!(r#"{} AND user_id = $2"#, query))
+ .bind(args.model_id)
+ .bind(id)
+ .fetch_one(pool)
+ .await?
+ }
+ None => {
+ sqlx::query(&format!(r#"{}"#, query))
+ .bind(args.model_id)
+ .fetch_one(pool)
+ .await?
+ }
+ };
+
+ let count: i64 = cursor.try_get(0).unwrap();
+ Ok(count)
+ }
}
diff --git a/src/routes/warning.rs b/src/routes/warning.rs
index 1870843..3a8573e 100644
--- a/src/routes/warning.rs
+++ b/src/routes/warning.rs
@@ -4,23 +4,22 @@ use crate::{
auth::Claims,
model::Model,
user::User,
- warning::{Warning, WarningCreate},
+ warning::{Warning, WarningCreate, WarningFilter, WarningFilterPayload},
},
pagination::{Pagination, WarningPagination},
routes::JsonCreate,
};
-use axum::{extract::Query, routing::get, Json, Router};
-use serde::Serialize;
+use axum::{
+ extract::Query,
+ routing::{get, post},
+ Json, Router,
+};
/// Create routes for `/v1/warnings/` namespace
pub fn create_route() -> Router {
- Router::new().route("/", get(list_warnings).post(create_warning))
-}
-
-#[derive(Serialize)]
-struct WarningPagination {
- count: i64,
- results: Vec<Warning>,
+ Router::new()
+ .route("/", get(list_warnings).post(create_warning))
+ .route("/filter", post(filter_warnings))
}
/// List warnings. A staffer can see everything.
@@ -62,3 +61,49 @@ async fn create_warning(
Ok(JsonCreate(warning_new))
}
+
+/// Apply a filter to warnings list
+async fn filter_warnings(
+ Json(payload): Json<WarningFilterPayload>,
+ pagination: Query<Pagination>,
+ claims: Claims,
+) -> Result<Json<WarningPagination>, AppError> {
+ let page = pagination.0.page.unwrap_or_default();
+
+ let user = User::find_by_id(claims.user_id).await?;
+
+ let (results, count) = match user.is_staff.unwrap() {
+ true => (
+ Warning::filter(
+ page,
+ WarningFilter {
+ model_id: payload.model_id,
+ user_id: None,
+ },
+ )
+ .await?,
+ Warning::count_by_model_id(WarningFilter {
+ model_id: payload.model_id,
+ user_id: None,
+ })
+ .await?,
+ ),
+ false => (
+ Warning::filter(
+ page,
+ WarningFilter {
+ model_id: payload.model_id,
+ user_id: Some(user.id),
+ },
+ )
+ .await?,
+ Warning::count_by_model_id(WarningFilter {
+ model_id: payload.model_id,
+ user_id: Some(user.id),
+ })
+ .await?,
+ ),
+ };
+
+ Ok(Json(WarningPagination { count, results }))
+}