microcks-testcontainers-java icon indicating copy to clipboard operation
microcks-testcontainers-java copied to clipboard

Using Microcks API to add header constraints to OpenAPI-based API mocks

Open frademacher opened this issue 1 year ago • 4 comments

Describe the bug

Hi all. I'm using Microcks Testcontainers Java (0.2.8) to mock an API based on an OpenAPI specification provided by an external party. The external implementation of this API relies on API keys to secure access to certain operations. When mocking this API, I'd also like to mock these API keys by requiring clients that call a mock operation to also send fake API keys.

Since the API keys are expected to be provided as HTTP header key-value pairs, I tried to specify Microcks header constraints for their mocking. If I understood Microcks' documentation correctly, there is currently no means (like x-microcks) to embed header constraints in OpenAPI specs that are to be imported into a Microcks Testcontainer instance. I therefore tried to rely on Microcks own API and more specifically its Override Service Operation endpoint.

However, when calling this endpoint, I'm always receiving a 403 Forbidden response, even though I understand Microcks Testcontainer Java build to disable both authentication and authorization. The former circumstance I checked using the Get Authentification Configuration of Microcks' API, which indeed returns "enabled": false as part of its JSON response.

Expected behavior

Assuming that the provided service ID, operation name, and body are correct, Microcks Override Service Operation endpoint should not emit a 403 Forbidden response but instead result in a successful alteration of the operation (and thus a 200 OK, I suspect).

Actual behavior

A 403 Forbidden response is returned even though all data provided to the Override Service Operation endpoint seems to be correct to the best of my knowledge.

How to Reproduce?

  1. Fire up a Microcks Testcontainers Java instance and import the attached OpenAPI spec.
  2. Try to install a header constraint by calling
curl --location --request PUT 'http://localhost:32864/api/services/encoding_test_api:1/operation?operationName=`GET%20%2Fcommon%2Fgenders' \
--header 'Content-Type: application/json' \
--data '{
  "parameterConstraints": [
    {
      "name": "mobileTokenHeader",
      "required": "true",
      "recopy": "false",
      "mustMatchRegexp": "someToken",
      "in": "header"
    }    
  ]
}'

(assuming that the container is reachable at http://localhost:32864). From my perspective, this call should result in extending the GET /common/genders operation with a header constraint of name mobileTokenHeader and expected fake value someToken.

encoding_test_openapi.json

Microcks version or git rev

Microcks Testcontainers Java 0.2.8 with nightly uber image

Install method (docker-compose, helm chart, operator, docker-desktop extension,...)

mvn test of a Java application that spins up the Microcks Testcontainer

Additional information

I tried to narrow down the cause of this behavior but couldn't see an issue on my side. I hops this information helps to clarify the issue (or otherwise tell me what I'm doing wrong ;-)):

  • Implementation of Microcks' Override Service Operation endpoint: https://github.com/microcks/microcks/blob/928a67f4c16b4f3a312129e67063e1ed39a311b1/webapp/src/main/java/io/github/microcks/web/ServiceController.java#L231
  • Here, the call to serviceService.updateOperation() returns true if (i) the provided service exists (verified by Microcks Get Service endpoint with service ID encoding_test_api:1); (ii) the calling user has the "manager" role or authorization is disabled (which I assume here; see https://github.com/microcks/microcks/blob/928a67f4c16b4f3a312129e67063e1ed39a311b1/webapp/src/main/java/io/github/microcks/security/AuthorizationChecker.java#L77); and (iii) the provided operation's name is correct.
  • First, I suspected the operation name to be wrong but in the snapshot I downloaded from the running Microcks Testcontainers instance I can see that the operation name is indeed "GET /common/genders". In the above curl command the name is percent-encoded (GET%20%2Fcommon%2Fgenders) because it's operationName is a query parameter.

frademacher avatar Jun 19 '24 18:06 frademacher

Thank you for opening this issue. You provide a lot of helpful details that may certainly accelerate the investigation. I'll probably be able to have a look at it tomorrow.

lbroudoux avatar Jun 19 '24 19:06 lbroudoux

Hi there!

So actually, this is an issue on Microcks side and not on the side of the testcontainers module.

serviceId as used in the API path has —most of the time— two different meanings. It can be the raw unique identifier used in the database to identify the service, OR it can be the service_name:service_version identifier.

In the case of this API (the operation properties update), the translation from service_name:service_version to raw identifier has not been put in place. So basically, Microcks fails to retrieve a service with this ID and then apply the update to the operation.

So basically, we would have to generalize this translation everywhere - not just on the /api/tests or /api/services/{serviceId} endpoints - but also on all the derivatives.

In the very short term, a workaround would be to first issue a call to the /api/services/{serviceId}?messages=false endpoint that could return the representation of the service and then access its 'id'. Then, reuse this id in the second call to override operation constraints.

I will create an issue on the Microcks side to track this one. Also, I think it could be nice to add these constraints specifications on the x-microcks OpenAPI extensions as well. What do you think?

We held on to constraints as they're currently managed independently of the OpenAPI parameter definitions, but we think we should have some kind of matching in the future. However, it doesn't prevent for adding them in extensions on short-mid term...

lbroudoux avatar Jun 20 '24 11:06 lbroudoux

Now tracked here: https://github.com/microcks/microcks/issues/1225

lbroudoux avatar Jun 20 '24 12:06 lbroudoux

This issue has been automatically marked as stale because it has not had recent activity :sleeping:

It will be closed in 30 days if no further activity occurs. To unstale this issue, add a comment with a detailed explanation.

There can be many reasons why some specific issue has no activity. The most probable cause is lack of time, not lack of interest. Microcks is a Cloud Native Computing Foundation project not owned by a single for-profit company. It is a community-driven initiative ruled under open governance model.

Let us figure out together how to push this issue forward. Connect with us through one of many communication channels we established here.

Thank you for your patience :heart:

github-actions[bot] avatar Aug 20 '24 00:08 github-actions[bot]