"async-trait",
"background-jobs",
"base64 0.13.0",
+ "diesel",
"http",
"http-signature-normalization-actix",
"http-signature-normalization-reqwest",
"diesel-derive-newtype",
"diesel_migrations",
"lazy_static",
+ "lemmy_apub_lib",
"lemmy_utils",
"log",
"regex",
+use crate::Perform;
use actix_web::web::Data;
-
use lemmy_api_common::{
blocking,
check_community_ban,
get_local_user_view_from_jwt,
is_mod_or_admin,
};
-use lemmy_apub::{fetcher::object_id::ObjectId, protocol::activities::community::report::Report};
+use lemmy_apub::protocol::activities::community::report::Report;
+use lemmy_apub_lib::object_id::ObjectId;
use lemmy_db_schema::{source::comment_report::*, traits::Reportable};
use lemmy_db_views::{
comment_report_view::{CommentReportQueryBuilder, CommentReportView},
use lemmy_utils::{ApiError, ConnectionId, LemmyError};
use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation};
-use crate::Perform;
-
/// Creates a comment report and notifies the moderators of the community
#[async_trait::async_trait(?Send)]
impl Perform for CreateCommentReport {
+use crate::Perform;
use actix_web::web::Data;
-
use lemmy_api_common::{
blocking,
check_community_ban,
ResolvePostReport,
},
};
-use lemmy_apub::{fetcher::object_id::ObjectId, protocol::activities::community::report::Report};
+use lemmy_apub::protocol::activities::community::report::Report;
+use lemmy_apub_lib::object_id::ObjectId;
use lemmy_db_schema::{
source::post_report::{PostReport, PostReportForm},
traits::Reportable,
use lemmy_utils::{ApiError, ConnectionId, LemmyError};
use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation};
-use crate::Perform;
-
/// Creates a post report and notifies the moderators of the community
#[async_trait::async_trait(?Send)]
impl Perform for CreatePostReport {
is_admin,
};
use lemmy_apub::{
- fetcher::object_id::ObjectId,
generate_followers_url,
generate_inbox_url,
generate_local_apub_endpoint,
objects::community::ApubCommunity,
EndpointType,
};
+use lemmy_apub_lib::object_id::ObjectId;
use lemmy_db_schema::{
diesel_option_overwrite_to_url,
source::{
use crate::PerformCrud;
use actix_web::web::Data;
use lemmy_api_common::{blocking, community::*, get_local_user_view_from_jwt_opt};
-use lemmy_apub::{
- fetcher::object_id::ObjectId,
- get_actor_id_from_name,
- objects::community::ApubCommunity,
-};
-use lemmy_apub_lib::webfinger::WebfingerType;
+use lemmy_apub::{get_actor_id_from_name, objects::community::ApubCommunity};
+use lemmy_apub_lib::{object_id::ObjectId, webfinger::WebfingerType};
use lemmy_db_schema::{
from_opt_str_to_opt_enum,
traits::DeleteableOrRemoveable,
+use crate::PerformCrud;
use actix_web::web::Data;
-use log::warn;
-use webmention::{Webmention, WebmentionError};
-
use lemmy_api_common::{
blocking,
check_community_ban,
LemmyError,
};
use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperationCrud};
-
-use crate::PerformCrud;
+use log::warn;
+use url::Url;
+use webmention::{Webmention, WebmentionError};
#[async_trait::async_trait(?Send)]
impl PerformCrud for CreatePost {
mark_post_as_read(person_id, post_id, context.pool()).await?;
if let Some(url) = &updated_post.url {
- let mut webmention = Webmention::new(
- updated_post.ap_id.clone().into_inner(),
- url.clone().into_inner(),
- )?;
+ let mut webmention =
+ Webmention::new::<Url>(updated_post.ap_id.clone().into(), url.clone().into())?;
webmention.set_checked(true);
match webmention.send().await {
Ok(_) => {}
use crate::PerformCrud;
use actix_web::web::Data;
use lemmy_api_common::{blocking, get_local_user_view_from_jwt_opt, person::*};
-use lemmy_apub::{
- fetcher::object_id::ObjectId,
- get_actor_id_from_name,
- objects::person::ApubPerson,
-};
-use lemmy_apub_lib::webfinger::WebfingerType;
+use lemmy_apub::{get_actor_id_from_name, objects::person::ApubPerson};
+use lemmy_apub_lib::{object_id::ObjectId, webfinger::WebfingerType};
use lemmy_db_schema::{from_opt_str_to_opt_enum, SortType};
use lemmy_db_views::{comment_view::CommentQueryBuilder, post_view::PostQueryBuilder};
use lemmy_db_views_actor::{
verify_person_in_community,
},
activity_lists::AnnouncableActivities,
- fetcher::object_id::ObjectId,
objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson},
protocol::activities::{create_or_update::comment::CreateOrUpdateComment, CreateOrUpdateType},
};
use lemmy_api_common::{blocking, check_post_deleted_or_removed};
use lemmy_apub_lib::{
data::Data,
+ object_id::ObjectId,
traits::{ActivityHandler, ActorType, ApubObject},
verify::verify_domains_match,
};
-use crate::{
- fetcher::object_id::ObjectId,
- objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson},
-};
+use crate::objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson};
use activitystreams::{
base::BaseExt,
link::{LinkExt, Mention},
use anyhow::anyhow;
use itertools::Itertools;
use lemmy_api_common::blocking;
-use lemmy_apub_lib::{traits::ActorType, webfinger::WebfingerResponse};
+use lemmy_apub_lib::{object_id::ObjectId, traits::ActorType, webfinger::WebfingerResponse};
use lemmy_db_schema::{
newtypes::LocalUserId,
source::{comment::Comment, person::Person, post::Post},
verify_person_in_community,
},
activity_lists::AnnouncableActivities,
- fetcher::object_id::ObjectId,
generate_moderators_url,
objects::{community::ApubCommunity, person::ApubPerson},
protocol::activities::community::add_mod::AddMod,
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
data::Data,
+ object_id::ObjectId,
traits::{ActivityHandler, ActorType},
};
use lemmy_db_schema::{
use crate::{
activities::{generate_activity_id, send_lemmy_activity, verify_activity, verify_is_public},
activity_lists::AnnouncableActivities,
- fetcher::object_id::ObjectId,
http::{is_activity_already_known, ActivityCommonFields},
insert_activity,
objects::community::ApubCommunity,
use activitystreams::{activity::kind::AnnounceType, public};
use lemmy_apub_lib::{
data::Data,
+ object_id::ObjectId,
traits::{ActivityHandler, ActorType},
};
use lemmy_utils::LemmyError;
actor: ObjectId::new(community.actor_id()),
to: vec![public()],
object,
- cc: vec![community.followers_url.clone().into_inner()],
+ cc: vec![community.followers_url.clone().into()],
kind: AnnounceType::Announce,
id: generate_activity_id(
&AnnounceType::Announce,
verify_person_in_community,
},
activity_lists::AnnouncableActivities,
- fetcher::object_id::ObjectId,
objects::{community::ApubCommunity, person::ApubPerson},
protocol::activities::community::block_user::BlockUserFromCommunity,
};
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
data::Data,
+ object_id::ObjectId,
traits::{ActivityHandler, ActorType},
};
use lemmy_db_schema::{
use crate::{
activities::send_lemmy_activity,
activity_lists::AnnouncableActivities,
- fetcher::object_id::ObjectId,
insert_activity,
objects::community::ApubCommunity,
protocol::activities::community::announce::AnnounceActivity,
};
-use lemmy_apub_lib::traits::ActorType;
+use lemmy_apub_lib::{object_id::ObjectId, traits::ActorType};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
verify_person_in_community,
},
activity_lists::AnnouncableActivities,
- fetcher::object_id::ObjectId,
generate_moderators_url,
objects::{community::ApubCommunity, person::ApubPerson},
protocol::activities::community::remove_mod::RemoveMod,
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
data::Data,
+ object_id::ObjectId,
traits::{ActivityHandler, ActorType},
};
use lemmy_db_schema::{
verify_activity,
verify_person_in_community,
},
- fetcher::object_id::ObjectId,
objects::{community::ApubCommunity, person::ApubPerson},
protocol::activities::community::report::Report,
PostOrComment,
use lemmy_api_common::{blocking, comment::CommentReportResponse, post::PostReportResponse};
use lemmy_apub_lib::{
data::Data,
+ object_id::ObjectId,
traits::{ActivityHandler, ActorType},
};
use lemmy_db_schema::{
verify_person_in_community,
},
activity_lists::AnnouncableActivities,
- fetcher::object_id::ObjectId,
objects::{community::ApubCommunity, person::ApubPerson},
protocol::activities::community::{
block_user::BlockUserFromCommunity,
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
data::Data,
+ object_id::ObjectId,
traits::{ActivityHandler, ActorType},
};
use lemmy_db_schema::{
verify_person_in_community,
},
activity_lists::AnnouncableActivities,
- fetcher::object_id::ObjectId,
objects::{community::ApubCommunity, person::ApubPerson},
protocol::{activities::community::update::UpdateCommunity, objects::group::Group},
};
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
data::Data,
+ object_id::ObjectId,
traits::{ActivityHandler, ActorType, ApubObject},
};
use lemmy_db_schema::{
use crate::{
activities::{
community::{announce::GetCommunity, send_to_community},
- deletion::{
- receive_delete_action,
- verify_delete_activity,
- DeletableObjects,
- },
+ deletion::{receive_delete_action, verify_delete_activity, DeletableObjects},
generate_activity_id,
verify_activity,
verify_is_public,
},
activity_lists::AnnouncableActivities,
- fetcher::object_id::ObjectId,
objects::{community::ApubCommunity, person::ApubPerson},
protocol::activities::deletion::delete::Delete,
};
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
data::Data,
+ object_id::ObjectId,
traits::{ActivityHandler, ActorType},
};
use lemmy_db_schema::{
use crate::{
activities::{verify_mod_action, verify_person_in_community},
- fetcher::object_id::ObjectId,
objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson, post::ApubPost},
protocol::activities::deletion::{delete::Delete, undo_delete::UndoDelete},
};
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
+ object_id::ObjectId,
traits::{ActorType, ApubObject},
verify::verify_domains_match,
};
verify_is_public,
},
activity_lists::AnnouncableActivities,
- fetcher::object_id::ObjectId,
objects::{community::ApubCommunity, person::ApubPerson},
protocol::activities::deletion::{delete::Delete, undo_delete::UndoDelete},
};
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
data::Data,
+ object_id::ObjectId,
traits::{ActivityHandler, ActorType},
};
use lemmy_db_schema::source::{comment::Comment, community::Community, post::Post};
use crate::{
activities::{generate_activity_id, send_lemmy_activity, verify_activity},
- fetcher::object_id::ObjectId,
protocol::activities::following::{accept::AcceptFollowCommunity, follow::FollowCommunity},
};
use activitystreams::activity::kind::AcceptType;
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
data::Data,
+ object_id::ObjectId,
traits::{ActivityHandler, ActorType},
verify::verify_urls_match,
};
verify_person,
verify_person_in_community,
},
- fetcher::object_id::ObjectId,
objects::{community::ApubCommunity, person::ApubPerson},
protocol::activities::following::{accept::AcceptFollowCommunity, follow::FollowCommunity},
};
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
data::Data,
+ object_id::ObjectId,
traits::{ActivityHandler, ActorType},
verify::verify_urls_match,
};
use crate::{
activities::{generate_activity_id, send_lemmy_activity, verify_activity, verify_person},
- fetcher::object_id::ObjectId,
objects::{community::ApubCommunity, person::ApubPerson},
protocol::activities::following::{follow::FollowCommunity, undo_follow::UndoFollowCommunity},
};
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
data::Data,
+ object_id::ObjectId,
traits::{ActivityHandler, ActorType},
verify::verify_urls_match,
};
use crate::{
check_is_apub_id_valid,
context::WithContext,
- fetcher::object_id::ObjectId,
generate_moderators_url,
insert_activity,
objects::{community::ApubCommunity, person::ApubPerson},
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
activity_queue::send_activity,
+ object_id::ObjectId,
traits::ActorType,
verify::verify_domains_match,
};
target: &Url,
community: &ApubCommunity,
) -> Result<(), LemmyError> {
- if target != &generate_moderators_url(&community.actor_id)?.into_inner() {
+ if target != &generate_moderators_url(&community.actor_id)?.into() {
return Err(anyhow!("Unkown target url").into());
}
Ok(())
verify_person_in_community,
},
activity_lists::AnnouncableActivities,
- fetcher::object_id::ObjectId,
objects::{community::ApubCommunity, person::ApubPerson, post::ApubPost},
protocol::activities::{create_or_update::post::CreateOrUpdatePost, CreateOrUpdateType},
};
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
data::Data,
+ object_id::ObjectId,
traits::{ActivityHandler, ActorType, ApubObject},
verify::{verify_domains_match, verify_urls_match},
};
use crate::{
activities::{generate_activity_id, send_lemmy_activity, verify_activity, verify_person},
- fetcher::object_id::ObjectId,
objects::{person::ApubPerson, private_message::ApubPrivateMessage},
protocol::activities::{
private_message::create_or_update::CreateOrUpdatePrivateMessage,
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
data::Data,
+ object_id::ObjectId,
traits::{ActivityHandler, ActorType, ApubObject},
verify::verify_domains_match,
};
use crate::{
activities::{generate_activity_id, send_lemmy_activity, verify_activity, verify_person},
- fetcher::object_id::ObjectId,
objects::{person::ApubPerson, private_message::ApubPrivateMessage},
protocol::activities::private_message::delete::DeletePrivateMessage,
};
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
data::Data,
+ object_id::ObjectId,
traits::{ActivityHandler, ActorType},
verify::verify_domains_match,
};
use crate::{
activities::{generate_activity_id, send_lemmy_activity, verify_activity, verify_person},
- fetcher::object_id::ObjectId,
objects::{person::ApubPerson, private_message::ApubPrivateMessage},
protocol::activities::private_message::{
delete::DeletePrivateMessage,
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
data::Data,
+ object_id::ObjectId,
traits::{ActivityHandler, ActorType},
verify::{verify_domains_match, verify_urls_match},
};
voting::{undo_vote_comment, undo_vote_post},
},
activity_lists::AnnouncableActivities,
- fetcher::object_id::ObjectId,
objects::{community::ApubCommunity, person::ApubPerson},
protocol::activities::voting::{
undo_vote::UndoVote,
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
data::Data,
+ object_id::ObjectId,
traits::{ActivityHandler, ActorType},
verify::verify_urls_match,
};
voting::{vote_comment, vote_post},
},
activity_lists::AnnouncableActivities,
- fetcher::object_id::ObjectId,
objects::{community::ApubCommunity, person::ApubPerson},
protocol::activities::voting::vote::{Vote, VoteType},
PostOrComment,
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
data::Data,
+ object_id::ObjectId,
traits::{ActivityHandler, ActorType},
};
use lemmy_db_schema::{
use crate::{
collections::CommunityContext,
- fetcher::object_id::ObjectId,
generate_moderators_url,
objects::person::ApubPerson,
protocol::collections::group_moderators::GroupModerators,
};
use activitystreams::{chrono::NaiveDateTime, collection::kind::OrderedCollectionType};
use lemmy_api_common::blocking;
-use lemmy_apub_lib::{traits::ApubObject, verify::verify_domains_match};
+use lemmy_apub_lib::{object_id::ObjectId, traits::ApubObject, verify::verify_domains_match};
use lemmy_db_schema::{
source::community::{CommunityModerator, CommunityModeratorForm},
traits::Joinable,
let ordered_items = self
.0
.iter()
- .map(|m| ObjectId::<ApubPerson>::new(m.moderator.actor_id.clone().into_inner()))
+ .map(|m| ObjectId::<ApubPerson>::new(m.moderator.actor_id.clone()))
.collect();
Ok(GroupModerators {
r#type: OrderedCollectionType::OrderedCollection,
.await??;
// Remove old mods from database which arent in the moderators collection anymore
for mod_user in ¤t_moderators {
- let mod_id = ObjectId::new(mod_user.moderator.actor_id.clone().into_inner());
+ let mod_id = ObjectId::new(mod_user.moderator.actor_id.clone());
if !apub.ordered_items.contains(&mod_id) {
let community_moderator_form = CommunityModeratorForm {
community_id: mod_user.community.id,
+use crate::{
+ collections::CommunityContext,
+ generate_outbox_url,
+ objects::{person::ApubPerson, post::ApubPost},
+ protocol::{
+ activities::{create_or_update::post::CreateOrUpdatePost, CreateOrUpdateType},
+ collections::group_outbox::GroupOutbox,
+ },
+};
use activitystreams::collection::kind::OrderedCollectionType;
use chrono::NaiveDateTime;
-use url::Url;
-
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
data::Data,
traits::Crud,
};
use lemmy_utils::LemmyError;
-
-use crate::{
- collections::CommunityContext,
- generate_outbox_url,
- objects::{person::ApubPerson, post::ApubPost},
- protocol::{
- activities::{create_or_update::post::CreateOrUpdatePost, CreateOrUpdateType},
- collections::group_outbox::GroupOutbox,
- },
-};
+use url::Url;
#[derive(Clone, Debug)]
pub(crate) struct ApubCommunityOutbox(Vec<ApubPost>);
-pub mod object_id;
pub mod post_or_comment;
pub mod search;
pub mod user_or_community;
-
-use chrono::NaiveDateTime;
-use lemmy_db_schema::naive_now;
-
-static ACTOR_REFETCH_INTERVAL_SECONDS: i64 = 24 * 60 * 60;
-static ACTOR_REFETCH_INTERVAL_SECONDS_DEBUG: i64 = 10;
-
-/// Determines when a remote actor should be refetched from its instance. In release builds, this is
-/// `ACTOR_REFETCH_INTERVAL_SECONDS` after the last refetch, in debug builds
-/// `ACTOR_REFETCH_INTERVAL_SECONDS_DEBUG`.
-///
-/// TODO it won't pick up new avatars, summaries etc until a day after.
-/// Actors need an "update" activity pushed to other servers to fix this.
-fn should_refetch_object(last_refreshed: NaiveDateTime) -> bool {
- let update_interval = if cfg!(debug_assertions) {
- // avoid infinite loop when fetching community outbox
- chrono::Duration::seconds(ACTOR_REFETCH_INTERVAL_SECONDS_DEBUG)
- } else {
- chrono::Duration::seconds(ACTOR_REFETCH_INTERVAL_SECONDS)
- };
- last_refreshed.lt(&(naive_now() - update_interval))
-}
+use crate::{
+ objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson, post::ApubPost},
+ protocol::objects::{group::Group, note::Note, page::Page, person::Person},
+};
use anyhow::anyhow;
use chrono::NaiveDateTime;
use itertools::Itertools;
-use serde::Deserialize;
-use url::Url;
-
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
+ object_id::ObjectId,
traits::ApubObject,
webfinger::{webfinger_resolve_actor, WebfingerType},
};
};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
-
-use crate::{
- fetcher::object_id::ObjectId,
- objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson, post::ApubPost},
- protocol::objects::{group::Group, note::Note, page::Page, person::Person},
-};
+use serde::Deserialize;
+use url::Url;
/// Attempt to parse the query as URL, and fetch an ActivityPub object from it.
///
CommunityContext,
},
context::WithContext,
- fetcher::object_id::ObjectId,
generate_outbox_url,
http::{
create_apub_response,
};
use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse};
use lemmy_api_common::blocking;
-use lemmy_apub_lib::traits::ApubObject;
+use lemmy_apub_lib::{object_id::ObjectId, traits::ApubObject};
use lemmy_db_schema::source::community::Community;
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
Community::read_from_name(conn, &info.community_name)
})
.await??;
- let id = ObjectId::new(generate_outbox_url(&community.actor_id)?.into_inner());
+ let id = ObjectId::new(generate_outbox_url(&community.actor_id)?);
let outbox_data = CommunityContext(community.into(), context.get_ref().clone());
let outbox: ApubCommunityOutbox = id.dereference(&outbox_data, &mut 0).await?;
Ok(create_apub_response(&outbox.to_apub(&outbox_data).await?))
})
.await??
.into();
- let id = ObjectId::new(generate_outbox_url(&community.actor_id)?.into_inner());
+ let id = ObjectId::new(generate_outbox_url(&community.actor_id)?);
let outbox_data = CommunityContext(community, context.get_ref().clone());
let moderators: ApubCommunityModerators = id.dereference(&outbox_data, &mut 0).await?;
Ok(create_apub_response(
activity_lists::SharedInboxActivities,
check_is_apub_id_valid,
context::WithContext,
- fetcher::{object_id::ObjectId, user_or_community::UserOrCommunity},
+ fetcher::user_or_community::UserOrCommunity,
http::{community::receive_group_inbox, person::receive_person_inbox},
insert_activity,
};
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
data::Data,
+ object_id::ObjectId,
signatures::verify_signature,
traits::{ActivityHandler, ActorType},
APUB_JSON_CONTENT_TYPE,
-use std::ops::Deref;
-
+use crate::{
+ activities::verify_person_in_community,
+ check_is_apub_id_valid,
+ protocol::{
+ objects::{
+ note::{Note, SourceCompat},
+ tombstone::Tombstone,
+ },
+ Source,
+ },
+ PostOrComment,
+};
use activitystreams::{object::kind::NoteType, public};
use anyhow::anyhow;
use chrono::NaiveDateTime;
use html2md::parse_html;
-use url::Url;
-
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
+ object_id::ObjectId,
traits::ApubObject,
values::{MediaTypeHtml, MediaTypeMarkdown},
+ verify::verify_domains_match,
};
use lemmy_db_schema::{
source::{
traits::Crud,
};
use lemmy_utils::{
- utils::{convert_datetime, remove_slurs},
+ utils::{convert_datetime, markdown_to_html, remove_slurs},
LemmyError,
};
use lemmy_websocket::LemmyContext;
-
-use crate::{
- activities::verify_person_in_community,
- check_is_apub_id_valid,
- fetcher::object_id::ObjectId,
- protocol::{
- objects::{
- note::{Note, SourceCompat},
- tombstone::Tombstone,
- },
- Source,
- },
- PostOrComment,
-};
-use lemmy_apub_lib::verify::verify_domains_match;
-use lemmy_utils::utils::markdown_to_html;
+use std::ops::Deref;
+use url::Url;
#[derive(Clone, Debug)]
pub struct ApubComment(Comment);
let in_reply_to = if let Some(comment_id) = self.parent_id {
let parent_comment =
blocking(context.pool(), move |conn| Comment::read(conn, comment_id)).await??;
- ObjectId::<PostOrComment>::new(parent_comment.ap_id.into_inner())
+ ObjectId::<PostOrComment>::new(parent_comment.ap_id)
} else {
- ObjectId::<PostOrComment>::new(post.ap_id.into_inner())
+ ObjectId::<PostOrComment>::new(post.ap_id)
};
let note = Note {
.await
.unwrap();
- assert_eq!(comment.ap_id.clone().into_inner(), url);
+ assert_eq!(comment.ap_id, url.into());
assert_eq!(comment.content.len(), 14);
assert!(!comment.local);
assert_eq!(request_counter, 0);
.await
.unwrap();
- assert_eq!(comment.ap_id.clone().into_inner(), pleroma_url);
+ assert_eq!(comment.ap_id, pleroma_url.into());
assert_eq!(comment.content.len(), 64);
assert!(!comment.local);
assert_eq!(request_counter, 0);
-use activitystreams::{
- actor::{kind::GroupType, Endpoints},
- object::kind::ImageType,
-};
-use chrono::NaiveDateTime;
-use itertools::Itertools;
-use log::debug;
-use std::ops::Deref;
-use url::Url;
-
use crate::{
check_is_apub_id_valid,
collections::{community_moderators::ApubCommunityModerators, CommunityContext},
- fetcher::object_id::ObjectId,
generate_moderators_url,
generate_outbox_url,
protocol::{
Source,
},
};
+use activitystreams::{
+ actor::{kind::GroupType, Endpoints},
+ object::kind::ImageType,
+};
+use chrono::NaiveDateTime;
+use itertools::Itertools;
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
+ object_id::ObjectId,
traits::{ActorType, ApubObject},
values::MediaTypeMarkdown,
};
LemmyError,
};
use lemmy_websocket::LemmyContext;
+use log::debug;
+use std::ops::Deref;
+use url::Url;
#[derive(Clone, Debug)]
pub struct ApubCommunity(Community);
image,
sensitive: Some(self.nsfw),
moderators: Some(ObjectId::<ApubCommunityModerators>::new(
- generate_moderators_url(&self.actor_id)?.into_inner(),
+ generate_moderators_url(&self.actor_id)?,
)),
inbox: self.inbox_url.clone().into(),
outbox: ObjectId::new(generate_outbox_url(&self.actor_id)?),
}
fn shared_inbox_url(&self) -> Option<Url> {
- self.shared_inbox_url.clone().map(|s| s.into_inner())
+ self.shared_inbox_url.clone().map(|s| s.into())
}
}
let follower_inboxes: Vec<Url> = follows
.into_iter()
.filter(|f| !f.follower.local)
- .map(|f| f.follower.shared_inbox_url.unwrap_or(f.follower.inbox_url))
- .map(|i| i.into_inner())
+ .map(|f| {
+ f.follower
+ .shared_inbox_url
+ .unwrap_or(f.follower.inbox_url)
+ .into()
+ })
.collect();
let inboxes = vec![follower_inboxes, additional_inboxes]
.into_iter()
use crate::{
check_is_apub_id_valid,
- fetcher::object_id::ObjectId,
generate_outbox_url,
objects::get_summary_from_string_or_source,
protocol::{
use chrono::NaiveDateTime;
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
+ object_id::ObjectId,
traits::{ActorType, ApubObject},
values::MediaTypeMarkdown,
verify::verify_domains_match,
self.local
}
fn actor_id(&self) -> Url {
- self.actor_id.to_owned().into_inner()
+ self.actor_id.to_owned().into()
}
fn name(&self) -> String {
self.name.clone()
}
fn shared_inbox_url(&self) -> Option<Url> {
- self.shared_inbox_url.clone().map(|s| s.into_inner())
+ self.shared_inbox_url.clone().map(|s| s.into())
}
}
.await
.unwrap();
- assert_eq!(person.actor_id.clone().into_inner(), url);
+ assert_eq!(person.actor_id, url.into());
assert_eq!(person.name, "lanodan");
assert!(person.public_key.is_some());
assert!(!person.local);
use crate::{
activities::verify_person_in_community,
check_is_apub_id_valid,
- fetcher::object_id::ObjectId,
protocol::{
objects::{page::Page, tombstone::Tombstone},
ImageObject,
use chrono::NaiveDateTime;
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
+ object_id::ObjectId,
traits::ApubObject,
values::{MediaTypeHtml, MediaTypeMarkdown},
verify::verify_domains_match,
.await
.unwrap();
- assert_eq!(post.ap_id.clone().into_inner(), url);
+ assert_eq!(post.ap_id, url.into());
assert_eq!(post.name, "Post title");
assert!(post.body.is_some());
assert_eq!(post.body.as_ref().unwrap().len(), 45);
-use crate::{
- fetcher::object_id::ObjectId,
- protocol::{
- objects::chat_message::{ChatMessage, ChatMessageType},
- Source,
- },
+use crate::protocol::{
+ objects::chat_message::{ChatMessage, ChatMessageType},
+ Source,
};
use chrono::NaiveDateTime;
use html2md::parse_html;
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
+ object_id::ObjectId,
traits::ApubObject,
values::{MediaTypeHtml, MediaTypeMarkdown},
verify::verify_domains_match,
.await
.unwrap();
- assert_eq!(pm.ap_id.clone().into_inner(), url);
+ assert_eq!(pm.ap_id.clone(), url.into());
assert_eq!(pm.content.len(), 20);
assert_eq!(request_counter, 0);
.await
.unwrap();
- assert_eq!(pm.ap_id.clone().into_inner(), pleroma_url);
+ assert_eq!(pm.ap_id, pleroma_url.into());
assert_eq!(pm.content.len(), 3);
assert_eq!(request_counter, 0);
-use crate::{fetcher::object_id::ObjectId, objects::person::ApubPerson};
+use crate::objects::person::ApubPerson;
use activitystreams::{activity::kind::AddType, unparsed::Unparsed};
+use lemmy_apub_lib::object_id::ObjectId;
use serde::{Deserialize, Serialize};
use url::Url;
-use crate::{
- activity_lists::AnnouncableActivities,
- fetcher::object_id::ObjectId,
- objects::community::ApubCommunity,
-};
+use crate::{activity_lists::AnnouncableActivities, objects::community::ApubCommunity};
use activitystreams::{activity::kind::AnnounceType, unparsed::Unparsed};
+use lemmy_apub_lib::object_id::ObjectId;
use serde::{Deserialize, Serialize};
use url::Url;
-use crate::{
- fetcher::object_id::ObjectId,
- objects::{community::ApubCommunity, person::ApubPerson},
-};
+use crate::objects::{community::ApubCommunity, person::ApubPerson};
use activitystreams::{activity::kind::BlockType, unparsed::Unparsed};
+use lemmy_apub_lib::object_id::ObjectId;
use serde::{Deserialize, Serialize};
use url::Url;
-use crate::{fetcher::object_id::ObjectId, objects::person::ApubPerson};
+use crate::objects::person::ApubPerson;
use activitystreams::{activity::kind::RemoveType, unparsed::Unparsed};
+use lemmy_apub_lib::object_id::ObjectId;
use serde::{Deserialize, Serialize};
use url::Url;
use crate::{
- fetcher::{object_id::ObjectId, post_or_comment::PostOrComment},
+ fetcher::post_or_comment::PostOrComment,
objects::{community::ApubCommunity, person::ApubPerson},
};
use activitystreams::{activity::kind::FlagType, unparsed::Unparsed};
+use lemmy_apub_lib::object_id::ObjectId;
use serde::{Deserialize, Serialize};
use url::Url;
use crate::{
- fetcher::object_id::ObjectId,
objects::person::ApubPerson,
protocol::activities::community::block_user::BlockUserFromCommunity,
};
use activitystreams::{activity::kind::UndoType, unparsed::Unparsed};
+use lemmy_apub_lib::object_id::ObjectId;
use serde::{Deserialize, Serialize};
use url::Url;
-use crate::{
- fetcher::object_id::ObjectId,
- objects::person::ApubPerson,
- protocol::objects::group::Group,
-};
+use crate::{objects::person::ApubPerson, protocol::objects::group::Group};
use activitystreams::{activity::kind::UpdateType, unparsed::Unparsed};
+use lemmy_apub_lib::object_id::ObjectId;
use serde::{Deserialize, Serialize};
use url::Url;
use crate::{
- fetcher::object_id::ObjectId,
objects::person::ApubPerson,
protocol::{activities::CreateOrUpdateType, objects::note::Note},
};
use activitystreams::{link::Mention, unparsed::Unparsed};
+use lemmy_apub_lib::object_id::ObjectId;
use serde::{Deserialize, Serialize};
use url::Url;
use crate::{
- fetcher::object_id::ObjectId,
objects::person::ApubPerson,
protocol::{activities::CreateOrUpdateType, objects::page::Page},
};
use activitystreams::unparsed::Unparsed;
+use lemmy_apub_lib::object_id::ObjectId;
use serde::{Deserialize, Serialize};
use url::Url;
-use crate::{fetcher::object_id::ObjectId, objects::person::ApubPerson};
+use crate::objects::person::ApubPerson;
use activitystreams::{activity::kind::DeleteType, unparsed::Unparsed};
+use lemmy_apub_lib::object_id::ObjectId;
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
use url::Url;
-use crate::{
- fetcher::object_id::ObjectId,
- objects::person::ApubPerson,
- protocol::activities::deletion::delete::Delete,
-};
+use crate::{objects::person::ApubPerson, protocol::activities::deletion::delete::Delete};
use activitystreams::{activity::kind::UndoType, unparsed::Unparsed};
+use lemmy_apub_lib::object_id::ObjectId;
use serde::{Deserialize, Serialize};
use url::Url;
use crate::{
- fetcher::object_id::ObjectId,
objects::{community::ApubCommunity, person::ApubPerson},
protocol::activities::following::follow::FollowCommunity,
};
use activitystreams::{activity::kind::AcceptType, unparsed::Unparsed};
+use lemmy_apub_lib::object_id::ObjectId;
use serde::{Deserialize, Serialize};
use url::Url;
-use crate::{
- fetcher::object_id::ObjectId,
- objects::{community::ApubCommunity, person::ApubPerson},
-};
+use crate::objects::{community::ApubCommunity, person::ApubPerson};
use activitystreams::{activity::kind::FollowType, unparsed::Unparsed};
+use lemmy_apub_lib::object_id::ObjectId;
use serde::{Deserialize, Serialize};
use url::Url;
use crate::{
- fetcher::object_id::ObjectId,
objects::{community::ApubCommunity, person::ApubPerson},
protocol::activities::following::follow::FollowCommunity,
};
use activitystreams::{activity::kind::UndoType, unparsed::Unparsed};
+use lemmy_apub_lib::object_id::ObjectId;
use serde::{Deserialize, Serialize};
use url::Url;
use crate::{
- fetcher::object_id::ObjectId,
objects::person::ApubPerson,
protocol::{activities::CreateOrUpdateType, objects::chat_message::ChatMessage},
};
use activitystreams::unparsed::Unparsed;
+use lemmy_apub_lib::object_id::ObjectId;
use serde::{Deserialize, Serialize};
use url::Url;
-use crate::{
- fetcher::object_id::ObjectId,
- objects::{person::ApubPerson, private_message::ApubPrivateMessage},
-};
+use crate::objects::{person::ApubPerson, private_message::ApubPrivateMessage};
use activitystreams::{activity::kind::DeleteType, unparsed::Unparsed};
+use lemmy_apub_lib::object_id::ObjectId;
use serde::{Deserialize, Serialize};
use url::Url;
use crate::{
- fetcher::object_id::ObjectId,
objects::person::ApubPerson,
protocol::activities::private_message::delete::DeletePrivateMessage,
};
use activitystreams::{activity::kind::UndoType, unparsed::Unparsed};
+use lemmy_apub_lib::object_id::ObjectId;
use serde::{Deserialize, Serialize};
use url::Url;
-use crate::{
- fetcher::object_id::ObjectId,
- objects::person::ApubPerson,
- protocol::activities::voting::vote::Vote,
-};
+use crate::{objects::person::ApubPerson, protocol::activities::voting::vote::Vote};
use activitystreams::{activity::kind::UndoType, unparsed::Unparsed};
+use lemmy_apub_lib::object_id::ObjectId;
use serde::{Deserialize, Serialize};
use url::Url;
-use crate::{
- fetcher::{object_id::ObjectId, post_or_comment::PostOrComment},
- objects::person::ApubPerson,
-};
+use crate::{fetcher::post_or_comment::PostOrComment, objects::person::ApubPerson};
use activitystreams::unparsed::Unparsed;
use anyhow::anyhow;
+use lemmy_apub_lib::object_id::ObjectId;
use lemmy_utils::LemmyError;
use serde::{Deserialize, Serialize};
use std::convert::TryFrom;
.await??;
Ok(GroupFollowers {
- id: generate_followers_url(&community.actor_id)?.into_inner(),
+ id: generate_followers_url(&community.actor_id)?.into(),
r#type: CollectionType::Collection,
total_items: community_followers.len() as i32,
items: vec![],
-use crate::{fetcher::object_id::ObjectId, objects::person::ApubPerson};
+use crate::objects::person::ApubPerson;
use activitystreams::collection::kind::OrderedCollectionType;
+use lemmy_apub_lib::object_id::ObjectId;
use serde::{Deserialize, Serialize};
use url::Url;
pub(crate) async fn new(user: Person) -> Result<PersonOutbox, LemmyError> {
Ok(PersonOutbox {
r#type: OrderedCollectionType::OrderedCollection,
- id: generate_outbox_url(&user.actor_id)?.into_inner(),
+ id: generate_outbox_url(&user.actor_id)?.into(),
ordered_items: vec![],
total_items: 0,
})
use crate::{
- fetcher::object_id::ObjectId,
objects::{person::ApubPerson, private_message::ApubPrivateMessage},
protocol::Source,
};
unparsed::Unparsed,
};
use anyhow::anyhow;
-use lemmy_apub_lib::{values::MediaTypeHtml, verify::verify_domains_match};
+use lemmy_apub_lib::{object_id::ObjectId, values::MediaTypeHtml, verify::verify_domains_match};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use serde::{Deserialize, Serialize};
community_moderators::ApubCommunityModerators,
community_outbox::ApubCommunityOutbox,
},
- fetcher::object_id::ObjectId,
objects::{community::ApubCommunity, get_summary_from_string_or_source},
protocol::{ImageObject, Source},
};
unparsed::Unparsed,
};
use chrono::{DateTime, FixedOffset};
-use lemmy_apub_lib::{signatures::PublicKey, verify::verify_domains_match};
+use lemmy_apub_lib::{object_id::ObjectId, signatures::PublicKey, verify::verify_domains_match};
use lemmy_db_schema::{naive_now, source::community::CommunityForm};
use lemmy_utils::{
settings::structs::Settings,
check_slurs(&title, slur_regex)?;
check_slurs_opt(&description, slur_regex)?;
+ // TODO: test_parse_lemmy_community_moderators() keeps failing here with stack overflow
Ok(CommunityForm {
name,
title,
use crate::{
activities::{verify_is_public, verify_person_in_community},
- fetcher::{object_id::ObjectId, post_or_comment::PostOrComment},
+ fetcher::post_or_comment::PostOrComment,
objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson, post::ApubPost},
protocol::Source,
};
use anyhow::anyhow;
use chrono::{DateTime, FixedOffset};
use lemmy_api_common::blocking;
-use lemmy_apub_lib::{values::MediaTypeHtml, verify::verify_domains_match};
+use lemmy_apub_lib::{object_id::ObjectId, values::MediaTypeHtml, verify::verify_domains_match};
use lemmy_db_schema::{
newtypes::CommentId,
source::{community::Community, post::Post},
use crate::{
activities::{verify_is_public, verify_person_in_community},
- fetcher::object_id::ObjectId,
objects::{community::ApubCommunity, person::ApubPerson, post::ApubPost},
protocol::{ImageObject, Source},
};
use activitystreams::{object::kind::PageType, unparsed::Unparsed};
use anyhow::anyhow;
use chrono::{DateTime, FixedOffset};
-use lemmy_apub_lib::{values::MediaTypeHtml, verify::verify_domains_match};
+use lemmy_apub_lib::{object_id::ObjectId, values::MediaTypeHtml, verify::verify_domains_match};
use lemmy_utils::{utils::check_slurs, LemmyError};
use lemmy_websocket::LemmyContext;
use serde::{Deserialize, Serialize};
use crate::{
- fetcher::object_id::ObjectId,
objects::person::ApubPerson,
protocol::{ImageObject, Source},
};
use activitystreams::{actor::Endpoints, unparsed::Unparsed, url::Url};
use chrono::{DateTime, FixedOffset};
-use lemmy_apub_lib::signatures::PublicKey;
+use lemmy_apub_lib::{object_id::ObjectId, signatures::PublicKey};
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
http-signature-normalization-actix = { version = "0.5.0-beta.10", default-features = false, features = ["server", "sha-2"] }
http-signature-normalization-reqwest = { version = "0.2.0", default-features = false, features = ["sha-2"] }
background-jobs = "0.9.1"
+diesel = "1.4.8"
pub mod activity_queue;
pub mod data;
+pub mod object_id;
pub mod signatures;
pub mod traits;
pub mod values;
-use crate::fetcher::should_refetch_object;
+use crate::{traits::ApubObject, APUB_JSON_CONTENT_TYPE};
+use activitystreams::chrono::{Duration as ChronoDuration, NaiveDateTime, Utc};
use anyhow::anyhow;
use diesel::NotFound;
-use lemmy_apub_lib::{traits::ApubObject, APUB_JSON_CONTENT_TYPE};
-use lemmy_db_schema::newtypes::DbUrl;
use lemmy_utils::{
request::{build_user_agent, retry},
settings::structs::Settings,
}
}
+static ACTOR_REFETCH_INTERVAL_SECONDS: i64 = 24 * 60 * 60;
+static ACTOR_REFETCH_INTERVAL_SECONDS_DEBUG: i64 = 10;
+
+/// Determines when a remote actor should be refetched from its instance. In release builds, this is
+/// `ACTOR_REFETCH_INTERVAL_SECONDS` after the last refetch, in debug builds
+/// `ACTOR_REFETCH_INTERVAL_SECONDS_DEBUG`.
+///
+/// TODO it won't pick up new avatars, summaries etc until a day after.
+/// Actors need an "update" activity pushed to other servers to fix this.
+fn should_refetch_object(last_refreshed: NaiveDateTime) -> bool {
+ let update_interval = if cfg!(debug_assertions) {
+ // avoid infinite loop when fetching community outbox
+ ChronoDuration::seconds(ACTOR_REFETCH_INTERVAL_SECONDS_DEBUG)
+ } else {
+ ChronoDuration::seconds(ACTOR_REFETCH_INTERVAL_SECONDS)
+ };
+ let refresh_limit = Utc::now().naive_utc() - update_interval;
+ last_refreshed.lt(&refresh_limit)
+}
+
impl<Kind> Display for ObjectId<Kind>
where
Kind: ApubObject + Send + 'static,
for<'de2> <Kind as ApubObject>::ApubType: serde::Deserialize<'de2>,
{
+ #[allow(clippy::to_string_in_display)]
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+ // Use to_string here because Url.display is not useful for us
write!(f, "{}", self.0.to_string())
}
}
}
}
-impl<Kind> From<ObjectId<Kind>> for DbUrl
-where
- Kind: ApubObject + Send + 'static,
- for<'de2> <Kind as ApubObject>::ApubType: serde::Deserialize<'de2>,
-{
- fn from(id: ObjectId<Kind>) -> Self {
- id.0.into()
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::object_id::should_refetch_object;
+
+ #[test]
+ fn test_should_refetch_object() {
+ let one_second_ago = Utc::now().naive_utc() - ChronoDuration::seconds(1);
+ assert!(!should_refetch_object(one_second_ago));
+
+ let two_days_ago = Utc::now().naive_utc() - ChronoDuration::days(2);
+ assert!(should_refetch_object(two_days_ago));
}
}
[dependencies]
lemmy_utils = { version = "=0.13.5-rc.7", path = "../utils" }
+lemmy_apub_lib = { version = "=0.13.5-rc.7", path = "../apub_lib" }
diesel = { version = "1.4.8", features = ["postgres","chrono","r2d2","serde_json"] }
diesel_migrations = "1.4.0"
chrono = { version = "0.4.19", features = ["serde"] }
serialize::{Output, ToSql},
sql_types::Text,
};
+use lemmy_apub_lib::{object_id::ObjectId, traits::ApubObject};
use serde::{Deserialize, Serialize};
use std::{
fmt,
}
}
-impl DbUrl {
- // TODO: remove this method and just use into()
- pub fn into_inner(self) -> Url {
- self.0
- }
-}
-
impl Display for DbUrl {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.to_owned().0.fmt(f)
}
}
-impl From<DbUrl> for Url {
- fn from(url: DbUrl) -> Self {
- url.0
+// the project doesnt compile with From
+#[allow(clippy::from_over_into)]
+impl Into<DbUrl> for Url {
+ fn into(self) -> DbUrl {
+ DbUrl(self)
+ }
+}
+#[allow(clippy::from_over_into)]
+impl Into<Url> for DbUrl {
+ fn into(self) -> Url {
+ self.0
}
}
-impl From<Url> for DbUrl {
- fn from(url: Url) -> Self {
- DbUrl(url)
+impl<Kind> From<ObjectId<Kind>> for DbUrl
+where
+ Kind: ApubObject + Send + 'static,
+ for<'de2> <Kind as ApubObject>::ApubType: serde::Deserialize<'de2>,
+{
+ fn from(id: ObjectId<Kind>) -> Self {
+ DbUrl(id.into())
}
}