From 622464e4c3c2b4b612a2fe2c9cc84905621dcb73 Mon Sep 17 00:00:00 2001 From: n08i40k Date: Tue, 28 Oct 2025 22:33:49 +0400 Subject: [PATCH] feat(users): add endpoints for getting user by ids --- src/main.rs | 17 ++++++++++++- src/routes/schema.rs | 1 + src/routes/users/by.rs | 56 +++++++++++++++++++++++++++++++++++++++++ src/routes/users/mod.rs | 1 + 4 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 src/routes/users/by.rs diff --git a/src/main.rs b/src/main.rs index e830673..3c1e340 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,7 +50,22 @@ pub fn get_api_scope< .service(routes::auth::sign_up_vk); let users_scope = utoipa_actix_web::scope("/users") - .wrap(JWTAuthorizationBuilder::new().build()) + .wrap( + JWTAuthorizationBuilder::new() + .add_paths( + ["/by/id/{id}", "/by/telegram-id/{id}"], + Some(ServiceConfig { + allow_service: true, + user_roles: Some(&[UserRole::Admin]), + }), + ) + .build(), + ) + .service( + utoipa_actix_web::scope("/by") + .service(routes::users::by::by_id) + .service(routes::users::by::by_telegram_id), + ) .service(routes::users::change_group) .service(routes::users::change_username) .service(routes::users::me); diff --git a/src/routes/schema.rs b/src/routes/schema.rs index bd01117..48bf6c0 100644 --- a/src/routes/schema.rs +++ b/src/routes/schema.rs @@ -163,6 +163,7 @@ pub mod user { #[schema(examples( "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjY3ZGNjOWE5NTA3YjAwMDA3NzI3NDRhMiIsImlhdCI6IjE3NDMxMDgwOTkiLCJleHAiOiIxODY5MjUyMDk5In0.rMgXRb3JbT9AvLK4eiY9HMB5LxgUudkpQyoWKOypZFY" ))] + #[serde(skip_serializing_if = "Option::is_none")] pub access_token: Option, } diff --git a/src/routes/users/by.rs b/src/routes/users/by.rs new file mode 100644 index 0000000..f930912 --- /dev/null +++ b/src/routes/users/by.rs @@ -0,0 +1,56 @@ +use crate::routes::schema::user::UserResponse; +use crate::routes::users::by::schema::{ErrorCode, ServiceResponse}; +use crate::state::AppState; +use actix_web::{get, web}; +use database::query::Query; + +#[utoipa::path(responses((status = OK, body = UserResponse)))] +#[get("/id/{id}")] +pub async fn by_id(app_state: web::Data, path: web::Path) -> ServiceResponse { + let user_id = path.into_inner(); + + let db = app_state.get_database(); + + match Query::find_user_by_id(db, &user_id).await { + Ok(Some(user)) => Ok(UserResponse::from(user)), + _ => Err(ErrorCode::NotFound), + } + .into() +} + +#[utoipa::path(responses((status = OK, body = UserResponse)))] +#[get("/telegram-id/{id}")] +pub async fn by_telegram_id( + app_state: web::Data, + path: web::Path, +) -> ServiceResponse { + let telegram_id = path.into_inner(); + + let db = app_state.get_database(); + + match Query::find_user_by_telegram_id(db, telegram_id).await { + Ok(Some(user)) => Ok(UserResponse::from(user)), + _ => Err(ErrorCode::NotFound), + } + .into() +} + +mod schema { + use crate::routes::schema::user::UserResponse; + use actix_macros::ErrResponse; + use derive_more::Display; + use serde::Serialize; + use utoipa::ToSchema; + + pub type ServiceResponse = crate::routes::schema::Response; + + #[derive(Clone, Serialize, Display, ToSchema, ErrResponse)] + #[serde(rename_all = "SCREAMING_SNAKE_CASE")] + #[schema(as = Users::By::ErrorCode)] + pub enum ErrorCode { + /// User not found. + #[status_code = "actix_web::http::StatusCode::NOT_FOUND"] + #[display("Required user not found.")] + NotFound, + } +} diff --git a/src/routes/users/mod.rs b/src/routes/users/mod.rs index 289e7cf..5707539 100644 --- a/src/routes/users/mod.rs +++ b/src/routes/users/mod.rs @@ -1,3 +1,4 @@ +pub mod by; mod change_group; mod change_username; mod me;