hoverfly icon indicating copy to clipboard operation
hoverfly copied to clipboard

application/x-www-form-urlencoded matcher

Open qcastel opened this issue 5 years ago • 3 comments

Is your feature request related to a problem? Please describe. One of our request contains a content type 'application/x-www-form-urlencoded'.

Example of payload:

{
	"matcher": "exact",
	"value": "client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&code=FAKE_CODE&grant_type=authorization_code&redirect_uri=https://local-auth.yapily.com:8081/&client_assertion=eyJraWQiOiJlcGwyT09Mem82WHlCWExDeFR4dUZ6SnJEQ0kiLCJhbGciOiJQUzI1NiJ9.eyJzdWIiOiIzZmMzMzljYS02MzM4LTRmNDMtOWUxYy1iYWZjNDM2MjA0MWMiLCJhdWQiOiJodHRwczpcL1wvbG9jYWwtZmFrZWJhbmsueWFwaWx5LmNvbTo4MDgxXC9vYXV0aDIiLCJpc3MiOiIzZmMzMzljYS02MzM4LTRmNDMtOWUxYy1iYWZjNDM2MjA0MWMiLCJleHAiOjE1ODIyMTY1ODMsImlhdCI6MTU4MjIxNjI4MywianRpIjoiYWQ3ZGI3NjctOTgxNC00ZDUzLWFmYTEtZjFlMDgxZjNmMDhkIn0.kVScfRmaQ3XX8JruabNg__baXo9pSgYHhmlgWHuxZwxd7RsFxIP-uCaGkzAIX8ZrLZ059VeeIZrGIySFYDnaTozb79MSN_Y9laDfEqj017e7zrfyuy1z21vpKyxgkaCAC1o226mIS9onldBRCHj3CXb-XL3arCM2X2fteNRURdrnBD9gJ_F3eXdyzTxbsUEe9siC8JCZ2YBXcp0SPODVooFA3NMvofSHRJf77a_0pQRAjFRX-xbQUYJGrNtXqfgiE0ImwkAStfZ-FTbGP0fMDE2t2BVSLat5pOBurhpE5_Hr8sPE0xb9YD4Uiyrco-pRwkMu8C95HitoOIiE2TXZqg"
}

Hoverfly seems to currently do a basic comparaison without parsing the payload.

Describe the solution you'd like

It would be nice to tell hoverfly which matching rule to apply for which parameter. In the example above, it would be interesting for us to tell hoverfly to use a JWT matcher (https://github.com/SpectoLabs/hoverfly/issues/902) for client_assertion.

In the example above, it would be nice to Describe alternatives you've considered

If specifying the matcher for each claims of the payload is not possible, at least a way to exclude some of them from the matching rules.

Additional context Note that this RFE would allow hoverfly to be compatible with OAuth2 implementation. If you look the two RFEs I raised, you can recognised that I am actually trying to mock an OAuth2 server. Those two RFEs are very valuable if you want to claim that hoverfly is OAuth2 friendly.

qcastel avatar Feb 20 '20 17:02 qcastel

hey @qcastel although hoverfly doesn't have the matcher that parse the form data and do further matching, a simple workaround would be to use glob or regex matchers. I wonder if you had a look into that?

tommysitu avatar Feb 25 '20 23:02 tommysitu

Here is an example of an oauth2 server simulation:

{
  "data" : {
    "pairs" : [ {
      "request" : {
        "path" : [ {
          "value" : "/api",
          "matcher" : "exact"
        } ],
        "method" : [ {
          "value" : "GET",
          "matcher" : "exact"
        } ],
        "headers" : {
          "Authorization" : [ {
            "value" : "Bearer some-api-token",
            "matcher" : "exact"
          } ]
        }
      },
      "response" : {
        "body" : "[{\"title\":\"Balance\",\"text\":\"{{ randomIntegerRange 0 10000 }}\"}]",
        "status" : 200,
        "headers" : {
          "Content-Type" : [ "application/json" ]
        },
        "templated" : true,
        "encodedBody" : false
      }
    }, {
      "request" : {
        "body" : [ {
          "value" : "code=hoverfly-auth-code&grant_type=authorization_code&client_secret=some-client-secret&redirect_uri=https%3A%2F%2Fyour-redirect-url%2Foauth-redirect%2Fhoverfly&client_id=some-client-id",
          "matcher" : "exact"
        } ],
        "path" : [ {
          "value" : "/oauth/token",
          "matcher" : "exact"
        } ],
        "method" : [ {
          "value" : "POST",
          "matcher" : "exact"
        } ]
      },
      "response" : {
        "body" : "{\"access_token\":\"some-api-token\",\"expires_in\":9999999999,\"refresh_token\":\"some-refresh-token\",\"token_type\":\"bearer\"}",
        "status" : 200,
        "headers" : {
          "Content-Type" : [ "application/json" ]
        },
        "templated" : false,
        "encodedBody" : false
      }
    }, {
      "request" : {
        "path" : [ {
          "value" : "/oauth/authorize",
          "matcher" : "exact"
        } ],
        "query" : {
          "scope" : [ {
            "value" : "balance",
            "matcher" : "exact"
          } ],
          "state" : [ {
            "value" : "*",
            "matcher" : "glob"
          } ],
          "client_id" : [ {
            "value" : "some-client-id",
            "matcher" : "exact"
          } ],
          "redirect_uri" : [ {
            "value" : "https://your-redirect-url/oauth-redirect/hoverfly",
            "matcher" : "exact"
          } ],
          "response_type" : [ {
            "value" : "code",
            "matcher" : "exact"
          } ]
        },
        "method" : [ {
          "value" : "GET",
          "matcher" : "exact"
        } ]
      },
      "response" : {
        "body" : "",
        "status" : 302,
        "headers" : {
          "Location" : [ "https://your-redirect-url/oauth-redirect/hoverfly?state={{ Request.QueryParam.state }}&code=hoverfly-auth-code" ]
        },
        "templated" : true,
        "encodedBody" : false
      }
    } ],
    "globalActions" : {
      "delays" : [ ],
      "delaysLogNormal" : [ ]
    }
  },
  "meta" : {
    "timeExported" : "2019-11-19T14:13:54Z",
    "schemaVersion" : "v5",
    "hoverflyVersion" : "v1.1.3"
  }
}

tommysitu avatar Feb 25 '20 23:02 tommysitu

@tommysitu thanks for the workaround. I actually used 'glob' and 'JsonPartial' a couple of time already, for those reason.

In your example:

          "value" : "code=hoverfly-auth-code&grant_type=authorization_code&client_secret=some-client-secret&redirect_uri=https%3A%2F%2Fyour-redirect-url%2Foauth-redirect%2Fhoverfly&client_id=some-client-id",

You got the change to have all the parameters non time dependent, so static, and always in the same order. I used the 'glob' matcher to workaround the non static element but couldn't workaround the order. Fortunately for now, we always generate the same order as it's the same code that execute the request behind. Although we may one day change it and all of our tests would need to see their simulation.json modified accordingly, which is not ideal.

Any, we got something working for now and we will follow up closely #761 and we may consider contributing if we see we are using more and more hoverfly in our testing framework :)

qcastel avatar Feb 26 '20 08:02 qcastel

@tommysitu I can work on this feature request.

kapishmalik avatar Dec 25 '22 04:12 kapishmalik

@kapishmalik thanks, but there is a pending PR for this already https://github.com/SpectoLabs/hoverfly/pull/1025

tommysitu avatar Dec 28 '22 16:12 tommysitu