Dont require leading ! or @ for webfinger resolve (#4513)
* Dont require leading ! or @ for webfinger resolve * fmt * clippy
This commit is contained in:
parent
43378c5bb3
commit
9d4299aaac
3 changed files with 46 additions and 52 deletions
|
@ -45,7 +45,7 @@ test("Create user", async () => {
|
||||||
if (!site.my_user) {
|
if (!site.my_user) {
|
||||||
throw "Missing site user";
|
throw "Missing site user";
|
||||||
}
|
}
|
||||||
apShortname = `@${site.my_user.local_user_view.person.name}@lemmy-alpha:8541`;
|
apShortname = `${site.my_user.local_user_view.person.name}@lemmy-alpha:8541`;
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Set some user settings, check that they are federated", async () => {
|
test("Set some user settings, check that they are federated", async () => {
|
||||||
|
@ -68,7 +68,7 @@ test("Delete user", async () => {
|
||||||
let user = await registerUser(alpha, alphaUrl);
|
let user = await registerUser(alpha, alphaUrl);
|
||||||
|
|
||||||
// make a local post and comment
|
// make a local post and comment
|
||||||
let alphaCommunity = (await resolveCommunity(user, "!main@lemmy-alpha:8541"))
|
let alphaCommunity = (await resolveCommunity(user, "main@lemmy-alpha:8541"))
|
||||||
.community;
|
.community;
|
||||||
if (!alphaCommunity) {
|
if (!alphaCommunity) {
|
||||||
throw "Missing alpha community";
|
throw "Missing alpha community";
|
||||||
|
@ -134,7 +134,7 @@ test("Create user with Arabic name", async () => {
|
||||||
if (!site.my_user) {
|
if (!site.my_user) {
|
||||||
throw "Missing site user";
|
throw "Missing site user";
|
||||||
}
|
}
|
||||||
apShortname = `@${site.my_user.local_user_view.person.name}@lemmy-alpha:8541`;
|
apShortname = `${site.my_user.local_user_view.person.name}@lemmy-alpha:8541`;
|
||||||
|
|
||||||
let alphaPerson = (await resolvePerson(alpha, apShortname)).person;
|
let alphaPerson = (await resolvePerson(alpha, apShortname)).person;
|
||||||
expect(alphaPerson).toBeDefined();
|
expect(alphaPerson).toBeDefined();
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::fetcher::search::{
|
use crate::fetcher::{
|
||||||
search_query_to_object_id,
|
search::{search_query_to_object_id, search_query_to_object_id_local, SearchableObjects},
|
||||||
search_query_to_object_id_local,
|
user_or_community::UserOrCommunity,
|
||||||
SearchableObjects,
|
|
||||||
};
|
};
|
||||||
use activitypub_federation::config::Data;
|
use activitypub_federation::config::Data;
|
||||||
use actix_web::web::{Json, Query};
|
use actix_web::web::{Json, Query};
|
||||||
|
@ -31,7 +30,7 @@ pub async fn resolve_object(
|
||||||
|
|
||||||
let res = if is_authenticated {
|
let res = if is_authenticated {
|
||||||
// user is fully authenticated; allow remote lookups as well.
|
// user is fully authenticated; allow remote lookups as well.
|
||||||
search_query_to_object_id(&data.q, &context).await
|
search_query_to_object_id(data.q.clone(), &context).await
|
||||||
} else {
|
} else {
|
||||||
// user isn't authenticated only allow a local search.
|
// user isn't authenticated only allow a local search.
|
||||||
search_query_to_object_id_local(&data.q, &context).await
|
search_query_to_object_id_local(&data.q, &context).await
|
||||||
|
@ -52,14 +51,6 @@ async fn convert_response(
|
||||||
let removed_or_deleted;
|
let removed_or_deleted;
|
||||||
let mut res = ResolveObjectResponse::default();
|
let mut res = ResolveObjectResponse::default();
|
||||||
match object {
|
match object {
|
||||||
Person(p) => {
|
|
||||||
removed_or_deleted = p.deleted;
|
|
||||||
res.person = Some(PersonView::read(pool, p.id).await?)
|
|
||||||
}
|
|
||||||
Community(c) => {
|
|
||||||
removed_or_deleted = c.deleted || c.removed;
|
|
||||||
res.community = Some(CommunityView::read(pool, c.id, user_id, false).await?)
|
|
||||||
}
|
|
||||||
Post(p) => {
|
Post(p) => {
|
||||||
removed_or_deleted = p.deleted || p.removed;
|
removed_or_deleted = p.deleted || p.removed;
|
||||||
res.post = Some(PostView::read(pool, p.id, user_id, false).await?)
|
res.post = Some(PostView::read(pool, p.id, user_id, false).await?)
|
||||||
|
@ -68,6 +59,16 @@ async fn convert_response(
|
||||||
removed_or_deleted = c.deleted || c.removed;
|
removed_or_deleted = c.deleted || c.removed;
|
||||||
res.comment = Some(CommentView::read(pool, c.id, user_id).await?)
|
res.comment = Some(CommentView::read(pool, c.id, user_id).await?)
|
||||||
}
|
}
|
||||||
|
PersonOrCommunity(p) => match *p {
|
||||||
|
UserOrCommunity::User(u) => {
|
||||||
|
removed_or_deleted = u.deleted;
|
||||||
|
res.person = Some(PersonView::read(pool, u.id).await?)
|
||||||
|
}
|
||||||
|
UserOrCommunity::Community(c) => {
|
||||||
|
removed_or_deleted = c.deleted || c.removed;
|
||||||
|
res.community = Some(CommunityView::read(pool, c.id, user_id, false).await?)
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
// if the object was deleted from database, dont return it
|
// if the object was deleted from database, dont return it
|
||||||
if removed_or_deleted {
|
if removed_or_deleted {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
|
fetcher::user_or_community::{PersonOrGroup, UserOrCommunity},
|
||||||
objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson, post::ApubPost},
|
objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson, post::ApubPost},
|
||||||
protocol::objects::{group::Group, note::Note, page::Page, person::Person},
|
protocol::objects::{note::Note, page::Page},
|
||||||
};
|
};
|
||||||
use activitypub_federation::{
|
use activitypub_federation::{
|
||||||
config::Data,
|
config::Data,
|
||||||
|
@ -9,7 +10,7 @@ use activitypub_federation::{
|
||||||
};
|
};
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use lemmy_api_common::context::LemmyContext;
|
use lemmy_api_common::context::LemmyContext;
|
||||||
use lemmy_utils::error::{LemmyError, LemmyErrorType};
|
use lemmy_utils::error::LemmyError;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
@ -18,28 +19,22 @@ use url::Url;
|
||||||
/// which gets resolved to an URL.
|
/// which gets resolved to an URL.
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
pub(crate) async fn search_query_to_object_id(
|
pub(crate) async fn search_query_to_object_id(
|
||||||
query: &str,
|
mut query: String,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
) -> Result<SearchableObjects, LemmyError> {
|
) -> Result<SearchableObjects, LemmyError> {
|
||||||
Ok(match Url::parse(query) {
|
Ok(match Url::parse(&query) {
|
||||||
Ok(url) => {
|
Ok(url) => {
|
||||||
// its already an url, just go with it
|
// its already an url, just go with it
|
||||||
ObjectId::from(url).dereference(context).await?
|
ObjectId::from(url).dereference(context).await?
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
// not an url, try to resolve via webfinger
|
// not an url, try to resolve via webfinger
|
||||||
let mut chars = query.chars();
|
if query.starts_with('!') || query.starts_with('@') {
|
||||||
let kind = chars.next();
|
query.remove(0);
|
||||||
let identifier = chars.as_str();
|
|
||||||
match kind {
|
|
||||||
Some('@') => SearchableObjects::Person(
|
|
||||||
webfinger_resolve_actor::<LemmyContext, ApubPerson>(identifier, context).await?,
|
|
||||||
),
|
|
||||||
Some('!') => SearchableObjects::Community(
|
|
||||||
webfinger_resolve_actor::<LemmyContext, ApubCommunity>(identifier, context).await?,
|
|
||||||
),
|
|
||||||
_ => return Err(LemmyErrorType::InvalidQuery)?,
|
|
||||||
}
|
}
|
||||||
|
SearchableObjects::PersonOrCommunity(Box::new(
|
||||||
|
webfinger_resolve_actor::<LemmyContext, UserOrCommunity>(&query, context).await?,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -59,19 +54,17 @@ pub(crate) async fn search_query_to_object_id_local(
|
||||||
/// The types of ActivityPub objects that can be fetched directly by searching for their ID.
|
/// The types of ActivityPub objects that can be fetched directly by searching for their ID.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) enum SearchableObjects {
|
pub(crate) enum SearchableObjects {
|
||||||
Person(ApubPerson),
|
|
||||||
Community(ApubCommunity),
|
|
||||||
Post(ApubPost),
|
Post(ApubPost),
|
||||||
Comment(ApubComment),
|
Comment(ApubComment),
|
||||||
|
PersonOrCommunity(Box<UserOrCommunity>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub(crate) enum SearchableKinds {
|
pub(crate) enum SearchableKinds {
|
||||||
Group(Group),
|
Page(Box<Page>),
|
||||||
Person(Person),
|
|
||||||
Page(Page),
|
|
||||||
Note(Note),
|
Note(Note),
|
||||||
|
PersonOrGroup(Box<PersonOrGroup>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
|
@ -82,10 +75,9 @@ impl Object for SearchableObjects {
|
||||||
|
|
||||||
fn last_refreshed_at(&self) -> Option<DateTime<Utc>> {
|
fn last_refreshed_at(&self) -> Option<DateTime<Utc>> {
|
||||||
match self {
|
match self {
|
||||||
SearchableObjects::Person(p) => p.last_refreshed_at(),
|
|
||||||
SearchableObjects::Community(c) => c.last_refreshed_at(),
|
|
||||||
SearchableObjects::Post(p) => p.last_refreshed_at(),
|
SearchableObjects::Post(p) => p.last_refreshed_at(),
|
||||||
SearchableObjects::Comment(c) => c.last_refreshed_at(),
|
SearchableObjects::Comment(c) => c.last_refreshed_at(),
|
||||||
|
SearchableObjects::PersonOrCommunity(p) => p.last_refreshed_at(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,13 +91,9 @@ impl Object for SearchableObjects {
|
||||||
object_id: Url,
|
object_id: Url,
|
||||||
context: &Data<Self::DataType>,
|
context: &Data<Self::DataType>,
|
||||||
) -> Result<Option<Self>, LemmyError> {
|
) -> Result<Option<Self>, LemmyError> {
|
||||||
let c = ApubCommunity::read_from_id(object_id.clone(), context).await?;
|
let uc = UserOrCommunity::read_from_id(object_id.clone(), context).await?;
|
||||||
if let Some(c) = c {
|
if let Some(uc) = uc {
|
||||||
return Ok(Some(SearchableObjects::Community(c)));
|
return Ok(Some(SearchableObjects::PersonOrCommunity(Box::new(uc))));
|
||||||
}
|
|
||||||
let p = ApubPerson::read_from_id(object_id.clone(), context).await?;
|
|
||||||
if let Some(p) = p {
|
|
||||||
return Ok(Some(SearchableObjects::Person(p)));
|
|
||||||
}
|
}
|
||||||
let p = ApubPost::read_from_id(object_id.clone(), context).await?;
|
let p = ApubPost::read_from_id(object_id.clone(), context).await?;
|
||||||
if let Some(p) = p {
|
if let Some(p) = p {
|
||||||
|
@ -121,10 +109,12 @@ impl Object for SearchableObjects {
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
async fn delete(self, data: &Data<Self::DataType>) -> Result<(), LemmyError> {
|
async fn delete(self, data: &Data<Self::DataType>) -> Result<(), LemmyError> {
|
||||||
match self {
|
match self {
|
||||||
SearchableObjects::Person(p) => p.delete(data).await,
|
|
||||||
SearchableObjects::Community(c) => c.delete(data).await,
|
|
||||||
SearchableObjects::Post(p) => p.delete(data).await,
|
SearchableObjects::Post(p) => p.delete(data).await,
|
||||||
SearchableObjects::Comment(c) => c.delete(data).await,
|
SearchableObjects::Comment(c) => c.delete(data).await,
|
||||||
|
SearchableObjects::PersonOrCommunity(pc) => match *pc {
|
||||||
|
UserOrCommunity::User(p) => p.delete(data).await,
|
||||||
|
UserOrCommunity::Community(c) => c.delete(data).await,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,10 +129,12 @@ impl Object for SearchableObjects {
|
||||||
data: &Data<Self::DataType>,
|
data: &Data<Self::DataType>,
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
match apub {
|
match apub {
|
||||||
SearchableKinds::Group(a) => ApubCommunity::verify(a, expected_domain, data).await,
|
|
||||||
SearchableKinds::Person(a) => ApubPerson::verify(a, expected_domain, data).await,
|
|
||||||
SearchableKinds::Page(a) => ApubPost::verify(a, expected_domain, data).await,
|
SearchableKinds::Page(a) => ApubPost::verify(a, expected_domain, data).await,
|
||||||
SearchableKinds::Note(a) => ApubComment::verify(a, expected_domain, data).await,
|
SearchableKinds::Note(a) => ApubComment::verify(a, expected_domain, data).await,
|
||||||
|
SearchableKinds::PersonOrGroup(pg) => match pg.as_ref() {
|
||||||
|
PersonOrGroup::Person(a) => ApubPerson::verify(a, expected_domain, data).await,
|
||||||
|
PersonOrGroup::Group(a) => ApubCommunity::verify(a, expected_domain, data).await,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,10 +143,11 @@ impl Object for SearchableObjects {
|
||||||
use SearchableKinds as SAT;
|
use SearchableKinds as SAT;
|
||||||
use SearchableObjects as SO;
|
use SearchableObjects as SO;
|
||||||
Ok(match apub {
|
Ok(match apub {
|
||||||
SAT::Group(g) => SO::Community(ApubCommunity::from_json(g, context).await?),
|
SAT::Page(p) => SO::Post(ApubPost::from_json(*p, context).await?),
|
||||||
SAT::Person(p) => SO::Person(ApubPerson::from_json(p, context).await?),
|
|
||||||
SAT::Page(p) => SO::Post(ApubPost::from_json(p, context).await?),
|
|
||||||
SAT::Note(n) => SO::Comment(ApubComment::from_json(n, context).await?),
|
SAT::Note(n) => SO::Comment(ApubComment::from_json(n, context).await?),
|
||||||
|
SAT::PersonOrGroup(pg) => {
|
||||||
|
SO::PersonOrCommunity(Box::new(UserOrCommunity::from_json(*pg, context).await?))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue