From ae6fe21ce664f98f166cbf392e94c9d2c7d3af15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B5=D0=B9=20=D0=A1=D0=B0?= =?UTF-8?q?=D0=B1=D0=B8=D0=BB=D0=B8=D0=BD?= Date: Tue, 26 May 2026 22:33:52 +0300 Subject: [PATCH] =?UTF-8?q?=20=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D1=81=D0=BF=D0=B8=D1=81=D0=BA=D0=B0=20=D0=B0?= =?UTF-8?q?=D0=B4=D0=BC=D0=B8=D0=BD=D0=B8=D1=81=D1=82=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=BE=D0=B2=20=D0=B8=20=D0=B0=D0=B4=D0=BC=D0=B8?= =?UTF-8?q?=D0=BD=D0=B8=D1=81=D1=82=D1=80=D0=B0=D1=82=D0=BE=D1=80=D0=B0=20?= =?UTF-8?q?=D0=BF=D0=BE=20ID=20(=D0=BB=D1=8E=D0=B1=D0=BE=D0=B9=20=D0=B0?= =?UTF-8?q?=D0=B4=D0=BC=D0=B8=D0=BD=D0=B8=D1=81=D1=82=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D0=BE=D1=80)=20https://git.sabilin.com/EventHub/EventHubBack/i?= =?UTF-8?q?ssues/22?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/handlers/admin/admin_handler_admins.erl | 10 +++--- .../admin/admin_handler_admins_by_id.erl | 18 +++++----- test/api/admins/admin_admins_tests.erl | 35 ++++++------------- test/api/admins/admin_users_tests.erl | 2 +- 4 files changed, 25 insertions(+), 40 deletions(-) diff --git a/src/handlers/admin/admin_handler_admins.erl b/src/handlers/admin/admin_handler_admins.erl index e473057..90a38d4 100644 --- a/src/handlers/admin/admin_handler_admins.erl +++ b/src/handlers/admin/admin_handler_admins.erl @@ -1,6 +1,6 @@ %%%------------------------------------------------------------------- %%% @doc Административный обработчик списка администраторов. -%%% GET – список всех администраторов (только для superadmin). +%%% GET – список всех администраторов (доступен всем администраторам). %%% POST – создать нового администратора (только для superadmin). %%% @end %%%------------------------------------------------------------------- @@ -26,7 +26,7 @@ trails() -> ListGet = #{ path => <<"/v1/admin/admins">>, method => <<"GET">>, - description => <<"List all admins (superadmin only)">>, + description => <<"List all admins (any admin)">>, tags => [<<"Admins">>], parameters => [ #{name => <<"role">>, in => <<"query">>, schema => #{type => string}}, @@ -98,10 +98,10 @@ admin_schema() -> %%% HTTP-методы %%%=================================================================== -%% @doc GET /v1/admin/admins – список администраторов. +%% @doc GET /v1/admin/admins – список администраторов (доступен всем администраторам). -spec list_admins(cowboy_req:req()) -> {ok, binary(), cowboy_req:req()}. list_admins(Req) -> - case handler_utils:is_superadmin(Req) of + case handler_utils:auth_admin(Req) of {ok, _AdminId, Req1} -> Filters = parse_admin_filters(Req1), Pagination = handler_utils:parse_pagination_params(Req1), @@ -113,7 +113,7 @@ list_admins(Req) -> handler_utils:send_error(Req1, Code, Msg) end. -%% @doc POST /v1/admin/admins – создание администратора. +%% @doc POST /v1/admin/admins – создание администратора (только суперадмин). -spec create_admin(cowboy_req:req()) -> {ok, binary(), cowboy_req:req()}. create_admin(Req) -> case handler_utils:is_superadmin(Req) of diff --git a/src/handlers/admin/admin_handler_admins_by_id.erl b/src/handlers/admin/admin_handler_admins_by_id.erl index 2cc513d..6f1d0ce 100644 --- a/src/handlers/admin/admin_handler_admins_by_id.erl +++ b/src/handlers/admin/admin_handler_admins_by_id.erl @@ -1,10 +1,8 @@ %%%------------------------------------------------------------------- %%% @doc Административный обработчик конкретного администратора. -%%% GET /v1/admin/admins/:id – получить администратора -%%% PUT /v1/admin/admins/:id – обновить администратора -%%% DELETE /v1/admin/admins/:id – удалить администратора -%%% -%%% Все операции доступны только суперадмину. +%%% GET /v1/admin/admins/:id – получить администратора (доступен всем администраторам) +%%% PUT /v1/admin/admins/:id – обновить администратора (только суперадмин) +%%% DELETE /v1/admin/admins/:id – удалить администратора (только суперадмин) %%% @end %%%------------------------------------------------------------------- -module(admin_handler_admins_by_id). @@ -32,7 +30,7 @@ trails() -> #{ % GET by id path => <<"/v1/admin/admins/:id">>, method => <<"GET">>, - description => <<"Get admin by ID (superadmin only)">>, + description => <<"Get admin by ID (any admin)">>, tags => [<<"Admins">>], parameters => IdParam, responses => #{ @@ -105,10 +103,10 @@ admin_update_schema() -> %%% Internal functions -%% @doc GET /v1/admin/admins/:id – получение администратора. +%% @doc GET /v1/admin/admins/:id – получение администратора (любой админ). -spec get_admin(cowboy_req:req()) -> {ok, binary(), cowboy_req:req()}. get_admin(Req) -> - case handler_utils:is_superadmin(Req) of + case handler_utils:auth_admin(Req) of {ok, _AdminId, Req1} -> Id = cowboy_req:binding(id, Req1), case logic_admin:get_admin(Id) of @@ -123,7 +121,7 @@ get_admin(Req) -> handler_utils:send_error(Req1, Code, Msg) end. -%% @doc PUT /v1/admin/admins/:id – обновление администратора. +%% @doc PUT /v1/admin/admins/:id – обновление администратора (только суперадмин). -spec update_admin(cowboy_req:req()) -> {ok, binary(), cowboy_req:req()}. update_admin(Req) -> case handler_utils:is_superadmin(Req) of @@ -152,7 +150,7 @@ update_admin(Req) -> handler_utils:send_error(Req1, Code, Msg) end. -%% @doc DELETE /v1/admin/admins/:id – физическое удаление администратора. +%% @doc DELETE /v1/admin/admins/:id – физическое удаление администратора (только суперадмин). -spec delete_admin(cowboy_req:req()) -> {ok, binary(), cowboy_req:req()}. delete_admin(Req) -> case handler_utils:is_superadmin(Req) of diff --git a/test/api/admins/admin_admins_tests.erl b/test/api/admins/admin_admins_tests.erl index 734a29a..4c7c8f2 100644 --- a/test/api/admins/admin_admins_tests.erl +++ b/test/api/admins/admin_admins_tests.erl @@ -9,12 +9,12 @@ %%% DELETE /v1/admin/admins/:id %%% %%% Проверяет: -%%% - получение списка администраторов (только суперадмин) -%%% - создание нового администратора -%%% - получение администратора по ID -%%% - обновление администратора -%%% - удаление (блокировку) администратора -%%% - ошибки 403 для обычного администратора +%%% - получение списка администраторов (любой администратор) +%%% - создание нового администратора (только суперадмин) +%%% - получение администратора по ID (любой администратор) +%%% - обновление администратора (только суперадмин) +%%% - удаление (блокировку) администратора (только суперадмин) +%%% - ошибки 403 для обычного администратора (POST/PUT/DELETE) %%% - ошибки 409 (дубликат email) и 400 (неверная роль) при создании %%% - **фильтрацию** по role и status %%% - **комбинации фильтров** (role + status) @@ -56,10 +56,12 @@ test() -> test_update_admin(SuperToken, maps:get(<<"id">>, Admin1)), test_delete_admin(SuperToken, maps:get(<<"id">>, Admin2)), - % ── Тесты ограничений для обычного админа ── - test_list_admins_forbidden(AdminToken), + % ── GET-запросы от обычного администратора (должны проходить) ── + test_list_admins(AdminToken), + test_get_admin(AdminToken, maps:get(<<"id">>, Admin3)), + + % ── POST/PUT/DELETE от обычного админа (по-прежнему 403) ── test_create_admin_forbidden(AdminToken), - test_get_admin_forbidden(AdminToken, maps:get(<<"id">>, Admin3)), test_update_admin_forbidden(AdminToken, maps:get(<<"id">>, Admin3)), test_delete_admin_forbidden(AdminToken, maps:get(<<"id">>, Admin3)), @@ -132,13 +134,6 @@ test_delete_admin(Token, AdminId) -> ?assertNot(lists:any(fun(A) -> maps:get(<<"id">>, A) =:= AdminId end, Admins)). %% ── Тесты ограничений ── --spec test_list_admins_forbidden(binary()) -> ok. -test_list_admins_forbidden(Token) -> - ct:pal(" TEST: List admins as non-superadmin (403)"), - Resp = api_test_runner:admin_request(get, <<"/v1/admin/admins">>, Token), - ?assertMatch({ok, 403, _, _}, Resp), - ct:pal(" OK: got 403"). - -spec test_create_admin_forbidden(binary()) -> ok. test_create_admin_forbidden(Token) -> ct:pal(" TEST: Create admin as non-superadmin (403)"), @@ -147,14 +142,6 @@ test_create_admin_forbidden(Token) -> ?assertMatch({ok, 403, _, _}, Resp), ct:pal(" OK: got 403"). --spec test_get_admin_forbidden(binary(), binary()) -> ok. -test_get_admin_forbidden(Token, AdminId) -> - ct:pal(" TEST: Get admin by ID as non-superadmin (403)"), - Path = <<"/v1/admin/admins/", AdminId/binary>>, - Resp = api_test_runner:admin_request(get, Path, Token), - ?assertMatch({ok, 403, _, _}, Resp), - ct:pal(" OK: got 403"). - -spec test_update_admin_forbidden(binary(), binary()) -> ok. test_update_admin_forbidden(Token, AdminId) -> ct:pal(" TEST: Update admin as non-superadmin (403)"), diff --git a/test/api/admins/admin_users_tests.erl b/test/api/admins/admin_users_tests.erl index 5d8e1d0..6526c8d 100644 --- a/test/api/admins/admin_users_tests.erl +++ b/test/api/admins/admin_users_tests.erl @@ -44,7 +44,7 @@ test() -> User3Email = api_test_runner:unique_email(<<"usertest3">>), User3Token = api_test_runner:register_and_login(User3Email, <<"testpass">>), Me3 = api_test_runner:client_get(<<"/v1/user/me">>, User3Token), - User3Id = maps:get(<<"id">>, Me3), + _User3Id = maps:get(<<"id">>, Me3), % Обновляем пользователей, чтобы получить разные роли и статусы % User1: роль bot, статус frozen (для тестов фильтрации)