feat: v2 rewrite — hexagonal arch, ActivityPub federation, NATS, deployment-ready #1
93
crates/presentation/src/handlers/federation_management.rs
Normal file
93
crates/presentation/src/handlers/federation_management.rs
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
use crate::{errors::ApiError, extractors::AuthUser, state::AppState};
|
||||||
|
use api_types::responses::RemoteActorResponse;
|
||||||
|
use application::use_cases::federation_management::{
|
||||||
|
accept_follow_request, list_pending_requests, list_remote_followers, list_remote_following,
|
||||||
|
reject_follow_request,
|
||||||
|
};
|
||||||
|
use axum::{extract::State, http::StatusCode, Json};
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct ActorUrlBody {
|
||||||
|
pub actor_url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct HandleBody {
|
||||||
|
pub handle: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_response(a: domain::models::remote_actor::RemoteActor) -> RemoteActorResponse {
|
||||||
|
RemoteActorResponse {
|
||||||
|
handle: a.handle,
|
||||||
|
display_name: a.display_name,
|
||||||
|
avatar_url: a.avatar_url,
|
||||||
|
url: a.url,
|
||||||
|
bio: a.bio,
|
||||||
|
banner_url: a.banner_url,
|
||||||
|
also_known_as: a.also_known_as,
|
||||||
|
outbox_url: a.outbox_url,
|
||||||
|
followers_url: a.followers_url,
|
||||||
|
following_url: a.following_url,
|
||||||
|
attachment: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_pending_requests(
|
||||||
|
State(s): State<AppState>,
|
||||||
|
AuthUser(uid): AuthUser,
|
||||||
|
) -> Result<Json<Vec<RemoteActorResponse>>, ApiError> {
|
||||||
|
let actors = list_pending_requests(&*s.federation, &uid).await?;
|
||||||
|
Ok(Json(actors.into_iter().map(to_response).collect()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn post_accept_request(
|
||||||
|
State(s): State<AppState>,
|
||||||
|
AuthUser(uid): AuthUser,
|
||||||
|
Json(body): Json<ActorUrlBody>,
|
||||||
|
) -> Result<StatusCode, ApiError> {
|
||||||
|
accept_follow_request(&*s.federation, &uid, &body.actor_url).await?;
|
||||||
|
Ok(StatusCode::NO_CONTENT)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn delete_follower(
|
||||||
|
State(s): State<AppState>,
|
||||||
|
AuthUser(uid): AuthUser,
|
||||||
|
Json(body): Json<ActorUrlBody>,
|
||||||
|
) -> Result<StatusCode, ApiError> {
|
||||||
|
reject_follow_request(&*s.federation, &uid, &body.actor_url).await?;
|
||||||
|
Ok(StatusCode::NO_CONTENT)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_remote_followers(
|
||||||
|
State(s): State<AppState>,
|
||||||
|
AuthUser(uid): AuthUser,
|
||||||
|
) -> Result<Json<Vec<RemoteActorResponse>>, ApiError> {
|
||||||
|
let actors = list_remote_followers(&*s.federation, &uid).await?;
|
||||||
|
Ok(Json(actors.into_iter().map(to_response).collect()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_remote_following(
|
||||||
|
State(s): State<AppState>,
|
||||||
|
AuthUser(uid): AuthUser,
|
||||||
|
) -> Result<Json<Vec<RemoteActorResponse>>, ApiError> {
|
||||||
|
let actors = list_remote_following(&*s.federation, &uid).await?;
|
||||||
|
Ok(Json(actors.into_iter().map(to_response).collect()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn delete_following(
|
||||||
|
State(s): State<AppState>,
|
||||||
|
AuthUser(uid): AuthUser,
|
||||||
|
Json(body): Json<HandleBody>,
|
||||||
|
) -> Result<StatusCode, ApiError> {
|
||||||
|
application::use_cases::social::unfollow_actor(
|
||||||
|
&*s.follows,
|
||||||
|
&*s.users,
|
||||||
|
&*s.federation,
|
||||||
|
&*s.events,
|
||||||
|
&uid,
|
||||||
|
&body.handle,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
Ok(StatusCode::NO_CONTENT)
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
pub mod api_keys;
|
pub mod api_keys;
|
||||||
pub mod auth;
|
pub mod auth;
|
||||||
pub mod federation_actors;
|
pub mod federation_actors;
|
||||||
|
pub mod federation_management;
|
||||||
pub mod feed;
|
pub mod feed;
|
||||||
pub mod health;
|
pub mod health;
|
||||||
pub mod notifications;
|
pub mod notifications;
|
||||||
|
|||||||
@@ -77,6 +77,24 @@ pub fn router() -> Router<AppState> {
|
|||||||
"/federation/actors/{handle}/following-list",
|
"/federation/actors/{handle}/following-list",
|
||||||
get(federation_actors::actor_following_handler),
|
get(federation_actors::actor_following_handler),
|
||||||
)
|
)
|
||||||
|
.route(
|
||||||
|
"/federation/me/followers/pending",
|
||||||
|
get(federation_management::get_pending_requests),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/federation/me/followers/accept",
|
||||||
|
post(federation_management::post_accept_request),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/federation/me/followers",
|
||||||
|
get(federation_management::get_remote_followers)
|
||||||
|
.delete(federation_management::delete_follower),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/federation/me/following",
|
||||||
|
get(federation_management::get_remote_following)
|
||||||
|
.delete(federation_management::delete_following),
|
||||||
|
)
|
||||||
.route("/tags/popular", get(feed::get_popular_tags))
|
.route("/tags/popular", get(feed::get_popular_tags))
|
||||||
.route("/tags/{name}", get(feed::tag_thoughts_handler))
|
.route("/tags/{name}", get(feed::tag_thoughts_handler))
|
||||||
// notifications
|
// notifications
|
||||||
|
|||||||
Reference in New Issue
Block a user