fmt
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
pub mod composite_handler;
|
pub mod composite_handler;
|
||||||
pub mod social_adapter;
|
|
||||||
pub mod event_handler;
|
pub mod event_handler;
|
||||||
pub mod federation_event_bridge;
|
pub mod federation_event_bridge;
|
||||||
pub mod goal_handler;
|
pub mod goal_handler;
|
||||||
@@ -7,6 +6,7 @@ pub mod objects;
|
|||||||
pub mod port;
|
pub mod port;
|
||||||
pub mod remote_review_repository;
|
pub mod remote_review_repository;
|
||||||
pub mod review_handler;
|
pub mod review_handler;
|
||||||
|
pub mod social_adapter;
|
||||||
pub(crate) mod urls;
|
pub(crate) mod urls;
|
||||||
pub mod user_adapter;
|
pub mod user_adapter;
|
||||||
pub mod watchlist_handler;
|
pub mod watchlist_handler;
|
||||||
|
|||||||
@@ -87,11 +87,7 @@ fn ap_err(e: anyhow::Error) -> DomainError {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl SocialCommand for CompositeSocialAdapter {
|
impl SocialCommand for CompositeSocialAdapter {
|
||||||
async fn follow(
|
async fn follow(&self, follower: &UserId, target: &SocialIdentity) -> Result<(), DomainError> {
|
||||||
&self,
|
|
||||||
follower: &UserId,
|
|
||||||
target: &SocialIdentity,
|
|
||||||
) -> Result<(), DomainError> {
|
|
||||||
if let SocialIdentity::Local(target_id) = target
|
if let SocialIdentity::Local(target_id) = target
|
||||||
&& follower == target_id
|
&& follower == target_id
|
||||||
{
|
{
|
||||||
@@ -154,11 +150,7 @@ impl SocialCommand for CompositeSocialAdapter {
|
|||||||
.map_err(ap_err)
|
.map_err(ap_err)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn block(
|
async fn block(&self, blocker: &UserId, target: &SocialIdentity) -> Result<(), DomainError> {
|
||||||
&self,
|
|
||||||
blocker: &UserId,
|
|
||||||
target: &SocialIdentity,
|
|
||||||
) -> Result<(), DomainError> {
|
|
||||||
let actor_url = self.actor_url_from_identity(target);
|
let actor_url = self.actor_url_from_identity(target);
|
||||||
self.ap_service
|
self.ap_service
|
||||||
.block_actor(blocker.value(), &actor_url)
|
.block_actor(blocker.value(), &actor_url)
|
||||||
@@ -166,11 +158,7 @@ impl SocialCommand for CompositeSocialAdapter {
|
|||||||
.map_err(ap_err)
|
.map_err(ap_err)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn unblock(
|
async fn unblock(&self, blocker: &UserId, target: &SocialIdentity) -> Result<(), DomainError> {
|
||||||
&self,
|
|
||||||
blocker: &UserId,
|
|
||||||
target: &SocialIdentity,
|
|
||||||
) -> Result<(), DomainError> {
|
|
||||||
let actor_url = self.actor_url_from_identity(target);
|
let actor_url = self.actor_url_from_identity(target);
|
||||||
self.ap_service
|
self.ap_service
|
||||||
.unblock_actor(blocker.value(), &actor_url)
|
.unblock_actor(blocker.value(), &actor_url)
|
||||||
@@ -181,10 +169,7 @@ impl SocialCommand for CompositeSocialAdapter {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl SocialQuery for CompositeSocialAdapter {
|
impl SocialQuery for CompositeSocialAdapter {
|
||||||
async fn get_following(
|
async fn get_following(&self, user: &UserId) -> Result<Vec<SocialActor>, DomainError> {
|
||||||
&self,
|
|
||||||
user: &UserId,
|
|
||||||
) -> Result<Vec<SocialActor>, DomainError> {
|
|
||||||
let actors = self
|
let actors = self
|
||||||
.ap_service
|
.ap_service
|
||||||
.get_following(user.value())
|
.get_following(user.value())
|
||||||
@@ -196,10 +181,7 @@ impl SocialQuery for CompositeSocialAdapter {
|
|||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_followers(
|
async fn get_followers(&self, user: &UserId) -> Result<Vec<SocialActor>, DomainError> {
|
||||||
&self,
|
|
||||||
user: &UserId,
|
|
||||||
) -> Result<Vec<SocialActor>, DomainError> {
|
|
||||||
let actors = self
|
let actors = self
|
||||||
.ap_service
|
.ap_service
|
||||||
.get_accepted_followers(user.value())
|
.get_accepted_followers(user.value())
|
||||||
@@ -211,10 +193,7 @@ impl SocialQuery for CompositeSocialAdapter {
|
|||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_pending_followers(
|
async fn get_pending_followers(&self, user: &UserId) -> Result<Vec<SocialActor>, DomainError> {
|
||||||
&self,
|
|
||||||
user: &UserId,
|
|
||||||
) -> Result<Vec<SocialActor>, DomainError> {
|
|
||||||
let actors = self
|
let actors = self
|
||||||
.ap_service
|
.ap_service
|
||||||
.get_pending_followers(user.value())
|
.get_pending_followers(user.value())
|
||||||
@@ -240,10 +219,7 @@ impl SocialQuery for CompositeSocialAdapter {
|
|||||||
.map_err(ap_err)
|
.map_err(ap_err)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_blocked(
|
async fn get_blocked(&self, user: &UserId) -> Result<Vec<SocialActor>, DomainError> {
|
||||||
&self,
|
|
||||||
user: &UserId,
|
|
||||||
) -> Result<Vec<SocialActor>, DomainError> {
|
|
||||||
let actors = self
|
let actors = self
|
||||||
.ap_service
|
.ap_service
|
||||||
.get_blocked_actors(user.value())
|
.get_blocked_actors(user.value())
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use domain::{
|
use domain::{errors::DomainError, models::RemoteActorInfo, ports::FederationAdminQuery};
|
||||||
errors::DomainError,
|
|
||||||
models::RemoteActorInfo,
|
|
||||||
ports::FederationAdminQuery,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::PostgresFederationRepository;
|
use super::PostgresFederationRepository;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use domain::{
|
use domain::{errors::DomainError, models::RemoteActorInfo, ports::FederationAdminQuery};
|
||||||
errors::DomainError,
|
|
||||||
models::RemoteActorInfo,
|
|
||||||
ports::FederationAdminQuery,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::SqliteFederationRepository;
|
use super::SqliteFederationRepository;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
use domain::{errors::DomainError, value_objects::{SocialActor, UserId}};
|
use domain::{
|
||||||
|
errors::DomainError,
|
||||||
|
value_objects::{SocialActor, UserId},
|
||||||
|
};
|
||||||
|
|
||||||
use super::{deps::SocialQueryDeps, queries::GetBlockedQuery};
|
use super::{deps::SocialQueryDeps, queries::GetBlockedQuery};
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
use domain::{errors::DomainError, value_objects::{SocialActor, UserId}};
|
use domain::{
|
||||||
|
errors::DomainError,
|
||||||
|
value_objects::{SocialActor, UserId},
|
||||||
|
};
|
||||||
|
|
||||||
use super::{deps::SocialQueryDeps, queries::GetFollowersQuery};
|
use super::{deps::SocialQueryDeps, queries::GetFollowersQuery};
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
use domain::{errors::DomainError, value_objects::{SocialActor, UserId}};
|
use domain::{
|
||||||
|
errors::DomainError,
|
||||||
|
value_objects::{SocialActor, UserId},
|
||||||
|
};
|
||||||
|
|
||||||
use super::{deps::SocialQueryDeps, queries::GetFollowingQuery};
|
use super::{deps::SocialQueryDeps, queries::GetFollowingQuery};
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
use domain::{errors::DomainError, value_objects::{SocialActor, UserId}};
|
use domain::{
|
||||||
|
errors::DomainError,
|
||||||
|
value_objects::{SocialActor, UserId},
|
||||||
|
};
|
||||||
|
|
||||||
use super::{deps::SocialQueryDeps, queries::GetPendingFollowersQuery};
|
use super::{deps::SocialQueryDeps, queries::GetPendingFollowersQuery};
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,11 @@ use crate::social::{
|
|||||||
follow,
|
follow,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn make_deps() -> (Arc<InMemorySocialRepository>, Arc<NoopEventPublisher>, SocialCommandDeps) {
|
fn make_deps() -> (
|
||||||
|
Arc<InMemorySocialRepository>,
|
||||||
|
Arc<NoopEventPublisher>,
|
||||||
|
SocialCommandDeps,
|
||||||
|
) {
|
||||||
let social = InMemorySocialRepository::new();
|
let social = InMemorySocialRepository::new();
|
||||||
let events = NoopEventPublisher::new();
|
let events = NoopEventPublisher::new();
|
||||||
let deps = SocialCommandDeps {
|
let deps = SocialCommandDeps {
|
||||||
@@ -53,7 +57,9 @@ async fn accept_follow_emits_follow_accepted_event() {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let published = events.published();
|
let published = events.published();
|
||||||
assert!(published
|
assert!(
|
||||||
|
published
|
||||||
.iter()
|
.iter()
|
||||||
.any(|e| matches!(e, DomainEvent::FollowAccepted { .. })));
|
.any(|e| matches!(e, DomainEvent::FollowAccepted { .. }))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,11 @@ use uuid::Uuid;
|
|||||||
|
|
||||||
use crate::social::{block, commands::BlockCommand, deps::SocialCommandDeps};
|
use crate::social::{block, commands::BlockCommand, deps::SocialCommandDeps};
|
||||||
|
|
||||||
fn make_deps() -> (Arc<InMemorySocialRepository>, Arc<NoopEventPublisher>, SocialCommandDeps) {
|
fn make_deps() -> (
|
||||||
|
Arc<InMemorySocialRepository>,
|
||||||
|
Arc<NoopEventPublisher>,
|
||||||
|
SocialCommandDeps,
|
||||||
|
) {
|
||||||
let social = InMemorySocialRepository::new();
|
let social = InMemorySocialRepository::new();
|
||||||
let events = NoopEventPublisher::new();
|
let events = NoopEventPublisher::new();
|
||||||
let deps = SocialCommandDeps {
|
let deps = SocialCommandDeps {
|
||||||
@@ -35,7 +39,9 @@ async fn block_emits_actor_blocked_event() {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let published = events.published();
|
let published = events.published();
|
||||||
assert!(published
|
assert!(
|
||||||
|
published
|
||||||
.iter()
|
.iter()
|
||||||
.any(|e| matches!(e, DomainEvent::ActorBlocked { .. })));
|
.any(|e| matches!(e, DomainEvent::ActorBlocked { .. }))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,11 @@ use uuid::Uuid;
|
|||||||
|
|
||||||
use crate::social::{commands::FollowCommand, deps::SocialCommandDeps, follow};
|
use crate::social::{commands::FollowCommand, deps::SocialCommandDeps, follow};
|
||||||
|
|
||||||
fn make_deps() -> (Arc<InMemorySocialRepository>, Arc<NoopEventPublisher>, SocialCommandDeps) {
|
fn make_deps() -> (
|
||||||
|
Arc<InMemorySocialRepository>,
|
||||||
|
Arc<NoopEventPublisher>,
|
||||||
|
SocialCommandDeps,
|
||||||
|
) {
|
||||||
let social = InMemorySocialRepository::new();
|
let social = InMemorySocialRepository::new();
|
||||||
let events = NoopEventPublisher::new();
|
let events = NoopEventPublisher::new();
|
||||||
let deps = SocialCommandDeps {
|
let deps = SocialCommandDeps {
|
||||||
@@ -35,9 +39,11 @@ async fn follow_emits_follow_requested_event() {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let published = events.published();
|
let published = events.published();
|
||||||
assert!(published
|
assert!(
|
||||||
|
published
|
||||||
.iter()
|
.iter()
|
||||||
.any(|e| matches!(e, DomainEvent::FollowRequested { .. })));
|
.any(|e| matches!(e, DomainEvent::FollowRequested { .. }))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
|||||||
@@ -50,12 +50,7 @@ async fn returns_accepted_followers() {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let followers = get_followers::execute(
|
let followers = get_followers::execute(&query_deps, GetFollowersQuery { user_id: owner_id })
|
||||||
&query_deps,
|
|
||||||
GetFollowersQuery {
|
|
||||||
user_id: owner_id,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(followers.len(), 1);
|
assert_eq!(followers.len(), 1);
|
||||||
|
|||||||
@@ -39,12 +39,7 @@ async fn returns_only_pending_followers() {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let pending = get_pending::execute(
|
let pending = get_pending::execute(&query_deps, GetPendingFollowersQuery { user_id: owner_id })
|
||||||
&query_deps,
|
|
||||||
GetPendingFollowersQuery {
|
|
||||||
user_id: owner_id,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(pending.len(), 1);
|
assert_eq!(pending.len(), 1);
|
||||||
|
|||||||
@@ -12,7 +12,11 @@ use crate::social::{
|
|||||||
follow, reject,
|
follow, reject,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn make_deps() -> (Arc<InMemorySocialRepository>, Arc<NoopEventPublisher>, SocialCommandDeps) {
|
fn make_deps() -> (
|
||||||
|
Arc<InMemorySocialRepository>,
|
||||||
|
Arc<NoopEventPublisher>,
|
||||||
|
SocialCommandDeps,
|
||||||
|
) {
|
||||||
let social = InMemorySocialRepository::new();
|
let social = InMemorySocialRepository::new();
|
||||||
let events = NoopEventPublisher::new();
|
let events = NoopEventPublisher::new();
|
||||||
let deps = SocialCommandDeps {
|
let deps = SocialCommandDeps {
|
||||||
|
|||||||
@@ -14,7 +14,11 @@ use crate::social::{
|
|||||||
follow, remove_follower,
|
follow, remove_follower,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn make_deps() -> (Arc<InMemorySocialRepository>, Arc<NoopEventPublisher>, SocialCommandDeps) {
|
fn make_deps() -> (
|
||||||
|
Arc<InMemorySocialRepository>,
|
||||||
|
Arc<NoopEventPublisher>,
|
||||||
|
SocialCommandDeps,
|
||||||
|
) {
|
||||||
let social = InMemorySocialRepository::new();
|
let social = InMemorySocialRepository::new();
|
||||||
let events = NoopEventPublisher::new();
|
let events = NoopEventPublisher::new();
|
||||||
let deps = SocialCommandDeps {
|
let deps = SocialCommandDeps {
|
||||||
@@ -62,7 +66,9 @@ async fn remove_follower_emits_follower_removed_event() {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let published = events.published();
|
let published = events.published();
|
||||||
assert!(published
|
assert!(
|
||||||
|
published
|
||||||
.iter()
|
.iter()
|
||||||
.any(|e| matches!(e, DomainEvent::FollowerRemoved { .. })));
|
.any(|e| matches!(e, DomainEvent::FollowerRemoved { .. }))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,12 +8,17 @@ use domain::{
|
|||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::social::{
|
use crate::social::{
|
||||||
|
block,
|
||||||
commands::{BlockCommand, UnblockCommand},
|
commands::{BlockCommand, UnblockCommand},
|
||||||
deps::SocialCommandDeps,
|
deps::SocialCommandDeps,
|
||||||
block, unblock,
|
unblock,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn make_deps() -> (Arc<InMemorySocialRepository>, Arc<NoopEventPublisher>, SocialCommandDeps) {
|
fn make_deps() -> (
|
||||||
|
Arc<InMemorySocialRepository>,
|
||||||
|
Arc<NoopEventPublisher>,
|
||||||
|
SocialCommandDeps,
|
||||||
|
) {
|
||||||
let social = InMemorySocialRepository::new();
|
let social = InMemorySocialRepository::new();
|
||||||
let events = NoopEventPublisher::new();
|
let events = NoopEventPublisher::new();
|
||||||
let deps = SocialCommandDeps {
|
let deps = SocialCommandDeps {
|
||||||
@@ -40,18 +45,14 @@ async fn unblock_emits_actor_unblocked_event() {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
unblock::execute(
|
unblock::execute(&deps, UnblockCommand { blocker_id, target })
|
||||||
&deps,
|
|
||||||
UnblockCommand {
|
|
||||||
blocker_id,
|
|
||||||
target,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let published = events.published();
|
let published = events.published();
|
||||||
assert!(published
|
assert!(
|
||||||
|
published
|
||||||
.iter()
|
.iter()
|
||||||
.any(|e| matches!(e, DomainEvent::ActorUnblocked { .. })));
|
.any(|e| matches!(e, DomainEvent::ActorUnblocked { .. }))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,11 @@ use crate::social::{
|
|||||||
follow, unfollow,
|
follow, unfollow,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn make_deps() -> (Arc<InMemorySocialRepository>, Arc<NoopEventPublisher>, SocialCommandDeps) {
|
fn make_deps() -> (
|
||||||
|
Arc<InMemorySocialRepository>,
|
||||||
|
Arc<NoopEventPublisher>,
|
||||||
|
SocialCommandDeps,
|
||||||
|
) {
|
||||||
let social = InMemorySocialRepository::new();
|
let social = InMemorySocialRepository::new();
|
||||||
let events = NoopEventPublisher::new();
|
let events = NoopEventPublisher::new();
|
||||||
let deps = SocialCommandDeps {
|
let deps = SocialCommandDeps {
|
||||||
@@ -51,7 +55,9 @@ async fn unfollow_emits_unfollowed_event() {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let published = events.published();
|
let published = events.published();
|
||||||
assert!(published
|
assert!(
|
||||||
|
published
|
||||||
.iter()
|
.iter()
|
||||||
.any(|e| matches!(e, DomainEvent::Unfollowed { .. })));
|
.any(|e| matches!(e, DomainEvent::Unfollowed { .. }))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,7 @@ use super::{commands::UnfollowCommand, deps::SocialCommandDeps};
|
|||||||
|
|
||||||
pub async fn execute(deps: &SocialCommandDeps, cmd: UnfollowCommand) -> Result<(), DomainError> {
|
pub async fn execute(deps: &SocialCommandDeps, cmd: UnfollowCommand) -> Result<(), DomainError> {
|
||||||
let follower = UserId::from_uuid(cmd.follower_id);
|
let follower = UserId::from_uuid(cmd.follower_id);
|
||||||
deps.social_command
|
deps.social_command.unfollow(&follower, &cmd.target).await?;
|
||||||
.unfollow(&follower, &cmd.target)
|
|
||||||
.await?;
|
|
||||||
deps.event_publisher
|
deps.event_publisher
|
||||||
.publish(&DomainEvent::Unfollowed {
|
.publish(&DomainEvent::Unfollowed {
|
||||||
follower,
|
follower,
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ use chrono::NaiveDateTime;
|
|||||||
use crate::{
|
use crate::{
|
||||||
errors::DomainError,
|
errors::DomainError,
|
||||||
models::{
|
models::{
|
||||||
DiaryEntry, FederationFlags, RemoteActorInfo, RemoteGoalEntry,
|
DiaryEntry, FederationFlags, RemoteActorInfo, RemoteGoalEntry, RemoteWatchlistEntry,
|
||||||
RemoteWatchlistEntry, WatchlistWithMovie,
|
WatchlistWithMovie,
|
||||||
},
|
},
|
||||||
value_objects::{MovieId, SocialActor, SocialIdentity, UserId},
|
value_objects::{MovieId, SocialActor, SocialIdentity, UserId},
|
||||||
};
|
};
|
||||||
@@ -14,17 +14,10 @@ use crate::{
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait SocialCommand: Send + Sync {
|
pub trait SocialCommand: Send + Sync {
|
||||||
async fn follow(
|
async fn follow(&self, follower: &UserId, target: &SocialIdentity) -> Result<(), DomainError>;
|
||||||
&self,
|
|
||||||
follower: &UserId,
|
|
||||||
target: &SocialIdentity,
|
|
||||||
) -> Result<(), DomainError>;
|
|
||||||
|
|
||||||
async fn unfollow(
|
async fn unfollow(&self, follower: &UserId, target: &SocialIdentity)
|
||||||
&self,
|
-> Result<(), DomainError>;
|
||||||
follower: &UserId,
|
|
||||||
target: &SocialIdentity,
|
|
||||||
) -> Result<(), DomainError>;
|
|
||||||
|
|
||||||
async fn accept_follow(
|
async fn accept_follow(
|
||||||
&self,
|
&self,
|
||||||
@@ -44,44 +37,24 @@ pub trait SocialCommand: Send + Sync {
|
|||||||
follower: &SocialIdentity,
|
follower: &SocialIdentity,
|
||||||
) -> Result<(), DomainError>;
|
) -> Result<(), DomainError>;
|
||||||
|
|
||||||
async fn block(
|
async fn block(&self, blocker: &UserId, target: &SocialIdentity) -> Result<(), DomainError>;
|
||||||
&self,
|
|
||||||
blocker: &UserId,
|
|
||||||
target: &SocialIdentity,
|
|
||||||
) -> Result<(), DomainError>;
|
|
||||||
|
|
||||||
async fn unblock(
|
async fn unblock(&self, blocker: &UserId, target: &SocialIdentity) -> Result<(), DomainError>;
|
||||||
&self,
|
|
||||||
blocker: &UserId,
|
|
||||||
target: &SocialIdentity,
|
|
||||||
) -> Result<(), DomainError>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait SocialQuery: Send + Sync {
|
pub trait SocialQuery: Send + Sync {
|
||||||
async fn get_following(
|
async fn get_following(&self, user: &UserId) -> Result<Vec<SocialActor>, DomainError>;
|
||||||
&self,
|
|
||||||
user: &UserId,
|
|
||||||
) -> Result<Vec<SocialActor>, DomainError>;
|
|
||||||
|
|
||||||
async fn get_followers(
|
async fn get_followers(&self, user: &UserId) -> Result<Vec<SocialActor>, DomainError>;
|
||||||
&self,
|
|
||||||
user: &UserId,
|
|
||||||
) -> Result<Vec<SocialActor>, DomainError>;
|
|
||||||
|
|
||||||
async fn get_pending_followers(
|
async fn get_pending_followers(&self, user: &UserId) -> Result<Vec<SocialActor>, DomainError>;
|
||||||
&self,
|
|
||||||
user: &UserId,
|
|
||||||
) -> Result<Vec<SocialActor>, DomainError>;
|
|
||||||
|
|
||||||
async fn count_following(&self, user: &UserId) -> Result<usize, DomainError>;
|
async fn count_following(&self, user: &UserId) -> Result<usize, DomainError>;
|
||||||
|
|
||||||
async fn count_followers(&self, user: &UserId) -> Result<usize, DomainError>;
|
async fn count_followers(&self, user: &UserId) -> Result<usize, DomainError>;
|
||||||
|
|
||||||
async fn get_blocked(
|
async fn get_blocked(&self, user: &UserId) -> Result<Vec<SocialActor>, DomainError>;
|
||||||
&self,
|
|
||||||
user: &UserId,
|
|
||||||
) -> Result<Vec<SocialActor>, DomainError>;
|
|
||||||
|
|
||||||
async fn is_following(
|
async fn is_following(
|
||||||
&self,
|
&self,
|
||||||
@@ -93,7 +66,6 @@ pub trait SocialQuery: Send + Sync {
|
|||||||
&self,
|
&self,
|
||||||
user_id: &UserId,
|
user_id: &UserId,
|
||||||
) -> Result<Vec<String>, DomainError>;
|
) -> Result<Vec<String>, DomainError>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
|
|||||||
@@ -893,11 +893,7 @@ impl InMemorySocialRepository {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl SocialCommand for InMemorySocialRepository {
|
impl SocialCommand for InMemorySocialRepository {
|
||||||
async fn follow(
|
async fn follow(&self, follower: &UserId, target: &SocialIdentity) -> Result<(), DomainError> {
|
||||||
&self,
|
|
||||||
follower: &UserId,
|
|
||||||
target: &SocialIdentity,
|
|
||||||
) -> Result<(), DomainError> {
|
|
||||||
if let SocialIdentity::Local(target_id) = target {
|
if let SocialIdentity::Local(target_id) = target {
|
||||||
if follower == target_id {
|
if follower == target_id {
|
||||||
return Err(DomainError::ValidationError(
|
return Err(DomainError::ValidationError(
|
||||||
@@ -925,7 +921,9 @@ impl SocialCommand for InMemorySocialRepository {
|
|||||||
let before = store.len();
|
let before = store.len();
|
||||||
store.retain(|(f, t, _)| !(*f == follower.value() && t == target));
|
store.retain(|(f, t, _)| !(*f == follower.value() && t == target));
|
||||||
if store.len() == before {
|
if store.len() == before {
|
||||||
return Err(DomainError::NotFound("Follow relationship not found".into()));
|
return Err(DomainError::NotFound(
|
||||||
|
"Follow relationship not found".into(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -1008,11 +1006,7 @@ impl SocialCommand for InMemorySocialRepository {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn block(
|
async fn block(&self, blocker: &UserId, target: &SocialIdentity) -> Result<(), DomainError> {
|
||||||
&self,
|
|
||||||
blocker: &UserId,
|
|
||||||
target: &SocialIdentity,
|
|
||||||
) -> Result<(), DomainError> {
|
|
||||||
let mut store = self.blocked.lock().unwrap();
|
let mut store = self.blocked.lock().unwrap();
|
||||||
store.push((blocker.value(), target.clone()));
|
store.push((blocker.value(), target.clone()));
|
||||||
// Also remove any existing follow relationships
|
// Also remove any existing follow relationships
|
||||||
@@ -1021,11 +1015,7 @@ impl SocialCommand for InMemorySocialRepository {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn unblock(
|
async fn unblock(&self, blocker: &UserId, target: &SocialIdentity) -> Result<(), DomainError> {
|
||||||
&self,
|
|
||||||
blocker: &UserId,
|
|
||||||
target: &SocialIdentity,
|
|
||||||
) -> Result<(), DomainError> {
|
|
||||||
let mut store = self.blocked.lock().unwrap();
|
let mut store = self.blocked.lock().unwrap();
|
||||||
store.retain(|(b, t)| !(*b == blocker.value() && t == target));
|
store.retain(|(b, t)| !(*b == blocker.value() && t == target));
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -1034,10 +1024,7 @@ impl SocialCommand for InMemorySocialRepository {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl SocialQuery for InMemorySocialRepository {
|
impl SocialQuery for InMemorySocialRepository {
|
||||||
async fn get_following(
|
async fn get_following(&self, user: &UserId) -> Result<Vec<SocialActor>, DomainError> {
|
||||||
&self,
|
|
||||||
user: &UserId,
|
|
||||||
) -> Result<Vec<SocialActor>, DomainError> {
|
|
||||||
let store = self.follows.lock().unwrap();
|
let store = self.follows.lock().unwrap();
|
||||||
Ok(store
|
Ok(store
|
||||||
.iter()
|
.iter()
|
||||||
@@ -1046,10 +1033,7 @@ impl SocialQuery for InMemorySocialRepository {
|
|||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_followers(
|
async fn get_followers(&self, user: &UserId) -> Result<Vec<SocialActor>, DomainError> {
|
||||||
&self,
|
|
||||||
user: &UserId,
|
|
||||||
) -> Result<Vec<SocialActor>, DomainError> {
|
|
||||||
let store = self.follows.lock().unwrap();
|
let store = self.follows.lock().unwrap();
|
||||||
let target = SocialIdentity::Local(user.clone());
|
let target = SocialIdentity::Local(user.clone());
|
||||||
Ok(store
|
Ok(store
|
||||||
@@ -1062,10 +1046,7 @@ impl SocialQuery for InMemorySocialRepository {
|
|||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_pending_followers(
|
async fn get_pending_followers(&self, user: &UserId) -> Result<Vec<SocialActor>, DomainError> {
|
||||||
&self,
|
|
||||||
user: &UserId,
|
|
||||||
) -> Result<Vec<SocialActor>, DomainError> {
|
|
||||||
let store = self.follows.lock().unwrap();
|
let store = self.follows.lock().unwrap();
|
||||||
let target = SocialIdentity::Local(user.clone());
|
let target = SocialIdentity::Local(user.clone());
|
||||||
Ok(store
|
Ok(store
|
||||||
@@ -1095,10 +1076,7 @@ impl SocialQuery for InMemorySocialRepository {
|
|||||||
.count())
|
.count())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_blocked(
|
async fn get_blocked(&self, user: &UserId) -> Result<Vec<SocialActor>, DomainError> {
|
||||||
&self,
|
|
||||||
user: &UserId,
|
|
||||||
) -> Result<Vec<SocialActor>, DomainError> {
|
|
||||||
let store = self.blocked.lock().unwrap();
|
let store = self.blocked.lock().unwrap();
|
||||||
Ok(store
|
Ok(store
|
||||||
.iter()
|
.iter()
|
||||||
@@ -1113,9 +1091,9 @@ impl SocialQuery for InMemorySocialRepository {
|
|||||||
target: &SocialIdentity,
|
target: &SocialIdentity,
|
||||||
) -> Result<bool, DomainError> {
|
) -> Result<bool, DomainError> {
|
||||||
let store = self.follows.lock().unwrap();
|
let store = self.follows.lock().unwrap();
|
||||||
Ok(store
|
Ok(store.iter().any(|(f, t, state)| {
|
||||||
.iter()
|
*f == follower.value() && t == target && *state == FollowState::Accepted
|
||||||
.any(|(f, t, state)| *f == follower.value() && t == target && *state == FollowState::Accepted))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_accepted_following_urls(
|
async fn get_accepted_following_urls(
|
||||||
|
|||||||
@@ -64,8 +64,8 @@ impl ObjectStorage for NoopObjectStorage {
|
|||||||
|
|
||||||
// Re-export production noop types so test code that imports from
|
// Re-export production noop types so test code that imports from
|
||||||
// `domain::testing` keeps compiling without changes.
|
// `domain::testing` keeps compiling without changes.
|
||||||
pub use crate::ports::noop::NoopRemoteWatchlistRepository;
|
|
||||||
pub use crate::ports::noop::NoopFederationAdminQuery;
|
pub use crate::ports::noop::NoopFederationAdminQuery;
|
||||||
|
pub use crate::ports::noop::NoopRemoteWatchlistRepository;
|
||||||
|
|
||||||
// ── NoopGoalCommand ───────────────────────────────────────────────────────────
|
// ── NoopGoalCommand ───────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ use crate::{
|
|||||||
AnnotatedRow, DiaryEntry, DiaryFilter, EntityType, ExportFormat, ExternalPersonId,
|
AnnotatedRow, DiaryEntry, DiaryFilter, EntityType, ExportFormat, ExternalPersonId,
|
||||||
FeedEntry, FeedSortBy, FieldMapping, FileFormat, FollowingFilter, ImportError,
|
FeedEntry, FeedSortBy, FieldMapping, FileFormat, FollowingFilter, ImportError,
|
||||||
ImportProfile, ImportSession, IndexableDocument, MovieProfile, MovieStats, ParsedFile,
|
ImportProfile, ImportSession, IndexableDocument, MovieProfile, MovieStats, ParsedFile,
|
||||||
Person, PersonCredits, PersonEnrichmentData, PersonId, RefreshSession,
|
Person, PersonCredits, PersonEnrichmentData, PersonId, RefreshSession, RemoteActorInfo,
|
||||||
RemoteActorInfo, ReviewHistory, SearchQuery, SearchResults, UserStats, UserTrends,
|
ReviewHistory, SearchQuery, SearchResults, UserStats, UserTrends,
|
||||||
collections::{PageParams, Paginated},
|
collections::{PageParams, Paginated},
|
||||||
},
|
},
|
||||||
ports::{
|
ports::{
|
||||||
|
|||||||
@@ -2,13 +2,14 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use domain::ports::{
|
use domain::ports::{
|
||||||
AuthService, DiaryExporter, DiaryQuery, DocumentParser, EventPublisher, FederatedProfileQuery,
|
AuthService, DiaryExporter, DiaryQuery, DocumentParser, EventPublisher, FederatedProfileQuery,
|
||||||
GoalCommand, GoalQuery, ImportProfileRepository, ImportSessionRepository, MetadataClient,
|
FederationAdminQuery, GoalCommand, GoalQuery, ImportProfileRepository, ImportSessionRepository,
|
||||||
MovieCommand, MovieProfileRepository, MovieQuery, ObjectStorage, PasswordHasher, PersonCommand,
|
MetadataClient, MovieCommand, MovieProfileRepository, MovieQuery, ObjectStorage,
|
||||||
PersonEnrichmentClient, PersonQuery, PosterFetcherClient, RefreshSessionRepository,
|
PasswordHasher, PersonCommand, PersonEnrichmentClient, PersonQuery, PosterFetcherClient,
|
||||||
RemoteGoalRepository, RemoteWatchlistRepository, ReviewRepository, SearchCommand, SearchPort,
|
RefreshSessionRepository, RemoteGoalRepository, RemoteWatchlistRepository, ReviewRepository,
|
||||||
FederationAdminQuery, SocialCommand, SocialQuery, StatsRepository, UserProfileFieldsRepository,
|
SearchCommand, SearchPort, SocialCommand, SocialQuery, StatsRepository,
|
||||||
UserRepository, UserSettingsRepository, WatchEventCommand, WatchEventQuery,
|
UserProfileFieldsRepository, UserRepository, UserSettingsRepository, WatchEventCommand,
|
||||||
WatchlistRepository, WebhookTokenRepository, WrapUpRepository, WrapUpStatsQuery,
|
WatchEventQuery, WatchlistRepository, WebhookTokenRepository, WrapUpRepository,
|
||||||
|
WrapUpStatsQuery,
|
||||||
};
|
};
|
||||||
|
|
||||||
use application::config::AppConfig;
|
use application::config::AppConfig;
|
||||||
|
|||||||
@@ -84,7 +84,9 @@ pub async fn get_blocked_domains_admin(
|
|||||||
_admin: AdminApiUser,
|
_admin: AdminApiUser,
|
||||||
) -> Result<Json<Vec<BlockedDomainResponse>>, ApiError> {
|
) -> Result<Json<Vec<BlockedDomainResponse>>, ApiError> {
|
||||||
let domains = state
|
let domains = state
|
||||||
.app_ctx.services.ap_service
|
.app_ctx
|
||||||
|
.services
|
||||||
|
.ap_service
|
||||||
.get_blocked_domains()
|
.get_blocked_domains()
|
||||||
.await
|
.await
|
||||||
.map_err(ap_to_domain)?;
|
.map_err(ap_to_domain)?;
|
||||||
@@ -116,7 +118,9 @@ pub async fn add_blocked_domain_admin(
|
|||||||
axum::Json(body): axum::Json<AddBlockedDomainRequest>,
|
axum::Json(body): axum::Json<AddBlockedDomainRequest>,
|
||||||
) -> Result<impl IntoResponse, ApiError> {
|
) -> Result<impl IntoResponse, ApiError> {
|
||||||
state
|
state
|
||||||
.app_ctx.services.ap_service
|
.app_ctx
|
||||||
|
.services
|
||||||
|
.ap_service
|
||||||
.add_blocked_domain(&body.domain, body.reason.as_deref())
|
.add_blocked_domain(&body.domain, body.reason.as_deref())
|
||||||
.await
|
.await
|
||||||
.map_err(ap_to_domain)?;
|
.map_err(ap_to_domain)?;
|
||||||
@@ -139,7 +143,9 @@ pub async fn remove_blocked_domain_admin(
|
|||||||
axum::extract::Path(domain): axum::extract::Path<String>,
|
axum::extract::Path(domain): axum::extract::Path<String>,
|
||||||
) -> Result<impl IntoResponse, ApiError> {
|
) -> Result<impl IntoResponse, ApiError> {
|
||||||
state
|
state
|
||||||
.app_ctx.services.ap_service
|
.app_ctx
|
||||||
|
.services
|
||||||
|
.ap_service
|
||||||
.remove_blocked_domain(&domain)
|
.remove_blocked_domain(&domain)
|
||||||
.await
|
.await
|
||||||
.map_err(ap_to_domain)?;
|
.map_err(ap_to_domain)?;
|
||||||
@@ -263,10 +269,7 @@ pub async fn get_following(
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(Json(ActorListResponse {
|
Ok(Json(ActorListResponse {
|
||||||
actors: identities
|
actors: identities.into_iter().map(social_actor_to_dto).collect(),
|
||||||
.into_iter()
|
|
||||||
.map(social_actor_to_dto)
|
|
||||||
.collect(),
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,10 +296,7 @@ pub async fn get_followers(
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(Json(ActorListResponse {
|
Ok(Json(ActorListResponse {
|
||||||
actors: identities
|
actors: identities.into_iter().map(social_actor_to_dto).collect(),
|
||||||
.into_iter()
|
|
||||||
.map(social_actor_to_dto)
|
|
||||||
.collect(),
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,10 +314,7 @@ pub async fn get_user_following(
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(Json(ActorListResponse {
|
Ok(Json(ActorListResponse {
|
||||||
actors: identities
|
actors: identities.into_iter().map(social_actor_to_dto).collect(),
|
||||||
.into_iter()
|
|
||||||
.map(social_actor_to_dto)
|
|
||||||
.collect(),
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,10 +332,7 @@ pub async fn get_user_followers(
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(Json(ActorListResponse {
|
Ok(Json(ActorListResponse {
|
||||||
actors: identities
|
actors: identities.into_iter().map(social_actor_to_dto).collect(),
|
||||||
.into_iter()
|
|
||||||
.map(social_actor_to_dto)
|
|
||||||
.collect(),
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -525,10 +519,7 @@ pub async fn get_pending_followers(
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(Json(ActorListResponse {
|
Ok(Json(ActorListResponse {
|
||||||
actors: identities
|
actors: identities.into_iter().map(social_actor_to_dto).collect(),
|
||||||
.into_iter()
|
|
||||||
.map(social_actor_to_dto)
|
|
||||||
.collect(),
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -563,7 +554,9 @@ pub async fn follow_remote_user(
|
|||||||
&deps,
|
&deps,
|
||||||
application::social::commands::FollowCommand {
|
application::social::commands::FollowCommand {
|
||||||
follower_id: user_id.value(),
|
follower_id: user_id.value(),
|
||||||
target: SocialIdentity::Remote { actor_url: form.handle },
|
target: SocialIdentity::Remote {
|
||||||
|
actor_url: form.handle,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@@ -604,7 +597,9 @@ pub async fn unfollow_remote_user(
|
|||||||
&deps,
|
&deps,
|
||||||
application::social::commands::UnfollowCommand {
|
application::social::commands::UnfollowCommand {
|
||||||
follower_id: user_id.value(),
|
follower_id: user_id.value(),
|
||||||
target: SocialIdentity::Remote { actor_url: form.actor_url },
|
target: SocialIdentity::Remote {
|
||||||
|
actor_url: form.actor_url,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@@ -645,7 +640,9 @@ pub async fn accept_follower_html(
|
|||||||
&deps,
|
&deps,
|
||||||
application::social::commands::AcceptFollowCommand {
|
application::social::commands::AcceptFollowCommand {
|
||||||
owner_id: user_id.value(),
|
owner_id: user_id.value(),
|
||||||
requester: SocialIdentity::Remote { actor_url: form.actor_url },
|
requester: SocialIdentity::Remote {
|
||||||
|
actor_url: form.actor_url,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@@ -680,7 +677,9 @@ pub async fn reject_follower_html(
|
|||||||
&deps,
|
&deps,
|
||||||
application::social::commands::RejectFollowCommand {
|
application::social::commands::RejectFollowCommand {
|
||||||
owner_id: user_id.value(),
|
owner_id: user_id.value(),
|
||||||
requester: SocialIdentity::Remote { actor_url: form.actor_url },
|
requester: SocialIdentity::Remote {
|
||||||
|
actor_url: form.actor_url,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@@ -706,7 +705,9 @@ pub async fn get_followers_collection(
|
|||||||
if accept.contains("application/activity+json") || accept.contains("application/ld+json") {
|
if accept.contains("application/activity+json") || accept.contains("application/ld+json") {
|
||||||
let page = params.get("page").and_then(|p| p.parse::<u32>().ok());
|
let page = params.get("page").and_then(|p| p.parse::<u32>().ok());
|
||||||
return match state
|
return match state
|
||||||
.app_ctx.services.ap_service
|
.app_ctx
|
||||||
|
.services
|
||||||
|
.ap_service
|
||||||
.followers_collection_json(user_id, page)
|
.followers_collection_json(user_id, page)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
@@ -737,7 +738,9 @@ pub async fn get_following_collection(
|
|||||||
if accept.contains("application/activity+json") || accept.contains("application/ld+json") {
|
if accept.contains("application/activity+json") || accept.contains("application/ld+json") {
|
||||||
let page = params.get("page").and_then(|p| p.parse::<u32>().ok());
|
let page = params.get("page").and_then(|p| p.parse::<u32>().ok());
|
||||||
return match state
|
return match state
|
||||||
.app_ctx.services.ap_service
|
.app_ctx
|
||||||
|
.services
|
||||||
|
.ap_service
|
||||||
.following_collection_json(user_id, page)
|
.following_collection_json(user_id, page)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
@@ -776,7 +779,9 @@ pub async fn get_following_page(
|
|||||||
};
|
};
|
||||||
match application::social::get_following::execute(
|
match application::social::get_following::execute(
|
||||||
&deps,
|
&deps,
|
||||||
application::social::queries::GetFollowingQuery { user_id: user_id.value() },
|
application::social::queries::GetFollowingQuery {
|
||||||
|
user_id: user_id.value(),
|
||||||
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
@@ -825,7 +830,9 @@ pub async fn get_followers_page(
|
|||||||
};
|
};
|
||||||
match application::social::get_followers::execute(
|
match application::social::get_followers::execute(
|
||||||
&deps,
|
&deps,
|
||||||
application::social::queries::GetFollowersQuery { user_id: user_id.value() },
|
application::social::queries::GetFollowersQuery {
|
||||||
|
user_id: user_id.value(),
|
||||||
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
@@ -875,7 +882,9 @@ pub async fn remove_follower_html(
|
|||||||
&deps,
|
&deps,
|
||||||
application::social::commands::RemoveFollowerCommand {
|
application::social::commands::RemoveFollowerCommand {
|
||||||
owner_id: user_id.value(),
|
owner_id: user_id.value(),
|
||||||
follower: SocialIdentity::Remote { actor_url: form.actor_url },
|
follower: SocialIdentity::Remote {
|
||||||
|
actor_url: form.actor_url,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@@ -902,7 +911,13 @@ pub async fn get_blocked_domains_page(
|
|||||||
let mut ctx = build_page_context(&state, Some(user_id), csrf.0).await;
|
let mut ctx = build_page_context(&state, Some(user_id), csrf.0).await;
|
||||||
ctx.page_title = "Blocked Domains — Movies Diary".to_string();
|
ctx.page_title = "Blocked Domains — Movies Diary".to_string();
|
||||||
ctx.canonical_url = format!("{}/admin/blocked-domains", state.app_ctx.config.base_url);
|
ctx.canonical_url = format!("{}/admin/blocked-domains", state.app_ctx.config.base_url);
|
||||||
match state.app_ctx.services.ap_service.get_blocked_domains().await {
|
match state
|
||||||
|
.app_ctx
|
||||||
|
.services
|
||||||
|
.ap_service
|
||||||
|
.get_blocked_domains()
|
||||||
|
.await
|
||||||
|
{
|
||||||
Ok(domains) => {
|
Ok(domains) => {
|
||||||
let entries: Vec<template_askama::BlockedDomainEntry> = domains
|
let entries: Vec<template_askama::BlockedDomainEntry> = domains
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@@ -940,7 +955,9 @@ pub async fn post_blocked_domain(
|
|||||||
}
|
}
|
||||||
let reason = form.reason.as_deref().filter(|s| !s.trim().is_empty());
|
let reason = form.reason.as_deref().filter(|s| !s.trim().is_empty());
|
||||||
match state
|
match state
|
||||||
.app_ctx.services.ap_service
|
.app_ctx
|
||||||
|
.services
|
||||||
|
.ap_service
|
||||||
.add_blocked_domain(&form.domain, reason)
|
.add_blocked_domain(&form.domain, reason)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
@@ -961,7 +978,13 @@ pub async fn post_remove_blocked_domain(
|
|||||||
if crate::csrf::mismatch(&csrf, &form.csrf_token) {
|
if crate::csrf::mismatch(&csrf, &form.csrf_token) {
|
||||||
return StatusCode::FORBIDDEN.into_response();
|
return StatusCode::FORBIDDEN.into_response();
|
||||||
}
|
}
|
||||||
match state.app_ctx.services.ap_service.remove_blocked_domain(&form.domain).await {
|
match state
|
||||||
|
.app_ctx
|
||||||
|
.services
|
||||||
|
.ap_service
|
||||||
|
.remove_blocked_domain(&form.domain)
|
||||||
|
.await
|
||||||
|
{
|
||||||
Ok(()) => Redirect::to("/admin/blocked-domains").into_response(),
|
Ok(()) => Redirect::to("/admin/blocked-domains").into_response(),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
tracing::error!("remove_blocked_domain error: {:?}", e);
|
tracing::error!("remove_blocked_domain error: {:?}", e);
|
||||||
@@ -983,7 +1006,9 @@ pub async fn get_blocked_actors_page(
|
|||||||
};
|
};
|
||||||
match application::social::get_blocked::execute(
|
match application::social::get_blocked::execute(
|
||||||
&deps,
|
&deps,
|
||||||
application::social::queries::GetBlockedQuery { user_id: user_id.value() },
|
application::social::queries::GetBlockedQuery {
|
||||||
|
user_id: user_id.value(),
|
||||||
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
@@ -1032,7 +1057,9 @@ pub async fn post_block_actor_html(
|
|||||||
&deps,
|
&deps,
|
||||||
application::social::commands::BlockCommand {
|
application::social::commands::BlockCommand {
|
||||||
blocker_id: user_id.value(),
|
blocker_id: user_id.value(),
|
||||||
target: SocialIdentity::Remote { actor_url: form.actor_url },
|
target: SocialIdentity::Remote {
|
||||||
|
actor_url: form.actor_url,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@@ -1063,7 +1090,9 @@ pub async fn post_unblock_actor(
|
|||||||
&deps,
|
&deps,
|
||||||
application::social::commands::UnblockCommand {
|
application::social::commands::UnblockCommand {
|
||||||
blocker_id: user_id.value(),
|
blocker_id: user_id.value(),
|
||||||
target: SocialIdentity::Remote { actor_url: form.actor_url },
|
target: SocialIdentity::Remote {
|
||||||
|
actor_url: form.actor_url,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
|||||||
@@ -66,7 +66,15 @@ async fn wire_dependencies() -> anyhow::Result<(AppState, axum::Router)> {
|
|||||||
let event_bus = EventBusBackend::from_env()?;
|
let event_bus = EventBusBackend::from_env()?;
|
||||||
|
|
||||||
#[cfg(feature = "federation")]
|
#[cfg(feature = "federation")]
|
||||||
let (event_publisher_arc, ap_router, ap_service, social_query, remote_watchlist_repo, social_command_arc, social_query_unified_arc) = {
|
let (
|
||||||
|
event_publisher_arc,
|
||||||
|
ap_router,
|
||||||
|
ap_service,
|
||||||
|
social_query,
|
||||||
|
remote_watchlist_repo,
|
||||||
|
social_command_arc,
|
||||||
|
social_query_unified_arc,
|
||||||
|
) = {
|
||||||
let (
|
let (
|
||||||
activity_repo,
|
activity_repo,
|
||||||
follow_repo,
|
follow_repo,
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use domain::{errors::DomainError, events::DomainEvent, ports::EventHandler, value_objects::SocialIdentity};
|
use domain::{
|
||||||
|
errors::DomainError, events::DomainEvent, ports::EventHandler, value_objects::SocialIdentity,
|
||||||
|
};
|
||||||
|
|
||||||
pub struct FollowBackfillHandler {
|
pub struct FollowBackfillHandler {
|
||||||
pub ap_service: Arc<dyn activitypub::ActivityPubPort>,
|
pub ap_service: Arc<dyn activitypub::ActivityPubPort>,
|
||||||
|
|||||||
Reference in New Issue
Block a user