получение списка администраторов и администратора по ID (любой администратор) #22
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
%%%-------------------------------------------------------------------
|
%%%-------------------------------------------------------------------
|
||||||
%%% @doc Административный обработчик списка администраторов.
|
%%% @doc Административный обработчик списка администраторов.
|
||||||
%%% GET – список всех администраторов (только для superadmin).
|
%%% GET – список всех администраторов (доступен всем администраторам).
|
||||||
%%% POST – создать нового администратора (только для superadmin).
|
%%% POST – создать нового администратора (только для superadmin).
|
||||||
%%% @end
|
%%% @end
|
||||||
%%%-------------------------------------------------------------------
|
%%%-------------------------------------------------------------------
|
||||||
@@ -26,7 +26,7 @@ trails() ->
|
|||||||
ListGet = #{
|
ListGet = #{
|
||||||
path => <<"/v1/admin/admins">>,
|
path => <<"/v1/admin/admins">>,
|
||||||
method => <<"GET">>,
|
method => <<"GET">>,
|
||||||
description => <<"List all admins (superadmin only)">>,
|
description => <<"List all admins (any admin)">>,
|
||||||
tags => [<<"Admins">>],
|
tags => [<<"Admins">>],
|
||||||
parameters => [
|
parameters => [
|
||||||
#{name => <<"role">>, in => <<"query">>, schema => #{type => string}},
|
#{name => <<"role">>, in => <<"query">>, schema => #{type => string}},
|
||||||
@@ -98,10 +98,10 @@ admin_schema() ->
|
|||||||
%%% HTTP-методы
|
%%% HTTP-методы
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
|
|
||||||
%% @doc GET /v1/admin/admins – список администраторов.
|
%% @doc GET /v1/admin/admins – список администраторов (доступен всем администраторам).
|
||||||
-spec list_admins(cowboy_req:req()) -> {ok, binary(), cowboy_req:req()}.
|
-spec list_admins(cowboy_req:req()) -> {ok, binary(), cowboy_req:req()}.
|
||||||
list_admins(Req) ->
|
list_admins(Req) ->
|
||||||
case handler_utils:is_superadmin(Req) of
|
case handler_utils:auth_admin(Req) of
|
||||||
{ok, _AdminId, Req1} ->
|
{ok, _AdminId, Req1} ->
|
||||||
Filters = parse_admin_filters(Req1),
|
Filters = parse_admin_filters(Req1),
|
||||||
Pagination = handler_utils:parse_pagination_params(Req1),
|
Pagination = handler_utils:parse_pagination_params(Req1),
|
||||||
@@ -113,7 +113,7 @@ list_admins(Req) ->
|
|||||||
handler_utils:send_error(Req1, Code, Msg)
|
handler_utils:send_error(Req1, Code, Msg)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%% @doc POST /v1/admin/admins – создание администратора.
|
%% @doc POST /v1/admin/admins – создание администратора (только суперадмин).
|
||||||
-spec create_admin(cowboy_req:req()) -> {ok, binary(), cowboy_req:req()}.
|
-spec create_admin(cowboy_req:req()) -> {ok, binary(), cowboy_req:req()}.
|
||||||
create_admin(Req) ->
|
create_admin(Req) ->
|
||||||
case handler_utils:is_superadmin(Req) of
|
case handler_utils:is_superadmin(Req) of
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
%%%-------------------------------------------------------------------
|
%%%-------------------------------------------------------------------
|
||||||
%%% @doc Административный обработчик конкретного администратора.
|
%%% @doc Административный обработчик конкретного администратора.
|
||||||
%%% GET /v1/admin/admins/:id – получить администратора
|
%%% GET /v1/admin/admins/:id – получить администратора (доступен всем администраторам)
|
||||||
%%% PUT /v1/admin/admins/:id – обновить администратора
|
%%% PUT /v1/admin/admins/:id – обновить администратора (только суперадмин)
|
||||||
%%% DELETE /v1/admin/admins/:id – удалить администратора
|
%%% DELETE /v1/admin/admins/:id – удалить администратора (только суперадмин)
|
||||||
%%%
|
|
||||||
%%% Все операции доступны только суперадмину.
|
|
||||||
%%% @end
|
%%% @end
|
||||||
%%%-------------------------------------------------------------------
|
%%%-------------------------------------------------------------------
|
||||||
-module(admin_handler_admins_by_id).
|
-module(admin_handler_admins_by_id).
|
||||||
@@ -32,7 +30,7 @@ trails() ->
|
|||||||
#{ % GET by id
|
#{ % GET by id
|
||||||
path => <<"/v1/admin/admins/:id">>,
|
path => <<"/v1/admin/admins/:id">>,
|
||||||
method => <<"GET">>,
|
method => <<"GET">>,
|
||||||
description => <<"Get admin by ID (superadmin only)">>,
|
description => <<"Get admin by ID (any admin)">>,
|
||||||
tags => [<<"Admins">>],
|
tags => [<<"Admins">>],
|
||||||
parameters => IdParam,
|
parameters => IdParam,
|
||||||
responses => #{
|
responses => #{
|
||||||
@@ -105,10 +103,10 @@ admin_update_schema() ->
|
|||||||
|
|
||||||
%%% Internal functions
|
%%% 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()}.
|
-spec get_admin(cowboy_req:req()) -> {ok, binary(), cowboy_req:req()}.
|
||||||
get_admin(Req) ->
|
get_admin(Req) ->
|
||||||
case handler_utils:is_superadmin(Req) of
|
case handler_utils:auth_admin(Req) of
|
||||||
{ok, _AdminId, Req1} ->
|
{ok, _AdminId, Req1} ->
|
||||||
Id = cowboy_req:binding(id, Req1),
|
Id = cowboy_req:binding(id, Req1),
|
||||||
case logic_admin:get_admin(Id) of
|
case logic_admin:get_admin(Id) of
|
||||||
@@ -123,7 +121,7 @@ get_admin(Req) ->
|
|||||||
handler_utils:send_error(Req1, Code, Msg)
|
handler_utils:send_error(Req1, Code, Msg)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%% @doc PUT /v1/admin/admins/:id – обновление администратора.
|
%% @doc PUT /v1/admin/admins/:id – обновление администратора (только суперадмин).
|
||||||
-spec update_admin(cowboy_req:req()) -> {ok, binary(), cowboy_req:req()}.
|
-spec update_admin(cowboy_req:req()) -> {ok, binary(), cowboy_req:req()}.
|
||||||
update_admin(Req) ->
|
update_admin(Req) ->
|
||||||
case handler_utils:is_superadmin(Req) of
|
case handler_utils:is_superadmin(Req) of
|
||||||
@@ -152,7 +150,7 @@ update_admin(Req) ->
|
|||||||
handler_utils:send_error(Req1, Code, Msg)
|
handler_utils:send_error(Req1, Code, Msg)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%% @doc DELETE /v1/admin/admins/:id – физическое удаление администратора.
|
%% @doc DELETE /v1/admin/admins/:id – физическое удаление администратора (только суперадмин).
|
||||||
-spec delete_admin(cowboy_req:req()) -> {ok, binary(), cowboy_req:req()}.
|
-spec delete_admin(cowboy_req:req()) -> {ok, binary(), cowboy_req:req()}.
|
||||||
delete_admin(Req) ->
|
delete_admin(Req) ->
|
||||||
case handler_utils:is_superadmin(Req) of
|
case handler_utils:is_superadmin(Req) of
|
||||||
|
|||||||
@@ -9,12 +9,12 @@
|
|||||||
%%% DELETE /v1/admin/admins/:id
|
%%% DELETE /v1/admin/admins/:id
|
||||||
%%%
|
%%%
|
||||||
%%% Проверяет:
|
%%% Проверяет:
|
||||||
%%% - получение списка администраторов (только суперадмин)
|
%%% - получение списка администраторов (любой администратор)
|
||||||
%%% - создание нового администратора
|
%%% - создание нового администратора (только суперадмин)
|
||||||
%%% - получение администратора по ID
|
%%% - получение администратора по ID (любой администратор)
|
||||||
%%% - обновление администратора
|
%%% - обновление администратора (только суперадмин)
|
||||||
%%% - удаление (блокировку) администратора
|
%%% - удаление (блокировку) администратора (только суперадмин)
|
||||||
%%% - ошибки 403 для обычного администратора
|
%%% - ошибки 403 для обычного администратора (POST/PUT/DELETE)
|
||||||
%%% - ошибки 409 (дубликат email) и 400 (неверная роль) при создании
|
%%% - ошибки 409 (дубликат email) и 400 (неверная роль) при создании
|
||||||
%%% - **фильтрацию** по role и status
|
%%% - **фильтрацию** по role и status
|
||||||
%%% - **комбинации фильтров** (role + status)
|
%%% - **комбинации фильтров** (role + status)
|
||||||
@@ -56,10 +56,12 @@ test() ->
|
|||||||
test_update_admin(SuperToken, maps:get(<<"id">>, Admin1)),
|
test_update_admin(SuperToken, maps:get(<<"id">>, Admin1)),
|
||||||
test_delete_admin(SuperToken, maps:get(<<"id">>, Admin2)),
|
test_delete_admin(SuperToken, maps:get(<<"id">>, Admin2)),
|
||||||
|
|
||||||
% ── Тесты ограничений для обычного админа ──
|
% ── GET-запросы от обычного администратора (должны проходить) ──
|
||||||
test_list_admins_forbidden(AdminToken),
|
test_list_admins(AdminToken),
|
||||||
|
test_get_admin(AdminToken, maps:get(<<"id">>, Admin3)),
|
||||||
|
|
||||||
|
% ── POST/PUT/DELETE от обычного админа (по-прежнему 403) ──
|
||||||
test_create_admin_forbidden(AdminToken),
|
test_create_admin_forbidden(AdminToken),
|
||||||
test_get_admin_forbidden(AdminToken, maps:get(<<"id">>, Admin3)),
|
|
||||||
test_update_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)),
|
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)).
|
?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.
|
-spec test_create_admin_forbidden(binary()) -> ok.
|
||||||
test_create_admin_forbidden(Token) ->
|
test_create_admin_forbidden(Token) ->
|
||||||
ct:pal(" TEST: Create admin as non-superadmin (403)"),
|
ct:pal(" TEST: Create admin as non-superadmin (403)"),
|
||||||
@@ -147,14 +142,6 @@ test_create_admin_forbidden(Token) ->
|
|||||||
?assertMatch({ok, 403, _, _}, Resp),
|
?assertMatch({ok, 403, _, _}, Resp),
|
||||||
ct:pal(" OK: got 403").
|
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.
|
-spec test_update_admin_forbidden(binary(), binary()) -> ok.
|
||||||
test_update_admin_forbidden(Token, AdminId) ->
|
test_update_admin_forbidden(Token, AdminId) ->
|
||||||
ct:pal(" TEST: Update admin as non-superadmin (403)"),
|
ct:pal(" TEST: Update admin as non-superadmin (403)"),
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ test() ->
|
|||||||
User3Email = api_test_runner:unique_email(<<"usertest3">>),
|
User3Email = api_test_runner:unique_email(<<"usertest3">>),
|
||||||
User3Token = api_test_runner:register_and_login(User3Email, <<"testpass">>),
|
User3Token = api_test_runner:register_and_login(User3Email, <<"testpass">>),
|
||||||
Me3 = api_test_runner:client_get(<<"/v1/user/me">>, User3Token),
|
Me3 = api_test_runner:client_get(<<"/v1/user/me">>, User3Token),
|
||||||
User3Id = maps:get(<<"id">>, Me3),
|
_User3Id = maps:get(<<"id">>, Me3),
|
||||||
|
|
||||||
% Обновляем пользователей, чтобы получить разные роли и статусы
|
% Обновляем пользователей, чтобы получить разные роли и статусы
|
||||||
% User1: роль bot, статус frozen (для тестов фильтрации)
|
% User1: роль bot, статус frozen (для тестов фильтрации)
|
||||||
|
|||||||
Reference in New Issue
Block a user