From d75d6bae1ca459287ab841d54c003b068bd9c6bf Mon Sep 17 00:00:00 2001 From: Siim Mardus Date: Wed, 29 May 2024 15:25:58 +0300 Subject: [PATCH] Allow adding custom auth token for pact verification This is useful if the provider wants to use real authentication flow for the contract tests. Disclaimer: `pactffi_verifier_add_custom_header` function unfortunately is not able to override an existing header, so using this requires the pact to not include the authorization header in the first place. This can either be done by simply not using it on the consumer-side test or removing it somehow before publishing the pact. Although I worked through the following issues: - https://github.com/pact-foundation/pact-net/issues/460 - https://github.com/pact-foundation/pact-reference/issues/275 from which the latter is actually marked as closed, and the fix is allegedly included in the pact-ffi version that we use, it still did not override an existing header. I tried bumping to a higher version as well but without any luck. I will create an issue to pact-foundation to try to get clarity on this. --- c_src/pactffi_nif.c | 17 ++++++++++++----- src/pact_escript.escript | 2 +- src/pact_verifier.erl | 4 ++++ src/pactffi_nif.erl | 20 ++++++++++---------- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/c_src/pactffi_nif.c b/c_src/pactffi_nif.c index 8b428a7..e67aa7f 100644 --- a/c_src/pactffi_nif.c +++ b/c_src/pactffi_nif.c @@ -699,12 +699,19 @@ static ERL_NIF_TERM verify_via_file(ErlNifEnv *env, int argc, const ERL_NIF_TERM pactffi_verifier_set_no_pacts_is_error(verifierhandle, 0); pactffi_verifier_set_provider_info(verifierhandle, name, scheme, host, port, path); pactffi_verifier_add_provider_transport(verifierhandle, protocol, port, path, scheme); - if (!enif_is_binary(env, argv[9])) + + char *auth_token_type = convert_erl_binary_to_c_string(env, argv[9]); + char *auth_token_value = convert_erl_binary_to_c_string(env, argv[10]); + char *auth_header = (char *)malloc((strlen(auth_token_type) + strlen(auth_token_value) + 1) * sizeof(char)); + sprintf(auth_header, "%s %s", auth_token_type, auth_token_value); + pactffi_verifier_add_custom_header(verifierhandle, "authorization", auth_header); + free(auth_header); + + if (!enif_is_binary(env, argv[11])) { return enif_make_badarg(env); } - - char *state_path = convert_erl_binary_to_c_string(env, argv[9]); + char *state_path = convert_erl_binary_to_c_string(env, argv[11]); if (state_path[0] != '\0') { pactffi_verifier_set_provider_state(verifierhandle, state_path, 0, 1); @@ -875,10 +882,10 @@ static ErlNifFunc nif_funcs[] = {"msg_given_with_param", 4, msg_given_with_param}, {"msg_with_contents", 3, msg_with_contents}, {"reify_message", 1, reify_message}, - {"schedule_async_file_verify", 10, schedule_async_file_verify}, + {"schedule_async_file_verify", 12, schedule_async_file_verify}, {"schedule_async_broker_verify", 15, schedule_async_broker_verify}, {"verify_via_broker", 15, verify_via_broker}, - {"verify_via_file", 10, verify_via_file} + {"verify_via_file", 12, verify_via_file} }; ERL_NIF_INIT(pactffi_nif, nif_funcs, NULL, NULL, NULL, NULL) diff --git a/src/pact_escript.escript b/src/pact_escript.escript index 8bc45d3..3bfc572 100755 --- a/src/pact_escript.escript +++ b/src/pact_escript.escript @@ -24,7 +24,7 @@ main([Module, Function | Args]) -> {[], 0}, Args ), - case length(AList) < 10 of + case length(AList) < 12 of true -> AList ++ [<<"">>]; false -> diff --git a/src/pact_verifier.erl b/src/pact_verifier.erl index cf0b4a0..62350e4 100644 --- a/src/pact_verifier.erl +++ b/src/pact_verifier.erl @@ -161,6 +161,8 @@ verify_pacts(VerifierRef, ProviderOpts, ProviderPortDetails) -> } = ProviderOpts, Protocol = maps:get(protocol, ProviderOpts, <<"http">>), BaseUrl = maps:get(base_url, ProviderOpts, <<"/">>), + AuthTokenType = maps:get(auth_token_type, ProviderOpts, <<"Bearer">>), + AuthTokenValue = maps:get(auth_token_value, ProviderOpts, <<"Token">>), StateChangeUrl = maps:get(state_change_url, ProviderOpts, <<"">>), Scheme = maps:get(scheme, ProviderOpts, <<"http">>), FilePath = maps:get(file_path, PactSourceOpts, undefined), @@ -182,6 +184,8 @@ verify_pacts(VerifierRef, ProviderOpts, ProviderPortDetails) -> Branch, FilePath, Protocol, + AuthTokenType, + AuthTokenValue, StateChangeUrl ], ArgsString = diff --git a/src/pactffi_nif.erl b/src/pactffi_nif.erl index 9ebd83d..a690fef 100644 --- a/src/pactffi_nif.erl +++ b/src/pactffi_nif.erl @@ -34,12 +34,12 @@ msg_with_contents/3, reify_message/1, get_reified_message/1, - verify_file_pacts/10, + verify_file_pacts/12, verify_broker_pacts/14, schedule_async_broker_verify/15, - schedule_async_file_verify/10, + schedule_async_file_verify/12, verify_via_broker/15, - verify_via_file/10 + verify_via_file/12 ]). % Import the NIF functions from the C library @@ -70,10 +70,10 @@ msg_given_with_param/4, msg_with_contents/3, reify_message/1, - schedule_async_file_verify/10, + schedule_async_file_verify/12, schedule_async_broker_verify/15, verify_via_broker/15, - verify_via_file/10 + verify_via_file/12 ]). -on_load(init/0). @@ -186,30 +186,30 @@ msg_with_contents(_, _, _) -> reify_message(_) -> erlang:nif_error("NIF library not loaded"). -schedule_async_file_verify(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) -> +schedule_async_file_verify(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) -> erlang:nif_error("NIF library not loaded"). schedule_async_broker_verify(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) -> erlang:nif_error("NIF library not loaded"). -verify_via_file(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) -> +verify_via_file(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) -> erlang:nif_error("NIF library not loaded"). verify_via_broker(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) -> erlang:nif_error("NIF library not loaded"). verify_file_pacts( - Name, Scheme, Host, Port, Path, Version, Branch, FilePath, Protocol, StatePath + Name, Scheme, Host, Port, Path, Version, Branch, FilePath, Protocol, AuthTokenType, AuthTokenValue, StatePath ) -> verify_via_file( - Name, Scheme, Host, Port, Path, Version, Branch, FilePath, Protocol, StatePath + Name, Scheme, Host, Port, Path, Version, Branch, FilePath, Protocol, AuthTokenType, AuthTokenValue, StatePath ). % receive % Output -> % Output % end. % verify_via_file( -% Name, Scheme, Host, Port, Path, Version, Branch, FilePath, Protocol, Pid, StatePath +% Name, Scheme, Host, Port, Path, Version, Branch, FilePath, Protocol, Pid, AuthTokenType, AuthTokenValue, StatePath % ). verify_broker_pacts(