wapi-lib/apps/wapi/test/wapi_report_tests_SUITE.erl
Toporkov Igor df471b4064
FF-143: Uac authorization (#165)
* Add uac dependency

* use uac to issue tokens

* Configure uac

* Authorize operations with uac

* Issue tokens with uac in tests

* wip: furthemore migrate to uac

* Remove unreachable case

* Adjust wapi config in tests

* Don't start old authorizer

* Fix auth context creation in tests

* Fix all definitions of create_auth_ctx

* Revert "Don't start old authorizer"

This reverts commit 2636fcfa48e798a8fb07534e512ea5b494f57b19.

* Fix old config naming

* Deduplicate unique id generation

* Provide dummy snowflake config

* Use macro for signee

* Authorize operation withc UAC (#140)

* Verify tokens with uac

* Implement dummy authorization

* Return quote verification

* Restore authorizer code order

* Restore signer code order

* Update commentaries

* Provide operation access lists

* Give party read/write permissions to the test tokens

* Introduce more resources, standardize CreateWithdrawal authoriation

* Download file with read access

* Authorize withdrawals with dedicated permission

* Fix permissions in tests

* Upgrade uac

* Remove redundant auth related modules

* Use uac issue

* Update tests

* Fix opaque type usage

* Add domain_name to uac config

* Remove signee from test config

* Rollback to old roles

* Upgrade uac

* Fix for wapi wallet tests

* Use macro for domain

* Remove domain name from configs

* Use uac utils functions

* Make operation access less strict

* Remove unused signee option

* Replace get_party_id with uac function

* Create ACL migration layer

* Reimplement operation access

* Fix style

* Remove reintroduced auth code

* Upgrade uac

* Remove redundant verification option

* Suppress opaque introspection dialyzer warning

* Fix nested resources ACLs

* Issue test quota without resource access

Co-Authored-By: Andrew Mayorov <a.mayorov@rbkmoney.com>

* Adapt new p2p code

* Rename refactor and move role mapping

* Refactor roles mapping

* Use uac dev branch

* Fix merge incompatibilities

* Fix even more incompatibilities

* Bump uac and adjust code to it

* Add operation access for new ops

* Upgrade uac

* Issue tokens the new way

* Fix merge artifacts

* Create simple resource hierarchy for new operations

* Fix authorization by bearer

* Fix missed merge issues

* Apply suggestions from code review

Co-Authored-By: Andrew Mayorov <a.mayorov@rbkmoney.com>

* Verify partyID in p2p continuation tokens, add signee to wapi config

* Remove OperationID from log message where it is already present in meta

Co-Authored-By: Andrew Mayorov <a.mayorov@rbkmoney.com>

* Add signee to app config

* Test if unauthorized user still can create withdrawal using grants

* Do withdrawal specific authorization inside create_withdrawal

* Test wapi_SUITE default with both tokens, specify domain when issuing tokens

* Upgrade uac

* Specify which domains to decode

* Throw withdrawal authorization errors

* Split too long lines

* Simplify grant authorization

* Do not handle 'missing' errors, handle wallet notfound

* Rework error mapping slightly

* Add resource to insufficient_access/claim error

* Try bumping cowboy_cors to fix CI dialyzer error

* Use fork-master version of cowboy_cors

Co-authored-by: Andrew Mayorov <a.mayorov@rbkmoney.com>
2020-05-14 13:44:52 +03:00

297 lines
8.6 KiB
Erlang

-module(wapi_report_tests_SUITE).
-include_lib("common_test/include/ct.hrl").
-include_lib("damsel/include/dmsl_domain_config_thrift.hrl").
-include_lib("fistful_reporter_proto/include/ff_reporter_reports_thrift.hrl").
-include_lib("file_storage_proto/include/fs_file_storage_thrift.hrl").
-include_lib("fistful_proto/include/ff_proto_base_thrift.hrl").
-include_lib("jose/include/jose_jwk.hrl").
-include_lib("wapi_wallet_dummy_data.hrl").
-export([all/0]).
-export([groups/0]).
-export([init_per_suite/1]).
-export([end_per_suite/1]).
-export([init_per_group/2]).
-export([end_per_group/2]).
-export([init_per_testcase/2]).
-export([end_per_testcase/2]).
-export([init/1]).
-export([
create_report_ok_test/1,
get_report_ok_test/1,
get_reports_ok_test/1,
reports_with_wrong_identity_ok_test/1,
download_file_ok_test/1
]).
% common-api is used since it is the domain used in production RN
% TODO: change to wallet-api (or just omit since it is the default one) when new tokens will be a thing
-define(DOMAIN, <<"common-api">>).
-define(badresp(Code), {error, {invalid_response_code, Code}}).
-define(emptyresp(Code), {error, {Code, #{}}}).
-type test_case_name() :: atom().
-type config() :: [{atom(), any()}].
-type group_name() :: atom().
-behaviour(supervisor).
-spec init([]) ->
{ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}.
init([]) ->
{ok, {#{strategy => one_for_all, intensity => 1, period => 1}, []}}.
-spec all() ->
[test_case_name()].
all() ->
[
{group, base}
].
-spec groups() ->
[{group_name(), list(), [test_case_name()]}].
groups() ->
[
{base, [],
[
create_report_ok_test,
get_report_ok_test,
get_reports_ok_test,
reports_with_wrong_identity_ok_test,
download_file_ok_test
]
}
].
%%
%% starting/stopping
%%
-spec init_per_suite(config()) ->
config().
init_per_suite(Config) ->
%% TODO remove this after cut off wapi
ok = application:set_env(wapi, transport, thrift),
ct_helper:makeup_cfg([
ct_helper:test_case_name(init),
ct_payment_system:setup(#{
optional_apps => [
bender_client,
wapi,
wapi_woody_client
]
})
], Config).
-spec end_per_suite(config()) ->
_.
end_per_suite(C) ->
%% TODO remove this after cut off wapi
ok = application:unset_env(wapi, transport),
ok = ct_payment_system:shutdown(C).
-spec init_per_group(group_name(), config()) ->
config().
init_per_group(Group, Config) when Group =:= base ->
ok = ff_context:save(ff_context:create(#{
party_client => party_client:create_client(),
woody_context => woody_context:new(<<"init_per_group/", (atom_to_binary(Group, utf8))/binary>>)
})),
Party = create_party(Config),
{ok, Token} = wapi_ct_helper:issue_token(Party, [{[party], write}], unlimited, ?DOMAIN),
Config1 = [{party, Party} | Config],
[{context, wapi_ct_helper:get_context(Token)} | Config1];
init_per_group(_, Config) ->
Config.
-spec end_per_group(group_name(), config()) ->
_.
end_per_group(_Group, _C) ->
ok.
-spec init_per_testcase(test_case_name(), config()) ->
config().
init_per_testcase(Name, C) ->
C1 = ct_helper:makeup_cfg([ct_helper:test_case_name(Name), ct_helper:woody_ctx()], C),
ok = ct_helper:set_context(C1),
[{test_sup, wapi_ct_helper:start_mocked_service_sup(?MODULE)} | C1].
-spec end_per_testcase(test_case_name(), config()) ->
config().
end_per_testcase(_Name, C) ->
ok = ct_helper:unset_context(),
wapi_ct_helper:stop_mocked_service_sup(?config(test_sup, C)),
ok.
%%% Tests
-spec create_report_ok_test(config()) ->
_.
create_report_ok_test(C) ->
{ok, Identity} = create_identity(C),
IdentityID = maps:get(<<"id">>, Identity),
wapi_ct_helper:mock_services([{fistful_report, fun
('GenerateReport', _) -> {ok, ?REPORT_ID};
('GetReport', _) -> {ok, ?REPORT}
end}], C),
{ok, _} = call_api(
fun swag_client_wallet_reports_api:create_report/3,
#{
binding => #{
<<"identityID">> => IdentityID
},
body => #{
<<"reportType">> => <<"withdrawalRegistry">>,
<<"fromTime">> => ?TIMESTAMP,
<<"toTime">> => ?TIMESTAMP
}
},
ct_helper:cfg(context, C)
).
-spec get_report_ok_test(config()) ->
_.
get_report_ok_test(C) ->
{ok, Identity} = create_identity(C),
IdentityID = maps:get(<<"id">>, Identity),
wapi_ct_helper:mock_services([{fistful_report, fun
('GetReport', _) -> {ok, ?REPORT}
end}], C),
{ok, _} = call_api(
fun swag_client_wallet_reports_api:get_report/3,
#{
binding => #{
<<"identityID">> => IdentityID,
<<"reportID">> => ?INTEGER
}
},
ct_helper:cfg(context, C)
).
-spec get_reports_ok_test(config()) ->
_.
get_reports_ok_test(C) ->
{ok, Identity} = create_identity(C),
IdentityID = maps:get(<<"id">>, Identity),
wapi_ct_helper:mock_services([{fistful_report, fun
('GetReports', _) -> {ok, [
?REPORT_EXT(pending, []),
?REPORT_EXT(created, undefined),
?REPORT_WITH_STATUS(canceled)]}
end}], C),
{ok, _} = call_api(
fun swag_client_wallet_reports_api:get_reports/3,
#{
binding => #{
<<"identityID">> => IdentityID
},
qs_val => #{
<<"fromTime">> => ?TIMESTAMP,
<<"toTime">> => ?TIMESTAMP,
<<"type">> => <<"withdrawalRegistry">>
}
},
ct_helper:cfg(context, C)
).
-spec reports_with_wrong_identity_ok_test(config()) ->
_.
reports_with_wrong_identity_ok_test(C) ->
IdentityID = <<"WrongIdentity">>,
wapi_ct_helper:mock_services([{fistful_report, fun
('GenerateReport', _) -> {ok, ?REPORT_ID};
('GetReport', _) -> {ok, ?REPORT};
('GetReports', _) -> {ok, [?REPORT, ?REPORT, ?REPORT]}
end}], C),
?emptyresp(400) = call_api(
fun swag_client_wallet_reports_api:create_report/3,
#{
binding => #{
<<"identityID">> => IdentityID
},
body => #{
<<"reportType">> => <<"withdrawalRegistry">>,
<<"fromTime">> => ?TIMESTAMP,
<<"toTime">> => ?TIMESTAMP
}
},
ct_helper:cfg(context, C)
),
?emptyresp(400) = call_api(
fun swag_client_wallet_reports_api:get_report/3,
#{
binding => #{
<<"identityID">> => IdentityID,
<<"reportID">> => ?INTEGER
}
},
ct_helper:cfg(context, C)
),
?emptyresp(400) = call_api(
fun swag_client_wallet_reports_api:get_reports/3,
#{
binding => #{
<<"identityID">> => IdentityID
},
qs_val => #{
<<"fromTime">> => ?TIMESTAMP,
<<"toTime">> => ?TIMESTAMP,
<<"type">> => <<"withdrawalRegistry">>
}
},
ct_helper:cfg(context, C)
).
-spec download_file_ok_test(config()) ->
_.
download_file_ok_test(C) ->
wapi_ct_helper:mock_services([{file_storage, fun
('GenerateDownloadUrl', _) -> {ok, ?STRING}
end}], C),
{ok, _} = call_api(
fun swag_client_wallet_downloads_api:download_file/3,
#{
binding => #{
<<"fileID">> => ?STRING
},
qs_val => #{
<<"expiresAt">> => ?TIMESTAMP
}
},
ct_helper:cfg(context, C)
).
%%
-spec call_api(function(), map(), wapi_client_lib:context()) ->
{ok, term()} | {error, term()}.
call_api(F, Params, Context) ->
{Url, PreparedParams, Opts} = wapi_client_lib:make_request(Context, Params),
Response = F(Url, PreparedParams, Opts),
wapi_client_lib:handle_response(Response).
create_party(_C) ->
ID = genlib:bsuuid(),
_ = ff_party:create(ID),
ID.
create_identity(C) ->
PartyID = ?config(party, C),
Params = #{
<<"provider">> => <<"good-one">>,
<<"class">> => <<"person">>,
<<"name">> => <<"HAHA NO2">>
},
wapi_wallet_ff_backend:create_identity(Params, create_context(PartyID, C)).
create_context(PartyID, C) ->
maps:merge(wapi_ct_helper:create_auth_ctx(PartyID), create_woody_ctx(C)).
create_woody_ctx(C) ->
#{
woody_context => ct_helper:get_woody_ctx(C)
}.