feat: replace instance actor decorator with real DB row
Some checks failed
CI / Check / Test (push) Failing after 52s
Some checks failed
CI / Check / Test (push) Failing after 52s
Migrations (postgres + sqlite) insert a service actor with a well-known UUID. Removes the InstanceActorUserRepo wrapper.
This commit is contained in:
@@ -1,57 +0,0 @@
|
|||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use k_ap::{ApActorType, ApUser, ApUserRepository};
|
|
||||||
|
|
||||||
pub const INSTANCE_ACTOR_ID: uuid::Uuid =
|
|
||||||
uuid::Uuid::from_bytes([0, 0, 0, 0, 0, 0, 0x40, 0, 0x80, 0, 0, 0, 0, 0, 0, 0]);
|
|
||||||
|
|
||||||
pub struct InstanceActorUserRepo {
|
|
||||||
inner: Arc<dyn ApUserRepository>,
|
|
||||||
base_url: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InstanceActorUserRepo {
|
|
||||||
pub fn new(inner: Arc<dyn ApUserRepository>, base_url: String) -> Self {
|
|
||||||
Self { inner, base_url }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn instance_ap_user(base_url: &str) -> ApUser {
|
|
||||||
ApUser {
|
|
||||||
id: INSTANCE_ACTOR_ID,
|
|
||||||
username: "instance".to_string(),
|
|
||||||
display_name: None,
|
|
||||||
bio: None,
|
|
||||||
avatar_url: None,
|
|
||||||
banner_url: None,
|
|
||||||
also_known_as: vec![],
|
|
||||||
profile_url: url::Url::parse(base_url).ok(),
|
|
||||||
attachment: vec![],
|
|
||||||
manually_approves_followers: false,
|
|
||||||
discoverable: false,
|
|
||||||
actor_type: ApActorType::Service,
|
|
||||||
featured_url: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl ApUserRepository for InstanceActorUserRepo {
|
|
||||||
async fn find_by_id(&self, id: uuid::Uuid) -> anyhow::Result<Option<ApUser>> {
|
|
||||||
if id == INSTANCE_ACTOR_ID {
|
|
||||||
return Ok(Some(instance_ap_user(&self.base_url)));
|
|
||||||
}
|
|
||||||
self.inner.find_by_id(id).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn find_by_username(&self, username: &str) -> anyhow::Result<Option<ApUser>> {
|
|
||||||
if username == "instance" {
|
|
||||||
return Ok(Some(instance_ap_user(&self.base_url)));
|
|
||||||
}
|
|
||||||
self.inner.find_by_username(username).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn count_users(&self) -> anyhow::Result<usize> {
|
|
||||||
self.inner.count_users().await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
pub mod composite_handler;
|
pub mod composite_handler;
|
||||||
pub mod event_handler;
|
pub mod event_handler;
|
||||||
pub mod federation_event_bridge;
|
pub mod federation_event_bridge;
|
||||||
pub mod instance_actor;
|
|
||||||
pub mod objects;
|
pub mod objects;
|
||||||
pub mod port;
|
pub mod port;
|
||||||
pub mod remote_review_repository;
|
pub mod remote_review_repository;
|
||||||
@@ -10,6 +9,9 @@ pub(crate) mod urls;
|
|||||||
pub mod user_adapter;
|
pub mod user_adapter;
|
||||||
pub mod watchlist_handler;
|
pub mod watchlist_handler;
|
||||||
|
|
||||||
|
pub const INSTANCE_ACTOR_ID: uuid::Uuid =
|
||||||
|
uuid::Uuid::from_bytes([0, 0, 0, 0, 0, 0, 0x40, 0, 0x80, 0, 0, 0, 0, 0, 0, 0]);
|
||||||
|
|
||||||
// Re-export the generic base types that callers need
|
// Re-export the generic base types that callers need
|
||||||
pub use k_ap::{
|
pub use k_ap::{
|
||||||
ActivityPubService, ActivityRepository, ActorRepository, ApContentReader, ApFederationConfig,
|
ActivityPubService, ActivityRepository, ActorRepository, ApContentReader, ApFederationConfig,
|
||||||
@@ -97,18 +99,17 @@ pub async fn wire(deps: ActivityPubDeps) -> anyhow::Result<ActivityPubWire> {
|
|||||||
federation_event_bridge::FederationEventBridge::new(event_publisher),
|
federation_event_bridge::FederationEventBridge::new(event_publisher),
|
||||||
);
|
);
|
||||||
|
|
||||||
let user_repo = std::sync::Arc::new(instance_actor::InstanceActorUserRepo::new(
|
|
||||||
std::sync::Arc::new(DomainUserRepoAdapter::new(user_repo, base_url.clone())),
|
|
||||||
base_url.clone(),
|
|
||||||
));
|
|
||||||
let concrete = std::sync::Arc::new(
|
let concrete = std::sync::Arc::new(
|
||||||
ActivityPubService::builder(base_url.clone())
|
ActivityPubService::builder(base_url.clone())
|
||||||
.activity_repo(activity_repo)
|
.activity_repo(activity_repo)
|
||||||
.follow_repo(follow_repo)
|
.follow_repo(follow_repo)
|
||||||
.actor_repo(actor_repo)
|
.actor_repo(actor_repo)
|
||||||
.blocklist_repo(blocklist_repo)
|
.blocklist_repo(blocklist_repo)
|
||||||
.user_repo(user_repo)
|
.user_repo(std::sync::Arc::new(DomainUserRepoAdapter::new(
|
||||||
.signed_fetch_actor_id(instance_actor::INSTANCE_ACTOR_ID)
|
user_repo,
|
||||||
|
base_url.clone(),
|
||||||
|
)))
|
||||||
|
.signed_fetch_actor_id(INSTANCE_ACTOR_ID)
|
||||||
.content_reader(composite.clone() as std::sync::Arc<dyn ApContentReader>)
|
.content_reader(composite.clone() as std::sync::Arc<dyn ApContentReader>)
|
||||||
.object_handler(composite as std::sync::Arc<dyn ApObjectHandler>)
|
.object_handler(composite as std::sync::Arc<dyn ApObjectHandler>)
|
||||||
.event_publisher(fed_event_bridge)
|
.event_publisher(fed_event_bridge)
|
||||||
|
|||||||
10
crates/adapters/postgres/migrations/0022_instance_actor.sql
Normal file
10
crates/adapters/postgres/migrations/0022_instance_actor.sql
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
INSERT INTO users (id, username, email, password_hash, created_at, role)
|
||||||
|
VALUES (
|
||||||
|
'00000000-0000-4000-8000-000000000000',
|
||||||
|
'instance',
|
||||||
|
'noreply@instance.invalid',
|
||||||
|
'!service-actor-no-login',
|
||||||
|
NOW(),
|
||||||
|
'standard'
|
||||||
|
)
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
INSERT OR IGNORE INTO users (id, email, password_hash, created_at, username)
|
||||||
|
VALUES (
|
||||||
|
'00000000-0000-4000-8000-000000000000',
|
||||||
|
'noreply@instance.invalid',
|
||||||
|
'!service-actor-no-login',
|
||||||
|
datetime('now'),
|
||||||
|
'instance'
|
||||||
|
);
|
||||||
Reference in New Issue
Block a user