use lemmy_api_common::{
blocking,
build_federated_instances,
+ check_private_instance,
get_local_user_view_from_jwt,
get_local_user_view_from_jwt_opt,
is_admin,
+ send_application_approved_email,
site::*,
};
use lemmy_apub::{
- fetcher::search::{search_by_apub_id, SearchableObjects},
- get_actor_id_from_name,
+ fetcher::{
+ search::{search_by_apub_id, SearchableObjects},
+ webfinger::webfinger_resolve,
+ },
+ objects::community::ApubCommunity,
+ EndpointType,
};
-use lemmy_apub_lib::webfinger::WebfingerType;
use lemmy_db_schema::{
+ diesel_option_overwrite,
from_opt_str_to_opt_enum,
newtypes::PersonId,
- source::{moderator::*, site::Site},
+ source::{
+ local_user::{LocalUser, LocalUserForm},
+ moderator::*,
+ registration_application::{RegistrationApplication, RegistrationApplicationForm},
+ site::Site,
+ },
traits::{Crud, DeleteableOrRemoveable},
DbPool,
ListingType,
};
use lemmy_db_views::{
comment_view::{CommentQueryBuilder, CommentView},
+ local_user_view::LocalUserView,
post_view::{PostQueryBuilder, PostView},
+ registration_application_view::{
+ RegistrationApplicationQueryBuilder,
+ RegistrationApplicationView,
+ },
site_view::SiteView,
};
use lemmy_db_views_actor::{
mod_sticky_post_view::ModStickyPostView,
mod_transfer_community_view::ModTransferCommunityView,
};
-use lemmy_utils::{
- location_info,
- settings::structs::Settings,
- version,
- ApiError,
- ConnectionId,
- LemmyError,
-};
+use lemmy_utils::{location_info, settings::structs::Settings, version, ConnectionId, LemmyError};
use lemmy_websocket::LemmyContext;
#[async_trait::async_trait(?Send)]
impl Perform for GetModlog {
type Response = GetModlogResponse;
+ #[tracing::instrument(skip(context, _websocket_id))]
async fn perform(
&self,
context: &Data<LemmyContext>,
) -> Result<GetModlogResponse, LemmyError> {
let data: &GetModlog = self;
+ let local_user_view =
+ get_local_user_view_from_jwt_opt(data.auth.as_ref(), context.pool(), context.secret())
+ .await?;
+
+ check_private_instance(&local_user_view, context.pool()).await?;
+
let community_id = data.community_id;
let mod_person_id = data.mod_person_id;
let page = data.page;
impl Perform for Search {
type Response = SearchResponse;
+ #[tracing::instrument(skip(context, _websocket_id))]
async fn perform(
&self,
context: &Data<LemmyContext>,
let data: &Search = self;
let local_user_view =
- get_local_user_view_from_jwt_opt(&data.auth, context.pool(), context.secret()).await?;
+ get_local_user_view_from_jwt_opt(data.auth.as_ref(), context.pool(), context.secret())
+ .await?;
+
+ check_private_instance(&local_user_view, context.pool()).await?;
let show_nsfw = local_user_view.as_ref().map(|t| t.local_user.show_nsfw);
let show_bot_accounts = local_user_view
let search_type: SearchType = from_opt_str_to_opt_enum(&data.type_).unwrap_or(SearchType::All);
let community_id = data.community_id;
let community_actor_id = if let Some(name) = &data.community_name {
- get_actor_id_from_name(WebfingerType::Group, name, context)
+ webfinger_resolve::<ApubCommunity>(name, EndpointType::Community, context, &mut 0)
.await
.ok()
} else {
impl Perform for ResolveObject {
type Response = ResolveObjectResponse;
+ #[tracing::instrument(skip(context, _websocket_id))]
async fn perform(
&self,
context: &Data<LemmyContext>,
_websocket_id: Option<ConnectionId>,
) -> Result<ResolveObjectResponse, LemmyError> {
let local_user_view =
- get_local_user_view_from_jwt_opt(&self.auth, context.pool(), context.secret()).await?;
+ get_local_user_view_from_jwt_opt(self.auth.as_ref(), context.pool(), context.secret())
+ .await?;
+ check_private_instance(&local_user_view, context.pool()).await?;
+
let res = search_by_apub_id(&self.q, context)
.await
- .map_err(|e| ApiError::err("couldnt_find_object", e))?;
+ .map_err(LemmyError::from)
+ .map_err(|e| e.with_message("couldnt_find_object"))?;
convert_response(res, local_user_view.map(|l| l.person.id), context.pool())
.await
- .map_err(|e| ApiError::err("couldnt_find_object", e).into())
+ .map_err(LemmyError::from)
+ .map_err(|e| e.with_message("couldnt_find_object"))
}
}
impl Perform for TransferSite {
type Response = GetSiteResponse;
+ #[tracing::instrument(skip(context, _websocket_id))]
async fn perform(
&self,
context: &Data<LemmyContext>,
// Make sure user is the creator
if read_site.creator_id != local_user_view.person.id {
- return Err(ApiError::err_plain("not_an_admin").into());
+ return Err(LemmyError::from_message("not_an_admin"));
}
let new_creator_id = data.person_id;
let transfer_site = move |conn: &'_ _| Site::transfer(conn, new_creator_id);
blocking(context.pool(), transfer_site)
.await?
- .map_err(|e| ApiError::err("couldnt_update_site", e))?;
+ .map_err(LemmyError::from)
+ .map_err(|e| e.with_message("couldnt_update_site"))?;
// Mod tables
let form = ModAddForm {
impl Perform for GetSiteConfig {
type Response = GetSiteConfigResponse;
+ #[tracing::instrument(skip(context, _websocket_id))]
async fn perform(
&self,
context: &Data<LemmyContext>,
impl Perform for SaveSiteConfig {
type Response = GetSiteConfigResponse;
+ #[tracing::instrument(skip(context, _websocket_id))]
async fn perform(
&self,
context: &Data<LemmyContext>,
// Make sure docker doesn't have :ro at the end of the volume, so its not a read-only filesystem
let config_hjson = Settings::save_config_file(&data.config_hjson)
- .map_err(|e| ApiError::err("couldnt_update_site", e))?;
+ .map_err(LemmyError::from)
+ .map_err(|e| e.with_message("couldnt_update_site"))?;
Ok(GetSiteConfigResponse { config_hjson })
}
}
+
+/// Lists registration applications, filterable by undenied only.
+#[async_trait::async_trait(?Send)]
+impl Perform for ListRegistrationApplications {
+ type Response = ListRegistrationApplicationsResponse;
+
+ async fn perform(
+ &self,
+ context: &Data<LemmyContext>,
+ _websocket_id: Option<ConnectionId>,
+ ) -> Result<Self::Response, LemmyError> {
+ let data = self;
+ let local_user_view =
+ get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
+
+ // Make sure user is an admin
+ is_admin(&local_user_view)?;
+
+ let unread_only = data.unread_only;
+ let verified_email_only = blocking(context.pool(), Site::read_simple)
+ .await??
+ .require_email_verification;
+
+ let page = data.page;
+ let limit = data.limit;
+ let registration_applications = blocking(context.pool(), move |conn| {
+ RegistrationApplicationQueryBuilder::create(conn)
+ .unread_only(unread_only)
+ .verified_email_only(verified_email_only)
+ .page(page)
+ .limit(limit)
+ .list()
+ })
+ .await??;
+
+ let res = Self::Response {
+ registration_applications,
+ };
+
+ Ok(res)
+ }
+}
+
+#[async_trait::async_trait(?Send)]
+impl Perform for ApproveRegistrationApplication {
+ type Response = RegistrationApplicationResponse;
+
+ async fn perform(
+ &self,
+ context: &Data<LemmyContext>,
+ _websocket_id: Option<ConnectionId>,
+ ) -> Result<Self::Response, LemmyError> {
+ let data = self;
+ let local_user_view =
+ get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
+
+ let app_id = data.id;
+
+ // Only let admins do this
+ is_admin(&local_user_view)?;
+
+ // Update the registration with reason, admin_id
+ let deny_reason = diesel_option_overwrite(&data.deny_reason);
+ let app_form = RegistrationApplicationForm {
+ admin_id: Some(local_user_view.person.id),
+ deny_reason,
+ ..RegistrationApplicationForm::default()
+ };
+
+ let registration_application = blocking(context.pool(), move |conn| {
+ RegistrationApplication::update(conn, app_id, &app_form)
+ })
+ .await??;
+
+ // Update the local_user row
+ let local_user_form = LocalUserForm {
+ accepted_application: Some(data.approve),
+ ..LocalUserForm::default()
+ };
+
+ let approved_user_id = registration_application.local_user_id;
+ blocking(context.pool(), move |conn| {
+ LocalUser::update(conn, approved_user_id, &local_user_form)
+ })
+ .await??;
+
+ if data.approve {
+ let approved_local_user_view = blocking(context.pool(), move |conn| {
+ LocalUserView::read(conn, approved_user_id)
+ })
+ .await??;
+
+ if approved_local_user_view.local_user.email.is_some() {
+ send_application_approved_email(&approved_local_user_view, &context.settings())?;
+ }
+ }
+
+ // Read the view
+ let registration_application = blocking(context.pool(), move |conn| {
+ RegistrationApplicationView::read(conn, app_id)
+ })
+ .await??;
+
+ Ok(Self::Response {
+ registration_application,
+ })
+ }
+}
+
+#[async_trait::async_trait(?Send)]
+impl Perform for GetUnreadRegistrationApplicationCount {
+ type Response = GetUnreadRegistrationApplicationCountResponse;
+
+ async fn perform(
+ &self,
+ context: &Data<LemmyContext>,
+ _websocket_id: Option<ConnectionId>,
+ ) -> Result<Self::Response, LemmyError> {
+ let data = self;
+ let local_user_view =
+ get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
+
+ // Only let admins do this
+ is_admin(&local_user_view)?;
+
+ let verified_email_only = blocking(context.pool(), Site::read_simple)
+ .await??
+ .require_email_verification;
+
+ let registration_applications = blocking(context.pool(), move |conn| {
+ RegistrationApplicationView::get_unread_count(conn, verified_email_only)
+ })
+ .await??;
+
+ Ok(Self::Response {
+ registration_applications,
+ })
+ }
+}