diff --git a/profiles/src/apub/actions/apub/note.rs b/profiles/src/apub/actions/apub/note.rs index a5df527..0543593 100644 --- a/profiles/src/apub/actions/apub/note.rs +++ b/profiles/src/apub/actions/apub/note.rs @@ -1,7 +1,10 @@ use crate::{ - apub::actions::{ - apub::require_federation, CreateComment, CreateSubmission, DeleteComment, DeleteSubmission, - Noop, UpdateComment, UpdateSubmission, + apub::{ + actions::{ + apub::require_federation, CreateComment, CreateSubmission, DeleteComment, + DeleteSubmission, Noop, UpdateComment, UpdateSubmission, + }, + ExtendedNote, }, recover, store::Visibility, @@ -9,7 +12,7 @@ use crate::{ }; use activitystreams::{object::Image, prelude::*, public}; -fn find_visibility(note: &activitystreams::object::Note) -> Visibility { +fn find_visibility(note: &ExtendedNote) -> Visibility { if note .to() .and_then(|one_or_many| { @@ -38,7 +41,7 @@ fn find_visibility(note: &activitystreams::object::Note) -> Visibility { } pub(super) fn note( - note: &activitystreams::object::Note, + note: &ExtendedNote, key_owner: Option, ctx: &Context, ) -> Result, RecoverableError>, Error> { @@ -167,7 +170,6 @@ pub(super) fn note( return Ok(Err(RecoverableError::MissingImages(missing_files))); } - log::warn!("logged_in_only not implmented"); return Ok(Ok(Box::new(CreateSubmission { note_apub_id: Some(note_id.to_owned()), profile_id, @@ -177,13 +179,14 @@ pub(super) fn note( files: existing_files, visibility: find_visibility(note), local_only: false, - logged_in_only: false, + logged_in_only: true, + sensitive: note.ext_one.sensitive, }))); } pub(super) fn create_note( create: &activitystreams::activity::Create, - note_obj: &activitystreams::object::Note, + note_obj: &ExtendedNote, key_owner: Option, ctx: &Context, ) -> Result, RecoverableError>, Error> { @@ -206,7 +209,7 @@ pub(super) fn create_note( pub(super) fn announce_note( announce: &activitystreams::activity::Announce, - note: &activitystreams::object::Note, + note: &ExtendedNote, key_owner: Option, ctx: &Context, ) -> Result, RecoverableError>, Error> { @@ -237,7 +240,7 @@ pub(super) fn announce_note( pub(super) fn announce_update_note( announce: &activitystreams::activity::Announce, update: &activitystreams::activity::Update, - _: &activitystreams::object::Note, + _: &ExtendedNote, key_owner: Option, ctx: &Context, ) -> Result, RecoverableError>, Error> { @@ -268,7 +271,7 @@ pub(super) fn announce_update_note( pub(super) fn announce_delete_note( announce: &activitystreams::activity::Announce, delete: &activitystreams::activity::Delete, - _: &activitystreams::object::Note, + _: &ExtendedNote, key_owner: Option, ctx: &Context, ) -> Result, RecoverableError>, Error> { @@ -298,7 +301,7 @@ pub(super) fn announce_delete_note( pub(super) fn update_note( update: &activitystreams::activity::Update, - note: &activitystreams::object::Note, + note: &ExtendedNote, key_owner: Option, ctx: &Context, ) -> Result, RecoverableError>, Error> { @@ -412,7 +415,6 @@ pub(super) fn update_note( return Ok(Err(RecoverableError::MissingImages(missing_files))); } - log::warn!("logged_in_only not implmented"); Ok(Ok(Box::new(UpdateSubmission { submission_id, title, @@ -426,13 +428,14 @@ pub(super) fn update_note( new_files: None, only_files: Some(existing_files), local_only: Some(false), - logged_in_only: Some(false), + logged_in_only: Some(true), + sensitive: Some(note.ext_one.sensitive), }))) } pub(super) fn delete_note( delete: &activitystreams::activity::Delete, - note: &activitystreams::object::Note, + note: &ExtendedNote, key_owner: Option, ctx: &Context, ) -> Result, RecoverableError>, Error> { diff --git a/profiles/src/apub/actions/mod.rs b/profiles/src/apub/actions/mod.rs index 5b3e891..23e6138 100644 --- a/profiles/src/apub/actions/mod.rs +++ b/profiles/src/apub/actions/mod.rs @@ -271,6 +271,7 @@ pub struct CreateSubmission { visibility: Visibility, local_only: bool, logged_in_only: bool, + sensitive: bool, } impl CreateSubmission { @@ -285,6 +286,7 @@ impl CreateSubmission { visibility: Visibility::Public, local_only: false, logged_in_only: false, + sensitive: false, } } } @@ -303,6 +305,7 @@ pub struct UpdateSubmission { removed_files: Option>, new_files: Option>, only_files: Option>, + sensitive: Option, } impl UpdateSubmission { @@ -335,6 +338,7 @@ impl UpdateSubmission { removed_files: None, new_files: None, only_files: None, + sensitive: None, } } @@ -358,6 +362,7 @@ impl UpdateSubmission { removed_files: None, new_files: None, only_files: None, + sensitive: None, } } @@ -376,6 +381,7 @@ impl UpdateSubmission { removed_files: None, new_files: Some(vec![file_id]), only_files: None, + sensitive: None, } } @@ -394,6 +400,26 @@ impl UpdateSubmission { removed_files: Some(vec![file_id]), new_files: None, only_files: None, + sensitive: None, + } + } + + pub fn from_sensitive(submission_id: Uuid, sensitive: bool) -> Self { + UpdateSubmission { + submission_id, + title: None, + title_source: None, + description: None, + description_source: None, + visibility: None, + local_only: None, + logged_in_only: None, + published: None, + updated: None, + removed_files: None, + new_files: None, + only_files: None, + sensitive: Some(sensitive), } } @@ -412,6 +438,7 @@ impl UpdateSubmission { removed_files: None, new_files: None, only_files: None, + sensitive: None, } } } diff --git a/profiles/src/apub/actions/submission.rs b/profiles/src/apub/actions/submission.rs index c8c2b60..2c006ac 100644 --- a/profiles/src/apub/actions/submission.rs +++ b/profiles/src/apub/actions/submission.rs @@ -18,7 +18,8 @@ impl Action for CreateSubmission { let mut changes = submission.update(); changes .local_only(self.local_only) - .logged_in_only(self.logged_in_only); + .logged_in_only(self.logged_in_only) + .sensitive(self.sensitive); if self.published.is_some() { changes.published(self.published); @@ -127,6 +128,9 @@ impl Action for UpdateSubmission { if let Some(logged_in_only) = self.logged_in_only { changes.logged_in_only(logged_in_only); } + if let Some(sensitive) = self.sensitive { + changes.sensitive(sensitive); + } let submission = if changes.any_changes() { ctx.store.submissions.update(&changes)? } else { diff --git a/profiles/src/apub/extensions.rs b/profiles/src/apub/extensions.rs new file mode 100644 index 0000000..f3ff0c5 --- /dev/null +++ b/profiles/src/apub/extensions.rs @@ -0,0 +1,113 @@ +use activitystreams::{ + actor::{ApActor, Application, Person}, + object::{ApObject, Note}, + unparsed::UnparsedMutExt, + url::Url, +}; +use activitystreams_ext::{Ext1, Ext2, Ext3, UnparsedExtension}; + +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] +#[serde(rename_all = "camelCase")] +pub struct Sensitive { + #[serde(default)] + pub(crate) sensitive: bool, +} + +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] +#[serde(rename_all = "camelCase")] +pub struct ManuallyApprovesFollowers { + #[serde(default)] + pub(crate) manually_approves_followers: bool, +} + +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] +#[serde(rename_all = "camelCase")] +pub struct PropertyValue { + #[serde(rename = "type")] + pub(crate) kind: String, + pub(crate) name: String, + pub(crate) value: String, +} + +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] +#[serde(rename_all = "camelCase")] +pub struct PublicKey { + pub(crate) public_key: PublicKeyInner, +} + +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] +#[serde(rename_all = "camelCase")] +pub struct PublicKeyInner { + pub(crate) id: Url, + pub(crate) owner: Url, + pub(crate) public_key_pem: String, +} + +impl UnparsedExtension for ManuallyApprovesFollowers +where + U: UnparsedMutExt, +{ + type Error = serde_json::Error; + + fn try_from_unparsed(unparsed_mut: &mut U) -> Result + where + Self: Sized, + { + Ok(ManuallyApprovesFollowers { + manually_approves_followers: unparsed_mut + .remove("manuallyApprovesFollowers") + .unwrap_or(false), + }) + } + + fn try_into_unparsed(self, unparsed_mut: &mut U) -> Result<(), Self::Error> { + unparsed_mut.insert( + "manuallyApprovesFollowers", + self.manually_approves_followers, + )?; + Ok(()) + } +} + +impl UnparsedExtension for Sensitive +where + U: UnparsedMutExt, +{ + type Error = serde_json::Error; + + fn try_from_unparsed(unparsed_mut: &mut U) -> Result + where + Self: Sized, + { + Ok(Sensitive { + sensitive: unparsed_mut.remove("sensitive").unwrap_or(false), + }) + } + + fn try_into_unparsed(self, unparsed_mut: &mut U) -> Result<(), Self::Error> { + unparsed_mut.insert("sensitive", self.sensitive)?; + Ok(()) + } +} + +impl UnparsedExtension for PublicKey +where + U: UnparsedMutExt, +{ + type Error = serde_json::Error; + + fn try_from_unparsed(unparsed_mut: &mut U) -> Result { + Ok(PublicKey { + public_key: unparsed_mut.remove("publicKey")?, + }) + } + + fn try_into_unparsed(self, unparsed_mut: &mut U) -> Result<(), Self::Error> { + unparsed_mut.insert("publicKey", self.public_key)?; + Ok(()) + } +} + +pub type ExtendedNote = Ext1, Sensitive>; +pub type ExtendedPerson = Ext3, PublicKey, ManuallyApprovesFollowers, Sensitive>; +pub type ExtendedApplication = Ext2, PublicKey, ManuallyApprovesFollowers>; diff --git a/profiles/src/apub/keys.rs b/profiles/src/apub/keys.rs deleted file mode 100644 index acb536f..0000000 --- a/profiles/src/apub/keys.rs +++ /dev/null @@ -1,41 +0,0 @@ -use activitystreams::{ - actor::{ApActor, Application, Person}, - unparsed::UnparsedMutExt, - url::Url, -}; -use activitystreams_ext::{Ext1, UnparsedExtension}; - -#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] -#[serde(rename_all = "camelCase")] -pub struct PublicKey { - pub(crate) public_key: PublicKeyInner, -} - -#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] -#[serde(rename_all = "camelCase")] -pub struct PublicKeyInner { - pub(crate) id: Url, - pub(crate) owner: Url, - pub(crate) public_key_pem: String, -} - -impl UnparsedExtension for PublicKey -where - U: UnparsedMutExt, -{ - type Error = serde_json::Error; - - fn try_from_unparsed(unparsed_mut: &mut U) -> Result { - Ok(PublicKey { - public_key: unparsed_mut.remove("publicKey")?, - }) - } - - fn try_into_unparsed(self, unparsed_mut: &mut U) -> Result<(), Self::Error> { - unparsed_mut.insert("publicKey", self.public_key)?; - Ok(()) - } -} - -pub type ExtendedPerson = Ext1, PublicKey>; -pub type ExtendedApplication = Ext1, PublicKey>; diff --git a/profiles/src/apub/mod.rs b/profiles/src/apub/mod.rs index cf346fa..edceb46 100644 --- a/profiles/src/apub/mod.rs +++ b/profiles/src/apub/mod.rs @@ -5,11 +5,14 @@ use url::Url; use uuid::Uuid; pub mod actions; -mod keys; +mod extensions; mod results; pub(crate) use actions::ingest; -use keys::{ExtendedApplication, ExtendedPerson, PublicKey, PublicKeyInner}; +use extensions::{ + ExtendedApplication, ExtendedNote, ExtendedPerson, ManuallyApprovesFollowers, PublicKey, + PublicKeyInner, Sensitive, +}; pub trait ApubIds { fn gen_id(&self) -> Option; diff --git a/profiles/src/apub/results/comment.rs b/profiles/src/apub/results/comment.rs index c863ab6..ed1e3fb 100644 --- a/profiles/src/apub/results/comment.rs +++ b/profiles/src/apub/results/comment.rs @@ -3,12 +3,16 @@ use super::{ CommentDeleted, CommentUpdated, LocalCommentCreated, LocalCommentUpdated, RemoteCommentCreated, RemoteCommentDeleted, RemoteCommentUpdated, }; -use crate::{store::Comment, Context, Error, OnBehalfOf, Outbound, Required}; +use crate::{ + apub::{ExtendedNote, Sensitive}, + store::Comment, + Context, Error, OnBehalfOf, Outbound, Required, +}; use activitystreams::{ activity::{Announce, Create, Delete, Update}, base::AnyBase, context, - object::Note, + object::{ApObject, Note}, prelude::*, public, security, }; @@ -16,6 +20,13 @@ use std::collections::HashSet; use url::Url; use uuid::Uuid; +fn comment_context() -> AnyBase { + AnyBase::from_arbitrary_json(serde_json::json!({ + "sensitive": "as:sensitive" + })) + .unwrap() +} + fn local_inboxes( submission_id: Uuid, comment_id: Option, @@ -95,7 +106,19 @@ fn build_comment( .endpoints_for_profile(comment.profile_id())? .req("endpoints for commenter")?; - let mut note = Note::new(); + let submission_sensitive = ctx + .store + .submissions + .by_id(comment.submission_id())? + .req("submission by id")? + .is_sensitive(); + + let mut note = ExtendedNote::new( + ApObject::new(Note::new()), + Sensitive { + sensitive: submission_sensitive, + }, + ); note.set_id(note_id) .set_content(comment.body()) .set_published(published.into()) @@ -165,7 +188,8 @@ impl Outbound for CommentCreated { create .set_id(ctx.apub.info.gen_id().req("id generation")?) .add_context(context()) - .add_context(security()); + .add_context(security()) + .add_context(comment_context()); let any_base = create.into_any_base()?; ctx.apub.store_object(&any_base)?; @@ -226,7 +250,8 @@ impl Outbound for AnnounceCommentCreated { announce .set_id(ctx.apub.info.gen_id().req("id generation")?) .add_context(context()) - .add_context(security()); + .add_context(security()) + .add_context(comment_context()); let any_base = announce.into_any_base()?; ctx.apub.store_object(&any_base)?; @@ -261,7 +286,8 @@ impl Outbound for RemoteCommentCreated { announce .set_id(ctx.apub.info.gen_id().req("id generation")?) .add_context(context()) - .add_context(security()); + .add_context(security()) + .add_context(comment_context()); let announce = announce.into_any_base()?; ctx.apub.store_object(&announce)?; @@ -314,7 +340,8 @@ impl Outbound for CommentUpdated { update .set_id(ctx.apub.info.gen_id().req("id generation")?) .add_context(context()) - .add_context(security()); + .add_context(security()) + .add_context(comment_context()); let any_base = update.into_any_base()?; ctx.apub.store_object(&any_base)?; @@ -381,7 +408,8 @@ impl Outbound for AnnounceCommentUpdated { update .set_id(ctx.apub.info.gen_id().req("id generation")?) .add_context(context()) - .add_context(security()); + .add_context(security()) + .add_context(comment_context()); let update = update.into_any_base()?; ctx.apub.store_object(&update)?; @@ -389,7 +417,8 @@ impl Outbound for AnnounceCommentUpdated { announce .set_id(ctx.apub.info.gen_id().req("id generation")?) .add_context(context()) - .add_context(security()); + .add_context(security()) + .add_context(comment_context()); let announce = announce.into_any_base()?; ctx.apub.store_object(&announce)?; @@ -424,7 +453,8 @@ impl Outbound for RemoteCommentUpdated { announce .set_id(ctx.apub.info.gen_id().req("id generation")?) .add_context(context()) - .add_context(security()); + .add_context(security()) + .add_context(comment_context()); let announce = announce.into_any_base()?; ctx.apub.store_object(&announce)?; @@ -456,7 +486,8 @@ impl Outbound for CommentDeleted { delete .set_id(ctx.apub.info.gen_id().req("id generation")?) .add_context(context()) - .add_context(security()); + .add_context(security()) + .add_context(comment_context()); let any_base = delete.into_any_base()?; ctx.apub.store_object(&any_base)?; @@ -492,7 +523,8 @@ impl Outbound for AnnounceCommentDeleted { delete .set_id(ctx.apub.info.gen_id().req("id generation")?) .add_context(context()) - .add_context(security()); + .add_context(security()) + .add_context(comment_context()); let delete = delete.into_any_base()?; ctx.apub.store_object(&delete)?; @@ -500,7 +532,8 @@ impl Outbound for AnnounceCommentDeleted { announce .set_id(ctx.apub.info.gen_id().req("id generation")?) .add_context(context()) - .add_context(security()); + .add_context(security()) + .add_context(comment_context()); let announce = announce.into_any_base()?; ctx.apub.store_object(&announce)?; @@ -535,7 +568,8 @@ impl Outbound for RemoteCommentDeleted { announce .set_id(ctx.apub.info.gen_id().req("id generation")?) .add_context(context()) - .add_context(security()); + .add_context(security()) + .add_context(comment_context()); let announce = announce.into_any_base()?; ctx.apub.store_object(&announce)?; diff --git a/profiles/src/apub/results/profile.rs b/profiles/src/apub/results/profile.rs index e424918..9b7129f 100644 --- a/profiles/src/apub/results/profile.rs +++ b/profiles/src/apub/results/profile.rs @@ -1,6 +1,6 @@ use super::{ProfileCreated, ProfileDeleted, ProfileUpdated}; use crate::{ - apub::{ExtendedPerson, PublicKey, PublicKeyInner}, + apub::{ExtendedPerson, ManuallyApprovesFollowers, PublicKey, PublicKeyInner, Sensitive}, store::FileSource, Context, Error, OnBehalfOf, Outbound, Required, }; @@ -17,6 +17,15 @@ use std::collections::HashSet; use url::Url; use uuid::Uuid; +fn profile_context() -> AnyBase { + AnyBase::from_arbitrary_json(serde_json::json!({ + "manuallyApprovesFollowers": "as:manuallyApprovesFollowers", + "PropertyValue": "schema:PropertyValue", + "sensitive": "as:sensitive" + })) + .unwrap() +} + fn build_image(file_id: Uuid, ctx: &Context) -> Result { if let Some(apub_id) = ctx.apub.apub_for_file(file_id)? { ctx.apub.object(&apub_id)?.req("image object by id") @@ -108,6 +117,10 @@ impl Outbound for ProfileCreated { public_key_pem, }, }, + ManuallyApprovesFollowers { + manually_approves_followers: true, + }, + Sensitive { sensitive: false }, ); person @@ -147,7 +160,8 @@ impl Outbound for ProfileCreated { create .set_id(ctx.apub.info.gen_id().req("id generation")?) .add_context(context()) - .add_context(security()); + .add_context(security()) + .add_context(profile_context()); let any_base = create.into_any_base()?; ctx.apub.store_object(&any_base)?; @@ -210,6 +224,10 @@ impl Outbound for ProfileUpdated { public_key_pem, }, }, + ManuallyApprovesFollowers { + manually_approves_followers: true, + }, + Sensitive { sensitive: false }, ); person @@ -256,7 +274,8 @@ impl Outbound for ProfileUpdated { update .set_id(ctx.apub.info.gen_id().req("id generation")?) .add_context(context()) - .add_context(security()); + .add_context(security()) + .add_context(profile_context()); let any_base = update.into_any_base()?; ctx.apub.store_object(&any_base)?; @@ -304,7 +323,8 @@ impl Outbound for ProfileDeleted { delete .set_id(ctx.apub.info.gen_id().req("id generation")?) .add_context(context()) - .add_context(security()); + .add_context(security()) + .add_context(profile_context()); let any_base = delete.into_any_base()?; ctx.apub.store_object(&any_base)?; diff --git a/profiles/src/apub/results/server.rs b/profiles/src/apub/results/server.rs index ba8e3b3..58471fb 100644 --- a/profiles/src/apub/results/server.rs +++ b/profiles/src/apub/results/server.rs @@ -1,6 +1,6 @@ use super::{ServerCreated, ServerUpdated}; use crate::{ - apub::{ExtendedApplication, PublicKey, PublicKeyInner}, + apub::{ExtendedApplication, ManuallyApprovesFollowers, PublicKey, PublicKeyInner}, Context, Error, OnBehalfOf, Outbound, Required, }; use activitystreams::{ @@ -15,6 +15,13 @@ use std::collections::HashSet; use url::Url; use uuid::Uuid; +fn application_context() -> AnyBase { + AnyBase::from_arbitrary_json(serde_json::json!({ + "manuallyApprovesFollowers": "as:manuallyApprovesFollowers", + })) + .unwrap() +} + impl Outbound for ServerCreated { fn id(&self) -> Option { Some(self.server_id) @@ -71,6 +78,9 @@ impl Outbound for ServerCreated { public_key_pem, }, }, + ManuallyApprovesFollowers { + manually_approves_followers: true, + }, ); application @@ -99,7 +109,8 @@ impl Outbound for ServerCreated { create .set_id(ctx.apub.info.gen_id().req("id generation")?) .add_context(context()) - .add_context(security()); + .add_context(security()) + .add_context(application_context()); let any_base = create.into_any_base()?; ctx.apub.store_object(&any_base)?; @@ -169,6 +180,9 @@ impl Outbound for ServerUpdated { public_key_pem, }, }, + ManuallyApprovesFollowers { + manually_approves_followers: true, + }, ); application @@ -204,7 +218,8 @@ impl Outbound for ServerUpdated { update .set_id(ctx.apub.info.gen_id().req("id generation")?) .add_context(context()) - .add_context(security()); + .add_context(security()) + .add_context(application_context()); let any_base = update.into_any_base()?; ctx.apub.store_object(&any_base)?; diff --git a/profiles/src/apub/results/submission.rs b/profiles/src/apub/results/submission.rs index 90a5376..6fcf07e 100644 --- a/profiles/src/apub/results/submission.rs +++ b/profiles/src/apub/results/submission.rs @@ -3,6 +3,7 @@ use super::{ SubmissionUpdated, UnpublishedSubmissionCreated, }; use crate::{ + apub::{ExtendedNote, Sensitive}, store::{FileSource, Submission, Visibility}, Context, Error, OnBehalfOf, Outbound, Required, }; @@ -11,7 +12,7 @@ use activitystreams::{ base::AnyBase, context, object::Image, - object::Note, + object::{ApObject, Note}, prelude::*, public, security, }; @@ -19,6 +20,13 @@ use std::collections::HashSet; use url::Url; use uuid::Uuid; +fn submission_context() -> AnyBase { + AnyBase::from_arbitrary_json(serde_json::json!({ + "sensitive": "as:sensitive" + })) + .unwrap() +} + fn build_image(file_id: Uuid, ctx: &Context) -> Result { if let Some(apub_id) = ctx.apub.apub_for_file(file_id)? { ctx.apub.object(&apub_id)?.req("image object by id") @@ -78,7 +86,12 @@ fn build_submission( .endpoints_for_profile(submission.profile_id())? .req("endpoints for profile")?; - let mut note = Note::new(); + let mut note = ExtendedNote::new( + ApObject::new(Note::new()), + Sensitive { + sensitive: submission.is_sensitive(), + }, + ); note.set_id(note_id) .set_summary(submission.title()) .set_published(published.into()) @@ -89,9 +102,6 @@ fn build_submission( if let Some(description) = submission.description() { note.set_content(description); } - if submission.is_logged_in_only() { - log::warn!("logged_in_only is not implemented yet"); - } match submission.visibility() { Visibility::Public => { note.add_to(public()); @@ -210,7 +220,8 @@ impl Outbound for SubmissionCreated { create .set_id(ctx.apub.info.gen_id().req("id generation")?) .add_context(context()) - .add_context(security()); + .add_context(security()) + .add_context(submission_context()); let any_base = create.into_any_base()?; ctx.apub.store_object(&any_base)?; @@ -265,7 +276,8 @@ impl Outbound for SubmissionUpdated { update .set_id(ctx.apub.info.gen_id().req("id generation")?) .add_context(context()) - .add_context(security()); + .add_context(security()) + .add_context(submission_context()); let any_base = update.into_any_base()?; ctx.apub.store_object(&any_base)?; @@ -323,7 +335,8 @@ impl Outbound for SubmissionDeleted { delete .set_id(ctx.apub.info.gen_id().req("id generation")?) .add_context(context()) - .add_context(security()); + .add_context(security()) + .add_context(submission_context()); let any_base = delete.into_any_base()?; ctx.apub.store_object(&any_base)?; diff --git a/profiles/src/store/submission.rs b/profiles/src/store/submission.rs index b2ffdc9..0770d4a 100644 --- a/profiles/src/store/submission.rs +++ b/profiles/src/store/submission.rs @@ -25,6 +25,7 @@ pub struct Submission { visibility: Visibility, local_only: bool, logged_in_only: bool, + sensitive: bool, } #[derive(Debug)] @@ -39,6 +40,7 @@ pub struct SubmissionChanges { updated: Option>, local_only: Option, logged_in_only: Option, + sensitive: Option, } #[derive(Debug)] @@ -79,6 +81,8 @@ struct StoredSubmission { local_only: bool, #[serde(default)] logged_in_only: bool, + #[serde(default)] + sensitive: bool, drafted_at: DateTime, } @@ -95,6 +99,7 @@ impl Submission { updated: None, local_only: None, logged_in_only: None, + sensitive: None, } } @@ -165,6 +170,10 @@ impl Submission { pub fn is_logged_in_only(&self) -> bool { self.logged_in_only } + + pub fn is_sensitive(&self) -> bool { + self.sensitive + } } impl SubmissionChanges { @@ -223,6 +232,11 @@ impl SubmissionChanges { self } + pub(crate) fn sensitive(&mut self, sensitive: bool) -> &mut Self { + self.sensitive = Some(sensitive); + self + } + pub(crate) fn any_changes(&self) -> bool { self.title.is_some() || self.description.is_some() @@ -231,6 +245,7 @@ impl SubmissionChanges { || self.visibility.is_some() || self.local_only.is_some() || self.logged_in_only.is_some() + || self.sensitive.is_some() } } @@ -292,6 +307,7 @@ impl Store { local_only: false, logged_in_only: false, drafted_at: now, + sensitive: false, }; serde_json::to_writer(writer, &stored_submission)?; self.submission_tree @@ -396,6 +412,9 @@ impl Store { if let Some(logged_in_only) = changes.logged_in_only { stored_submission.logged_in_only = logged_in_only; } + if let Some(sensitive) = changes.sensitive { + stored_submission.sensitive = sensitive; + } if stored_submission.published.is_some() { if let Some(updated) = changes.updated { stored_submission.updated = Some(updated); @@ -836,6 +855,7 @@ impl From for Submission { visibility: ss.visibility, local_only: ss.local_only, logged_in_only: ss.logged_in_only, + sensitive: ss.sensitive, } } }