diff --git a/src/backend/api/article.rs b/src/backend/api/article.rs index 63e9db0..21e7f5d 100644 --- a/src/backend/api/article.rs +++ b/src/backend/api/article.rs @@ -5,7 +5,7 @@ use crate::{ article::DbArticleForm, conflict::{DbConflict, DbConflictForm}, edit::DbEditForm, - IbisData, + IbisContext, }, federation::activities::{create_article::CreateArticle, submit_article_update}, utils::{ @@ -50,13 +50,13 @@ use diffy::create_patch; #[debug_handler] pub(in crate::backend::api) async fn create_article( user: Extension, - data: Data, + context: Data, Form(mut params): Form, ) -> MyResult> { params.title = validate_article_title(¶ms.title)?; validate_not_empty(¶ms.text)?; - let local_instance = DbInstance::read_local(&data)?; + let local_instance = DbInstance::read_local(&context)?; let ap_id = ObjectId::parse(&format!( "{}://{}/article/{}", http_protocol_str(), @@ -70,23 +70,23 @@ pub(in crate::backend::api) async fn create_article( instance_id: local_instance.id, local: true, protected: false, - approved: !data.config.options.article_approval, + approved: !context.config.options.article_approval, }; - let article = DbArticle::create(form, &data)?; + let article = DbArticle::create(form, &context)?; let edit_data = EditArticleParams { article_id: article.id, new_text: params.text, summary: params.summary, - previous_version_id: article.latest_edit_version(&data)?, + previous_version_id: article.latest_edit_version(&context)?, resolve_conflict_id: None, }; - let _ = edit_article(user, data.reset_request_count(), Form(edit_data)).await?; + let _ = edit_article(user, context.reset_request_count(), Form(edit_data)).await?; // allow reading unapproved article here - let article_view = DbArticle::read_view(article.id, &data)?; - CreateArticle::send_to_followers(article_view.article.clone(), &data).await?; + let article_view = DbArticle::read_view(article.id, &context)?; + CreateArticle::send_to_followers(article_view.article.clone(), &context).await?; Ok(Json(article_view)) } @@ -103,15 +103,15 @@ pub(in crate::backend::api) async fn create_article( #[debug_handler] pub(in crate::backend::api) async fn edit_article( Extension(user): Extension, - data: Data, + context: Data, Form(mut params): Form, ) -> MyResult>> { validate_not_empty(¶ms.new_text)?; // resolve conflict if any if let Some(resolve_conflict_id) = params.resolve_conflict_id { - DbConflict::delete(resolve_conflict_id, user.person.id, &data)?; + DbConflict::delete(resolve_conflict_id, user.person.id, &context)?; } - let original_article = DbArticle::read_view(params.article_id, &data)?; + let original_article = DbArticle::read_view(params.article_id, &context)?; if params.new_text == original_article.article.text { return Err(anyhow!("Edit contains no changes").into()); } @@ -123,7 +123,7 @@ pub(in crate::backend::api) async fn edit_article( if !params.new_text.ends_with('\n') { params.new_text.push('\n'); } - let local_link = format!("](https://{}", data.config.federation.domain); + let local_link = format!("](https://{}", context.config.federation.domain); if params.new_text.contains(&local_link) { return Err(anyhow!("Links to local instance don't work over federation").into()); } @@ -139,18 +139,18 @@ pub(in crate::backend::api) async fn edit_article( params.previous_version_id, &original_article.article, user.person.id, - &data, + &context, ) .await?; Ok(Json(None)) } else { // There have been other changes since this edit was initiated. Get the common ancestor // version and generate a diff to find out what exactly has changed. - let edits = DbEdit::list_for_article(original_article.article.id, &data)?; + let edits = DbEdit::list_for_article(original_article.article.id, &context)?; let ancestor = generate_article_version(&edits, ¶ms.previous_version_id)?; let patch = create_patch(&ancestor, &new_text); - let previous_version = DbEdit::read(¶ms.previous_version_id, &data)?; + let previous_version = DbEdit::read(¶ms.previous_version_id, &context)?; let form = DbConflictForm { hash: EditVersion::new(&patch.to_string()), diff: patch.to_string(), @@ -159,8 +159,8 @@ pub(in crate::backend::api) async fn edit_article( article_id: original_article.article.id, previous_version_id: previous_version.hash, }; - let conflict = DbConflict::create(&form, &data)?; - Ok(Json(conflict.to_api_conflict(&data).await?)) + let conflict = DbConflict::create(&form, &context)?; + Ok(Json(conflict.to_api_conflict(&context).await?)) } } @@ -168,19 +168,19 @@ pub(in crate::backend::api) async fn edit_article( #[debug_handler] pub(in crate::backend::api) async fn get_article( Query(query): Query, - data: Data, + context: Data, ) -> MyResult> { match (query.title, query.id) { (Some(title), None) => Ok(Json(DbArticle::read_view_title( &title, query.domain, - &data, + &context, )?)), (None, Some(id)) => { if query.domain.is_some() { return Err(anyhow!("Cant combine id and instance_domain").into()); } - let article = DbArticle::read_view(id, &data)?; + let article = DbArticle::read_view(id, &context)?; Ok(Json(article)) } _ => Err(anyhow!("Must pass exactly one of title, id").into()), @@ -190,12 +190,12 @@ pub(in crate::backend::api) async fn get_article( #[debug_handler] pub(in crate::backend::api) async fn list_articles( Query(query): Query, - data: Data, + context: Data, ) -> MyResult>> { Ok(Json(DbArticle::read_all( query.only_local, query.instance_id, - &data, + &context, )?)) } @@ -204,14 +204,14 @@ pub(in crate::backend::api) async fn list_articles( #[debug_handler] pub(in crate::backend::api) async fn fork_article( Extension(_user): Extension, - data: Data, + context: Data, Form(mut params): Form, ) -> MyResult> { // TODO: lots of code duplicated from create_article(), can move it into helper - let original_article = DbArticle::read_view(params.article_id, &data)?; + let original_article = DbArticle::read_view(params.article_id, &context)?; params.new_title = validate_article_title(¶ms.new_title)?; - let local_instance = DbInstance::read_local(&data)?; + let local_instance = DbInstance::read_local(&context)?; let ap_id = ObjectId::parse(&format!( "{}://{}/article/{}", http_protocol_str(), @@ -225,14 +225,14 @@ pub(in crate::backend::api) async fn fork_article( instance_id: local_instance.id, local: true, protected: false, - approved: !data.config.options.article_approval, + approved: !context.config.options.article_approval, }; - let article = DbArticle::create(form, &data)?; + let article = DbArticle::create(form, &context)?; // copy edits to new article // this could also be done in sql - let edits = DbEdit::list_for_article(original_article.article.id, &data)?; + let edits = DbEdit::list_for_article(original_article.article.id, &context)?; for e in edits { let ap_id = DbEditForm::generate_ap_id(&article, &e.hash)?; let form = DbEditForm { @@ -246,12 +246,12 @@ pub(in crate::backend::api) async fn fork_article( published: Utc::now(), pending: false, }; - DbEdit::create(&form, &data)?; + DbEdit::create(&form, &context)?; } - CreateArticle::send_to_followers(article.clone(), &data).await?; + CreateArticle::send_to_followers(article.clone(), &context).await?; - Ok(Json(DbArticle::read_view(article.id, &data)?)) + Ok(Json(DbArticle::read_view(article.id, &context)?)) } /// Fetch a remote article, including edits collection. Allows viewing and editing. Note that new @@ -259,12 +259,12 @@ pub(in crate::backend::api) async fn fork_article( #[debug_handler] pub(super) async fn resolve_article( Query(query): Query, - data: Data, + context: Data, ) -> MyResult> { - let article: DbArticle = ObjectId::from(query.id).dereference(&data).await?; - let instance = DbInstance::read(article.instance_id, &data)?; - let comments = DbComment::read_for_article(article.id, &data)?; - let latest_version = article.latest_edit_version(&data)?; + let article: DbArticle = ObjectId::from(query.id).dereference(&context).await?; + let instance = DbInstance::read(article.instance_id, &context)?; + let comments = DbComment::read_for_article(article.id, &context)?; + let latest_version = article.latest_edit_version(&context)?; Ok(Json(DbArticleView { article, instance, @@ -277,23 +277,23 @@ pub(super) async fn resolve_article( #[debug_handler] pub(super) async fn search_article( Query(query): Query, - data: Data, + context: Data, ) -> MyResult>> { if query.query.is_empty() { return Err(anyhow!("Query is empty").into()); } - let article = DbArticle::search(&query.query, &data)?; + let article = DbArticle::search(&query.query, &context)?; Ok(Json(article)) } #[debug_handler] pub(in crate::backend::api) async fn protect_article( Extension(user): Extension, - data: Data, + context: Data, Form(params): Form, ) -> MyResult> { check_is_admin(&user)?; - let article = DbArticle::update_protected(params.article_id, params.protected, &data)?; + let article = DbArticle::update_protected(params.article_id, params.protected, &context)?; Ok(Json(article)) } @@ -301,14 +301,14 @@ pub(in crate::backend::api) async fn protect_article( #[debug_handler] pub async fn approve_article( Extension(user): Extension, - data: Data, + context: Data, Form(params): Form, ) -> MyResult> { check_is_admin(&user)?; if params.approve { - DbArticle::update_approved(params.article_id, true, &data)?; + DbArticle::update_approved(params.article_id, true, &context)?; } else { - DbArticle::delete(params.article_id, &data)?; + DbArticle::delete(params.article_id, &context)?; } Ok(Json(())) } @@ -317,9 +317,9 @@ pub async fn approve_article( #[debug_handler] pub async fn delete_conflict( Extension(user): Extension, - data: Data, + context: Data, Form(params): Form, ) -> MyResult> { - DbConflict::delete(params.conflict_id, user.person.id, &data)?; + DbConflict::delete(params.conflict_id, user.person.id, &context)?; Ok(Json(())) } diff --git a/src/backend/api/comment.rs b/src/backend/api/comment.rs index 32cc9ce..d9ab110 100644 --- a/src/backend/api/comment.rs +++ b/src/backend/api/comment.rs @@ -2,7 +2,7 @@ use crate::{ backend::{ database::{ comment::{DbCommentInsertForm, DbCommentUpdateForm}, - IbisData, + IbisContext, }, federation::activities::comment::{ create_or_update_comment::CreateOrUpdateComment, @@ -29,13 +29,13 @@ use chrono::Utc; #[debug_handler] pub(in crate::backend::api) async fn create_comment( user: Extension, - data: Data, + context: Data, Form(params): Form, ) -> MyResult> { validate_not_empty(¶ms.content)?; let mut depth = 0; if let Some(parent_id) = params.parent_id { - let parent = DbComment::read(parent_id, &data)?; + let parent = DbComment::read(parent_id, &context)?; if parent.deleted { return Err(anyhow!("Cant reply to deleted comment").into()); } @@ -57,18 +57,18 @@ pub(in crate::backend::api) async fn create_comment( published: Utc::now(), updated: None, }; - let comment = DbComment::create(form, &data)?; + let comment = DbComment::create(form, &context)?; // Set the ap_id which contains db id (so it is not know before inserting) let proto = http_protocol_str(); - let ap_id = format!("{}://{}/comment/{}", proto, data.domain(), comment.id.0).parse()?; + let ap_id = format!("{}://{}/comment/{}", proto, context.domain(), comment.id.0).parse()?; let form = DbCommentUpdateForm { ap_id: Some(ap_id), ..Default::default() }; - let comment = DbComment::update(form, comment.id, &data)?; + let comment = DbComment::update(form, comment.id, &context)?; - CreateOrUpdateComment::send(&comment.comment, &data).await?; + CreateOrUpdateComment::send(&comment.comment, &context).await?; Ok(Json(comment)) } @@ -76,7 +76,7 @@ pub(in crate::backend::api) async fn create_comment( #[debug_handler] pub(in crate::backend::api) async fn edit_comment( user: Extension, - data: Data, + context: Data, Form(params): Form, ) -> MyResult> { if let Some(content) = ¶ms.content { @@ -85,7 +85,7 @@ pub(in crate::backend::api) async fn edit_comment( if params.content.is_none() && params.deleted.is_none() { return Err(anyhow!("Edit has no parameters").into()); } - let orig_comment = DbComment::read(params.id, &data)?; + let orig_comment = DbComment::read(params.id, &context)?; if orig_comment.creator_id != user.person.id { return Err(anyhow!("Cannot edit comment created by another user").into()); } @@ -95,17 +95,17 @@ pub(in crate::backend::api) async fn edit_comment( updated: Some(Utc::now()), ..Default::default() }; - let comment = DbComment::update(form, params.id, &data)?; + let comment = DbComment::update(form, params.id, &context)?; // federate if orig_comment.content != comment.comment.content { - CreateOrUpdateComment::send(&comment.comment, &data).await?; + CreateOrUpdateComment::send(&comment.comment, &context).await?; } if !orig_comment.deleted && comment.comment.deleted { - DeleteComment::send(&comment.comment, &data).await?; + DeleteComment::send(&comment.comment, &context).await?; } if orig_comment.deleted && !comment.comment.deleted { - UndoDeleteComment::send(&comment.comment, &data).await?; + UndoDeleteComment::send(&comment.comment, &context).await?; } Ok(Json(comment)) diff --git a/src/backend/api/instance.rs b/src/backend/api/instance.rs index 0387c83..3694b6d 100644 --- a/src/backend/api/instance.rs +++ b/src/backend/api/instance.rs @@ -1,5 +1,9 @@ use crate::{ - backend::{database::IbisData, federation::activities::follow::Follow, utils::error::MyResult}, + backend::{ + database::IbisContext, + federation::activities::follow::Follow, + utils::error::MyResult, + }, common::{ instance::{DbInstance, FollowInstanceParams, GetInstanceParams, InstanceView}, user::LocalUserView, @@ -14,10 +18,10 @@ use axum_macros::debug_handler; /// Retrieve details about an instance. If no id is provided, return local instance. #[debug_handler] pub(in crate::backend::api) async fn get_instance( - data: Data, + context: Data, Form(params): Form, ) -> MyResult> { - let local_instance = DbInstance::read_view(params.id, &data)?; + let local_instance = DbInstance::read_view(params.id, &context)?; Ok(Json(local_instance)) } @@ -26,14 +30,14 @@ pub(in crate::backend::api) async fn get_instance( #[debug_handler] pub(in crate::backend::api) async fn follow_instance( Extension(user): Extension, - data: Data, + context: Data, Form(params): Form, ) -> MyResult> { - let target = DbInstance::read(params.id, &data)?; + let target = DbInstance::read(params.id, &context)?; let pending = !target.local; - DbInstance::follow(&user.person, &target, pending, &data)?; - let instance = DbInstance::read(params.id, &data)?; - Follow::send(user.person, &instance, &data).await?; + DbInstance::follow(&user.person, &target, pending, &context)?; + let instance = DbInstance::read(params.id, &context)?; + Follow::send(user.person, &instance, &context).await?; Ok(Json(SuccessResponse::default())) } @@ -42,16 +46,16 @@ pub(in crate::backend::api) async fn follow_instance( #[debug_handler] pub(super) async fn resolve_instance( Query(params): Query, - data: Data, + context: Data, ) -> MyResult> { - let instance: DbInstance = ObjectId::from(params.id).dereference(&data).await?; + let instance: DbInstance = ObjectId::from(params.id).dereference(&context).await?; Ok(Json(instance)) } #[debug_handler] pub(in crate::backend::api) async fn list_remote_instances( - data: Data, + context: Data, ) -> MyResult>> { - let instances = DbInstance::read_remote(&data)?; + let instances = DbInstance::read_remote(&context)?; Ok(Json(instances)) } diff --git a/src/backend/api/mod.rs b/src/backend/api/mod.rs index e4a8001..4694ae2 100644 --- a/src/backend/api/mod.rs +++ b/src/backend/api/mod.rs @@ -16,7 +16,7 @@ use crate::{ instance::{follow_instance, get_instance, resolve_instance}, user::{get_user, login_user, logout_user, register_user}, }, - database::IbisData, + database::IbisContext, utils::error::MyResult, }, common::{ @@ -83,12 +83,12 @@ fn check_is_admin(user: &LocalUserView) -> MyResult<()> { #[debug_handler] pub(in crate::backend::api) async fn site_view( - data: Data, + context: Data, user: Option>, ) -> MyResult> { Ok(Json(SiteView { my_profile: user.map(|u| u.0), - config: data.config.options.clone(), + config: context.config.options.clone(), })) } @@ -97,7 +97,7 @@ pub(in crate::backend::api) async fn site_view( pub async fn edit_list( Query(query): Query, user: Option>, - data: Data, + context: Data, ) -> MyResult>> { let params = if let Some(article_id) = query.article_id { ViewEditParams::ArticleId(article_id) @@ -106,7 +106,7 @@ pub async fn edit_list( } else { return Err(anyhow!("Must provide article_id or person_id").into()); }; - Ok(Json(DbEdit::view(params, &user.map(|u| u.0), &data)?)) + Ok(Json(DbEdit::view(params, &user.map(|u| u.0), &context)?)) } /// Trims the string param, and converts to None if it is empty diff --git a/src/backend/api/user.rs b/src/backend/api/user.rs index 7752195..afec467 100644 --- a/src/backend/api/user.rs +++ b/src/backend/api/user.rs @@ -1,7 +1,7 @@ use super::{check_is_admin, empty_to_none}; use crate::{ backend::{ - database::{conflict::DbConflict, read_jwt_secret, IbisData}, + database::{conflict::DbConflict, read_jwt_secret, IbisContext}, utils::{ error::MyResult, validate::{validate_display_name, validate_user_name}, @@ -54,8 +54,8 @@ struct Claims { pub exp: u64, } -fn generate_login_token(person: &DbPerson, data: &Data) -> MyResult { - let hostname = data.domain().to_string(); +fn generate_login_token(person: &DbPerson, context: &Data) -> MyResult { + let hostname = context.domain().to_string(); let claims = Claims { sub: person.username.clone(), iss: hostname, @@ -63,58 +63,58 @@ fn generate_login_token(person: &DbPerson, data: &Data) -> MyResult MyResult { +pub async fn validate(jwt: &str, context: &IbisContext) -> MyResult { let validation = Validation::default(); - let secret = read_jwt_secret(data)?; + let secret = read_jwt_secret(context)?; let key = DecodingKey::from_secret(secret.as_bytes()); let claims = decode::(jwt, &key, &validation)?; - DbPerson::read_local_from_name(&claims.claims.sub, data) + DbPerson::read_local_from_name(&claims.claims.sub, context) } #[debug_handler] pub(in crate::backend::api) async fn register_user( - data: Data, + context: Data, jar: CookieJar, Form(params): Form, ) -> MyResult<(CookieJar, Json)> { - if !data.config.options.registration_open { + if !context.config.options.registration_open { return Err(anyhow!("Registration is closed").into()); } validate_user_name(¶ms.username)?; - let user = DbPerson::create_local(params.username, params.password, false, &data)?; - let token = generate_login_token(&user.person, &data)?; - let jar = jar.add(create_cookie(token, &data)); + let user = DbPerson::create_local(params.username, params.password, false, &context)?; + let token = generate_login_token(&user.person, &context)?; + let jar = jar.add(create_cookie(token, &context)); Ok((jar, Json(user))) } #[debug_handler] pub(in crate::backend::api) async fn login_user( - data: Data, + context: Data, jar: CookieJar, Form(params): Form, ) -> MyResult<(CookieJar, Json)> { - let user = DbPerson::read_local_from_name(¶ms.username, &data)?; + let user = DbPerson::read_local_from_name(¶ms.username, &context)?; let valid = verify(¶ms.password, &user.local_user.password_encrypted)?; if !valid { return Err(anyhow!("Invalid login").into()); } - let token = generate_login_token(&user.person, &data)?; - let jar = jar.add(create_cookie(token, &data)); + let token = generate_login_token(&user.person, &context)?; + let jar = jar.add(create_cookie(token, &context)); Ok((jar, Json(user))) } -fn create_cookie(jwt: String, data: &Data) -> Cookie<'static> { +fn create_cookie(jwt: String, context: &Data) -> Cookie<'static> { let mut cookie = Cookie::build((AUTH_COOKIE, jwt)); // Must not set cookie domain on localhost // https://stackoverflow.com/a/1188145 - let domain = data.domain().to_string(); + let domain = context.domain().to_string(); if !domain.starts_with("localhost") && !domain.starts_with("127.0.0.1") { cookie = cookie.domain(domain); } @@ -131,45 +131,45 @@ fn create_cookie(jwt: String, data: &Data) -> Cookie<'static> { #[debug_handler] pub(in crate::backend::api) async fn logout_user( - data: Data, + context: Data, jar: CookieJar, ) -> MyResult<(CookieJar, Json)> { - let jar = jar.remove(create_cookie(String::new(), &data)); + let jar = jar.remove(create_cookie(String::new(), &context)); Ok((jar, Json(SuccessResponse::default()))) } #[debug_handler] pub(in crate::backend::api) async fn get_user( params: Query, - data: Data, + context: Data, ) -> MyResult> { Ok(Json(DbPerson::read_from_name( ¶ms.name, ¶ms.domain, - &data, + &context, )?)) } #[debug_handler] pub(in crate::backend::api) async fn update_user_profile( - data: Data, + context: Data, Form(mut params): Form, ) -> MyResult> { empty_to_none(&mut params.display_name); empty_to_none(&mut params.bio); validate_display_name(¶ms.display_name)?; - DbPerson::update_profile(¶ms, &data)?; + DbPerson::update_profile(¶ms, &context)?; Ok(Json(SuccessResponse::default())) } #[debug_handler] pub(crate) async fn list_notifications( Extension(user): Extension, - data: Data, + context: Data, ) -> MyResult>> { - let conflicts = DbConflict::list(&user.person, &data)?; + let conflicts = DbConflict::list(&user.person, &context)?; let conflicts: Vec<_> = try_join_all(conflicts.into_iter().map(|c| { - let data = data.reset_request_count(); + let data = context.reset_request_count(); async move { c.to_api_conflict(&data).await } })) .await?; @@ -180,7 +180,7 @@ pub(crate) async fn list_notifications( .collect(); if check_is_admin(&user).is_ok() { - let articles = DbArticle::list_approval_required(&data)?; + let articles = DbArticle::list_approval_required(&context)?; notifications.extend( articles .into_iter() @@ -195,13 +195,13 @@ pub(crate) async fn list_notifications( #[debug_handler] pub(crate) async fn count_notifications( Extension(user): Extension, - data: Data, + context: Data, ) -> MyResult> { let mut count = 0; - let conflicts = DbConflict::list(&user.person, &data)?; + let conflicts = DbConflict::list(&user.person, &context)?; count += conflicts.len(); if check_is_admin(&user).is_ok() { - let articles = DbArticle::list_approval_required(&data)?; + let articles = DbArticle::list_approval_required(&context)?; count += articles.len(); } diff --git a/src/backend/database/article.rs b/src/backend/database/article.rs index 658b5f6..e3861e5 100644 --- a/src/backend/database/article.rs +++ b/src/backend/database/article.rs @@ -2,7 +2,7 @@ use crate::{ backend::{ database::{ schema::{article, edit, instance}, - IbisData, + IbisContext, }, federation::objects::edits_collection::DbEditCollection, utils::error::MyResult, @@ -46,15 +46,15 @@ impl DbArticle { Ok(CollectionId::parse(&format!("{}/edits", self.ap_id))?) } - pub fn create(form: DbArticleForm, data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn create(form: DbArticleForm, context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; Ok(insert_into(article::table) .values(form) .get_result(conn.deref_mut())?) } - pub fn create_or_update(form: DbArticleForm, data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn create_or_update(form: DbArticleForm, context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; Ok(insert_into(article::table) .values(&form) .on_conflict(article::dsl::ap_id) @@ -63,48 +63,48 @@ impl DbArticle { .get_result(conn.deref_mut())?) } - pub fn update_text(id: ArticleId, text: &str, data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn update_text(id: ArticleId, text: &str, context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; Ok(diesel::update(article::dsl::article.find(id)) .set(article::dsl::text.eq(text)) .get_result::(conn.deref_mut())?) } - pub fn update_protected(id: ArticleId, locked: bool, data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn update_protected(id: ArticleId, locked: bool, context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; Ok(diesel::update(article::dsl::article.find(id)) .set(article::dsl::protected.eq(locked)) .get_result::(conn.deref_mut())?) } - pub fn update_approved(id: ArticleId, approved: bool, data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn update_approved(id: ArticleId, approved: bool, context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; Ok(diesel::update(article::dsl::article.find(id)) .set(article::dsl::approved.eq(approved)) .get_result::(conn.deref_mut())?) } - pub fn delete(id: ArticleId, data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn delete(id: ArticleId, context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; Ok(diesel::delete(article::dsl::article.find(id)).get_result::(conn.deref_mut())?) } - pub fn read(id: ArticleId, data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn read(id: ArticleId, context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; Ok(article::table .find(id) .get_result::(conn.deref_mut())?) } - pub fn read_view(id: ArticleId, data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn read_view(id: ArticleId, context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; let query = article::table .find(id) .inner_join(instance::table) .into_boxed(); let (article, instance): (DbArticle, DbInstance) = query.get_result(conn.deref_mut())?; - let comments = DbComment::read_for_article(article.id, data)?; - let latest_version = article.latest_edit_version(data)?; + let comments = DbComment::read_for_article(article.id, context)?; + let latest_version = article.latest_edit_version(context)?; Ok(DbArticleView { article, instance, @@ -116,9 +116,9 @@ impl DbArticle { pub fn read_view_title( title: &str, domain: Option, - data: &IbisData, + context: &IbisContext, ) -> MyResult { - let mut conn = data.db_pool.get()?; + let mut conn = context.db_pool.get()?; let (article, instance): (DbArticle, DbInstance) = { let query = article::table .inner_join(instance::table) @@ -131,8 +131,8 @@ impl DbArticle { }; query.get_result(conn.deref_mut())? }; - let comments = DbComment::read_for_article(article.id, data)?; - let latest_version = article.latest_edit_version(data)?; + let comments = DbComment::read_for_article(article.id, context)?; + let latest_version = article.latest_edit_version(context)?; Ok(DbArticleView { article, instance, @@ -141,8 +141,8 @@ impl DbArticle { }) } - pub fn read_from_ap_id(ap_id: &ObjectId, data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn read_from_ap_id(ap_id: &ObjectId, context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; Ok(article::table .filter(article::dsl::ap_id.eq(ap_id)) .get_result(conn.deref_mut())?) @@ -154,9 +154,9 @@ impl DbArticle { pub fn read_all( only_local: Option, instance_id: Option, - data: &IbisData, + context: &IbisContext, ) -> MyResult> { - let mut conn = data.db_pool.get()?; + let mut conn = context.db_pool.get()?; let mut query = article::table .inner_join(edit::table) .inner_join(instance::table) @@ -175,8 +175,8 @@ impl DbArticle { Ok(query.get_results(&mut conn)?) } - pub fn search(query: &str, data: &IbisData) -> MyResult> { - let mut conn = data.db_pool.get()?; + pub fn search(query: &str, context: &IbisContext) -> MyResult> { + let mut conn = context.db_pool.get()?; let replaced = query .replace('%', "\\%") .replace('_', "\\_") @@ -191,8 +191,8 @@ impl DbArticle { .get_results(conn.deref_mut())?) } - pub fn latest_edit_version(&self, data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn latest_edit_version(&self, context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; let latest_version: Option = edit::table .filter(edit::dsl::article_id.eq(self.id)) .order_by(edit::dsl::id.desc()) @@ -206,8 +206,8 @@ impl DbArticle { } } - pub fn list_approval_required(data: &IbisData) -> MyResult> { - let mut conn = data.db_pool.get()?; + pub fn list_approval_required(context: &IbisContext) -> MyResult> { + let mut conn = context.db_pool.get()?; let query = article::table .group_by(article::dsl::id) .filter(article::dsl::approved.eq(false)) diff --git a/src/backend/database/comment.rs b/src/backend/database/comment.rs index 3ac1816..7e3775d 100644 --- a/src/backend/database/comment.rs +++ b/src/backend/database/comment.rs @@ -1,6 +1,6 @@ use super::{ schema::{comment, person}, - IbisData, + IbisContext, }; use crate::{ backend::utils::error::MyResult, @@ -48,8 +48,8 @@ pub struct DbCommentUpdateForm { } impl DbComment { - pub fn create(form: DbCommentInsertForm, data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn create(form: DbCommentInsertForm, context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; Ok(insert_into(comment::table) .values(form) .get_result(conn.deref_mut())?) @@ -58,18 +58,18 @@ impl DbComment { pub fn update( form: DbCommentUpdateForm, id: CommentId, - data: &IbisData, + context: &IbisContext, ) -> MyResult { - let mut conn = data.db_pool.get()?; + let mut conn = context.db_pool.get()?; let comment: DbComment = update(comment::table.find(id)) .set(form) .get_result(conn.deref_mut())?; - let creator = DbPerson::read(comment.creator_id, data)?; + let creator = DbPerson::read(comment.creator_id, context)?; Ok(DbCommentView { comment, creator }) } - pub fn create_or_update(form: DbCommentInsertForm, data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn create_or_update(form: DbCommentInsertForm, context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; Ok(insert_into(comment::table) .values(&form) .on_conflict(comment::dsl::ap_id) @@ -78,24 +78,24 @@ impl DbComment { .get_result(conn.deref_mut())?) } - pub fn read(id: CommentId, data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn read(id: CommentId, context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; Ok(comment::table .find(id) .get_result::(conn.deref_mut())?) } - pub fn read_view(id: CommentId, data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn read_view(id: CommentId, context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; let comment = comment::table .find(id) .get_result::(conn.deref_mut())?; - let creator = DbPerson::read(comment.creator_id, data)?; + let creator = DbPerson::read(comment.creator_id, context)?; Ok(DbCommentView { comment, creator }) } - pub fn read_from_ap_id(ap_id: &ObjectId, data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn read_from_ap_id(ap_id: &ObjectId, context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; Ok(comment::table .filter(comment::dsl::ap_id.eq(ap_id)) .get_result(conn.deref_mut())?) @@ -103,9 +103,9 @@ impl DbComment { pub fn read_for_article( article_id: ArticleId, - data: &IbisData, + context: &IbisContext, ) -> MyResult> { - let mut conn = data.db_pool.get()?; + let mut conn = context.db_pool.get()?; let comments = comment::table .inner_join(person::table) .filter(comment::article_id.eq(article_id)) diff --git a/src/backend/database/conflict.rs b/src/backend/database/conflict.rs index f0bbe47..4826029 100644 --- a/src/backend/database/conflict.rs +++ b/src/backend/database/conflict.rs @@ -2,7 +2,7 @@ use crate::{ backend::{ database::{ schema::{conflict, edit}, - IbisData, + IbisContext, }, federation::activities::submit_article_update, utils::{error::MyResult, generate_article_version}, @@ -57,23 +57,23 @@ pub struct DbConflictForm { } impl DbConflict { - pub fn create(form: &DbConflictForm, data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn create(form: &DbConflictForm, context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; Ok(insert_into(conflict::table) .values(form) .get_result(conn.deref_mut())?) } - pub fn list(person: &DbPerson, data: &IbisData) -> MyResult> { - let mut conn = data.db_pool.get()?; + pub fn list(person: &DbPerson, context: &IbisContext) -> MyResult> { + let mut conn = context.db_pool.get()?; Ok(conflict::table .filter(conflict::dsl::creator_id.eq(person.id)) .get_results(conn.deref_mut())?) } /// Delete merge conflict which was created by specific user - pub fn delete(id: ConflictId, creator_id: PersonId, data: &IbisData) -> MyResult<()> { - let mut conn = data.db_pool.get()?; + pub fn delete(id: ConflictId, creator_id: PersonId, context: &IbisContext) -> MyResult<()> { + let mut conn = context.db_pool.get()?; let conflict: Self = delete( conflict::table .filter(conflict::dsl::creator_id.eq(creator_id)) @@ -89,13 +89,16 @@ impl DbConflict { Ok(()) } - pub async fn to_api_conflict(&self, data: &Data) -> MyResult> { - let article = DbArticle::read_view(self.article_id, data)?; + pub async fn to_api_conflict( + &self, + context: &Data, + ) -> MyResult> { + let article = DbArticle::read_view(self.article_id, context)?; // Make sure to get latest version from origin so that all conflicts can be resolved - let original_article = article.article.ap_id.dereference_forced(data).await?; + let original_article = article.article.ap_id.dereference_forced(context).await?; // create common ancestor version - let edits = DbEdit::list_for_article(original_article.id, data)?; + let edits = DbEdit::list_for_article(original_article.id, context)?; let ancestor = generate_article_version(&edits, &self.previous_version_id)?; let patch = Patch::from_str(&self.diff)?; @@ -111,10 +114,10 @@ impl DbConflict { self.previous_version_id.clone(), &original_article, self.creator_id, - data, + context, ) .await?; - DbConflict::delete(self.id, self.creator_id, data)?; + DbConflict::delete(self.id, self.creator_id, context)?; Ok(None) } Err(three_way_merge) => { @@ -125,7 +128,7 @@ impl DbConflict { three_way_merge, summary: self.summary.clone(), article: original_article.clone(), - previous_version_id: original_article.latest_edit_version(data)?, + previous_version_id: original_article.latest_edit_version(context)?, published: self.published, })) } diff --git a/src/backend/database/edit.rs b/src/backend/database/edit.rs index 4426862..d706227 100644 --- a/src/backend/database/edit.rs +++ b/src/backend/database/edit.rs @@ -2,7 +2,7 @@ use crate::{ backend::{ database::schema::{article, edit, person}, utils::error::MyResult, - IbisData, + IbisContext, }, common::{ article::{DbArticle, DbEdit, EditVersion, EditView}, @@ -77,8 +77,8 @@ impl DbEditForm { } impl DbEdit { - pub fn create(form: &DbEditForm, data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn create(form: &DbEditForm, context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; Ok(insert_into(edit::table) .values(form) .on_conflict(edit::dsl::ap_id) @@ -87,22 +87,22 @@ impl DbEdit { .get_result(conn.deref_mut())?) } - pub fn read(version: &EditVersion, data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn read(version: &EditVersion, context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; Ok(edit::table .filter(edit::dsl::hash.eq(version)) .get_result(conn.deref_mut())?) } - pub fn read_from_ap_id(ap_id: &ObjectId, data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn read_from_ap_id(ap_id: &ObjectId, context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; Ok(edit::table .filter(edit::dsl::ap_id.eq(ap_id)) .get_result(conn.deref_mut())?) } - pub fn list_for_article(id: ArticleId, data: &IbisData) -> MyResult> { - let mut conn = data.db_pool.get()?; + pub fn list_for_article(id: ArticleId, context: &IbisContext) -> MyResult> { + let mut conn = context.db_pool.get()?; Ok(edit::table .filter(edit::article_id.eq(id)) .order(edit::published) @@ -112,9 +112,9 @@ impl DbEdit { pub fn view( params: ViewEditParams, user: &Option, - data: &IbisData, + context: &IbisContext, ) -> MyResult> { - let mut conn = data.db_pool.get()?; + let mut conn = context.db_pool.get()?; let person_id = user.as_ref().map(|u| u.person.id).unwrap_or(PersonId(-1)); let query = edit::table .inner_join(article::table) diff --git a/src/backend/database/instance.rs b/src/backend/database/instance.rs index 22c02fc..1cb8408 100644 --- a/src/backend/database/instance.rs +++ b/src/backend/database/instance.rs @@ -2,7 +2,7 @@ use crate::{ backend::{ database::{ schema::{article, comment, instance, instance_follow}, - IbisData, + IbisContext, }, federation::objects::{ articles_collection::DbArticleCollection, @@ -48,8 +48,8 @@ pub struct DbInstanceForm { } impl DbInstance { - pub fn create(form: &DbInstanceForm, data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn create(form: &DbInstanceForm, context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; Ok(insert_into(instance::table) .values(form) .on_conflict(instance::ap_id) @@ -58,34 +58,37 @@ impl DbInstance { .get_result(conn.deref_mut())?) } - pub fn read(id: InstanceId, data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn read(id: InstanceId, context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; Ok(instance::table.find(id).get_result(conn.deref_mut())?) } pub fn read_from_ap_id( ap_id: &ObjectId, - data: &Data, + context: &Data, ) -> MyResult { - let mut conn = data.db_pool.get()?; + let mut conn = context.db_pool.get()?; Ok(instance::table .filter(instance::ap_id.eq(ap_id)) .get_result(conn.deref_mut())?) } - pub fn read_local(data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn read_local(context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; Ok(instance::table .filter(instance::local.eq(true)) .get_result(conn.deref_mut())?) } - pub fn read_view(id: Option, data: &Data) -> MyResult { + pub fn read_view( + id: Option, + context: &Data, + ) -> MyResult { let instance = match id { - Some(id) => DbInstance::read(id, data), - None => DbInstance::read_local(data), + Some(id) => DbInstance::read(id, context), + None => DbInstance::read_local(context), }?; - let followers = DbInstance::read_followers(instance.id, data)?; + let followers = DbInstance::read_followers(instance.id, context)?; Ok(InstanceView { instance, @@ -97,10 +100,10 @@ impl DbInstance { follower: &DbPerson, instance: &DbInstance, pending_: bool, - data: &Data, + context: &Data, ) -> MyResult<()> { use instance_follow::dsl::{follower_id, instance_id, pending}; - let mut conn = data.db_pool.get()?; + let mut conn = context.db_pool.get()?; let form = ( instance_id.eq(instance.id), follower_id.eq(follower.id), @@ -116,10 +119,10 @@ impl DbInstance { Ok(()) } - pub fn read_followers(id_: InstanceId, data: &IbisData) -> MyResult> { + pub fn read_followers(id_: InstanceId, context: &IbisContext) -> MyResult> { use crate::backend::database::schema::person; use instance_follow::dsl::{follower_id, instance_id}; - let mut conn = data.db_pool.get()?; + let mut conn = context.db_pool.get()?; Ok(instance_follow::table .inner_join(person::table.on(follower_id.eq(person::id))) .filter(instance_id.eq(id_)) @@ -127,8 +130,8 @@ impl DbInstance { .get_results(conn.deref_mut())?) } - pub fn read_remote(data: &Data) -> MyResult> { - let mut conn = data.db_pool.get()?; + pub fn read_remote(context: &Data) -> MyResult> { + let mut conn = context.db_pool.get()?; Ok(instance::table .filter(instance::local.eq(false)) .get_results(conn.deref_mut())?) @@ -136,8 +139,11 @@ impl DbInstance { /// Read the instance where an article is hosted, based on a comment id. /// Note this may be different from the instance where the comment is hosted. - pub fn read_for_comment(comment_id: CommentId, data: &Data) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn read_for_comment( + comment_id: CommentId, + context: &Data, + ) -> MyResult { + let mut conn = context.db_pool.get()?; Ok(instance::table .inner_join(article::table) .inner_join(comment::table.on(comment::article_id.eq(article::id))) diff --git a/src/backend/database/instance_stats.rs b/src/backend/database/instance_stats.rs index 5131ee6..f01ad60 100644 --- a/src/backend/database/instance_stats.rs +++ b/src/backend/database/instance_stats.rs @@ -1,5 +1,5 @@ use super::schema::instance_stats; -use crate::backend::{IbisData, MyResult}; +use crate::backend::{IbisContext, MyResult}; use diesel::{query_dsl::methods::FindDsl, Queryable, RunQueryDsl, Selectable}; use std::ops::DerefMut; @@ -15,8 +15,8 @@ pub struct InstanceStats { } impl InstanceStats { - pub fn read(data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn read(context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; Ok(instance_stats::table.find(1).get_result(conn.deref_mut())?) } } diff --git a/src/backend/database/mod.rs b/src/backend/database/mod.rs index d2f7fa0..736e9bd 100644 --- a/src/backend/database/mod.rs +++ b/src/backend/database/mod.rs @@ -19,13 +19,13 @@ pub mod user; pub type DbPool = Pool>; #[derive(Clone)] -pub struct IbisData { +pub struct IbisContext { pub db_pool: DbPool, pub config: IbisConfig, } -pub fn read_jwt_secret(data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; +pub fn read_jwt_secret(context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; Ok(jwt_secret::table .select(jwt_secret::dsl::secret) .first(conn.deref_mut())?) diff --git a/src/backend/database/user.rs b/src/backend/database/user.rs index 540fef9..167e607 100644 --- a/src/backend/database/user.rs +++ b/src/backend/database/user.rs @@ -2,7 +2,7 @@ use crate::{ backend::{ database::{ schema::{instance, instance_follow, local_user, person}, - IbisData, + IbisContext, }, utils::{error::MyResult, generate_keypair}, }, @@ -51,8 +51,8 @@ pub struct DbPersonForm { } impl DbPerson { - pub fn create(person_form: &DbPersonForm, data: &Data) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn create(person_form: &DbPersonForm, context: &Data) -> MyResult { + let mut conn = context.db_pool.get()?; Ok(insert_into(person::table) .values(person_form) .on_conflict(person::dsl::ap_id) @@ -61,8 +61,8 @@ impl DbPerson { .get_result::(conn.deref_mut())?) } - pub fn read(id: PersonId, data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn read(id: PersonId, context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; Ok(person::table.find(id).get_result(conn.deref_mut())?) } @@ -70,10 +70,10 @@ impl DbPerson { username: String, password: String, admin: bool, - data: &IbisData, + context: &IbisContext, ) -> MyResult { - let mut conn = data.db_pool.get()?; - let domain = &data.config.federation.domain; + let mut conn = context.db_pool.get()?; + let domain = &context.config.federation.domain; let ap_id = ObjectId::parse(&format!( "{}://{domain}/user/{username}", http_protocol_str() @@ -115,9 +115,9 @@ impl DbPerson { pub fn read_from_ap_id( ap_id: &ObjectId, - data: &Data, + context: &Data, ) -> MyResult { - let mut conn = data.db_pool.get()?; + let mut conn = context.db_pool.get()?; Ok(person::table .filter(person::dsl::ap_id.eq(ap_id)) .get_result(conn.deref_mut())?) @@ -126,9 +126,9 @@ impl DbPerson { pub fn read_from_name( username: &str, domain: &Option, - data: &Data, + context: &Data, ) -> MyResult { - let mut conn = data.db_pool.get()?; + let mut conn = context.db_pool.get()?; let mut query = person::table .filter(person::username.eq(username)) .select(person::all_columns) @@ -144,8 +144,8 @@ impl DbPerson { Ok(query.get_result(conn.deref_mut())?) } - pub fn update_profile(params: &UpdateUserParams, data: &Data) -> MyResult<()> { - let mut conn = data.db_pool.get()?; + pub fn update_profile(params: &UpdateUserParams, context: &Data) -> MyResult<()> { + let mut conn = context.db_pool.get()?; diesel::update(person::table.find(params.person_id)) .set(( person::dsl::display_name.eq(¶ms.display_name), @@ -155,15 +155,15 @@ impl DbPerson { Ok(()) } - pub fn read_local_from_name(username: &str, data: &IbisData) -> MyResult { - let mut conn = data.db_pool.get()?; + pub fn read_local_from_name(username: &str, context: &IbisContext) -> MyResult { + let mut conn = context.db_pool.get()?; let (person, local_user) = person::table .inner_join(local_user::table) .filter(person::dsl::local) .filter(person::dsl::username.eq(username)) .get_result::<(DbPerson, DbLocalUser)>(conn.deref_mut())?; // TODO: handle this in single query - let following = Self::read_following(person.id, data)?; + let following = Self::read_following(person.id, context)?; Ok(LocalUserView { person, local_user, @@ -171,9 +171,9 @@ impl DbPerson { }) } - fn read_following(id_: PersonId, data: &IbisData) -> MyResult> { + fn read_following(id_: PersonId, context: &IbisContext) -> MyResult> { use instance_follow::dsl::{follower_id, instance_id}; - let mut conn = data.db_pool.get()?; + let mut conn = context.db_pool.get()?; Ok(instance_follow::table .inner_join(instance::table.on(instance_id.eq(instance::dsl::id))) .filter(follower_id.eq(id_)) @@ -182,13 +182,13 @@ impl DbPerson { } /// Ghost user serves as placeholder for deleted accounts - pub fn ghost(data: &Data) -> MyResult { + pub fn ghost(context: &Data) -> MyResult { let username = "ghost"; - let read = DbPerson::read_from_name(username, &None, data); + let read = DbPerson::read_from_name(username, &None, context); if read.is_ok() { read } else { - let domain = &data.config.federation.domain; + let domain = &context.config.federation.domain; let ap_id = ObjectId::parse(&format!( "{}://{domain}/user/{username}", http_protocol_str() @@ -206,7 +206,7 @@ impl DbPerson { display_name: None, bio: None, }; - DbPerson::create(&person_form, data) + DbPerson::create(&person_form, context) } } } diff --git a/src/backend/federation/activities/accept.rs b/src/backend/federation/activities/accept.rs index fd8cb2b..2c65abc 100644 --- a/src/backend/federation/activities/accept.rs +++ b/src/backend/federation/activities/accept.rs @@ -1,6 +1,6 @@ use crate::{ backend::{ - database::IbisData, + database::IbisContext, federation::{activities::follow::Follow, send_activity}, utils::{ error::{Error, MyResult}, @@ -32,10 +32,10 @@ impl Accept { pub async fn send( local_instance: DbInstance, object: Follow, - data: &Data, + context: &Data, ) -> MyResult<()> { - let id = generate_activity_id(data)?; - let follower = object.actor.dereference(data).await?; + let id = generate_activity_id(context)?; + let follower = object.actor.dereference(context).await?; let accept = Accept { actor: local_instance.ap_id.clone(), object, @@ -46,7 +46,7 @@ impl Accept { &local_instance, accept, vec![follower.shared_inbox_or_inbox()], - data, + context, ) .await?; Ok(()) @@ -55,7 +55,7 @@ impl Accept { #[async_trait::async_trait] impl ActivityHandler for Accept { - type DataType = IbisData; + type DataType = IbisContext; type Error = Error; fn id(&self) -> &Url { @@ -66,15 +66,15 @@ impl ActivityHandler for Accept { self.actor.inner() } - async fn verify(&self, _data: &Data) -> Result<(), Self::Error> { + async fn verify(&self, _context: &Data) -> Result<(), Self::Error> { Ok(()) } - async fn receive(self, data: &Data) -> Result<(), Self::Error> { + async fn receive(self, context: &Data) -> Result<(), Self::Error> { // add to follows - let person = self.object.actor.dereference_local(data).await?; - let instance = self.actor.dereference(data).await?; - DbInstance::follow(&person, &instance, false, data)?; + let person = self.object.actor.dereference_local(context).await?; + let instance = self.actor.dereference(context).await?; + DbInstance::follow(&person, &instance, false, context)?; Ok(()) } } diff --git a/src/backend/federation/activities/announce.rs b/src/backend/federation/activities/announce.rs index 6270eca..6c96a6b 100644 --- a/src/backend/federation/activities/announce.rs +++ b/src/backend/federation/activities/announce.rs @@ -1,6 +1,6 @@ use crate::{ backend::{ - database::IbisData, + database::IbisContext, federation::{routes::AnnouncableActivities, send_activity}, utils::{ error::{Error, MyResult}, @@ -32,7 +32,7 @@ pub struct AnnounceActivity { } impl AnnounceActivity { - pub async fn send(object: AnnouncableActivities, context: &Data) -> MyResult<()> { + pub async fn send(object: AnnouncableActivities, context: &Data) -> MyResult<()> { let id = generate_activity_id(context)?; let instance = DbInstance::read_local(context)?; let announce = AnnounceActivity { @@ -56,7 +56,7 @@ impl AnnounceActivity { #[async_trait::async_trait] impl ActivityHandler for AnnounceActivity { - type DataType = IbisData; + type DataType = IbisContext; type Error = Error; fn id(&self) -> &Url { diff --git a/src/backend/federation/activities/comment/create_or_update_comment.rs b/src/backend/federation/activities/comment/create_or_update_comment.rs index 8bfdcf0..200a217 100644 --- a/src/backend/federation/activities/comment/create_or_update_comment.rs +++ b/src/backend/federation/activities/comment/create_or_update_comment.rs @@ -1,7 +1,7 @@ use super::generate_comment_activity_to; use crate::{ backend::{ - database::IbisData, + database::IbisContext, federation::{ objects::comment::ApubComment, routes::AnnouncableActivities, @@ -40,16 +40,16 @@ pub struct CreateOrUpdateComment { } impl CreateOrUpdateComment { - pub async fn send(comment: &DbComment, data: &Data) -> MyResult<()> { - let instance = DbInstance::read_for_comment(comment.id, data)?; + pub async fn send(comment: &DbComment, context: &Data) -> MyResult<()> { + let instance = DbInstance::read_for_comment(comment.id, context)?; let kind = if comment.updated.is_none() { CreateOrUpdateType::Create } else { CreateOrUpdateType::Update }; - let object = comment.clone().into_json(data).await?; - let id = generate_activity_id(data)?; + let object = comment.clone().into_json(context).await?; + let id = generate_activity_id(context)?; let activity = Self { actor: object.attributed_to.clone(), object, @@ -58,15 +58,15 @@ impl CreateOrUpdateComment { id, }; let activity = AnnouncableActivities::CreateOrUpdateComment(activity); - let creator = DbPerson::read(comment.creator_id, data)?; - send_activity_to_instance(&creator, activity, &instance, data).await?; + let creator = DbPerson::read(comment.creator_id, context)?; + send_activity_to_instance(&creator, activity, &instance, context).await?; Ok(()) } } #[async_trait::async_trait] impl ActivityHandler for CreateOrUpdateComment { - type DataType = IbisData; + type DataType = IbisContext; type Error = Error; fn id(&self) -> &Url { @@ -77,18 +77,18 @@ impl ActivityHandler for CreateOrUpdateComment { self.actor.inner() } - async fn verify(&self, _data: &Data) -> Result<(), Self::Error> { + async fn verify(&self, _context: &Data) -> Result<(), Self::Error> { verify_domains_match(&self.id, self.object.id.inner())?; verify_domains_match(&self.id, self.actor.inner())?; Ok(()) } - async fn receive(self, data: &Data) -> Result<(), Self::Error> { - let comment = DbComment::from_json(self.object, data).await?; + async fn receive(self, context: &Data) -> Result<(), Self::Error> { + let comment = DbComment::from_json(self.object, context).await?; - let instance = DbInstance::read_for_comment(comment.id, data)?; + let instance = DbInstance::read_for_comment(comment.id, context)?; if instance.local { - Self::send(&comment, data).await?; + Self::send(&comment, context).await?; } Ok(()) } diff --git a/src/backend/federation/activities/comment/delete_comment.rs b/src/backend/federation/activities/comment/delete_comment.rs index e527177..86dc2b9 100644 --- a/src/backend/federation/activities/comment/delete_comment.rs +++ b/src/backend/federation/activities/comment/delete_comment.rs @@ -1,7 +1,7 @@ use super::generate_comment_activity_to; use crate::{ backend::{ - database::{comment::DbCommentUpdateForm, IbisData}, + database::{comment::DbCommentUpdateForm, IbisContext}, federation::{routes::AnnouncableActivities, send_activity_to_instance}, utils::{ error::{Error, MyResult}, @@ -38,9 +38,9 @@ impl DeleteComment { comment: &DbComment, creator: &DbPerson, instance: &DbInstance, - data: &Data, + context: &Data, ) -> MyResult { - let id = generate_activity_id(data)?; + let id = generate_activity_id(context)?; Ok(DeleteComment { actor: creator.ap_id.clone(), object: comment.ap_id.clone(), @@ -49,19 +49,19 @@ impl DeleteComment { id, }) } - pub async fn send(comment: &DbComment, data: &Data) -> MyResult<()> { - let instance = DbInstance::read_for_comment(comment.id, data)?; - let creator = DbPerson::read(comment.creator_id, data)?; - let activity = Self::new(comment, &creator, &instance, data)?; + pub async fn send(comment: &DbComment, context: &Data) -> MyResult<()> { + let instance = DbInstance::read_for_comment(comment.id, context)?; + let creator = DbPerson::read(comment.creator_id, context)?; + let activity = Self::new(comment, &creator, &instance, context)?; let activity = AnnouncableActivities::DeleteComment(activity); - send_activity_to_instance(&creator, activity, &instance, data).await?; + send_activity_to_instance(&creator, activity, &instance, context).await?; Ok(()) } } #[async_trait::async_trait] impl ActivityHandler for DeleteComment { - type DataType = IbisData; + type DataType = IbisContext; type Error = Error; fn id(&self) -> &Url { @@ -72,24 +72,24 @@ impl ActivityHandler for DeleteComment { self.actor.inner() } - async fn verify(&self, _data: &Data) -> Result<(), Self::Error> { + async fn verify(&self, _context: &Data) -> Result<(), Self::Error> { verify_domains_match(self.actor.inner(), &self.id)?; verify_domains_match(self.actor.inner(), self.object.inner())?; Ok(()) } - async fn receive(self, data: &Data) -> Result<(), Self::Error> { + async fn receive(self, context: &Data) -> Result<(), Self::Error> { let form = DbCommentUpdateForm { deleted: Some(true), updated: Some(Utc::now()), ..Default::default() }; - let comment = self.object.dereference(data).await?; - DbComment::update(form, comment.id, data)?; + let comment = self.object.dereference(context).await?; + DbComment::update(form, comment.id, context)?; - let instance = DbInstance::read_for_comment(comment.id, data)?; + let instance = DbInstance::read_for_comment(comment.id, context)?; if instance.local { - Self::send(&comment, data).await?; + Self::send(&comment, context).await?; } Ok(()) } diff --git a/src/backend/federation/activities/comment/undo_delete_comment.rs b/src/backend/federation/activities/comment/undo_delete_comment.rs index c189d0e..30b049d 100644 --- a/src/backend/federation/activities/comment/undo_delete_comment.rs +++ b/src/backend/federation/activities/comment/undo_delete_comment.rs @@ -1,7 +1,7 @@ use super::{delete_comment::DeleteComment, generate_comment_activity_to}; use crate::{ backend::{ - database::{comment::DbCommentUpdateForm, IbisData}, + database::{comment::DbCommentUpdateForm, IbisContext}, federation::{routes::AnnouncableActivities, send_activity_to_instance}, utils::{ error::{Error, MyResult}, @@ -37,11 +37,11 @@ pub struct UndoDeleteComment { } impl UndoDeleteComment { - pub async fn send(comment: &DbComment, data: &Data) -> MyResult<()> { - let instance = DbInstance::read_for_comment(comment.id, data)?; - let id = generate_activity_id(data)?; - let creator = DbPerson::read(comment.creator_id, data)?; - let object = DeleteComment::new(comment, &creator, &instance, data)?; + pub async fn send(comment: &DbComment, context: &Data) -> MyResult<()> { + let instance = DbInstance::read_for_comment(comment.id, context)?; + let id = generate_activity_id(context)?; + let creator = DbPerson::read(comment.creator_id, context)?; + let object = DeleteComment::new(comment, &creator, &instance, context)?; let activity = UndoDeleteComment { actor: creator.ap_id.clone(), object, @@ -50,14 +50,14 @@ impl UndoDeleteComment { id, }; let activity = AnnouncableActivities::UndoDeleteComment(activity); - send_activity_to_instance(&creator, activity, &instance, data).await?; + send_activity_to_instance(&creator, activity, &instance, context).await?; Ok(()) } } #[async_trait::async_trait] impl ActivityHandler for UndoDeleteComment { - type DataType = IbisData; + type DataType = IbisContext; type Error = Error; fn id(&self) -> &Url { @@ -68,24 +68,24 @@ impl ActivityHandler for UndoDeleteComment { self.actor.inner() } - async fn verify(&self, _data: &Data) -> Result<(), Self::Error> { + async fn verify(&self, _context: &Data) -> Result<(), Self::Error> { verify_urls_match(self.actor.inner(), self.object.actor.inner())?; verify_domains_match(self.actor.inner(), &self.id)?; Ok(()) } - async fn receive(self, data: &Data) -> Result<(), Self::Error> { + async fn receive(self, context: &Data) -> Result<(), Self::Error> { let form = DbCommentUpdateForm { deleted: Some(false), updated: Some(Utc::now()), ..Default::default() }; - let comment = self.object.object.dereference(data).await?; - DbComment::update(form, comment.id, data)?; + let comment = self.object.object.dereference(context).await?; + DbComment::update(form, comment.id, context)?; - let instance = DbInstance::read_for_comment(comment.id, data)?; + let instance = DbInstance::read_for_comment(comment.id, context)?; if instance.local { - Self::send(&comment, data).await?; + Self::send(&comment, context).await?; } Ok(()) } diff --git a/src/backend/federation/activities/create_article.rs b/src/backend/federation/activities/create_article.rs index 8965a58..7a4b973 100644 --- a/src/backend/federation/activities/create_article.rs +++ b/src/backend/federation/activities/create_article.rs @@ -1,6 +1,6 @@ use crate::{ backend::{ - database::IbisData, + database::IbisContext, federation::objects::article::ApubArticle, utils::{ error::{Error, MyResult}, @@ -32,11 +32,14 @@ pub struct CreateArticle { } impl CreateArticle { - pub async fn send_to_followers(article: DbArticle, data: &Data) -> MyResult<()> { - let local_instance = DbInstance::read_local(data)?; - let object = article.clone().into_json(data).await?; - let id = generate_activity_id(data)?; - let to = local_instance.follower_ids(data)?; + pub async fn send_to_followers( + article: DbArticle, + context: &Data, + ) -> MyResult<()> { + let local_instance = DbInstance::read_local(context)?; + let object = article.clone().into_json(context).await?; + let id = generate_activity_id(context)?; + let to = local_instance.follower_ids(context)?; let create = CreateArticle { actor: local_instance.ap_id.clone(), to, @@ -45,14 +48,14 @@ impl CreateArticle { id, }; local_instance - .send_to_followers(create, vec![], data) + .send_to_followers(create, vec![], context) .await?; Ok(()) } } #[async_trait::async_trait] impl ActivityHandler for CreateArticle { - type DataType = IbisData; + type DataType = IbisContext; type Error = Error; fn id(&self) -> &Url { @@ -63,15 +66,17 @@ impl ActivityHandler for CreateArticle { self.actor.inner() } - async fn verify(&self, _data: &Data) -> Result<(), Self::Error> { + async fn verify(&self, _context: &Data) -> Result<(), Self::Error> { Ok(()) } - async fn receive(self, data: &Data) -> Result<(), Self::Error> { - let article = DbArticle::from_json(self.object.clone(), data).await?; + async fn receive(self, context: &Data) -> Result<(), Self::Error> { + let article = DbArticle::from_json(self.object.clone(), context).await?; if article.local { - let local_instance = DbInstance::read_local(data)?; - local_instance.send_to_followers(self, vec![], data).await?; + let local_instance = DbInstance::read_local(context)?; + local_instance + .send_to_followers(self, vec![], context) + .await?; } Ok(()) } diff --git a/src/backend/federation/activities/follow.rs b/src/backend/federation/activities/follow.rs index 2dc2f23..93de0a7 100644 --- a/src/backend/federation/activities/follow.rs +++ b/src/backend/federation/activities/follow.rs @@ -1,6 +1,6 @@ use crate::{ backend::{ - database::IbisData, + database::IbisContext, federation::{activities::accept::Accept, send_activity}, generate_activity_id, utils::error::{Error, MyResult}, @@ -28,22 +28,26 @@ pub struct Follow { } impl Follow { - pub async fn send(actor: DbPerson, to: &DbInstance, data: &Data) -> MyResult<()> { - let id = generate_activity_id(data)?; + pub async fn send( + actor: DbPerson, + to: &DbInstance, + context: &Data, + ) -> MyResult<()> { + let id = generate_activity_id(context)?; let follow = Follow { actor: actor.ap_id.clone(), object: to.ap_id.clone(), kind: Default::default(), id, }; - send_activity(&actor, follow, vec![to.shared_inbox_or_inbox()], data).await?; + send_activity(&actor, follow, vec![to.shared_inbox_or_inbox()], context).await?; Ok(()) } } #[async_trait::async_trait] impl ActivityHandler for Follow { - type DataType = IbisData; + type DataType = IbisContext; type Error = Error; fn id(&self) -> &Url { @@ -54,18 +58,18 @@ impl ActivityHandler for Follow { self.actor.inner() } - async fn verify(&self, _data: &Data) -> Result<(), Self::Error> { + async fn verify(&self, _context: &Data) -> Result<(), Self::Error> { Ok(()) } - async fn receive(self, data: &Data) -> Result<(), Self::Error> { - let actor = self.actor.dereference(data).await?; - let local_instance = DbInstance::read_local(data)?; + async fn receive(self, context: &Data) -> Result<(), Self::Error> { + let actor = self.actor.dereference(context).await?; + let local_instance = DbInstance::read_local(context)?; verify_urls_match(self.object.inner(), local_instance.ap_id.inner())?; - DbInstance::follow(&actor, &local_instance, false, data)?; + DbInstance::follow(&actor, &local_instance, false, context)?; // send back an accept - Accept::send(local_instance, self, data).await?; + Accept::send(local_instance, self, context).await?; Ok(()) } } diff --git a/src/backend/federation/activities/mod.rs b/src/backend/federation/activities/mod.rs index 9db93a4..fc4fa57 100644 --- a/src/backend/federation/activities/mod.rs +++ b/src/backend/federation/activities/mod.rs @@ -1,6 +1,6 @@ use crate::{ backend::{ - database::{edit::DbEditForm, IbisData}, + database::{edit::DbEditForm, IbisContext}, federation::activities::{ update_local_article::UpdateLocalArticle, update_remote_article::UpdateRemoteArticle, @@ -30,7 +30,7 @@ pub async fn submit_article_update( previous_version: EditVersion, original_article: &DbArticle, creator_id: PersonId, - data: &Data, + context: &Data, ) -> Result<(), Error> { let mut form = DbEditForm::new( original_article, @@ -41,16 +41,16 @@ pub async fn submit_article_update( false, )?; if original_article.local { - let edit = DbEdit::create(&form, data)?; - let updated_article = DbArticle::update_text(edit.article_id, &new_text, data)?; + let edit = DbEdit::create(&form, context)?; + let updated_article = DbArticle::update_text(edit.article_id, &new_text, context)?; - UpdateLocalArticle::send(updated_article, vec![], data).await?; + UpdateLocalArticle::send(updated_article, vec![], context).await?; } else { // insert edit as pending, so only the creator can see it form.pending = true; - let edit = DbEdit::create(&form, data)?; - let instance = DbInstance::read(original_article.instance_id, data)?; - UpdateRemoteArticle::send(edit, instance, data).await?; + let edit = DbEdit::create(&form, context)?; + let instance = DbInstance::read(original_article.instance_id, context)?; + UpdateRemoteArticle::send(edit, instance, context).await?; } Ok(()) } diff --git a/src/backend/federation/activities/reject.rs b/src/backend/federation/activities/reject.rs index 7c0d5fc..99cc767 100644 --- a/src/backend/federation/activities/reject.rs +++ b/src/backend/federation/activities/reject.rs @@ -2,7 +2,7 @@ use crate::{ backend::{ database::{ conflict::{DbConflict, DbConflictForm}, - IbisData, + IbisContext, }, federation::{objects::edit::ApubEdit, send_activity}, utils::{ @@ -38,10 +38,10 @@ impl RejectEdit { pub async fn send( edit: ApubEdit, user_instance: DbInstance, - data: &Data, + context: &Data, ) -> MyResult<()> { - let local_instance = DbInstance::read_local(data)?; - let id = generate_activity_id(data)?; + let local_instance = DbInstance::read_local(context)?; + let id = generate_activity_id(context)?; let reject = RejectEdit { actor: local_instance.ap_id.clone(), to: vec![user_instance.ap_id.into_inner()], @@ -53,7 +53,7 @@ impl RejectEdit { &local_instance, reject, vec![Url::parse(&user_instance.inbox_url)?], - data, + context, ) .await?; Ok(()) @@ -62,7 +62,7 @@ impl RejectEdit { #[async_trait::async_trait] impl ActivityHandler for RejectEdit { - type DataType = IbisData; + type DataType = IbisContext; type Error = Error; fn id(&self) -> &Url { @@ -73,14 +73,14 @@ impl ActivityHandler for RejectEdit { self.actor.inner() } - async fn verify(&self, _data: &Data) -> Result<(), Self::Error> { + async fn verify(&self, _context: &Data) -> Result<(), Self::Error> { Ok(()) } - async fn receive(self, data: &Data) -> Result<(), Self::Error> { + async fn receive(self, context: &Data) -> Result<(), Self::Error> { // cant convert this to DbEdit as it tries to apply patch and fails - let article = self.object.object.dereference(data).await?; - let creator = self.object.attributed_to.dereference(data).await?; + let article = self.object.object.dereference(context).await?; + let creator = self.object.attributed_to.dereference(context).await?; let form = DbConflictForm { hash: EditVersion::new(&self.object.content), diff: self.object.content, @@ -89,7 +89,7 @@ impl ActivityHandler for RejectEdit { article_id: article.id, previous_version_id: self.object.previous_version, }; - DbConflict::create(&form, data)?; + DbConflict::create(&form, context)?; Ok(()) } } diff --git a/src/backend/federation/activities/update_local_article.rs b/src/backend/federation/activities/update_local_article.rs index 69d9e6e..93fe240 100644 --- a/src/backend/federation/activities/update_local_article.rs +++ b/src/backend/federation/activities/update_local_article.rs @@ -1,6 +1,6 @@ use crate::{ backend::{ - database::IbisData, + database::IbisContext, federation::objects::article::ApubArticle, utils::{ error::{Error, MyResult}, @@ -36,22 +36,22 @@ impl UpdateLocalArticle { pub async fn send( article: DbArticle, extra_recipients: Vec, - data: &Data, + context: &Data, ) -> MyResult<()> { debug_assert!(article.local); - let local_instance = DbInstance::read_local(data)?; - let id = generate_activity_id(data)?; - let mut to = local_instance.follower_ids(data)?; + let local_instance = DbInstance::read_local(context)?; + let id = generate_activity_id(context)?; + let mut to = local_instance.follower_ids(context)?; to.extend(extra_recipients.iter().map(|i| i.ap_id.inner().clone())); let update = UpdateLocalArticle { actor: local_instance.ap_id.clone(), to, - object: article.into_json(data).await?, + object: article.into_json(context).await?, kind: Default::default(), id, }; local_instance - .send_to_followers(update, extra_recipients, data) + .send_to_followers(update, extra_recipients, context) .await?; Ok(()) } @@ -59,7 +59,7 @@ impl UpdateLocalArticle { #[async_trait::async_trait] impl ActivityHandler for UpdateLocalArticle { - type DataType = IbisData; + type DataType = IbisContext; type Error = Error; fn id(&self) -> &Url { @@ -70,13 +70,13 @@ impl ActivityHandler for UpdateLocalArticle { self.actor.inner() } - async fn verify(&self, _data: &Data) -> Result<(), Self::Error> { + async fn verify(&self, _context: &Data) -> Result<(), Self::Error> { Ok(()) } /// Received on article follower instances (where article is always remote) - async fn receive(self, data: &Data) -> Result<(), Self::Error> { - DbArticle::from_json(self.object, data).await?; + async fn receive(self, context: &Data) -> Result<(), Self::Error> { + DbArticle::from_json(self.object, context).await?; Ok(()) } diff --git a/src/backend/federation/activities/update_remote_article.rs b/src/backend/federation/activities/update_remote_article.rs index a089a86..f7fc01e 100644 --- a/src/backend/federation/activities/update_remote_article.rs +++ b/src/backend/federation/activities/update_remote_article.rs @@ -1,6 +1,6 @@ use crate::{ backend::{ - database::IbisData, + database::IbisContext, federation::{ activities::{reject::RejectEdit, update_local_article::UpdateLocalArticle}, objects::edit::ApubEdit, @@ -45,14 +45,14 @@ impl UpdateRemoteArticle { pub async fn send( edit: DbEdit, article_instance: DbInstance, - data: &Data, + context: &Data, ) -> MyResult<()> { - let local_instance = DbInstance::read_local(data)?; - let id = generate_activity_id(data)?; + let local_instance = DbInstance::read_local(context)?; + let id = generate_activity_id(context)?; let update = UpdateRemoteArticle { actor: local_instance.ap_id.clone(), to: vec![article_instance.ap_id.into_inner()], - object: edit.into_json(data).await?, + object: edit.into_json(context).await?, kind: Default::default(), id, }; @@ -60,7 +60,7 @@ impl UpdateRemoteArticle { &local_instance, update, vec![Url::parse(&article_instance.inbox_url)?], - data, + context, ) .await?; Ok(()) @@ -69,7 +69,7 @@ impl UpdateRemoteArticle { #[async_trait::async_trait] impl ActivityHandler for UpdateRemoteArticle { - type DataType = IbisData; + type DataType = IbisContext; type Error = Error; fn id(&self) -> &Url { @@ -80,27 +80,31 @@ impl ActivityHandler for UpdateRemoteArticle { self.actor.inner() } - async fn verify(&self, data: &Data) -> Result<(), Self::Error> { - let article = DbArticle::read_from_ap_id(&self.object.object, data)?; + async fn verify(&self, context: &Data) -> Result<(), Self::Error> { + let article = DbArticle::read_from_ap_id(&self.object.object, context)?; can_edit_article(&article, false)?; Ok(()) } /// Received on article origin instance - async fn receive(self, data: &Data) -> Result<(), Self::Error> { - let local_article = DbArticle::read_from_ap_id(&self.object.object, data)?; + async fn receive(self, context: &Data) -> Result<(), Self::Error> { + let local_article = DbArticle::read_from_ap_id(&self.object.object, context)?; let patch = Patch::from_str(&self.object.content)?; match apply(&local_article.text, &patch) { Ok(applied) => { - let edit = DbEdit::from_json(self.object.clone(), data).await?; - let article = DbArticle::update_text(edit.article_id, &applied, data)?; - UpdateLocalArticle::send(article, vec![self.actor.dereference(data).await?], data) - .await?; + let edit = DbEdit::from_json(self.object.clone(), context).await?; + let article = DbArticle::update_text(edit.article_id, &applied, context)?; + UpdateLocalArticle::send( + article, + vec![self.actor.dereference(context).await?], + context, + ) + .await?; } Err(_e) => { - let user_instance = self.actor.dereference(data).await?; - RejectEdit::send(self.object.clone(), user_instance, data).await?; + let user_instance = self.actor.dereference(context).await?; + RejectEdit::send(self.object.clone(), user_instance, context).await?; } } diff --git a/src/backend/federation/mod.rs b/src/backend/federation/mod.rs index d5c9a8a..318a11f 100644 --- a/src/backend/federation/mod.rs +++ b/src/backend/federation/mod.rs @@ -1,6 +1,6 @@ use super::utils::error::MyResult; use crate::{ - backend::{config::IbisConfig, database::IbisData}, + backend::{config::IbisConfig, database::IbisContext}, common::{instance::DbInstance, user::DbPerson}, }; use activities::announce::AnnounceActivity; @@ -25,14 +25,14 @@ pub async fn send_activity( actor: &ActorType, activity: Activity, recipients: Vec, - data: &Data, + context: &Data, ) -> Result<(), ::Error> where Activity: ActivityHandler + Serialize + Debug + Send + Sync, ::Error: From, { let activity = WithContext::new_default(activity); - queue_activity(&activity, actor, recipients, data).await?; + queue_activity(&activity, actor, recipients, context).await?; Ok(()) } @@ -40,13 +40,13 @@ pub async fn send_activity_to_instance( actor: &DbPerson, activity: AnnouncableActivities, instance: &DbInstance, - data: &Data, + context: &Data, ) -> MyResult<()> { if instance.local { - AnnounceActivity::send(activity, data).await?; + AnnounceActivity::send(activity, context).await?; } else { let inbox_url = instance.inbox_url.parse()?; - send_activity(actor, activity, vec![inbox_url], data).await?; + send_activity(actor, activity, vec![inbox_url], context).await?; } Ok(()) } diff --git a/src/backend/federation/objects/article.rs b/src/backend/federation/objects/article.rs index d742d00..85702f5 100644 --- a/src/backend/federation/objects/article.rs +++ b/src/backend/federation/objects/article.rs @@ -1,6 +1,6 @@ use crate::{ backend::{ - database::{article::DbArticleForm, IbisData}, + database::{article::DbArticleForm, IbisContext}, federation::objects::edits_collection::DbEditCollection, utils::{error::Error, validate::validate_article_title}, }, @@ -40,27 +40,27 @@ pub struct ApubArticle { #[async_trait::async_trait] impl Object for DbArticle { - type DataType = IbisData; + type DataType = IbisContext; type Kind = ApubArticle; type Error = Error; async fn read_from_id( object_id: Url, - data: &Data, + context: &Data, ) -> Result, Self::Error> { - let article = DbArticle::read_from_ap_id(&object_id.into(), data).ok(); + let article = DbArticle::read_from_ap_id(&object_id.into(), context).ok(); Ok(article) } - async fn into_json(self, data: &Data) -> Result { - let local_instance = DbInstance::read_local(data)?; + async fn into_json(self, context: &Data) -> Result { + let local_instance = DbInstance::read_local(context)?; Ok(ApubArticle { kind: Default::default(), id: self.ap_id.clone(), attributed_to: local_instance.ap_id.clone(), to: vec![public(), local_instance.followers_url()?], edits: self.edits_id()?, - latest_version: self.latest_edit_version(data)?, + latest_version: self.latest_edit_version(context)?, content: self.text, name: self.title, protected: self.protected, @@ -70,15 +70,18 @@ impl Object for DbArticle { async fn verify( json: &Self::Kind, expected_domain: &Url, - data: &Data, + context: &Data, ) -> Result<(), Self::Error> { verify_domains_match(json.id.inner(), expected_domain)?; - verify_is_remote_object(&json.id, data)?; + verify_is_remote_object(&json.id, context)?; Ok(()) } - async fn from_json(json: Self::Kind, data: &Data) -> Result { - let instance = json.attributed_to.dereference(data).await?; + async fn from_json( + json: Self::Kind, + context: &Data, + ) -> Result { + let instance = json.attributed_to.dereference(context).await?; let mut form = DbArticleForm { title: json.name, text: json.content, @@ -89,9 +92,9 @@ impl Object for DbArticle { approved: true, }; form.title = validate_article_title(&form.title)?; - let article = DbArticle::create_or_update(form, data)?; + let article = DbArticle::create_or_update(form, context)?; - json.edits.dereference(&article, data).await?; + json.edits.dereference(&article, context).await?; Ok(article) } diff --git a/src/backend/federation/objects/article_or_comment.rs b/src/backend/federation/objects/article_or_comment.rs index 874c568..0ff9365 100644 --- a/src/backend/federation/objects/article_or_comment.rs +++ b/src/backend/federation/objects/article_or_comment.rs @@ -1,7 +1,7 @@ use super::{article::ApubArticle, comment::ApubComment}; use crate::{ backend::{ - database::IbisData, + database::IbisContext, utils::error::{Error, MyResult}, }, common::{article::DbArticle, comment::DbComment}, @@ -26,7 +26,7 @@ pub enum ApubArticleOrComment { #[async_trait::async_trait] impl Object for DbArticleOrComment { - type DataType = IbisData; + type DataType = IbisContext; type Kind = ApubArticleOrComment; type Error = Error; @@ -34,38 +34,41 @@ impl Object for DbArticleOrComment { None } - async fn read_from_id(object_id: Url, data: &Data) -> MyResult> { - let post = DbArticle::read_from_id(object_id.clone(), data).await?; + async fn read_from_id( + object_id: Url, + context: &Data, + ) -> MyResult> { + let post = DbArticle::read_from_id(object_id.clone(), context).await?; Ok(match post { Some(o) => Some(Self::Article(o)), - None => DbComment::read_from_id(object_id, data) + None => DbComment::read_from_id(object_id, context) .await? .map(Self::Comment), }) } - async fn delete(self, data: &Data) -> MyResult<()> { + async fn delete(self, context: &Data) -> MyResult<()> { match self { - Self::Article(p) => p.delete(data).await, - Self::Comment(c) => c.delete(data).await, + Self::Article(p) => p.delete(context).await, + Self::Comment(c) => c.delete(context).await, } } - async fn into_json(self, data: &Data) -> MyResult { + async fn into_json(self, context: &Data) -> MyResult { Ok(match self { - Self::Article(p) => Self::Kind::Article(Box::new(p.into_json(data).await?)), - Self::Comment(c) => Self::Kind::Comment(Box::new(c.into_json(data).await?)), + Self::Article(p) => Self::Kind::Article(Box::new(p.into_json(context).await?)), + Self::Comment(c) => Self::Kind::Comment(Box::new(c.into_json(context).await?)), }) } async fn verify( apub: &Self::Kind, expected_domain: &Url, - data: &Data, + context: &Data, ) -> MyResult<()> { match apub { - Self::Kind::Article(a) => DbArticle::verify(a, expected_domain, data).await, - Self::Kind::Comment(a) => DbComment::verify(a, expected_domain, data).await, + Self::Kind::Article(a) => DbArticle::verify(a, expected_domain, context).await, + Self::Kind::Comment(a) => DbComment::verify(a, expected_domain, context).await, } } diff --git a/src/backend/federation/objects/articles_collection.rs b/src/backend/federation/objects/articles_collection.rs index 03b8ac6..e73eff0 100644 --- a/src/backend/federation/objects/articles_collection.rs +++ b/src/backend/federation/objects/articles_collection.rs @@ -1,6 +1,6 @@ use crate::{ backend::{ - database::IbisData, + database::IbisContext, federation::objects::article::ApubArticle, utils::error::{Error, MyResult}, }, @@ -40,25 +40,25 @@ pub fn local_articles_url(domain: &str) -> MyResult, + context: &Data, ) -> Result { - let local_articles = DbArticle::read_all(Some(true), None, data)?; + let local_articles = DbArticle::read_all(Some(true), None, context)?; let articles = try_join_all( local_articles .into_iter() - .map(|a| a.into_json(data)) + .map(|a| a.into_json(context)) .collect::>(), ) .await?; let collection = ArticleCollection { r#type: Default::default(), - id: local_articles_url(&data.config.federation.domain)?.into(), + id: local_articles_url(&context.config.federation.domain)?.into(), total_items: articles.len() as i32, items: articles, }; @@ -68,7 +68,7 @@ impl Collection for DbArticleCollection { async fn verify( json: &Self::Kind, expected_domain: &Url, - _data: &Data, + _context: &Data, ) -> Result<(), Self::Error> { verify_domains_match(&json.id, expected_domain)?; Ok(()) @@ -77,20 +77,20 @@ impl Collection for DbArticleCollection { async fn from_json( apub: Self::Kind, _owner: &Self::Owner, - data: &Data, + context: &Data, ) -> Result { - let articles = - apub.items - .into_iter() - .filter(|i| !i.id.is_local(data)) - .map(|article| async { - let id = article.id.clone(); - let res = DbArticle::from_json(article, data).await; - if let Err(e) = &res { - warn!("Failed to synchronize article {id}: {e}"); - } - res - }); + let articles = apub + .items + .into_iter() + .filter(|i| !i.id.is_local(context)) + .map(|article| async { + let id = article.id.clone(); + let res = DbArticle::from_json(article, context).await; + if let Err(e) = &res { + warn!("Failed to synchronize article {id}: {e}"); + } + res + }); join_all(articles).await; Ok(DbArticleCollection(())) diff --git a/src/backend/federation/objects/comment.rs b/src/backend/federation/objects/comment.rs index 5cbd287..c6e6b6f 100644 --- a/src/backend/federation/objects/comment.rs +++ b/src/backend/federation/objects/comment.rs @@ -1,7 +1,7 @@ use super::article_or_comment::DbArticleOrComment; use crate::{ backend::{ - database::{comment::DbCommentInsertForm, IbisData}, + database::{comment::DbCommentInsertForm, IbisContext}, utils::{error::Error, validate::validate_comment_max_depth}, }, common::{article::DbArticle, comment::DbComment, user::DbPerson}, @@ -37,24 +37,24 @@ pub struct ApubComment { #[async_trait::async_trait] impl Object for DbComment { - type DataType = IbisData; + type DataType = IbisContext; type Kind = ApubComment; type Error = Error; async fn read_from_id( object_id: Url, - data: &Data, + context: &Data, ) -> Result, Self::Error> { - Ok(DbComment::read_from_ap_id(&object_id.into(), data).ok()) + Ok(DbComment::read_from_ap_id(&object_id.into(), context).ok()) } - async fn into_json(self, data: &Data) -> Result { - let creator = DbPerson::read(self.creator_id, data)?; + async fn into_json(self, context: &Data) -> Result { + let creator = DbPerson::read(self.creator_id, context)?; let in_reply_to = if let Some(parent_comment_id) = self.parent_id { - let comment = DbComment::read(parent_comment_id, data)?; + let comment = DbComment::read(parent_comment_id, context)?; comment.ap_id.into_inner().into() } else { - let article = DbArticle::read(self.article_id, data)?; + let article = DbArticle::read(self.article_id, context)?; article.ap_id.into_inner().into() }; Ok(ApubComment { @@ -72,15 +72,18 @@ impl Object for DbComment { async fn verify( json: &Self::Kind, expected_domain: &Url, - data: &Data, + context: &Data, ) -> Result<(), Self::Error> { verify_domains_match(json.id.inner(), expected_domain)?; - verify_is_remote_object(&json.id, data)?; + verify_is_remote_object(&json.id, context)?; Ok(()) } - async fn from_json(json: Self::Kind, data: &Data) -> Result { - let parent = json.in_reply_to.dereference(data).await?; + async fn from_json( + json: Self::Kind, + context: &Data, + ) -> Result { + let parent = json.in_reply_to.dereference(context).await?; let (article_id, parent_id, depth) = match parent { DbArticleOrComment::Article(db_article) => (db_article.id, None, 0), DbArticleOrComment::Comment(db_comment) => ( @@ -89,7 +92,7 @@ impl Object for DbComment { db_comment.depth + 1, ), }; - let creator = json.attributed_to.dereference(data).await?; + let creator = json.attributed_to.dereference(context).await?; validate_comment_max_depth(depth)?; let form = DbCommentInsertForm { @@ -105,6 +108,6 @@ impl Object for DbComment { depth, }; - Ok(DbComment::create_or_update(form, data)?) + Ok(DbComment::create_or_update(form, context)?) } } diff --git a/src/backend/federation/objects/edit.rs b/src/backend/federation/objects/edit.rs index e16aead..ae3522f 100644 --- a/src/backend/federation/objects/edit.rs +++ b/src/backend/federation/objects/edit.rs @@ -1,6 +1,6 @@ use crate::{ backend::{ - database::{edit::DbEditForm, IbisData}, + database::{edit::DbEditForm, IbisContext}, utils::error::Error, }, common::{ @@ -43,20 +43,20 @@ pub struct ApubEdit { #[async_trait::async_trait] impl Object for DbEdit { - type DataType = IbisData; + type DataType = IbisContext; type Kind = ApubEdit; type Error = Error; async fn read_from_id( object_id: Url, - data: &Data, + context: &Data, ) -> Result, Self::Error> { - Ok(DbEdit::read_from_ap_id(&object_id.into(), data).ok()) + Ok(DbEdit::read_from_ap_id(&object_id.into(), context).ok()) } - async fn into_json(self, data: &Data) -> Result { - let article = DbArticle::read_view(self.article_id, data)?; - let creator = DbPerson::read(self.creator_id, data)?; + async fn into_json(self, context: &Data) -> Result { + let article = DbArticle::read_view(self.article_id, context)?; + let creator = DbPerson::read(self.creator_id, context)?; Ok(ApubEdit { kind: PatchType::Patch, id: self.ap_id, @@ -73,21 +73,24 @@ impl Object for DbEdit { async fn verify( json: &Self::Kind, expected_domain: &Url, - data: &Data, + context: &Data, ) -> Result<(), Self::Error> { verify_domains_match(json.id.inner(), expected_domain)?; - verify_is_remote_object(&json.id, data)?; + verify_is_remote_object(&json.id, context)?; Ok(()) } - async fn from_json(json: Self::Kind, data: &Data) -> Result { - let article = json.object.dereference(data).await?; - let creator = match json.attributed_to.dereference(data).await { + async fn from_json( + json: Self::Kind, + context: &Data, + ) -> Result { + let article = json.object.dereference(context).await?; + let creator = match json.attributed_to.dereference(context).await { Ok(c) => c, Err(e) => { // If actor couldnt be fetched, use ghost as placeholder warn!("Failed to fetch user {}: {e}", json.attributed_to); - DbPerson::ghost(data)? + DbPerson::ghost(context)? } }; let form = DbEditForm { @@ -101,7 +104,7 @@ impl Object for DbEdit { published: json.published, pending: false, }; - let edit = DbEdit::create(&form, data)?; + let edit = DbEdit::create(&form, context)?; Ok(edit) } } diff --git a/src/backend/federation/objects/edits_collection.rs b/src/backend/federation/objects/edits_collection.rs index 69ae89f..f712de1 100644 --- a/src/backend/federation/objects/edits_collection.rs +++ b/src/backend/federation/objects/edits_collection.rs @@ -1,5 +1,5 @@ use crate::{ - backend::{database::IbisData, federation::objects::edit::ApubEdit, utils::error::Error}, + backend::{database::IbisContext, federation::objects::edit::ApubEdit, utils::error::Error}, common::article::{DbArticle, DbEdit}, }; use activitypub_federation::{ @@ -28,20 +28,20 @@ pub struct DbEditCollection(); #[async_trait::async_trait] impl Collection for DbEditCollection { type Owner = DbArticle; - type DataType = IbisData; + type DataType = IbisContext; type Kind = ApubEditCollection; type Error = Error; async fn read_local( article: &Self::Owner, - data: &Data, + context: &Data, ) -> Result { - let article = DbArticle::read(article.id, data)?; - let edits = DbEdit::list_for_article(article.id, data)?; + let article = DbArticle::read(article.id, context)?; + let edits = DbEdit::list_for_article(article.id, context)?; let edits = future::try_join_all( edits .into_iter() - .map(|e| e.into_json(data)) + .map(|e| e.into_json(context)) .collect::>(), ) .await?; @@ -57,7 +57,7 @@ impl Collection for DbEditCollection { async fn verify( json: &Self::Kind, expected_domain: &Url, - _data: &Data, + _context: &Data, ) -> Result<(), Self::Error> { verify_domains_match(&json.id, expected_domain)?; Ok(()) @@ -66,12 +66,16 @@ impl Collection for DbEditCollection { async fn from_json( apub: Self::Kind, owner: &Self::Owner, - data: &Data, + context: &Data, ) -> Result { - try_join_all(apub.items.into_iter().map(|i| DbEdit::from_json(i, data))) - .await - .map_err(|e| warn!("Failed to synchronize edits for {}: {e}", owner.ap_id)) - .ok(); + try_join_all( + apub.items + .into_iter() + .map(|i| DbEdit::from_json(i, context)), + ) + .await + .map_err(|e| warn!("Failed to synchronize edits for {}: {e}", owner.ap_id)) + .ok(); Ok(DbEditCollection()) } } diff --git a/src/backend/federation/objects/instance.rs b/src/backend/federation/objects/instance.rs index 7353662..9906714 100644 --- a/src/backend/federation/objects/instance.rs +++ b/src/backend/federation/objects/instance.rs @@ -1,7 +1,7 @@ use super::instance_collection::DbInstanceCollection; use crate::{ backend::{ - database::{instance::DbInstanceForm, IbisData}, + database::{instance::DbInstanceForm, IbisContext}, federation::{objects::articles_collection::DbArticleCollection, send_activity}, utils::error::{Error, MyResult}, }, @@ -40,8 +40,8 @@ impl DbInstance { Ok(Url::parse(&format!("{}/followers", self.ap_id.inner()))?) } - pub fn follower_ids(&self, data: &Data) -> MyResult> { - Ok(DbInstance::read_followers(self.id, data)? + pub fn follower_ids(&self, context: &Data) -> MyResult> { + Ok(DbInstance::read_followers(self.id, context)? .into_iter() .map(|f| f.ap_id.into()) .collect()) @@ -51,26 +51,26 @@ impl DbInstance { &self, activity: Activity, extra_recipients: Vec, - data: &Data, + context: &Data, ) -> Result<(), ::Error> where Activity: ActivityHandler + Serialize + Debug + Send + Sync, ::Error: From, ::Error: From, { - let mut inboxes: Vec<_> = DbInstance::read_followers(self.id, data)? + let mut inboxes: Vec<_> = DbInstance::read_followers(self.id, context)? .iter() .map(|f| f.inbox_url()) .collect(); inboxes.extend(extra_recipients.into_iter().map(|i| i.inbox_url())); - send_activity(self, activity, inboxes, data).await?; + send_activity(self, activity, inboxes, context).await?; Ok(()) } } #[async_trait::async_trait] impl Object for DbInstance { - type DataType = IbisData; + type DataType = IbisContext; type Kind = ApubInstance; type Error = Error; @@ -80,12 +80,12 @@ impl Object for DbInstance { async fn read_from_id( object_id: Url, - data: &Data, + context: &Data, ) -> Result, Self::Error> { - Ok(DbInstance::read_from_ap_id(&object_id.into(), data).ok()) + Ok(DbInstance::read_from_ap_id(&object_id.into(), context).ok()) } - async fn into_json(self, _data: &Data) -> Result { + async fn into_json(self, _context: &Data) -> Result { Ok(ApubInstance { kind: Default::default(), id: self.ap_id.clone(), @@ -100,14 +100,17 @@ impl Object for DbInstance { async fn verify( json: &Self::Kind, expected_domain: &Url, - data: &Data, + context: &Data, ) -> Result<(), Self::Error> { verify_domains_match(json.id.inner(), expected_domain)?; - verify_is_remote_object(&json.id, data)?; + verify_is_remote_object(&json.id, context)?; Ok(()) } - async fn from_json(json: Self::Kind, data: &Data) -> Result { + async fn from_json( + json: Self::Kind, + context: &Data, + ) -> Result { let domain = extract_domain(&json.id); let form = DbInstanceForm { domain, @@ -121,20 +124,20 @@ impl Object for DbInstance { last_refreshed_at: Utc::now(), local: false, }; - let instance = DbInstance::create(&form, data)?; + let instance = DbInstance::create(&form, context)?; // TODO: very inefficient to sync all articles every time let instance_ = instance.clone(); - let data_ = data.reset_request_count(); + let context_ = context.reset_request_count(); tokio::spawn(async move { if let Some(articles_url) = &instance_.articles_url { - let res = articles_url.dereference(&(), &data_).await; + let res = articles_url.dereference(&(), &context_).await; if let Err(e) = res { tracing::warn!("error in spawn: {e}"); } } if let Some(instances_url) = &instance_.instances_url { - let res = instances_url.dereference(&(), &data_).await; + let res = instances_url.dereference(&(), &context_).await; if let Err(e) = res { tracing::warn!("error in spawn: {e}"); } diff --git a/src/backend/federation/objects/instance_collection.rs b/src/backend/federation/objects/instance_collection.rs index 27e19d9..270eaa6 100644 --- a/src/backend/federation/objects/instance_collection.rs +++ b/src/backend/federation/objects/instance_collection.rs @@ -1,7 +1,7 @@ use super::instance::ApubInstance; use crate::{ backend::{ - database::IbisData, + database::IbisContext, utils::error::{Error, MyResult}, }, common::{instance::DbInstance, utils::http_protocol_str}, @@ -40,25 +40,25 @@ pub fn linked_instances_url(domain: &str) -> MyResult, + context: &Data, ) -> Result { - let instances = DbInstance::read_remote(data)?; + let instances = DbInstance::read_remote(context)?; let instances = future::try_join_all( instances .into_iter() - .map(|i| i.into_json(data)) + .map(|i| i.into_json(context)) .collect::>(), ) .await?; let collection = InstanceCollection { r#type: Default::default(), - id: linked_instances_url(&data.config.federation.domain)?.into(), + id: linked_instances_url(&context.config.federation.domain)?.into(), total_items: instances.len() as i32, items: instances, }; @@ -68,7 +68,7 @@ impl Collection for DbInstanceCollection { async fn verify( json: &Self::Kind, expected_domain: &Url, - _data: &Data, + _context: &Data, ) -> Result<(), Self::Error> { verify_domains_match(&json.id, expected_domain)?; Ok(()) @@ -77,20 +77,20 @@ impl Collection for DbInstanceCollection { async fn from_json( apub: Self::Kind, _owner: &Self::Owner, - data: &Data, + context: &Data, ) -> Result { - let instances = - apub.items - .into_iter() - .filter(|i| !i.id.is_local(data)) - .map(|instance| async { - let id = instance.id.clone(); - let res = DbInstance::from_json(instance, data).await; - if let Err(e) = &res { - warn!("Failed to synchronize article {id}: {e}"); - } - res - }); + let instances = apub + .items + .into_iter() + .filter(|i| !i.id.is_local(context)) + .map(|instance| async { + let id = instance.id.clone(); + let res = DbInstance::from_json(instance, context).await; + if let Err(e) = &res { + warn!("Failed to synchronize article {id}: {e}"); + } + res + }); join_all(instances).await; Ok(DbInstanceCollection(())) diff --git a/src/backend/federation/objects/user.rs b/src/backend/federation/objects/user.rs index af374be..cea0858 100644 --- a/src/backend/federation/objects/user.rs +++ b/src/backend/federation/objects/user.rs @@ -1,6 +1,6 @@ use crate::{ backend::{ - database::{user::DbPersonForm, IbisData}, + database::{user::DbPersonForm, IbisContext}, utils::error::Error, }, common::user::DbPerson, @@ -33,7 +33,7 @@ pub struct ApubUser { #[async_trait::async_trait] impl Object for DbPerson { - type DataType = IbisData; + type DataType = IbisContext; type Kind = ApubUser; type Error = Error; @@ -43,12 +43,12 @@ impl Object for DbPerson { async fn read_from_id( object_id: Url, - data: &Data, + context: &Data, ) -> Result, Self::Error> { - Ok(DbPerson::read_from_ap_id(&object_id.into(), data).ok()) + Ok(DbPerson::read_from_ap_id(&object_id.into(), context).ok()) } - async fn into_json(self, _data: &Data) -> Result { + async fn into_json(self, _context: &Data) -> Result { Ok(ApubUser { kind: Default::default(), id: __self.ap_id.clone(), @@ -63,13 +63,16 @@ impl Object for DbPerson { async fn verify( json: &Self::Kind, expected_domain: &Url, - _data: &Data, + _context: &Data, ) -> Result<(), Self::Error> { verify_domains_match(json.id.inner(), expected_domain)?; Ok(()) } - async fn from_json(json: Self::Kind, data: &Data) -> Result { + async fn from_json( + json: Self::Kind, + context: &Data, + ) -> Result { let form = DbPersonForm { username: json.preferred_username, ap_id: json.id, @@ -81,7 +84,7 @@ impl Object for DbPerson { display_name: json.name, bio: json.summary, }; - DbPerson::create(&form, data) + DbPerson::create(&form, context) } } diff --git a/src/backend/federation/routes.rs b/src/backend/federation/routes.rs index 429cd22..43f6b54 100644 --- a/src/backend/federation/routes.rs +++ b/src/backend/federation/routes.rs @@ -11,7 +11,7 @@ use super::{ }; use crate::{ backend::{ - database::IbisData, + database::IbisContext, federation::{ activities::{ accept::Accept, @@ -74,66 +74,66 @@ pub fn federation_routes() -> Router<()> { #[debug_handler] async fn http_get_instance( - data: Data, + context: Data, ) -> MyResult>> { - let local_instance = DbInstance::read_local(&data)?; - let json_instance = local_instance.into_json(&data).await?; + let local_instance = DbInstance::read_local(&context)?; + let json_instance = local_instance.into_json(&context).await?; Ok(FederationJson(WithContext::new_default(json_instance))) } #[debug_handler] async fn http_get_person( Path(name): Path, - data: Data, + context: Data, ) -> MyResult>> { - let person = DbPerson::read_local_from_name(&name, &data)?.person; - let json_person = person.into_json(&data).await?; + let person = DbPerson::read_local_from_name(&name, &context)?.person; + let json_person = person.into_json(&context).await?; Ok(FederationJson(WithContext::new_default(json_person))) } #[debug_handler] async fn http_get_all_articles( - data: Data, + context: Data, ) -> MyResult>> { - let collection = DbArticleCollection::read_local(&(), &data).await?; + let collection = DbArticleCollection::read_local(&(), &context).await?; Ok(FederationJson(WithContext::new_default(collection))) } #[debug_handler] async fn http_get_linked_instances( - data: Data, + context: Data, ) -> MyResult>> { - let collection = DbInstanceCollection::read_local(&(), &data).await?; + let collection = DbInstanceCollection::read_local(&(), &context).await?; Ok(FederationJson(WithContext::new_default(collection))) } #[debug_handler] async fn http_get_article( Path(title): Path, - data: Data, + context: Data, ) -> MyResult>> { - let article = DbArticle::read_view_title(&title, None, &data)?; - let json = article.article.into_json(&data).await?; + let article = DbArticle::read_view_title(&title, None, &context)?; + let json = article.article.into_json(&context).await?; Ok(FederationJson(WithContext::new_default(json))) } #[debug_handler] async fn http_get_article_edits( Path(title): Path, - data: Data, + context: Data, ) -> MyResult>> { - let article = DbArticle::read_view_title(&title, None, &data)?; - let json = DbEditCollection::read_local(&article.article, &data).await?; + let article = DbArticle::read_view_title(&title, None, &context)?; + let json = DbEditCollection::read_local(&article.article, &context).await?; Ok(FederationJson(WithContext::new_default(json))) } #[debug_handler] async fn http_get_comment( Path(id): Path, - data: Data, + context: Data, ) -> MyResult>> { - let comment = DbComment::read(CommentId(id), &data)?; - let json = comment.into_json(&data).await?; + let comment = DbComment::read(CommentId(id), &context)?; + let json = comment.into_json(&context).await?; Ok(FederationJson(WithContext::new_default(json))) } @@ -163,10 +163,10 @@ pub enum AnnouncableActivities { #[debug_handler] pub async fn http_post_inbox( - data: Data, + context: Data, activity_data: ActivityData, ) -> impl IntoResponse { - receive_activity::, UserOrInstance, IbisData>(activity_data, &data) + receive_activity::, UserOrInstance, _>(activity_data, &context) .await } @@ -191,7 +191,7 @@ pub enum PersonOrInstanceType { #[async_trait::async_trait] impl Object for UserOrInstance { - type DataType = IbisData; + type DataType = IbisContext; type Kind = PersonOrInstance; type Error = Error; diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 70cdb28..79b6996 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -1,7 +1,7 @@ use crate::{ backend::{ config::IbisConfig, - database::{article::DbArticleForm, instance::DbInstanceForm, IbisData}, + database::{article::DbArticleForm, instance::DbInstanceForm, IbisContext}, federation::{activities::submit_article_update, VerifyUrlData}, utils::{ error::{Error, MyResult}, @@ -59,11 +59,11 @@ pub async fn start( .get()? .run_pending_migrations(MIGRATIONS) .expect("run migrations"); - let ibis_data = IbisData { db_pool, config }; + let context = IbisContext { db_pool, config }; let data = FederationConfig::builder() - .domain(ibis_data.config.federation.domain.clone()) - .url_verifier(Box::new(VerifyUrlData(ibis_data.config.clone()))) - .app_data(ibis_data) + .domain(context.config.federation.domain.clone()) + .url_verifier(Box::new(VerifyUrlData(context.config.clone()))) + .app_data(context) .http_fetch_limit(1000) .debug(cfg!(debug_assertions)) .build() @@ -89,8 +89,8 @@ const MAIN_PAGE_DEFAULT_TEXT: &str = "Welcome to Ibis, the federated Wikipedia a This main page can only be edited by the admin. Use it as an introduction for new users, \ and to list interesting articles."; -async fn setup(data: &Data) -> Result<(), Error> { - let domain = &data.config.federation.domain; +async fn setup(context: &Data) -> Result<(), Error> { + let domain = &context.config.federation.domain; let ap_id = ObjectId::parse(&format!("{}://{domain}", http_protocol_str()))?; let inbox_url = format!("{}://{domain}/inbox", http_protocol_str()); let keypair = generate_keypair()?; @@ -106,13 +106,13 @@ async fn setup(data: &Data) -> Result<(), Error> { last_refreshed_at: Utc::now(), local: true, }; - let instance = DbInstance::create(&form, data)?; + let instance = DbInstance::create(&form, context)?; let person = DbPerson::create_local( - data.config.setup.admin_username.clone(), - data.config.setup.admin_password.clone(), + context.config.setup.admin_username.clone(), + context.config.setup.admin_password.clone(), true, - data, + context, )?; // Create the main page which is shown by default @@ -128,7 +128,7 @@ async fn setup(data: &Data) -> Result<(), Error> { protected: true, approved: true, }; - let article = DbArticle::create(form, data)?; + let article = DbArticle::create(form, context)?; // also create an article so its included in most recently edited list submit_article_update( MAIN_PAGE_DEFAULT_TEXT.to_string(), @@ -136,12 +136,12 @@ async fn setup(data: &Data) -> Result<(), Error> { EditVersion::default(), &article, person.person.id, - data, + context, ) .await?; // create ghost user - DbPerson::ghost(data)?; + DbPerson::ghost(context)?; Ok(()) } diff --git a/src/backend/server/middleware.rs b/src/backend/server/middleware.rs index dff0605..751607f 100644 --- a/src/backend/server/middleware.rs +++ b/src/backend/server/middleware.rs @@ -1,5 +1,5 @@ use crate::{ - backend::{api::user::validate, database::IbisData}, + backend::{api::user::validate, database::IbisContext}, common::{Auth, AUTH_COOKIE}, }; use axum::{body::Body, extract::State, http::Request, middleware::Next, response::Response}; @@ -14,7 +14,7 @@ pub(super) const FEDERATION_ROUTES_PREFIX: &str = "/federation_routes"; /// If user is authenticated sets extensions `Auth` and `LocalUserView`. #[debug_middleware] pub(super) async fn auth_middleware( - State(data): State>, + State(context): State>, mut request: Request, next: Next, ) -> Response { @@ -34,7 +34,7 @@ pub(super) async fn auth_middleware( let auth: HashSet<_> = headers.chain(cookies).map(|s| s.to_string()).collect(); for auth in auth { - if let Ok(local_user) = validate(&auth, &data).await { + if let Ok(local_user) = validate(&auth, &context).await { request.extensions_mut().insert(Auth(Some(auth))); request.extensions_mut().insert(local_user); } diff --git a/src/backend/server/mod.rs b/src/backend/server/mod.rs index d448c5b..7d43976 100644 --- a/src/backend/server/mod.rs +++ b/src/backend/server/mod.rs @@ -1,4 +1,4 @@ -use super::{database::IbisData, utils::error::MyResult}; +use super::{database::IbisContext, utils::error::MyResult}; use crate::{ backend::{api::api_routes, federation::routes::federation_routes}, common::Auth, @@ -31,7 +31,7 @@ mod middleware; mod nodeinfo; pub(super) async fn start_server( - data: FederationConfig, + context: FederationConfig, override_hostname: Option, notify_start: Option>, ) -> MyResult<()> { @@ -42,7 +42,7 @@ pub(super) async fn start_server( } let routes = generate_route_list(App); - let arc_data = Arc::new(data.deref().clone()); + let arc_data = Arc::new(context.deref().clone()); let app = Router::new() .leptos_routes_with_handler(routes, get(leptos_routes_handler)) .fallback(file_and_error_handler) @@ -50,7 +50,7 @@ pub(super) async fn start_server( .nest(FEDERATION_ROUTES_PREFIX, federation_routes()) .nest("/api/v1", api_routes()) .nest("", nodeinfo::config()) - .layer(FederationMiddleware::new(data)) + .layer(FederationMiddleware::new(context)) .layer(CorsLayer::permissive()) .layer(CompressionLayer::new()) .route_layer(from_fn_with_state(arc_data, auth_middleware)); diff --git a/src/backend/server/nodeinfo.rs b/src/backend/server/nodeinfo.rs index 4a5ed0b..d2a323f 100644 --- a/src/backend/server/nodeinfo.rs +++ b/src/backend/server/nodeinfo.rs @@ -1,6 +1,6 @@ use crate::{ backend::{ - database::{instance_stats::InstanceStats, IbisData}, + database::{instance_stats::InstanceStats, IbisContext}, utils::error::MyResult, }, common::utils::http_protocol_str, @@ -16,21 +16,21 @@ pub fn config() -> Router<()> { .route("/.well-known/nodeinfo", get(node_info_well_known)) } -async fn node_info_well_known(data: Data) -> MyResult> { +async fn node_info_well_known(context: Data) -> MyResult> { Ok(Json(NodeInfoWellKnown { links: vec![NodeInfoWellKnownLinks { rel: Url::parse("http://nodeinfo.diaspora.software/ns/schema/2.1")?, href: Url::parse(&format!( "{}://{}/nodeinfo/2.1.json", http_protocol_str(), - data.domain() + context.domain() ))?, }], })) } -async fn node_info(data: Data) -> MyResult> { - let stats = InstanceStats::read(&data)?; +async fn node_info(context: Data) -> MyResult> { + let stats = InstanceStats::read(&context)?; Ok(Json(NodeInfo { version: "2.1".to_string(), software: NodeInfoSoftware { @@ -49,7 +49,7 @@ async fn node_info(data: Data) -> MyResult> { local_posts: stats.articles, local_comments: stats.comments, }, - open_registrations: data.config.options.registration_open, + open_registrations: context.config.options.registration_open, services: Default::default(), metadata: vec![], })) diff --git a/src/backend/utils/mod.rs b/src/backend/utils/mod.rs index d7c5bc6..5722606 100644 --- a/src/backend/utils/mod.rs +++ b/src/backend/utils/mod.rs @@ -1,5 +1,5 @@ use crate::{ - backend::{database::IbisData, utils::error::MyResult}, + backend::{database::IbisContext, utils::error::MyResult}, common::{ article::{DbEdit, EditVersion}, utils, @@ -19,8 +19,8 @@ pub mod error; pub(super) mod scheduled_tasks; pub(super) mod validate; -pub(super) fn generate_activity_id(data: &Data) -> Result { - let domain = &data.config.federation.domain; +pub(super) fn generate_activity_id(context: &Data) -> Result { + let domain = &context.config.federation.domain; let id: String = thread_rng() .sample_iter(&Alphanumeric) .take(7)