refactor: move UUID/username routing to application use case — fix handler boundary leak
This commit is contained in:
@@ -23,6 +23,21 @@ pub async fn get_user_by_username(
|
|||||||
.ok_or(DomainError::NotFound)
|
.ok_or(DomainError::NotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resolve a path segment that is either a UUID (AP actor URL) or a username.
|
||||||
|
pub async fn get_user_by_id_or_username(
|
||||||
|
users: &dyn UserRepository,
|
||||||
|
id_or_username: &str,
|
||||||
|
) -> Result<User, DomainError> {
|
||||||
|
if let Ok(uuid) = uuid::Uuid::parse_str(id_or_username) {
|
||||||
|
users
|
||||||
|
.find_by_id(&UserId::from_uuid(uuid))
|
||||||
|
.await?
|
||||||
|
.ok_or(DomainError::NotFound)
|
||||||
|
} else {
|
||||||
|
get_user_by_username(users, id_or_username).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn update_profile(
|
pub async fn update_profile(
|
||||||
users: &dyn UserRepository,
|
users: &dyn UserRepository,
|
||||||
user_id: &UserId,
|
user_id: &UserId,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use api_types::{
|
|||||||
responses::{ErrorResponse, ProfileField, RemoteActorResponse, UserResponse},
|
responses::{ErrorResponse, ProfileField, RemoteActorResponse, UserResponse},
|
||||||
};
|
};
|
||||||
use application::use_cases::feed::list_users;
|
use application::use_cases::feed::list_users;
|
||||||
use application::use_cases::profile::{get_user_by_username, update_profile};
|
use application::use_cases::profile::{get_user_by_id_or_username, update_profile};
|
||||||
use application::use_cases::search::search_users;
|
use application::use_cases::search::search_users;
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::{Path, Query, State},
|
extract::{Path, Query, State},
|
||||||
@@ -32,16 +32,7 @@ pub async fn get_user(
|
|||||||
OptionalAuthUser(viewer): OptionalAuthUser,
|
OptionalAuthUser(viewer): OptionalAuthUser,
|
||||||
headers: HeaderMap,
|
headers: HeaderMap,
|
||||||
) -> Result<Response, ApiError> {
|
) -> Result<Response, ApiError> {
|
||||||
// AP actor URLs use the user's UUID (e.g. /users/{uuid}). Fall back to UUID lookup
|
let user = get_user_by_id_or_username(&*s.users, &username).await?;
|
||||||
// so remote servers can fetch the actor JSON for HTTP signature verification.
|
|
||||||
let user = if let Ok(uuid) = uuid::Uuid::parse_str(&username) {
|
|
||||||
s.users
|
|
||||||
.find_by_id(&domain::value_objects::UserId::from_uuid(uuid))
|
|
||||||
.await?
|
|
||||||
.ok_or(ApiError::Domain(domain::errors::DomainError::NotFound))?
|
|
||||||
} else {
|
|
||||||
get_user_by_username(&*s.users, &username).await?
|
|
||||||
};
|
|
||||||
|
|
||||||
let accept = headers
|
let accept = headers
|
||||||
.get(header::ACCEPT)
|
.get(header::ACCEPT)
|
||||||
|
|||||||
Reference in New Issue
Block a user