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

Allow path parameters to be specified as security inputs (Tapir) #53

Open
smosca-ct opened this issue Aug 28, 2023 · 1 comment
Open

Comments

@smosca-ct
Copy link

smosca-ct commented Aug 28, 2023

Sometimes, the security logic of an endpoint needs to get access to path parameters. For example, the product search endpoint (/:projectKey/products/search) security logic checks that the API token provided by the client actually has the permission to read products off the :projectKey path parameter.

Currently, this kind of checks can't be implemented cleanly by using code generated by this generator, because path parameters expressed as both security inputs and normal inputs don't care about each other. For example, this endpoint definition (for the product search endpoint described above):

endpoint
  .post
  .in(path[String]("projectKey") / "products" / "search")
  .securityIn(path[String]("projectKey"))

Actually matches /:projectKey/:projectKey/products/search.

To work around this problem, we currently employ extractFromRequest, but we consider this solution pretty much an hack.

To properly support this use case, we could instead:

  1. Either leverage a setting in the build definition, which flags a path parameter as a security input for certain endpoints. Something along the lines of scramlSecurityInputs = Map("/:projectKey/products/search" -> "projectKey"), or
  2. Parse the security scopes of an endpoint, and include the matching path parameters as security inputs instead (when present)
@osxhacker
Copy link
Contributor

Hi @smosca-ct ,

As you have identified, Tapir's path method interacts with URI segments much like an IterableOnce. The implementation of securityIn supports this conceptual model:

def securityIn[B, AB](i: EndpointInput[B])(implicit concat: ParamConcat.Aux[A, B, AB]): EndpointType[AB, I, E, O, R] =
    withSecurityInput(securityInput.and(i))

Hence the "double projectKey" matching you documented when securityIn is used with the path method. Where the challenge lies in introducing path-based security tokens is that the specification of supported RAML Security Scheme Types does not define support for path-based tokens. There is a supported security scheme named "Pass Through" which is close to the scenario you describe, but notably does not include path segments:

Headers or query parameters are passed through to the API based on a defined mapping.

To my knowledge, the projectKey concept referenced in the project tests does not refer to a security key/token.

HTH

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