Use same federation keypair for all new users and communities (#5709)

This commit is contained in:
Nutomic 2025-05-29 12:07:39 +00:00 committed by GitHub
parent 3c7f6be908
commit b4180a57bf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 28 additions and 43 deletions

View file

@ -1,5 +1,5 @@
use super::check_community_visibility_allowed;
use activitypub_federation::{config::Data, http_signatures::generate_actor_keypair};
use activitypub_federation::config::Data;
use actix_web::web::Json;
use lemmy_api_common::{
build_response::build_community_response,
@ -88,15 +88,12 @@ pub async fn create_community(
Err(LemmyErrorType::CommunityAlreadyExists)?
}
// When you create a community, make sure the user becomes a moderator and a follower
let keypair = generate_actor_keypair()?;
let community_form = CommunityInsertForm {
sidebar,
description,
nsfw: data.nsfw,
ap_id: Some(community_ap_id.clone()),
private_key: Some(keypair.private_key),
private_key: site_view.site.private_key,
followers_url: Some(generate_followers_url(&community_ap_id)?),
inbox_url: Some(generate_inbox_url()?),
posting_restricted_to_mods: data.posting_restricted_to_mods,
@ -105,7 +102,7 @@ pub async fn create_community(
site_view.site.instance_id,
data.name.clone(),
data.title.clone(),
keypair.public_key,
site_view.site.public_key,
)
};

View file

@ -1,4 +1,4 @@
use activitypub_federation::{config::Data, http_signatures::generate_actor_keypair};
use activitypub_federation::config::Data;
use actix_web::{web::Json, HttpRequest};
use diesel_async::{scoped_futures::ScopedFutureExt, AsyncConnection, AsyncPgConnection};
use lemmy_api_common::{
@ -17,7 +17,7 @@ use lemmy_api_common::{
},
};
use lemmy_db_schema::{
newtypes::{InstanceId, OAuthProviderId},
newtypes::OAuthProviderId,
source::{
actor_language::SiteLanguage,
captcha_answer::{CaptchaAnswer, CheckCaptchaAnswer},
@ -41,7 +41,6 @@ use lemmy_email::{
};
use lemmy_utils::{
error::{LemmyError, LemmyErrorExt, LemmyErrorType, LemmyResult},
settings::structs::Settings,
utils::{
slurs::{check_slurs, check_slurs_opt},
validation::is_valid_actor_name,
@ -132,20 +131,13 @@ pub async fn register(
// in a transaction, so that if any fail, the rows aren't created.
let conn = &mut get_conn(pool).await?;
let tx_data = data.clone();
let tx_local_site = local_site.clone();
let tx_settings = context.settings();
let tx_context = context.clone();
let user = conn
.transaction::<_, LemmyError, _>(|conn| {
async move {
let site_view = SiteView::read_local(&mut tx_context.pool()).await?;
// We have to create both a person, and local_user
let person = create_person(
tx_data.username.clone(),
&tx_local_site,
site_view.site.instance_id,
tx_settings,
conn,
)
.await?;
let person = create_person(tx_data.username.clone(), &site_view, &tx_context, conn).await?;
// Create the local user
let local_user_form = LocalUserInsertForm {
@ -156,7 +148,7 @@ pub async fn register(
};
let local_user =
create_local_user(conn, language_tags, local_user_form, &tx_local_site).await?;
create_local_user(conn, language_tags, local_user_form, &site_view.local_site).await?;
if local_site.site_setup && require_registration_application {
if let Some(answer) = tx_data.answer.clone() {
@ -356,11 +348,11 @@ pub async fn authenticate_with_oauth(
// in a transaction, so that if any fail, the rows aren't created.
let conn = &mut get_conn(pool).await?;
let tx_data = data.clone();
let tx_local_site = local_site.clone();
let tx_settings = context.settings();
let tx_context = context.clone();
let user = conn
.transaction::<_, LemmyError, _>(|conn| {
async move {
let site_view = SiteView::read_local(&mut tx_context.pool()).await?;
// make sure the username is provided
let username = tx_data
.username
@ -373,14 +365,7 @@ pub async fn authenticate_with_oauth(
Person::check_username_taken(&mut conn.into(), username).await?;
// We have to create a person, a local_user, and an oauth_account
let person = create_person(
username.clone(),
&tx_local_site,
site_view.site.instance_id,
tx_settings,
conn,
)
.await?;
let person = create_person(username.clone(), &site_view, &tx_context, conn).await?;
// Create the local user
let local_user_form = LocalUserInsertForm {
@ -392,7 +377,8 @@ pub async fn authenticate_with_oauth(
};
let local_user =
create_local_user(conn, language_tags, local_user_form, &tx_local_site).await?;
create_local_user(conn, language_tags, local_user_form, &site_view.local_site)
.await?;
// Create the oauth account
let oauth_account_form =
@ -452,21 +438,23 @@ pub async fn authenticate_with_oauth(
async fn create_person(
username: String,
local_site: &LocalSite,
instance_id: InstanceId,
settings: &Settings,
site_view: &SiteView,
context: &LemmyContext,
conn: &mut AsyncPgConnection,
) -> Result<Person, LemmyError> {
let actor_keypair = generate_actor_keypair()?;
is_valid_actor_name(&username, local_site.actor_name_max_length)?;
let ap_id = Person::local_url(&username, settings)?;
is_valid_actor_name(&username, site_view.local_site.actor_name_max_length)?;
let ap_id = Person::local_url(&username, context.settings())?;
// Register the new person
let person_form = PersonInsertForm {
ap_id: Some(ap_id.clone()),
inbox_url: Some(generate_inbox_url()?),
private_key: Some(actor_keypair.private_key),
..PersonInsertForm::new(username.clone(), actor_keypair.public_key, instance_id)
private_key: site_view.site.private_key.clone(),
..PersonInsertForm::new(
username.clone(),
site_view.site.public_key.clone(),
site_view.site.instance_id,
)
};
// insert the person

View file

@ -126,7 +126,7 @@ pub struct CommunityInsertForm {
#[new(default)]
pub local: Option<bool>,
#[new(default)]
pub private_key: Option<String>,
pub private_key: Option<SensitiveString>,
#[new(default)]
pub last_refreshed_at: Option<DateTime<Utc>>,
#[new(default)]

View file

@ -93,7 +93,7 @@ pub struct PersonInsertForm {
#[new(default)]
pub local: Option<bool>,
#[new(default)]
pub private_key: Option<String>,
pub private_key: Option<SensitiveString>,
#[new(default)]
pub last_refreshed_at: Option<DateTime<Utc>>,
#[new(default)]

View file

@ -496,7 +496,7 @@ mod test {
let ap_id: DbUrl = Url::parse("http://local.com/u/alice")?.into();
let person_form = PersonInsertForm {
ap_id: Some(ap_id.clone()),
private_key: (Some(actor_keypair.private_key)),
private_key: (Some(actor_keypair.private_key.into())),
inbox_url: Some(generate_inbox_url()?),
..PersonInsertForm::new("alice".to_string(), actor_keypair.public_key, instance.id)
};

View file

@ -406,7 +406,7 @@ async fn initialize_local_site_2022_10_10(
let person_form = PersonInsertForm {
ap_id: Some(person_ap_id.clone()),
inbox_url: Some(generate_inbox_url()?),
private_key: Some(person_keypair.private_key),
private_key: Some(person_keypair.private_key.into()),
..PersonInsertForm::new(
setup.admin_username.clone(),
person_keypair.public_key,