Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding custom header is not able to overwrite existing header #430

Open
SiimMardus opened this issue May 30, 2024 · 2 comments
Open

Adding custom header is not able to overwrite existing header #430

SiimMardus opened this issue May 30, 2024 · 2 comments

Comments

@SiimMardus
Copy link

SiimMardus commented May 30, 2024

What happens:

Given a pact with request header authorization: some_token
When verifying pact via Pact FFI function
And using pactffi_verifier_add_custom_header to replace authorization value with other_token
Then pact verifier makes request with authorization: some_token

What should happen:

Given a pact with request header authorization: some_token
When verifying pact via Pact FFI function
And using pactffi_verifier_add_custom_header to replace authorization value with other_token
Then pact verifier makes request with authorization: other_token


An alleged fix was mentioned in this discussion: #275 (comment) (cc @rholshausen )
It was difficult to track down the version in which the fix was included, but since:

  • The linked issue was closed on Feb 22, 2024
  • Pact FFI 0.4.17 was released on Feb 22, 2024
  • 0.4.17 source code includes the mentioned fix

... I tried 0.4.17, but the headers can still not be overwritten (even tried the current latest version 0.4.20 for good measure, but no luck).


For context, here is where we are attempting to use this feature: https://github.com/salemove/pact_erlang/blob/9945d0bd1ea882812e62db61171bd8671b60b2db/c_src/pactffi_nif.c#L707.

The headers get nicely added when I do something like:

pactffi_verifier_add_custom_header(verifierhandle, "foo", auth_header);
pactffi_verifier_add_custom_header(verifierhandle, "bar", "baz");
...

Additionally, replacing headers added by this function itself works:

pactffi_verifier_add_custom_header(verifierhandle, "foo", "bar");
pactffi_verifier_add_custom_header(verifierhandle, "foo", "baz");
// The outcome - `foo: baz` is included in headers

Let me know if there is any extra context I could provide from my side to track down the problem quicker.

@SiimMardus
Copy link
Author

I actually found a solid workaround for the problem I was trying to solve with this.

The issue I had was that I wanted to use a real authentication token when verifying the provider. Consumer obviously used a fake token, which was not an issue on its side, but I wanted to replace with with a real token in provider so that the auth flow would be covered as well.

  • That's why not being able to override the header was a problem. I would have had to exclude auth header from consumer side.

How I solved the problem with existing pact features: Matchers.fromProviderState in combination with state change callback

On the consumer side:

const authToken = "my-fake-token"
const headers = {
  Accept: 'application/json',
  Authorization: fromProviderState(
    `Bearer \${authToken}`,
    regex(/^Bearer \/^[A-Za-z0-9-_]*\.[A-Za-z0-9-_]*\.[A-Za-z0-9-_]*$/, `Bearer ${authToken}`)
  )
}

What this does:

  • Uses Bearer my-fake-token when running consumer tests
  • Uses authToken variable from Provider tests state change callback (see below)
  • Checks that provider matches Bearer <JWT> regex

On the Provider side (I am using elixir, but it's quite universal)

def state_change(conn, params) do
  case params do
    %{"state" => "some state"} ->
      # Using a helper function to generate real auth token
      authToken = generateAuthToken()

      conn
      |>put_status(:ok)
      |>json(%{authToken: authToken})
    _ ->
      conn
      |>put_status(:ok)
  end
end

What this does:

  • the state_change function is what the State Change URL endpoint given to pact verifier would call with POST
  • The response includes values to be replaced
  • ${authToken} will be replaced with the generated real auth token

Maybe this might help someone trying to find a good solution for authentication in pact verifier as well.

@mefellows
Copy link
Member

Another alternative (if it helps) is to add a test-only middleware that can intercept auth headers and replace them dynamically with whatever you need (this is a decent approach if you're stuck on older versions of the framework and don't have the fromProviderState generators etc. mentioned above)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants