Add AuthType.Cookie(name) for endpoint cookie authentication - #4112
Draft
guizmaii wants to merge 11 commits into
Draft
Add AuthType.Cookie(name) for endpoint cookie authentication#4112guizmaii wants to merge 11 commits into
AuthType.Cookie(name) for endpoint cookie authentication#4112guizmaii wants to merge 11 commits into
Conversation
`AuthType.Custom(HeaderCodec.cookie)` already let an endpoint accept
auth via a cookie header, but it returned the entire `Header.Cookie`
value (a `NonEmptyChunk[Cookie.Request]`) and required the user to
hand-roll the lookup-by-name plus the encode-side codec. This adds a
typed shortcut that does both:
```scala
Endpoint(Method.GET / "download" / fileId)
.auth(AuthType.Bearer | AuthType.Cookie("session"))
.unauthorizedStatus(Status.Unauthorized)
```
The handler / context middleware receives the cookie value as a `String`.
If the named cookie is missing, the codec fails to decode and the
endpoint responds with `unauthorizedStatus` -- matching the existing
behaviour for `Basic`/`Bearer`/`Digest` when the `Authorization` header
is absent. Hooked into `Endpoint`'s missing-header handler via a small
`authHeaderNames` helper that walks `Or` / `WithStatus` / `ScopedAuth`
wrappers, so composed auth types behave consistently too.
✅ Deploy Preview for zio-http ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
- Make the codec error message end with " auth required" so the endpoint returns `unauthorizedStatus` (matching `Basic`/`Bearer`/ `Digest`) when the `Cookie` header is present but the named cookie is absent. Previously this path leaked a generic decode error. - Handle `AuthType.Cookie` in both `OpenAPIGen` loops so endpoints using it emit an `apiKey` security scheme with `in: cookie` and the corresponding security requirement, matching what the `AuthType.Custom(HeaderCodec.cookie)` workaround produced. - Add a test exercising the present-but-wrong-name cookie path.
- Keep "authorization" in authHeaderNames(Custom(_)) for backward
compatibility: the pre-existing missing-header → unauth flow fired on
any missing Authorization header regardless of auth type, so a Custom
auth on Authorization would otherwise silently lose its 401 response.
- Sanitize the OpenAPI components-map key for AuthType.Cookie to
[A-Za-z0-9._-]+ so unusual cookie names can't crash OpenAPI
generation. The actual cookie name is preserved verbatim in
SecurityScheme.ApiKey.name.
- Add three tests for the AuthType.Bearer | AuthType.Cookie("session")
combined path (Bearer wins, Cookie wins, neither → 401 when
configured).
- Add an OpenAPIGenSpec test asserting the JSON shape produced by
AuthType.Cookie("session").
"session" looks like a magic keyword; "myAppAuthCookie" makes it obvious the argument is the caller's choice of cookie name.
Matches the Scaladoc example and makes it obvious throughout the tests that the argument to AuthType.Cookie is the caller's chosen cookie name, not a magic keyword.
- Switch return type from List to Set (the result is only ever used with .contains; duplicates make no semantic sense). - Use a worklist + inner @tailrec loop so deep AuthType trees can't overflow the stack. - Accumulate into a local mutable Set inside the function and freeze to immutable on return; the mutation is contained and avoids allocating an intermediate Set per recursion step.
Makes the data flow visible in the signature instead of capturing the mutable Set from the enclosing scope.
…base case Import scala.collection.mutable so the body uses the short `mutable.Set` name. Drop the wrapper function and convert from mutable to immutable Set inside the recursion's base case, so the function's return type is the immutable `Set[String]` the call site needs.
Outer function takes just the AuthType and returns Set[String]; an inner @tailrec loop carries the mutable accumulator and converts to immutable Set at the base case. Caller stays simple.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
AuthType.Custom(HeaderCodec.cookie)already let an endpoint accept auth via a cookie header, but it returned the entireHeader.Cookievalue (aNonEmptyChunk[Cookie.Request]) and required the user to hand-roll the lookup-by-name plus the encode-side codec. This adds a typed shortcut that does both:The handler / context middleware receives the cookie value as a
String. If the named cookie is missing, the codec fails to decode and the endpoint responds withunauthorizedStatus-- matching the existing behaviour forBasic/Bearer/Digestwhen theAuthorizationheader is absent. Hooked intoEndpoint's missing-header handler via a smallauthHeaderNameshelper that walksOr/WithStatus/ScopedAuthwrappers, so composed auth types behave consistently too.