From 5fe7de2bff31843cbf012c25c4e19538073a88b1 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Tue, 20 Jul 2021 00:29:50 -0400 Subject: [PATCH] Adding shortname fetching for users and communities. Fixes #1662 (#1663) --- crates/api/src/site.rs | 21 ++++++++----- crates/api_common/src/community.rs | 1 + crates/api_common/src/person.rs | 1 + crates/api_crud/src/comment/read.rs | 9 ++++-- crates/api_crud/src/community/read.rs | 12 +++---- crates/api_crud/src/post/read.rs | 9 ++++-- crates/api_crud/src/user/read.rs | 15 +++++---- crates/apub/src/lib.rs | 45 +++++++++++++++++++++------ crates/db_views/src/comment_view.rs | 15 +++++---- crates/db_views/src/post_view.rs | 14 ++++----- 10 files changed, 92 insertions(+), 50 deletions(-) diff --git a/crates/api/src/site.rs b/crates/api/src/site.rs index 53f9bd305..f9d7962be 100644 --- a/crates/api/src/site.rs +++ b/crates/api/src/site.rs @@ -10,7 +10,7 @@ use lemmy_api_common::{ is_admin, site::*, }; -use lemmy_apub::fetcher::search::search_by_apub_id; +use lemmy_apub::{build_actor_id_from_shortname, fetcher::search::search_by_apub_id, EndpointType}; use lemmy_db_queries::{ from_opt_str_to_opt_enum, source::site::Site_, @@ -167,7 +167,11 @@ impl Perform for Search { let listing_type: Option = from_opt_str_to_opt_enum(&data.listing_type); let search_type: SearchType = from_opt_str_to_opt_enum(&data.type_).unwrap_or(SearchType::All); let community_id = data.community_id; - let community_name = data.community_name.to_owned(); + let community_actor_id = data + .community_name + .as_ref() + .map(|t| build_actor_id_from_shortname(EndpointType::Community, t).ok()) + .unwrap_or(None); let creator_id = data.creator_id; match search_type { SearchType::Posts => { @@ -179,7 +183,7 @@ impl Perform for Search { .show_read_posts(show_read_posts) .listing_type(listing_type) .community_id(community_id) - .community_name(community_name) + .community_actor_id(community_actor_id) .creator_id(creator_id) .my_person_id(person_id) .search_term(q) @@ -197,7 +201,7 @@ impl Perform for Search { .search_term(q) .show_bot_accounts(show_bot_accounts) .community_id(community_id) - .community_name(community_name) + .community_actor_id(community_actor_id) .creator_id(creator_id) .my_person_id(person_id) .page(page) @@ -234,6 +238,7 @@ impl Perform for Search { // If the community or creator is included, dont search communities or users let community_or_creator_included = data.community_id.is_some() || data.community_name.is_some() || data.creator_id.is_some(); + let community_actor_id_2 = community_actor_id.to_owned(); posts = blocking(context.pool(), move |conn| { PostQueryBuilder::create(conn) @@ -243,7 +248,7 @@ impl Perform for Search { .show_read_posts(show_read_posts) .listing_type(listing_type) .community_id(community_id) - .community_name(community_name) + .community_actor_id(community_actor_id_2) .creator_id(creator_id) .my_person_id(person_id) .search_term(q) @@ -254,7 +259,7 @@ impl Perform for Search { .await??; let q = data.q.to_owned(); - let community_name = data.community_name.to_owned(); + let community_actor_id = community_actor_id.to_owned(); comments = blocking(context.pool(), move |conn| { CommentQueryBuilder::create(conn) @@ -263,7 +268,7 @@ impl Perform for Search { .search_term(q) .show_bot_accounts(show_bot_accounts) .community_id(community_id) - .community_name(community_name) + .community_actor_id(community_actor_id) .creator_id(creator_id) .my_person_id(person_id) .page(page) @@ -316,7 +321,7 @@ impl Perform for Search { .listing_type(listing_type) .my_person_id(person_id) .community_id(community_id) - .community_name(community_name) + .community_actor_id(community_actor_id) .creator_id(creator_id) .url_search(q) .page(page) diff --git a/crates/api_common/src/community.rs b/crates/api_common/src/community.rs index 129b149ad..ab4e9d2a1 100644 --- a/crates/api_common/src/community.rs +++ b/crates/api_common/src/community.rs @@ -10,6 +10,7 @@ use serde::{Deserialize, Serialize}; #[derive(Deserialize)] pub struct GetCommunity { pub id: Option, + /// Example: star_trek , or star_trek@xyz.tld pub name: Option, pub auth: Option, } diff --git a/crates/api_common/src/person.rs b/crates/api_common/src/person.rs index 12cc5deeb..0b43568d7 100644 --- a/crates/api_common/src/person.rs +++ b/crates/api_common/src/person.rs @@ -82,6 +82,7 @@ pub struct LoginResponse { #[derive(Deserialize)] pub struct GetPersonDetails { pub person_id: Option, // One of these two are required + /// Example: dessalines , or dessalines@xyz.tld pub username: Option, pub sort: Option, pub page: Option, diff --git a/crates/api_crud/src/comment/read.rs b/crates/api_crud/src/comment/read.rs index 767311d2a..47394402c 100644 --- a/crates/api_crud/src/comment/read.rs +++ b/crates/api_crud/src/comment/read.rs @@ -1,6 +1,7 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{blocking, comment::*, get_local_user_view_from_jwt_opt}; +use lemmy_apub::{build_actor_id_from_shortname, EndpointType}; use lemmy_db_queries::{from_opt_str_to_opt_enum, ListingType, SortType}; use lemmy_db_views::comment_view::CommentQueryBuilder; use lemmy_utils::{ApiError, ConnectionId, LemmyError}; @@ -27,7 +28,11 @@ impl PerformCrud for GetComments { let listing_type: Option = from_opt_str_to_opt_enum(&data.type_); let community_id = data.community_id; - let community_name = data.community_name.to_owned(); + let community_actor_id = data + .community_name + .as_ref() + .map(|t| build_actor_id_from_shortname(EndpointType::Community, t).ok()) + .unwrap_or(None); let saved_only = data.saved_only; let page = data.page; let limit = data.limit; @@ -37,7 +42,7 @@ impl PerformCrud for GetComments { .sort(sort) .saved_only(saved_only) .community_id(community_id) - .community_name(community_name) + .community_actor_id(community_actor_id) .my_person_id(person_id) .show_bot_accounts(show_bot_accounts) .page(page) diff --git a/crates/api_crud/src/community/read.rs b/crates/api_crud/src/community/read.rs index eb11cb397..0cca08df8 100644 --- a/crates/api_crud/src/community/read.rs +++ b/crates/api_crud/src/community/read.rs @@ -1,12 +1,8 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{blocking, community::*, get_local_user_view_from_jwt_opt}; -use lemmy_db_queries::{ - from_opt_str_to_opt_enum, - source::community::Community_, - ListingType, - SortType, -}; +use lemmy_apub::{build_actor_id_from_shortname, EndpointType}; +use lemmy_db_queries::{from_opt_str_to_opt_enum, ApubObject, ListingType, SortType}; use lemmy_db_schema::source::community::*; use lemmy_db_views_actor::{ community_moderator_view::CommunityModeratorView, @@ -32,8 +28,10 @@ impl PerformCrud for GetCommunity { Some(id) => id, None => { let name = data.name.to_owned().unwrap_or_else(|| "main".to_string()); + let community_actor_id = build_actor_id_from_shortname(EndpointType::Community, &name)?; + blocking(context.pool(), move |conn| { - Community::read_from_name(conn, &name) + Community::read_from_apub_id(conn, &community_actor_id) }) .await? .map_err(|_| ApiError::err("couldnt_find_community"))? diff --git a/crates/api_crud/src/post/read.rs b/crates/api_crud/src/post/read.rs index 4a25b3a8d..77e7a2163 100644 --- a/crates/api_crud/src/post/read.rs +++ b/crates/api_crud/src/post/read.rs @@ -1,6 +1,7 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{blocking, get_local_user_view_from_jwt_opt, mark_post_as_read, post::*}; +use lemmy_apub::{build_actor_id_from_shortname, EndpointType}; use lemmy_db_queries::{from_opt_str_to_opt_enum, ListingType, SortType}; use lemmy_db_views::{ comment_view::CommentQueryBuilder, @@ -111,7 +112,11 @@ impl PerformCrud for GetPosts { let page = data.page; let limit = data.limit; let community_id = data.community_id; - let community_name = data.community_name.to_owned(); + let community_actor_id = data + .community_name + .as_ref() + .map(|t| build_actor_id_from_shortname(EndpointType::Community, t).ok()) + .unwrap_or(None); let saved_only = data.saved_only; let posts = blocking(context.pool(), move |conn| { @@ -122,7 +127,7 @@ impl PerformCrud for GetPosts { .show_bot_accounts(show_bot_accounts) .show_read_posts(show_read_posts) .community_id(community_id) - .community_name(community_name) + .community_actor_id(community_actor_id) .saved_only(saved_only) .my_person_id(person_id) .page(page) diff --git a/crates/api_crud/src/user/read.rs b/crates/api_crud/src/user/read.rs index f7275ef70..ff8db0a7e 100644 --- a/crates/api_crud/src/user/read.rs +++ b/crates/api_crud/src/user/read.rs @@ -1,7 +1,8 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{blocking, get_local_user_view_from_jwt_opt, person::*}; -use lemmy_db_queries::{from_opt_str_to_opt_enum, source::person::Person_, SortType}; +use lemmy_apub::{build_actor_id_from_shortname, EndpointType}; +use lemmy_db_queries::{from_opt_str_to_opt_enum, ApubObject, SortType}; use lemmy_db_schema::source::person::*; use lemmy_db_views::{comment_view::CommentQueryBuilder, post_view::PostQueryBuilder}; use lemmy_db_views_actor::{ @@ -34,15 +35,17 @@ impl PerformCrud for GetPersonDetails { let sort: Option = from_opt_str_to_opt_enum(&data.sort); - let username = data - .username - .to_owned() - .unwrap_or_else(|| "admin".to_string()); let person_details_id = match data.person_id { Some(id) => id, None => { + let name = data + .username + .to_owned() + .unwrap_or_else(|| "admin".to_string()); + let actor_id = build_actor_id_from_shortname(EndpointType::Person, &name)?; + let person = blocking(context.pool(), move |conn| { - Person::find_by_name(conn, &username) + Person::read_from_apub_id(conn, &actor_id) }) .await?; person diff --git a/crates/apub/src/lib.rs b/crates/apub/src/lib.rs index bbc6d515a..c79d14bd7 100644 --- a/crates/apub/src/lib.rs +++ b/crates/apub/src/lib.rs @@ -279,10 +279,11 @@ pub enum EndpointType { PrivateMessage, } -/// Generates the ActivityPub ID for a given object type and ID. -pub fn generate_apub_endpoint( +/// Generates an apub endpoint for a given domain, IE xyz.tld +pub fn generate_apub_endpoint_for_domain( endpoint_type: EndpointType, name: &str, + domain: &str, ) -> Result { let point = match endpoint_type { EndpointType::Community => "c", @@ -292,14 +293,18 @@ pub fn generate_apub_endpoint( EndpointType::PrivateMessage => "private_message", }; - Ok( - Url::parse(&format!( - "{}/{}/{}", - Settings::get().get_protocol_and_hostname(), - point, - name - ))? - .into(), + Ok(Url::parse(&format!("{}/{}/{}", domain, point, name))?.into()) +} + +/// Generates the ActivityPub ID for a given object type and ID. +pub fn generate_apub_endpoint( + endpoint_type: EndpointType, + name: &str, +) -> Result { + generate_apub_endpoint_for_domain( + endpoint_type, + name, + &Settings::get().get_protocol_and_hostname(), ) } @@ -330,6 +335,26 @@ pub fn generate_moderators_url(community_id: &DbUrl) -> Result Result { + let split = short_name.split('@').collect::>(); + + let name = split[0]; + + // If there's no @, its local + let domain = if split.len() == 1 { + Settings::get().get_protocol_and_hostname() + } else { + format!("https://{}", split[1]) + }; + + generate_apub_endpoint_for_domain(endpoint_type, name, &domain) +} + /// Store a sent or received activity in the database, for logging purposes. These records are not /// persistent. pub async fn insert_activity( diff --git a/crates/db_views/src/comment_view.rs b/crates/db_views/src/comment_view.rs index fbb2b7f7d..3449141d0 100644 --- a/crates/db_views/src/comment_view.rs +++ b/crates/db_views/src/comment_view.rs @@ -32,6 +32,7 @@ use lemmy_db_schema::{ }, CommentId, CommunityId, + DbUrl, PersonId, PostId, }; @@ -175,7 +176,7 @@ pub struct CommentQueryBuilder<'a> { listing_type: Option, sort: Option, community_id: Option, - community_name: Option, + community_actor_id: Option, post_id: Option, creator_id: Option, recipient_id: Option, @@ -195,7 +196,7 @@ impl<'a> CommentQueryBuilder<'a> { listing_type: None, sort: None, community_id: None, - community_name: None, + community_actor_id: None, post_id: None, creator_id: None, recipient_id: None, @@ -244,8 +245,8 @@ impl<'a> CommentQueryBuilder<'a> { self } - pub fn community_name>(mut self, community_name: T) -> Self { - self.community_name = community_name.get_optional(); + pub fn community_actor_id>(mut self, community_actor_id: T) -> Self { + self.community_actor_id = community_actor_id.get_optional(); self } @@ -362,10 +363,8 @@ impl<'a> CommentQueryBuilder<'a> { query = query.filter(post::community_id.eq(community_id)); } - if let Some(community_name) = self.community_name { - query = query - .filter(community::name.eq(community_name)) - .filter(comment::local.eq(true)); + if let Some(community_actor_id) = self.community_actor_id { + query = query.filter(community::actor_id.eq(community_actor_id)) } if let Some(post_id) = self.post_id { diff --git a/crates/db_views/src/post_view.rs b/crates/db_views/src/post_view.rs index d0f46dad3..34847dcde 100644 --- a/crates/db_views/src/post_view.rs +++ b/crates/db_views/src/post_view.rs @@ -28,6 +28,7 @@ use lemmy_db_schema::{ post::{Post, PostRead, PostSaved}, }, CommunityId, + DbUrl, PersonId, PostId, }; @@ -159,7 +160,7 @@ pub struct PostQueryBuilder<'a> { sort: Option, creator_id: Option, community_id: Option, - community_name: Option, + community_actor_id: Option, my_person_id: Option, search_term: Option, url_search: Option, @@ -179,7 +180,7 @@ impl<'a> PostQueryBuilder<'a> { sort: None, creator_id: None, community_id: None, - community_name: None, + community_actor_id: None, my_person_id: None, search_term: None, url_search: None, @@ -212,8 +213,8 @@ impl<'a> PostQueryBuilder<'a> { self } - pub fn community_name>(mut self, community_name: T) -> Self { - self.community_name = community_name.get_optional(); + pub fn community_actor_id>(mut self, community_actor_id: T) -> Self { + self.community_actor_id = community_actor_id.get_optional(); self } @@ -334,10 +335,9 @@ impl<'a> PostQueryBuilder<'a> { .then_order_by(post_aggregates::stickied.desc()); } - if let Some(community_name) = self.community_name { + if let Some(community_actor_id) = self.community_actor_id { query = query - .filter(community::name.eq(community_name)) - .filter(community::local.eq(true)) + .filter(community::actor_id.eq(community_actor_id)) .then_order_by(post_aggregates::stickied.desc()); }