diff --git a/crates/api/src/site/registration_applications/get.rs b/crates/api/src/site/registration_applications/get.rs new file mode 100644 index 000000000..2d5d6bf5b --- /dev/null +++ b/crates/api/src/site/registration_applications/get.rs @@ -0,0 +1,28 @@ +use actix_web::web::{Data, Json, Query}; +use lemmy_api_common::{ + context::LemmyContext, + site::{GetRegistrationApplication, RegistrationApplicationResponse}, + utils::is_admin, +}; +use lemmy_db_views::structs::{LocalUserView, RegistrationApplicationView}; +use lemmy_utils::{error::LemmyResult, LemmyErrorType}; + +/// Lists registration applications, filterable by undenied only. +pub async fn get_registration_application( + data: Query, + context: Data, + local_user_view: LocalUserView, +) -> LemmyResult> { + // Make sure user is an admin + is_admin(&local_user_view)?; + + // Read the view + let registration_application = + RegistrationApplicationView::read_by_person(&mut context.pool(), data.person_id) + .await? + .ok_or(LemmyErrorType::CouldntFindRegistrationApplication)?; + + Ok(Json(RegistrationApplicationResponse { + registration_application, + })) +} diff --git a/crates/api/src/site/registration_applications/mod.rs b/crates/api/src/site/registration_applications/mod.rs index e5082615a..e904f597d 100644 --- a/crates/api/src/site/registration_applications/mod.rs +++ b/crates/api/src/site/registration_applications/mod.rs @@ -1,3 +1,4 @@ pub mod approve; +pub mod get; pub mod list; pub mod unread_count; diff --git a/crates/api_common/src/site.rs b/crates/api_common/src/site.rs index 77bfcd8ee..3850de1c6 100644 --- a/crates/api_common/src/site.rs +++ b/crates/api_common/src/site.rs @@ -1,7 +1,15 @@ use crate::federate_retry_sleep_duration; use chrono::{DateTime, Utc}; use lemmy_db_schema::{ - newtypes::{CommentId, CommunityId, InstanceId, LanguageId, PersonId, PostId}, + newtypes::{ + CommentId, + CommunityId, + InstanceId, + LanguageId, + PersonId, + PostId, + RegistrationApplicationId, + }, source::{ federation_queue_state::FederationQueueState, instance::Instance, @@ -440,13 +448,22 @@ pub struct ListRegistrationApplicationsResponse { pub registration_applications: Vec, } +#[skip_serializing_none] +#[derive(Debug, Serialize, Deserialize, Clone, Copy, Default, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "full", derive(TS))] +#[cfg_attr(feature = "full", ts(export))] +/// Gets a registration application for a person +pub struct GetRegistrationApplication { + pub person_id: PersonId, +} + #[skip_serializing_none] #[derive(Debug, Serialize, Deserialize, Clone, Default, PartialEq, Eq, Hash)] #[cfg_attr(feature = "full", derive(TS))] #[cfg_attr(feature = "full", ts(export))] /// Approves a registration application. pub struct ApproveRegistrationApplication { - pub id: i32, + pub id: RegistrationApplicationId, pub approve: bool, pub deny_reason: Option, } diff --git a/crates/db_schema/src/impls/registration_application.rs b/crates/db_schema/src/impls/registration_application.rs index 46b7d4bee..055ffb51f 100644 --- a/crates/db_schema/src/impls/registration_application.rs +++ b/crates/db_schema/src/impls/registration_application.rs @@ -1,6 +1,6 @@ use crate::{ diesel::OptionalExtension, - newtypes::LocalUserId, + newtypes::{LocalUserId, RegistrationApplicationId}, schema::registration_application::dsl::{local_user_id, registration_application}, source::registration_application::{ RegistrationApplication, @@ -17,7 +17,7 @@ use diesel_async::RunQueryDsl; impl Crud for RegistrationApplication { type InsertForm = RegistrationApplicationInsertForm; type UpdateForm = RegistrationApplicationUpdateForm; - type IdType = i32; + type IdType = RegistrationApplicationId; async fn create(pool: &mut DbPool<'_>, form: &Self::InsertForm) -> Result { let conn = &mut get_conn(pool).await?; diff --git a/crates/db_schema/src/newtypes.rs b/crates/db_schema/src/newtypes.rs index 9aeaa5266..c715305bb 100644 --- a/crates/db_schema/src/newtypes.rs +++ b/crates/db_schema/src/newtypes.rs @@ -148,6 +148,12 @@ pub struct LocalSiteId(i32); /// The custom emoji id. pub struct CustomEmojiId(i32); +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Default)] +#[cfg_attr(feature = "full", derive(DieselNewType, TS))] +#[cfg_attr(feature = "full", ts(export))] +/// The registration application id. +pub struct RegistrationApplicationId(i32); + #[cfg(feature = "full")] #[derive(Serialize, Deserialize)] #[serde(remote = "Ltree")] diff --git a/crates/db_schema/src/source/registration_application.rs b/crates/db_schema/src/source/registration_application.rs index 2824951d7..2ac973f34 100644 --- a/crates/db_schema/src/source/registration_application.rs +++ b/crates/db_schema/src/source/registration_application.rs @@ -1,4 +1,4 @@ -use crate::newtypes::{LocalUserId, PersonId}; +use crate::newtypes::{LocalUserId, PersonId, RegistrationApplicationId}; #[cfg(feature = "full")] use crate::schema::registration_application; use chrono::{DateTime, Utc}; @@ -15,7 +15,7 @@ use ts_rs::TS; #[cfg_attr(feature = "full", ts(export))] /// A registration application. pub struct RegistrationApplication { - pub id: i32, + pub id: RegistrationApplicationId, pub local_user_id: LocalUserId, pub answer: String, pub admin_id: Option, diff --git a/crates/db_views/src/registration_application_view.rs b/crates/db_views/src/registration_application_view.rs index 9a85d534a..54c7f7598 100644 --- a/crates/db_views/src/registration_application_view.rs +++ b/crates/db_views/src/registration_application_view.rs @@ -11,12 +11,18 @@ use diesel::{ use diesel_async::RunQueryDsl; use lemmy_db_schema::{ aliases, + newtypes::{PersonId, RegistrationApplicationId}, schema::{local_user, person, registration_application}, utils::{get_conn, limit_and_offset, DbConn, DbPool, ListFn, Queries, ReadFn}, }; +enum ReadBy { + Id(RegistrationApplicationId), + Person(PersonId), +} + fn queries<'a>() -> Queries< - impl ReadFn<'a, RegistrationApplicationView, i32>, + impl ReadFn<'a, RegistrationApplicationView, ReadBy>, impl ListFn<'a, RegistrationApplicationView, RegistrationApplicationQuery>, > { let all_joins = |query: registration_application::BoxedQuery<'a, Pg>| { @@ -36,14 +42,15 @@ fn queries<'a>() -> Queries< )) }; - let read = move |mut conn: DbConn<'a>, registration_application_id: i32| async move { - all_joins( - registration_application::table - .find(registration_application_id) - .into_boxed(), - ) - .first(&mut conn) - .await + let read = move |mut conn: DbConn<'a>, search: ReadBy| async move { + let mut query = all_joins(registration_application::table.into_boxed()); + + query = match search { + ReadBy::Id(id) => query.filter(registration_application::id.eq(id)), + ReadBy::Person(person_id) => query.filter(person::id.eq(person_id)), + }; + + query.first(&mut conn).await }; let list = move |mut conn: DbConn<'a>, options: RegistrationApplicationQuery| async move { @@ -76,11 +83,17 @@ fn queries<'a>() -> Queries< impl RegistrationApplicationView { pub async fn read( pool: &mut DbPool<'_>, - registration_application_id: i32, + id: RegistrationApplicationId, ) -> Result, Error> { - queries().read(pool, registration_application_id).await + queries().read(pool, ReadBy::Id(id)).await } + pub async fn read_by_person( + pool: &mut DbPool<'_>, + person_id: PersonId, + ) -> Result, Error> { + queries().read(pool, ReadBy::Person(person_id)).await + } /// Returns the current unread registration_application count pub async fn get_unread_count( pool: &mut DbPool<'_>, diff --git a/src/api_routes_http.rs b/src/api_routes_http.rs index 2a15b4ca6..7b4b34158 100644 --- a/src/api_routes_http.rs +++ b/src/api_routes_http.rs @@ -82,6 +82,7 @@ use lemmy_api::{ }, registration_applications::{ approve::approve_registration_application, + get::get_registration_application, list::list_registration_applications, unread_count::get_unread_registration_application_count, }, @@ -361,6 +362,10 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) { "/registration_application/approve", web::put().to(approve_registration_application), ) + .route( + "/registration_application", + web::get().to(get_registration_application), + ) .route("/list_all_media", web::get().to(list_all_media)) .service( web::scope("/purge")