Multi webfinger response (#33)

* Add support for building webfinger for multiple URLs with type

Update `build_webfinger_response` to accept `Vec<(Url, Option<&str>)>`
where `Url` is the ActivityPub ID and `&str` is the optional type.

* Update docs for `build_webfinger_response`

* Update tests to use new `build_webfinger_response`

Tests and docs don't cover usage with some `kind` value.

* Run formatter with nightly

* Revert "Add support for building webfinger for multiple URLs with type"

This reverts commits until 3f70586e63.
This was a breaking change and should be made into a separate function.

* Add `build_webfinger_response_with_type`

* Construct links separately and update `build_webfinger_response`

- `build_webfinger_response` calls `build_webfinger_response_with_type`.
- Links are constructed in a separate variable.
- Update docs for `build_webfinger_response_with_type` to be clearer
about usage.
- TODO: Use `derive_builder` to simplify function.

* Extract properties into variable

* Remove `other` from docs
This commit is contained in:
Grafcube 2023-04-05 01:26:34 +05:30 committed by GitHub
parent 813d7943e1
commit 99cdbb5d58
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -101,22 +101,61 @@ where
/// # Ok::<(), anyhow::Error>(())
/// ```
pub fn build_webfinger_response(subject: String, url: Url) -> Webfinger {
build_webfinger_response_with_type(subject, vec![(url, None)])
}
/// Builds a webfinger response similar to `build_webfinger_response`. Use this when you want to
/// return multiple actors who share the same namespace and to specify the type of the actor.
///
/// `urls` takes a vector of tuples. The first item of the tuple is the URL while the second
/// item is the type, such as `"Person"` or `"Group"`. If `None` is passed for the type, the field
/// will be empty.
///
/// ```
/// # use url::Url;
/// # use activitypub_federation::fetch::webfinger::build_webfinger_response_with_type;
/// let subject = "acct:nutomic@lemmy.ml".to_string();
/// let user = Url::parse("https://lemmy.ml/u/nutomic")?;
/// let group = Url::parse("https://lemmy.ml/c/asklemmy")?;
/// build_webfinger_response_with_type(subject, vec![
/// (user, Some("Person")),
/// (group, Some("Group"))]);
/// # Ok::<(), anyhow::Error>(())
/// ```
pub fn build_webfinger_response_with_type(
subject: String,
urls: Vec<(Url, Option<&str>)>,
) -> Webfinger {
Webfinger {
subject,
links: vec![
WebfingerLink {
rel: Some("http://webfinger.net/rel/profile-page".to_string()),
kind: Some("text/html".to_string()),
href: Some(url.clone()),
properties: Default::default(),
},
WebfingerLink {
rel: Some("self".to_string()),
kind: Some(FEDERATION_CONTENT_TYPE.to_string()),
href: Some(url),
properties: Default::default(),
},
],
links: urls.iter().fold(vec![], |mut acc, (url, kind)| {
let properties: HashMap<Url, String> = kind
.map(|kind| {
HashMap::from([(
"https://www.w3.org/ns/activitystreams#type"
.parse()
.expect("parse url"),
kind.to_string(),
)])
})
.unwrap_or_default();
let mut links = vec![
WebfingerLink {
rel: Some("http://webfinger.net/rel/profile-page".to_string()),
kind: Some("text/html".to_string()),
href: Some(url.clone()),
properties: Default::default(),
},
WebfingerLink {
rel: Some("self".to_string()),
kind: Some(FEDERATION_CONTENT_TYPE.to_string()),
href: Some(url.clone()),
properties,
},
];
acc.append(&mut links);
acc
}),
aliases: vec![],
properties: Default::default(),
}