use axum::{
extract::{Path, State},
middleware,
routing::{get, post, put},
Extension, Json, Router,
};
use axum_extra::extract::Query;
use crate::{
config::InfraPool,
error::{ApiError, ApiResult},
schema::*,
service::{
self,
auth::{user_auth_middleware, AuthUser},
},
};
pub fn groups_router(st: InfraPool) -> Router<InfraPool> {
Router::new()
.route("/", post(create_group))
.route("/{group_name}", get(get_group))
.route("/{group_name}/users/remove", post(remove_user_group))
.route(
"/{group_name}/users",
put(update_user_group).delete(remove_user_group_params),
)
.route(
"/{group_name}/download/attachments/{*key}",
get(download_attachment),
)
.route(
"/{group_name}/attachments/{*key}",
get(query_single_attachment).delete(delete_attachment),
)
.route("/{group_name}/attachments", post(upload_attachment))
.route("/{group_name}/attachments/query", post(query_attachments))
.route(
"/{group_name}/download/attachments",
post(batch_download_attachments_by_filter),
)
.route(
"/{group_name}/download/attachments/list",
post(batch_download_attachments_by_keys),
)
.route(
"/{group_name}/delete/attachments",
post(batch_delete_attachments_by_filter),
)
.route(
"/{group_name}/delete/attachments/list",
post(batch_delete_attachments_by_keys),
)
.route_layer(middleware::from_fn_with_state(
st.clone(),
user_auth_middleware,
))
.with_state(st)
}
pub async fn create_group(
Extension(u): Extension<AuthUser>,
State(pool): State<InfraPool>,
Json(req): Json<CreateGroupReq>,
) -> ApiResult<()> {
service::group::user_create_group(&pool.db, u.id, req.group_name)
.await
.map_err(|e| match e {
crate::error::Error::AuthError(err) => ApiError::AuthError(err),
crate::error::Error::ApiError(e) => e,
_ => {
tracing::error!("{}", e);
ApiError::InternalServerError
}
})?;
Ok(())
}
pub async fn get_group(
Extension(u): Extension<AuthUser>,
State(pool): State<InfraPool>,
Path(group_name): Path<String>,
) -> ApiResult<Json<GroupQueryInfo>> {
let info = service::group::user_get_group_by_name(u.id, group_name, &pool)
.await
.map_err(|e| match e {
crate::error::Error::AuthError(err) => ApiError::AuthError(err),
crate::error::Error::ApiError(e) => e,
_ => {
tracing::error!("{}", e);
ApiError::InternalServerError
}
})?;
Ok(Json(info))
}
pub async fn update_user_group(
Extension(u): Extension<AuthUser>,
State(pool): State<InfraPool>,
Path(group_name): Path<String>,
Json(req): Json<UpdateUserGroupRoleReq>,
) -> ApiResult<()> {
service::group::update_user_group_role(u.id, group_name, req.relations, &pool)
.await
.map_err(|e| match e {
crate::error::Error::AuthError(err) => ApiError::AuthError(err),
crate::error::Error::ApiError(e) => e,
_ => {
tracing::error!("{}", e);
ApiError::InternalServerError
}
})?;
Ok(())
}
pub async fn remove_user_group(
Extension(u): Extension<AuthUser>,
State(pool): State<InfraPool>,
Path(group_name): Path<String>,
Json(req): Json<RemoveUserGroupRoleReq>,
) -> ApiResult<()> {
service::group::remove_user_group_role(u.id, group_name, req.users, &pool)
.await
.map_err(|e| match e {
crate::error::Error::AuthError(err) => ApiError::AuthError(err),
crate::error::Error::ApiError(e) => e,
_ => {
tracing::error!("{}", e);
ApiError::InternalServerError
}
})?;
Ok(())
}
pub async fn remove_user_group_params(
Extension(u): Extension<AuthUser>,
State(pool): State<InfraPool>,
Path(group_name): Path<String>,
Query(params): Query<RemoveUserGroupRoleParams>,
) -> ApiResult<()> {
service::group::remove_user_group_role(u.id, group_name, params.users, &pool)
.await
.map_err(|e| match e {
crate::error::Error::AuthError(err) => ApiError::AuthError(err),
crate::error::Error::ApiError(e) => e,
_ => {
tracing::error!("{}", e);
ApiError::InternalServerError
}
})?;
Ok(())
}
pub async fn upload_attachment(
Extension(u): Extension<AuthUser>,
State(pool): State<InfraPool>,
Path(group_name): Path<String>,
Json(req): Json<UploadAttachmentReq>,
) -> Result<Json<UploadAttachmentResp>, ApiError> {
let (exist, url) =
service::s3::user_upload_attachment(u.id, &pool, group_name, req.key, req.content_length)
.await
.map_err(|e| match e {
crate::error::Error::AuthError(err) => ApiError::AuthError(err),
crate::error::Error::ApiError(e) => e,
_ => {
tracing::error!("{}", e);
ApiError::InternalServerError
}
})?;
Ok(Json(UploadAttachmentResp { exist, url }))
}
pub async fn download_attachment(
Extension(u): Extension<AuthUser>,
State(pool): State<InfraPool>,
Path((group_name, key)): Path<(String, String)>,
) -> Result<Json<RemoteResourceDownloadResp>, ApiError> {
let attachment = service::s3::user_get_attachment(&pool, u.id, group_name, key)
.await
.map_err(|e| match e {
crate::error::Error::AuthError(err) => ApiError::AuthError(err),
crate::error::Error::ApiError(e) => e,
_ => {
tracing::error!("{}", e);
ApiError::InternalServerError
}
})?;
Ok(Json(attachment))
}
pub async fn delete_attachment(
Extension(u): Extension<AuthUser>,
State(pool): State<InfraPool>,
Path((group_name, key)): Path<(String, String)>,
) -> Result<(), ApiError> {
service::s3::user_delete_attachment(&pool, u.id, group_name, key)
.await
.map_err(|e| match e {
crate::error::Error::AuthError(err) => ApiError::AuthError(err),
crate::error::Error::ApiError(e) => e,
_ => {
tracing::error!("{}", e);
ApiError::InternalServerError
}
})?;
Ok(())
}
pub async fn query_single_attachment(
Extension(u): Extension<AuthUser>,
State(pool): State<InfraPool>,
Path((group_name, key)): Path<(String, String)>,
) -> Result<Json<AttachmentMetadata>, ApiError> {
let attachment = service::s3::user_query_attachment(&pool, u.id, group_name, key)
.await
.map_err(|e| match e {
crate::error::Error::AuthError(err) => ApiError::AuthError(err),
crate::error::Error::ApiError(e) => e,
_ => {
tracing::error!("{}", e);
ApiError::InternalServerError
}
})?;
Ok(Json(attachment))
}
pub async fn query_attachments(
Extension(u): Extension<AuthUser>,
State(pool): State<InfraPool>,
Path(group_name): Path<String>,
Json(req): Json<AttachmentsQueryReq>,
) -> Result<Json<AttachmentsQueryResp>, ApiError> {
let attachments = service::s3::query_attachments_by_filter(u.id, &pool, group_name, req)
.await
.map_err(|e| match e {
crate::error::Error::AuthError(err) => ApiError::AuthError(err),
crate::error::Error::ApiError(e) => e,
_ => {
tracing::error!("{}", e);
ApiError::InternalServerError
}
})?;
Ok(Json(attachments))
}
pub async fn batch_download_attachments_by_filter(
Extension(u): Extension<AuthUser>,
State(pool): State<InfraPool>,
Path(group_name): Path<String>,
Json(req): Json<AttachmentsDownloadByFilterReq>,
) -> Result<Json<AttachmentsDownloadListResp>, ApiError> {
let resp = service::s3::batch_download_attachments_by_filter(u.id, &pool, group_name, req)
.await
.map_err(|e| match e {
crate::error::Error::AuthError(err) => ApiError::AuthError(err),
crate::error::Error::ApiError(e) => e,
_ => {
tracing::error!("{}", e);
ApiError::InternalServerError
}
})?;
Ok(Json(resp))
}
pub async fn batch_download_attachments_by_keys(
Extension(u): Extension<AuthUser>,
State(pool): State<InfraPool>,
Path(group_name): Path<String>,
Json(req): Json<AttachmentsDownloadByKeysReq>,
) -> Result<Json<AttachmentsDownloadListResp>, ApiError> {
let resp = service::s3::batch_download_attachments_by_keys(u.id, &pool, group_name, req)
.await
.map_err(|e| match e {
crate::error::Error::AuthError(err) => ApiError::AuthError(err),
crate::error::Error::ApiError(e) => e,
_ => {
tracing::error!("{}", e);
ApiError::InternalServerError
}
})?;
Ok(Json(resp))
}
pub async fn batch_delete_attachments_by_filter(
Extension(u): Extension<AuthUser>,
State(pool): State<InfraPool>,
Path(group_name): Path<String>,
Json(req): Json<AttachmentsDeleteByFilterReq>,
) -> Result<Json<AttachmentsDeleteByFilterResp>, ApiError> {
let resp = service::s3::batch_delete_attachments_by_filter(u.id, &pool, group_name, req)
.await
.map_err(|e| match e {
crate::error::Error::AuthError(err) => ApiError::AuthError(err),
crate::error::Error::ApiError(e) => e,
_ => {
tracing::error!("{}", e);
ApiError::InternalServerError
}
})?;
Ok(Json(resp))
}
pub async fn batch_delete_attachments_by_keys(
Extension(u): Extension<AuthUser>,
State(pool): State<InfraPool>,
Path(group_name): Path<String>,
Json(req): Json<AttachmentsDeleteByKeysReq>,
) -> Result<Json<AttachmentsDeleteByKeysResp>, ApiError> {
let resp = service::s3::batch_delete_attachments_by_keys(u.id, &pool, group_name, req)
.await
.map_err(|e| match e {
crate::error::Error::AuthError(err) => ApiError::AuthError(err),
crate::error::Error::ApiError(e) => e,
_ => {
tracing::error!("{}", e);
ApiError::InternalServerError
}
})?;
Ok(Json(resp))
}