mirror of
https://github.com/valitydev/fistful-server.git
synced 2024-11-06 02:35:18 +00:00
FF-172: Screen for pans in destination using swagger_validator callback (#206)
This commit is contained in:
parent
e8a3bad7ed
commit
0d7150a39a
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@ -41,7 +41,7 @@ build('fistful-server', 'docker-host', finalHook) {
|
||||
}
|
||||
|
||||
runStage('dialyze') {
|
||||
withWsCache("_build/default/rebar3_21.3.8.7_plt") {
|
||||
withWsCache("_build/default/rebar3_22.3.1_plt") {
|
||||
sh 'make wc_dialyze'
|
||||
}
|
||||
}
|
||||
|
2
Makefile
2
Makefile
@ -20,7 +20,7 @@ BASE_IMAGE_NAME := service-erlang
|
||||
BASE_IMAGE_TAG := da0ab769f01b650b389d18fc85e7418e727cbe96
|
||||
|
||||
# Build image tag to be used
|
||||
BUILD_IMAGE_TAG := 4536c31941b9c27c134e8daf0fd18848809219c9
|
||||
BUILD_IMAGE_TAG := 442c2c274c1d8e484e5213089906a4271641d95e
|
||||
|
||||
REGISTRY := dr2.rbkmoney.com
|
||||
|
||||
|
@ -112,6 +112,11 @@ start_app(wapi = AppName) ->
|
||||
decryption_key_paths => [
|
||||
"/opt/wapi/config/jwk.json"
|
||||
]
|
||||
}},
|
||||
{swagger_handler_opts, #{
|
||||
validation_opts => #{
|
||||
custom_validator => wapi_swagger_validator
|
||||
}
|
||||
}}
|
||||
]), #{}};
|
||||
|
||||
|
@ -28,7 +28,8 @@ init([]) ->
|
||||
{LogicHandlers, LogicHandlerSpecs} = get_logic_handler_info(),
|
||||
HealthCheck = enable_health_logging(genlib_app:env(wapi, health_check, #{})),
|
||||
HealthRoutes = [{'_', [erl_health_handle:get_route(HealthCheck)]}],
|
||||
SwaggerSpec = wapi_swagger_server:child_spec(HealthRoutes, LogicHandlers),
|
||||
SwaggerHandlerOpts = genlib_app:env(wapi, swagger_handler_opts, #{}),
|
||||
SwaggerSpec = wapi_swagger_server:child_spec(HealthRoutes, LogicHandlers, SwaggerHandlerOpts),
|
||||
{ok, {
|
||||
{one_for_all, 0, 1},
|
||||
[LechiffreSpec] ++
|
||||
|
@ -1,6 +1,6 @@
|
||||
-module(wapi_swagger_server).
|
||||
|
||||
-export([child_spec/2]).
|
||||
-export([child_spec/3]).
|
||||
|
||||
-export_type([logic_handler/0]).
|
||||
-export_type([logic_handlers/0]).
|
||||
@ -8,16 +8,18 @@
|
||||
-type logic_handler() :: swag_server_wallet:logic_handler(_).
|
||||
-type logic_handlers() :: #{atom() => logic_handler()}.
|
||||
|
||||
-type swagger_handler_opts() :: swag_server_wallet_router:swagger_handler_opts().
|
||||
|
||||
-define(APP, wapi).
|
||||
-define(DEFAULT_ACCEPTORS_POOLSIZE, 100).
|
||||
-define(DEFAULT_IP_ADDR, "::").
|
||||
-define(DEFAULT_PORT, 8080).
|
||||
|
||||
-spec child_spec(cowboy_router:routes(), logic_handlers()) ->
|
||||
-spec child_spec(cowboy_router:routes(), logic_handlers(), swagger_handler_opts()) ->
|
||||
supervisor:child_spec().
|
||||
child_spec(HealthRoutes, LogicHandlers) ->
|
||||
child_spec(HealthRoutes, LogicHandlers, SwaggerHandlerOpts) ->
|
||||
{Transport, TransportOpts} = get_socket_transport(),
|
||||
CowboyOpts = get_cowboy_config(HealthRoutes, LogicHandlers),
|
||||
CowboyOpts = get_cowboy_config(HealthRoutes, LogicHandlers, SwaggerHandlerOpts),
|
||||
ranch:child_spec(?MODULE, Transport, TransportOpts, cowboy_clear, CowboyOpts).
|
||||
|
||||
get_socket_transport() ->
|
||||
@ -26,11 +28,14 @@ get_socket_transport() ->
|
||||
AcceptorsPool = genlib_app:env(?APP, acceptors_poolsize, ?DEFAULT_ACCEPTORS_POOLSIZE),
|
||||
{ranch_tcp, #{socket_opts => [{ip, IP}, {port, Port}], num_acceptors => AcceptorsPool}}.
|
||||
|
||||
get_cowboy_config(HealthRoutes, LogicHandlers) ->
|
||||
get_cowboy_config(HealthRoutes, LogicHandlers, SwaggerHandlerOpts) ->
|
||||
Dispatch =
|
||||
cowboy_router:compile(squash_routes(
|
||||
HealthRoutes ++
|
||||
swag_server_wallet_router:get_paths(maps:get(wallet, LogicHandlers))
|
||||
swag_server_wallet_router:get_paths(
|
||||
maps:get(wallet, LogicHandlers),
|
||||
SwaggerHandlerOpts
|
||||
)
|
||||
)),
|
||||
CowboyOpts = #{
|
||||
env => #{
|
||||
|
80
apps/wapi/src/wapi_swagger_validator.erl
Normal file
80
apps/wapi/src/wapi_swagger_validator.erl
Normal file
@ -0,0 +1,80 @@
|
||||
-module(wapi_swagger_validator).
|
||||
|
||||
-type param_rule() :: swag_server_wallet_param_validator:param_rule().
|
||||
-type schema_rule() :: swag_server_wallet_schema_validator:schema_rule().
|
||||
-type value() :: swag_server_wallet:value().
|
||||
-type param_context() :: swag_server_wallet_param_validator:context().
|
||||
-type schema_context() :: swag_server_wallet_schema_validator:context().
|
||||
|
||||
-type validate_param_result() ::
|
||||
ok | {ok, term()} | pass | error | {error, Error :: term()}.
|
||||
|
||||
-type validate_schema_result() ::
|
||||
jesse_state:state() | pass | no_return().
|
||||
|
||||
-behaviour(swag_server_wallet_custom_validator).
|
||||
|
||||
-export([validate_param/3]).
|
||||
-export([validate_schema/4]).
|
||||
|
||||
-spec validate_param(param_rule(), value(), param_context()) ->
|
||||
validate_param_result().
|
||||
validate_param(_Rule, _Value, _Meta) ->
|
||||
pass.
|
||||
|
||||
-spec validate_schema(schema_rule(), value(), schema_context(), jesse_state:state()) ->
|
||||
validate_schema_result().
|
||||
|
||||
validate_schema(
|
||||
{<<"type">>, <<"string">>},
|
||||
Value,
|
||||
#{
|
||||
operation_id := 'CreateDestination',
|
||||
definition_name := 'Destination',
|
||||
% current_path := [<<"name">>], % check all fields
|
||||
msg_type := request
|
||||
},
|
||||
JesseState
|
||||
) when is_binary(Value) ->
|
||||
case check_destination_name(Value) of
|
||||
ok ->
|
||||
pass; % pass back to the built-in validator
|
||||
error ->
|
||||
jesse_error:handle_data_invalid(wrong_format, Value, JesseState)
|
||||
end;
|
||||
validate_schema(_Rule, _Value, _Meta, _JesseState) ->
|
||||
pass.
|
||||
|
||||
check_destination_name(Name) ->
|
||||
case re:run(Name, <<"\\d{12,19}">>, [{capture, all, binary}, global]) of
|
||||
nomatch -> ok;
|
||||
{match, Captured} -> check_luhn(Captured)
|
||||
end.
|
||||
|
||||
check_luhn([]) ->
|
||||
ok;
|
||||
check_luhn([Captured | Rest]) ->
|
||||
case lists:any(fun do_check_luhn/1, Captured) of
|
||||
true -> error;
|
||||
false -> check_luhn(Rest)
|
||||
end.
|
||||
|
||||
do_check_luhn(String) ->
|
||||
do_check_luhn(String, 0).
|
||||
|
||||
do_check_luhn(<<CheckSum>>, Sum) ->
|
||||
case Sum * 9 rem 10 of
|
||||
M when M =:= CheckSum - $0 ->
|
||||
true;
|
||||
_M ->
|
||||
false
|
||||
end;
|
||||
do_check_luhn(<<N, Rest/binary>>, Sum) when byte_size(Rest) rem 2 =:= 1 ->
|
||||
case (N - $0) * 2 of
|
||||
M when M >= 10 ->
|
||||
do_check_luhn(Rest, Sum + M div 10 + M rem 10);
|
||||
M ->
|
||||
do_check_luhn(Rest, Sum + M)
|
||||
end;
|
||||
do_check_luhn(<<N, Rest/binary>>, Sum) ->
|
||||
do_check_luhn(Rest, Sum + N - $0).
|
@ -357,7 +357,6 @@ create_destination(Params = #{<<"identity">> := IdenityId}, Context) ->
|
||||
CreateFun = fun(ID, EntityCtx) ->
|
||||
_ = check_resource(identity, IdenityId, Context),
|
||||
DestinationParams = from_swag(destination_params, Params),
|
||||
_ = check_destination_params(DestinationParams),
|
||||
Resource = unwrap(construct_resource(maps:get(resource, DestinationParams))),
|
||||
ff_destination:create(
|
||||
DestinationParams#{id => ID, resource => Resource},
|
||||
@ -841,13 +840,6 @@ when Type =:= <<"CryptoWalletDestinationResource">> ->
|
||||
currency => from_swag(crypto_wallet_currency, Resource)
|
||||
})}}}.
|
||||
|
||||
%%@TODO delete as soon as a more permanent solution is in place
|
||||
check_destination_params(#{name := Name}) ->
|
||||
case re:run(Name, <<"\\d{12,19}">>, [{capture, none}]) of
|
||||
nomatch -> ok;
|
||||
match -> throw({illegal_pattern, name})
|
||||
end.
|
||||
|
||||
encode_resource_bank_card(BankCard, AuthData) ->
|
||||
EncodedBankCard = encode_bank_card(BankCard),
|
||||
{bank_card, EncodedBankCard#{auth_data => {session, #{session_id => AuthData}}}}.
|
||||
|
@ -272,12 +272,6 @@ process_request('CreateDestination', #{'Destination' := Params}, Context, Opts)
|
||||
wapi_handler_utils:logic_error(external_id_conflict, {ID, ExternalID});
|
||||
{error, invalid} ->
|
||||
wapi_handler_utils:reply_ok(422, wapi_handler_utils:get_error_msg(<<"Invalid currency">>));
|
||||
{error, {illegal_pattern, Name}} ->
|
||||
wapi_handler_utils:reply_error(400, #{
|
||||
<<"errorType">> => <<"SchemaViolated">>,
|
||||
<<"name">> => Name,
|
||||
<<"description">> => <<"Illegal pattern found in parameter">>
|
||||
});
|
||||
{error, {invalid_resource_token, Type}} ->
|
||||
wapi_handler_utils:reply_error(400, #{
|
||||
<<"errorType">> => <<"InvalidResourceToken">>,
|
||||
|
@ -173,11 +173,25 @@ create_destination_failed_test(C) ->
|
||||
{error, {400, #{<<"errorType">> := <<"InvalidResourceToken">>}}}
|
||||
= create_destination(IdentityID, Resource0, C),
|
||||
%%
|
||||
DestinationName = <<"4242424242424242">>,
|
||||
DestinationName0 = <<"abc4242424242424242">>,
|
||||
CardToken = store_bank_card(C),
|
||||
Resource1 = make_bank_card_resource(CardToken),
|
||||
{error, {400, #{<<"errorType">> := <<"SchemaViolated">>}}}
|
||||
= create_destination(DestinationName, IdentityID, Resource1, C).
|
||||
{error, {response_validation_failed, _,
|
||||
#{
|
||||
<<"errorType">> := <<"schema_violated">>,
|
||||
<<"name">> := <<"Destination">>
|
||||
}
|
||||
}} = create_destination(DestinationName0, IdentityID, Resource1, C),
|
||||
DestinationName1 = <<"abc1231241241241244">>,
|
||||
IdentityID1 = <<"4242424242424242">>,
|
||||
{error, {response_validation_failed, _,
|
||||
#{
|
||||
<<"errorType">> := <<"schema_violated">>,
|
||||
<<"name">> := <<"Destination">>
|
||||
}
|
||||
}} = create_destination(DestinationName1, IdentityID1, Resource1, C),
|
||||
DestinationName2 = <<"1231241241241244">>,
|
||||
{ok, _} = create_destination(DestinationName2, IdentityID, Resource1, C).
|
||||
|
||||
-spec withdrawal_to_bank_card_test(config()) -> test_return().
|
||||
|
||||
|
@ -45,6 +45,10 @@
|
||||
{git,"git@github.com:rbkmoney/dmt_core.git",
|
||||
{ref,"8ac78cb1c94abdcdda6675dd7519893626567573"}},
|
||||
1},
|
||||
{<<"email_validator">>,
|
||||
{git,"https://github.com/rbkmoney/email_validator.git",
|
||||
{ref,"be90c6ebd34d29fa9390136469b99d8a68ad4996"}},
|
||||
0},
|
||||
{<<"erl_health">>,
|
||||
{git,"https://github.com/rbkmoney/erlang-health.git",
|
||||
{ref,"c190cb8de0359b933a27cd20ddc74180c0e5f5c4"}},
|
||||
|
Loading…
Reference in New Issue
Block a user