You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm working on a Quarkus application that interacts with Forgejo/Gitea via its own rest client interfaces. I've been trying to replace the custom interfaces with ones generated directly from the specification using this library. However, I am running into an issue with the CompositeAuthenticationProvider mechanism.
I will go into more details, but firstly let me provide a snippet of the spec relevant to the issue:
schemes:
- https
- httpswagger: '2.0'info:
description: This documentation describes the Forgejo API.title: Forgejo APIlicense:
name: This file is distributed under the MIT license for the purpose of interoperabilityurl: http://opensource.org/licenses/MITversion: 9.0.3+gitea-1.22.0paths:
/api/v1/repos/{owner}/{repo}/contents/{filepath}:
get:
produces:
- application/jsontags:
- repositorysummary: Gets the metadata and contents (if a file) of an entry in a repository, or a list of entries if a diroperationId: repoGetContentsparameters:
- type: stringdescription: owner of the reponame: ownerin: pathrequired: true
- type: stringdescription: name of the reponame: repoin: pathrequired: true
- type: stringdescription: path of the dir, file, symlink or submodule in the reponame: filepathin: pathrequired: true
- type: stringdescription: The name of the commit/branch/tag. Default the repository’s default branch (usually master)name: refin: queryresponses:
'200':
description: Successful responseschema:
type: arrayitems:
$ref: '#/definitions/ContentsResponse''404':
$ref: '#/responses/notFound'securityDefinitions:
AuthorizationHeaderToken:
description: API tokens must be prepended with "token" followed by a space.type: apiKeyname: Authorizationin: headersecurity:
- AuthorizationHeaderToken: []
I've omitted everything that has no impact on the issue for brevity.
So, I am injecting the RepositoryApi, which looks like this:
/** * Forgejo API * <p>This documentation describes the Forgejo API.</p> */@jakarta.ws.rs.Path("/api/v1")
@org.eclipse.microprofile.rest.client.inject.RegisterRestClient(configKey="forgejo_yaml")
@io.quarkiverse.openapi.generator.annotations.GeneratedClass(value="forgejo.yaml", tag = "Repository")
@org.eclipse.microprofile.rest.client.annotation.RegisterProvider(com.example.forgejo.api.auth.CompositeAuthenticationProvider.class)
@org.eclipse.microprofile.rest.client.annotation.RegisterClientHeaders(com.example.forgejo.api.auth.AuthenticationPropagationHeadersFactory.class)
@jakarta.enterprise.context.ApplicationScopedpublicinterfaceRepositoryApi {
/** * Gets the metadata and contents (if a file) of an entry in a repository, or a list of entries if a dir * * @param owner owner of the repo * @param repo name of the repo * @param filepath path of the dir, file, symlink or submodule in the repo * @param ref The name of the commit/branch/tag. Default the repository’s default branch (usually master) */@io.quarkiverse.openapi.generator.markers.OperationMarker(name="AuthorizationHeaderToken", openApiSpecId="forgejo_yaml", operationId="repoGetContents", method="GET", path="/api/v1/repos/{owner}/{repo}/contents/{filepath}")
@jakarta.ws.rs.GET@jakarta.ws.rs.Path("/repos/{owner}/{repo}/contents/{filepath}")
@jakarta.ws.rs.Produces({"application/json"})
@io.quarkiverse.openapi.generator.annotations.GeneratedMethod("repoGetContents")
publicList<ContentsResponse> repoGetContents(
@io.quarkiverse.openapi.generator.annotations.GeneratedParam("owner") @jakarta.ws.rs.PathParam("owner")Stringowner,
@io.quarkiverse.openapi.generator.annotations.GeneratedParam("repo") @jakarta.ws.rs.PathParam("repo")Stringrepo,
@io.quarkiverse.openapi.generator.annotations.GeneratedParam("filepath") @jakarta.ws.rs.PathParam("filepath")Stringfilepath,
@io.quarkiverse.openapi.generator.annotations.GeneratedParam("ref") @jakarta.ws.rs.QueryParam("ref") Stringref
);
}
In order to use the built-in mechanism for Authentication, I've added the following property:
Yet. when I use the client to retrieve contents of a filepath that contains / into it, the mechanism fails to add the Authorization header. Upon debugging, it became clear that the fault lies on OperationAuthInfo#matchPath and the underlying UrlPatternMatcher.
Lets say that I am invoking the repoGetContents with a filepath value of some/dir, this value will be URL Encoded by the client to some%2Fdir when the HTTP request is actually made. However, OperationAuthInfo#matchPath is called by CompositeAuthenticationProvider with a requestUrl value of some/dir, which is passed to the UrlPatternMatcher instance and it fails the match because the compiler URL pattern is
Now, the obvious first thought is to URL encode the String filepath. I've added it and debugged, by doing so the pattern will match, yet the integration tests will fail, because the client will double encode the final path, so this simple solution is not viable.
I've looked all over your documentation, but couldn't find anything similar to this, or any configuration that I could add that would add something like the @Encoded annotation to this parameter.
Have you faced anything similar? Anyone know any possible solution with the existing version, or would it require changes to the library?
Best regards
The text was updated successfully, but these errors were encountered:
jorgebsa
changed the title
Can't use built-in auth mechanism due to OperationAuthInfo#matchPath failure given requestPath isn't URL Encoded at the time it's called
CompositeAuthenticationProvider fails to apply authentication if a parameter of the path must be URL encoded
Jan 17, 2025
Hi @jorgebsa, thanks for reporting this issue. I haven't seen this problem before, so if you have an idea how to improve or fix it, please feel free to send a PR.
I'm working on a Quarkus application that interacts with Forgejo/Gitea via its own rest client interfaces. I've been trying to replace the custom interfaces with ones generated directly from the specification using this library. However, I am running into an issue with the
CompositeAuthenticationProvider
mechanism.I will go into more details, but firstly let me provide a snippet of the spec relevant to the issue:
I've omitted everything that has no impact on the issue for brevity.
So, I am injecting the
RepositoryApi
, which looks like this:In order to use the built-in mechanism for Authentication, I've added the following property:
quarkus.openapi-generator.forgejo_yaml.auth.AuthorizationHeaderToken.api-key=test my-token
Yet. when I use the client to retrieve contents of a
filepath
that contains/
into it, the mechanism fails to add theAuthorization
header. Upon debugging, it became clear that the fault lies onOperationAuthInfo#matchPath
and the underlyingUrlPatternMatcher
.Lets say that I am invoking the
repoGetContents
with afilepath
value ofsome/dir
, this value will be URL Encoded by the client tosome%2Fdir
when the HTTP request is actually made. However,OperationAuthInfo#matchPath
is called byCompositeAuthenticationProvider
with arequestUrl
value ofsome/dir
, which is passed to theUrlPatternMatcher
instance and it fails the match because the compiler URL pattern is/api/v1/repos/([%\w-.\~!$&'\(\)\*\+,;=:\[\]@]+?)/([%\w-.\~!$&'\(\)\*\+,;=:\[\]@]+?)/contents/([%\w-.\~!$&'\(\)\*\+,;=:\[\]@]+?)(?:\?.*?)?$
Now, the obvious first thought is to URL encode the String
filepath
. I've added it and debugged, by doing so the pattern will match, yet the integration tests will fail, because the client will double encode the final path, so this simple solution is not viable.I've looked all over your documentation, but couldn't find anything similar to this, or any configuration that I could add that would add something like the
@Encoded
annotation to this parameter.Have you faced anything similar? Anyone know any possible solution with the existing version, or would it require changes to the library?
Best regards
The text was updated successfully, but these errors were encountered: