Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix missing private key for signed fetch #4516

Merged
merged 6 commits into from Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 1 addition & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Expand Up @@ -96,7 +96,7 @@ lemmy_routes = { version = "=0.19.3", path = "./crates/routes" }
lemmy_db_views = { version = "=0.19.3", path = "./crates/db_views" }
lemmy_db_views_actor = { version = "=0.19.3", path = "./crates/db_views_actor" }
lemmy_db_views_moderator = { version = "=0.19.3", path = "./crates/db_views_moderator" }
activitypub_federation = { version = "0.5.1", default-features = false, features = [
activitypub_federation = { git = "https://github.com/LemmyNet/activitypub-federation-rust.git", branch = "debug-signed-fetch", default-features = false, features = [
Nutomic marked this conversation as resolved.
Show resolved Hide resolved
"actix-web",
] }
diesel = "2.1.4"
Expand Down
1 change: 1 addition & 0 deletions crates/apub/src/objects/instance.rs
Expand Up @@ -96,6 +96,7 @@ impl Object for ApubSite {
kind: ApplicationType::Application,
id: self.id().into(),
name: self.name.clone(),
preferred_username: data.domain().to_string(),
content: self.sidebar.as_ref().map(|d| markdown_to_html(d)),
source: self.sidebar.clone().map(Source::new),
summary: self.description.clone(),
Expand Down
4 changes: 3 additions & 1 deletion crates/apub/src/protocol/objects/instance.rs
Expand Up @@ -19,8 +19,10 @@ pub struct Instance {
#[serde(rename = "type")]
pub(crate) kind: ApplicationType,
pub(crate) id: ObjectId<ApubSite>,
// site name
/// site name
pub(crate) name: String,
/// domain, necessary for mastodon authorized fetch
pub(crate) preferred_username: String,
pub(crate) inbox: Url,
/// mandatory field in activitypub, lemmy currently serves an empty outbox
pub(crate) outbox: Url,
Expand Down
2 changes: 2 additions & 0 deletions crates/db_schema/src/source/site.rs
Expand Up @@ -34,7 +34,9 @@ pub struct Site {
pub last_refreshed_at: DateTime<Utc>,
/// The site inbox
pub inbox_url: DbUrl,
#[serde(skip)]
pub private_key: Option<String>,
#[serde(skip)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't the pub key need to get sent elsewhere? I guess the federation tests would be failing if that weren't the case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes but that is done in a separate struct. You can compare the db structs for user or community which have the same skip attributes.

pub public_key: String,
pub instance_id: InstanceId,
/// If present, nsfw content is visible by default. Should be displayed by frontends/clients
Expand Down
7 changes: 2 additions & 5 deletions crates/db_views/src/site_view.rs
Expand Up @@ -9,7 +9,7 @@ use lemmy_db_schema::{
impl SiteView {
pub async fn read_local(pool: &mut DbPool<'_>) -> Result<Self, Error> {
let conn = &mut get_conn(pool).await?;
let mut res = site::table
site::table
.inner_join(local_site::table)
.inner_join(
local_site_rate_limit::table.on(local_site::id.eq(local_site_rate_limit::local_site_id)),
Expand All @@ -22,9 +22,6 @@ impl SiteView {
site_aggregates::all_columns,
))
.first::<SiteView>(conn)
.await?;

res.site.private_key = None;
Ok(res)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The output of this function is used for signed fetch, and it would crash due to missing private key. Actually there should be no need to set it as None, we can simply use serde(skip).

.await
}
}
49 changes: 28 additions & 21 deletions crates/routes/src/webfinger.rs
Expand Up @@ -38,28 +38,35 @@ async fn get_webfinger_response(
) -> Result<HttpResponse, LemmyError> {
let name = extract_webfinger_name(&info.resource, &context)?;

let user_id: Option<Url> = Person::read_from_name(&mut context.pool(), name, false)
.await
.ok()
.map(|c| c.actor_id.into());
let community_id: Option<Url> = Community::read_from_name(&mut context.pool(), name, false)
.await
.ok()
.and_then(|c| {
if c.visibility == CommunityVisibility::Public {
let id: Url = c.actor_id.into();
Some(id)
} else {
None
}
});
let links = if name == context.domain() {
// webfinger response for instance actor (required for mastodon authorized fetch)
let url = Url::parse(&format!("https://{name}"))?;
vec![webfinger_link_for_actor(Some(url), "none", &context)]
} else {
// webfinger response for user/community
let user_id: Option<Url> = Person::read_from_name(&mut context.pool(), name, false)
.await
.ok()
.map(|c| c.actor_id.into());
let community_id: Option<Url> = Community::read_from_name(&mut context.pool(), name, false)
.await
.ok()
.and_then(|c| {
if c.visibility == CommunityVisibility::Public {
let id: Url = c.actor_id.into();
Some(id)
} else {
None
}
});

// Mastodon seems to prioritize the last webfinger item in case of duplicates. Put
// community last so that it gets prioritized. For Lemmy the order doesnt matter.
let links = vec![
webfinger_link_for_actor(user_id, "Person", &context),
webfinger_link_for_actor(community_id, "Group", &context),
]
// Mastodon seems to prioritize the last webfinger item in case of duplicates. Put
// community last so that it gets prioritized. For Lemmy the order doesnt matter.
vec![
webfinger_link_for_actor(user_id, "Person", &context),
webfinger_link_for_actor(community_id, "Group", &context),
]
}
.into_iter()
.flatten()
.collect();
Expand Down