Skip to content
Clone
194c44c
97 lines 3.2 KB Rust
use axum::Json;
use axum::extract::{Path, Query, State};
use export::rest::{AppResponseData, NoData};
use serde::Deserialize;
use jwt::Session;
use jwt::share::session::require_uid;
use utoipa::IntoParams;
use uuid::Uuid;
use crate::errors::ApiError;
use crate::services::AuthService;
use crate::share::types::UserPublic;
#[derive(Debug, Deserialize, IntoParams)]
pub struct UsersBatchQuery {
pub ids: Vec<Uuid>,
}
#[utoipa::path(
get,
path = "/users",
tag = "users",
description = "按 ID 批量解析用户公开资料,并自动隐藏不可见账号。",
params(UsersBatchQuery),
responses(
(status = 200, description = "resolved public identities", body = AppResponseData<Vec<UserPublic>>),
(status = 404, description = "resource not found", body = AppResponseData<NoData>),
(status = 401, description = "authentication required", body = AppResponseData<NoData>)
)
)]
pub async fn list_users_batch(
State(service): State<AuthService>,
session: Session,
Query(query): Query<UsersBatchQuery>,
) -> Result<AppResponseData<Vec<UserPublic>>, ApiError> {
let caller = require_uid(&session)?;
let users = service
.public_users(caller, query.ids)
.await
.map_err(ApiError::from)?;
Ok(AppResponseData::ok(users))
}
#[utoipa::path(
get,
path = "/users/by-username/{username}",
tag = "users",
description = "按用户名精确查询用户公开资料,并遵循可见性规则。",
params(("username" = String, Path, description = "username")),
responses(
(status = 200, description = "public user identity", body = AppResponseData<UserPublic>),
(status = 404, description = "resource not found", body = AppResponseData<NoData>),
(status = 401, description = "authentication required", body = AppResponseData<NoData>)
)
)]
pub async fn get_user_by_username(
State(service): State<AuthService>,
session: Session,
Path(username): Path<String>,
) -> Result<AppResponseData<UserPublic>, ApiError> {
let caller = require_uid(&session)?;
let user = service
.public_user_by_name(caller, &username)
.await
.map_err(ApiError::from)?;
Ok(AppResponseData::ok(user))
}
#[derive(Debug, Deserialize, utoipa::ToSchema)]
pub struct UpdateUsernameCmd {
pub username: String,
}
#[utoipa::path(
put,
path = "/me/username",
tag = "account",
description = "校验格式和全局唯一性后修改当前用户用户名。",
request_body = UpdateUsernameCmd,
responses(
(status = 200, description = "username updated", body = AppResponseData<UserPublic>),
(status = 400, description = "request failed validation", body = AppResponseData<NoData>),
(status = 401, description = "authentication required", body = AppResponseData<NoData>)
)
)]
pub async fn update_username(
State(service): State<AuthService>,
session: Session,
Json(cmd): Json<UpdateUsernameCmd>,
) -> Result<AppResponseData<UserPublic>, ApiError> {
let uid = require_uid(&session)?;
let user = service
.update_username(uid, &cmd.username)
.await
.map_err(ApiError::from)?;
Ok(AppResponseData::ok(user))
}