Repository: owncloud/ocis
Pull request #8926 (2024-04-23 07:32:36)

[full-ci] [bump-reva] Replacement for TokenInfo endpoint
<!--
Thanks for submitting a change to ownCloud!

This is the bug tracker for the oCIS component. Find other components at https://github.com/owncloud/core/blob/master/.github/CONTRIBUTING.md#guidelines

For fixing potential security issues please see https://owncloud.org/security/

To make it possible for us to get your change reviewed and merged please carefully fill out the requested information below.

Please note that any kind of change needs first be submitted to the master branch which holds the next version of oCIS.

Please set the following labels:

- Set label "Status:Needs-Review" for review or "Status:In-Progress" if the PR still has open tasks.
- Assignment: assign to self
- Reviewers: pick at least one
-->

## Description
<!--- Describe your changes in detail -->

## Related Issue
<!--- This project only accepts pull requests related to open issues -->
<!--- If suggesting a new feature or change, please discuss it in an issue first -->
<!--- If fixing a bug, there should be an issue describing it with steps to reproduce -->
<!--- Please link to the issue here: -->
[https://github.com/owncloud/ocis/issues/8858](https://github.com/owncloud/ocis/issues/8858)

## Motivation and Context
<!--- Why is this change required? What problem does it solve? -->

## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran to -->
<!--- see how your change affects other areas of the code, etc. -->
- test environment:
- test case 1:
- test case 2:
- ...

## Screenshots (if appropriate):

## Types of changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Technical debt
- [ ] Tests only (no source changes)

## Checklist:
<!-- Tick the checkboxes when done. -->
<!-- Raise documentation ticket in owncloud.github.io/ -->
- [ ] Code changes
- [ ] Unit tests added
- [ ] Acceptance tests added
- [ ] Documentation ticket raised: <link> 


update-docs[bot]: Thanks for opening this pull request! The maintainers of this repository would appreciate it if you would create a [changelog](https://github.com/owncloud/ocis/blob/master/changelog/README.md) item based on your changes.

sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=8926) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [1 New issue](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=8926&resolved=false&inNewCodePeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=8926&metric=new_accepted_issues&view=list)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=8926&resolved=false&inNewCodePeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=8926&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=8926&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=8926)


sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=8926) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [2 New issues](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=8926&resolved=false&inNewCodePeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=8926&metric=new_accepted_issues&view=list)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=8926&resolved=false&inNewCodePeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=8926&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=8926&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=8926)


sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=8926) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [2 New issues](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=8926&resolved=false&inNewCodePeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=8926&metric=new_accepted_issues&view=list)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=8926&resolved=false&inNewCodePeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=8926&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=8926&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=8926)


sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=8926) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [2 New issues](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=8926&resolved=false&inNewCodePeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=8926&metric=new_accepted_issues&view=list)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=8926&resolved=false&inNewCodePeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=8926&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=8926&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=8926)


sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=8926) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [2 New issues](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=8926&resolved=false&inNewCodePeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=8926&metric=new_accepted_issues&view=list)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=8926&resolved=false&inNewCodePeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=8926&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=8926&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=8926)


sonarcloud[bot]: ## [![Quality Gate Failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-failed-20px.png 'Quality Gate Failed')](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=8926) **Quality Gate failed**  
Failed conditions  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/failed-16px.png '') [1 New Bugs](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=8926) (required ≤ 0)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=8926)

##   
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/light_bulb-16px.png '') Catch issues before they fail your Quality Gate with our IDE extension ![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/sonarlint-16px.png '') [SonarLint](https://www.sonarsource.com/products/sonarlint/features/connected-mode/?referrer=pull-request)


sonarcloud[bot]: ## [![Quality Gate Failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-failed-20px.png 'Quality Gate Failed')](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=8926) **Quality Gate failed**  
Failed conditions  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/failed-16px.png '') [1 New Bugs](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=8926) (required ≤ 0)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=8926)

##   
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/light_bulb-16px.png '') Catch issues before they fail your Quality Gate with our IDE extension ![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/sonarlint-16px.png '') [SonarLint](https://www.sonarsource.com/products/sonarlint/features/connected-mode/?referrer=pull-request)


JammingBen: I'm not 100% sure here, but after a quick research I think we can't get rid of the browser auth popup when sending a `401` response code *and* the `WWW-Authenticate` header. So we might need to find a slightly different solution. Things that come to my mind:

* Changing the status code to e.g. `400` (semantically not correct though).
* Remove the `WWW-Authenticate` header so clients need differentiate based on the returned error message. I guess that would be okay if we don't plan to translate it.
sonarcloud[bot]: ## [![Quality Gate Failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-failed-20px.png 'Quality Gate Failed')](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=8926) **Quality Gate failed**  
Failed conditions  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/failed-16px.png '') [1 New Bugs](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=8926) (required ≤ 0)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=8926)

##   
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/light_bulb-16px.png '') Catch issues before they fail your Quality Gate with our IDE extension ![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/sonarlint-16px.png '') [SonarLint](https://www.sonarsource.com/products/sonarlint/features/connected-mode/?referrer=pull-request)


2403905: @JammingBen I removed the `WWW-Authenticate Basic` header
The popup authentication also made the webUITest faled
Please try without authentication popup
JammingBen: > @JammingBen I removed the `WWW-Authenticate Basic` header The popup authentication also made the webUITest faled Please try without authentication popup

Yup that works 👍 I'm simply checking the error message now: https://github.com/owncloud/web/pull/10869/files#diff-90681f8aba50079e5c32cf69d1f1c61af3dbf496f0adfd5fa45936a5647eb767R144. If @micbar or @rhafer don't have any objections I'm fine with that.
sonarcloud[bot]: ## [![Quality Gate Failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-failed-20px.png 'Quality Gate Failed')](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=8926) **Quality Gate failed**  
Failed conditions  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/failed-16px.png '') [1 New Bugs](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=8926) (required ≤ 0)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=8926)

##   
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/light_bulb-16px.png '') Catch issues before they fail your Quality Gate with our IDE extension ![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/sonarlint-16px.png '') [SonarLint](https://www.sonarsource.com/products/sonarlint/features/connected-mode/?referrer=pull-request)


rhafer: @2403905 Now that the reva part is merged we can rebase and remove the reva replacement.
sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=8926) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [2 New issues](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=8926&resolved=false&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=8926&resolutions=WONTFIX)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=8926&resolved=false&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [50.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=8926&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=8926&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=8926)



Patch:
diff --git a/changelog/unreleased/tokenInfo-endpoint-replacement.md b/changelog/unreleased/tokenInfo-endpoint-replacement.md
new file mode 100644
index 00000000000..8a5d1880f3a
--- /dev/null
+++ b/changelog/unreleased/tokenInfo-endpoint-replacement.md
@@ -0,0 +1,13 @@
+Enhancement: Allow to resolve public shares without the ocs tokeninfo endpoint
+
+
+Instead of querying the /v1.php/apps/files_sharing/api/v1/tokeninfo/ endpoint, a client can now resolve public and internal links by sending a PROPFIND request to /dav/public-files/{sharetoken}
+
+* authenticated clients accessing an internal link are redirected to the "real" resource (`/dav/spaces/{target-resource-id}
+* authenticated clients are able to resolve public links like before. For password protected links they need to supply the password even if they have access to the underlying resource by other means.
+* unauthenticated clients accessing an internal link get a 401 returned with  WWW-Authenticate set to Bearer (so that the client knows that it need to get a token via the IDP login page.
+* unauthenticated clients accessing a password protected link get a 401 returned with an error message to indicate the requirement for needing the link's password.
+
+https://github.com/owncloud/ocis/pull/8926
+https://github.com/cs3org/reva/pull/4653
+https://github.com/owncloud/ocis/issues/8858
diff --git a/services/proxy/pkg/command/server.go b/services/proxy/pkg/command/server.go
index cfdb828337a..46987b6ed64 100644
--- a/services/proxy/pkg/command/server.go
+++ b/services/proxy/pkg/command/server.go
@@ -272,10 +272,6 @@ func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config,
 		})
 	}
 
-	authenticators = append(authenticators, middleware.PublicShareAuthenticator{
-		Logger:              logger,
-		RevaGatewaySelector: gatewaySelector,
-	})
 	authenticators = append(authenticators, middleware.NewOIDCAuthenticator(
 		middleware.Logger(logger),
 		middleware.UserInfoCache(userInfoCache),
@@ -291,6 +287,10 @@ func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config,
 		)),
 		middleware.SkipUserInfo(cfg.OIDC.SkipUserInfo),
 	))
+	authenticators = append(authenticators, middleware.PublicShareAuthenticator{
+		Logger:              logger,
+		RevaGatewaySelector: gatewaySelector,
+	})
 	authenticators = append(authenticators, middleware.SignedURLAuthenticator{
 		Logger:             logger,
 		PreSignedURLConfig: cfg.PreSignedURL,
diff --git a/services/proxy/pkg/middleware/basic_auth.go b/services/proxy/pkg/middleware/basic_auth.go
index 913e7404865..81ebadf0e84 100644
--- a/services/proxy/pkg/middleware/basic_auth.go
+++ b/services/proxy/pkg/middleware/basic_auth.go
@@ -18,7 +18,7 @@ type BasicAuthenticator struct {
 
 // Authenticate implements the authenticator interface to authenticate requests via basic auth.
 func (m BasicAuthenticator) Authenticate(r *http.Request) (*http.Request, bool) {
-	if isPublicPath(r.URL.Path) {
+	if isPublicPath(r.URL.Path) && isPublicWithShareToken(r) {
 		// The authentication of public path requests is handled by another authenticator.
 		// Since we can't guarantee the order of execution of the authenticators, we better
 		// implement an early return here for paths we can't authenticate in this authenticator.
diff --git a/services/proxy/pkg/middleware/oidc_auth.go b/services/proxy/pkg/middleware/oidc_auth.go
index 66101921eca..fd3f466a318 100644
--- a/services/proxy/pkg/middleware/oidc_auth.go
+++ b/services/proxy/pkg/middleware/oidc_auth.go
@@ -168,13 +168,16 @@ func (m OIDCAuthenticator) shouldServe(req *http.Request) bool {
 // Authenticate implements the authenticator interface to authenticate requests via oidc auth.
 func (m *OIDCAuthenticator) Authenticate(r *http.Request) (*http.Request, bool) {
 	// there is no bearer token on the request,
-	if !m.shouldServe(r) || isPublicPath(r.URL.Path) {
+	if !m.shouldServe(r) {
 		// The authentication of public path requests is handled by another authenticator.
 		// Since we can't guarantee the order of execution of the authenticators, we better
 		// implement an early return here for paths we can't authenticate in this authenticator.
 		return nil, false
 	}
 	token := strings.TrimPrefix(r.Header.Get(_headerAuthorization), _bearerPrefix)
+	if token == "" {
+		return nil, false
+	}
 
 	claims, err := m.getClaims(token, r)
 	if err != nil {
diff --git a/services/proxy/pkg/middleware/public_share_auth.go b/services/proxy/pkg/middleware/public_share_auth.go
index 403d5d598bb..c7468d6bbcc 100644
--- a/services/proxy/pkg/middleware/public_share_auth.go
+++ b/services/proxy/pkg/middleware/public_share_auth.go
@@ -48,6 +48,13 @@ func isPublicShareAppOpen(r *http.Request) bool {
 		(r.URL.Query().Get(headerShareToken) != "" || r.Header.Get(headerShareToken) != "")
 }
 
+// The public-files requests can also be made in authenticated context. In these cases the OIDCAuthenticator and
+// the BasicAuthenticator needs to ignore the request when the headerShareToken exist.
+func isPublicWithShareToken(r *http.Request) bool {
+	return (strings.HasPrefix(r.URL.Path, "/dav/public-files") || strings.HasPrefix(r.URL.Path, "/remote.php/dav/public-files")) &&
+		(r.URL.Query().Get(headerShareToken) != "" || r.Header.Get(headerShareToken) != "")
+}
+
 // Authenticate implements the authenticator interface to authenticate requests via public share auth.
 func (a PublicShareAuthenticator) Authenticate(r *http.Request) (*http.Request, bool) {
 	if !isPublicPath(r.URL.Path) && !isPublicShareArchive(r) && !isPublicShareAppOpen(r) {


Test patch:
diff --git a/services/proxy/pkg/middleware/authentication_test.go b/services/proxy/pkg/middleware/authentication_test.go
index 17c151aebac..afc9782919d 100644
--- a/services/proxy/pkg/middleware/authentication_test.go
+++ b/services/proxy/pkg/middleware/authentication_test.go
@@ -1,8 +1,27 @@
 package middleware
 
 import (
+	"context"
+	"net/http"
+	"net/http/httptest"
+	"time"
+
+	gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
+	userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
+	rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
+	"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
+	"github.com/golang-jwt/jwt/v4"
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
+	"github.com/owncloud/ocis/v2/ocis-pkg/log"
+	"github.com/owncloud/ocis/v2/ocis-pkg/oidc"
+	oidcmocks "github.com/owncloud/ocis/v2/ocis-pkg/oidc/mocks"
+	"github.com/owncloud/ocis/v2/services/proxy/pkg/router"
+	"github.com/owncloud/ocis/v2/services/proxy/pkg/user/backend"
+	"github.com/owncloud/ocis/v2/services/proxy/pkg/user/backend/mocks"
+	"github.com/stretchr/testify/mock"
+	"go-micro.dev/v4/store"
+	"google.golang.org/grpc"
 )
 
 var _ = Describe("authentication helpers", func() {
@@ -18,3 +37,167 @@ var _ = Describe("authentication helpers", func() {
 		Entry("capabilities", "/ocs/v1.php/cloud/capabilities", true),
 	)
 })
+
+var _ = Describe("Authenticating requests", Label("Authentication"), func() {
+	var (
+		authenticators []Authenticator
+	)
+	oc := oidcmocks.OIDCClient{}
+	oc.On("VerifyAccessToken", mock.Anything, mock.Anything).Return(
+		oidc.RegClaimsWithSID{
+			SessionID: "a-session-id",
+			RegisteredClaims: jwt.RegisteredClaims{
+				ExpiresAt: jwt.NewNumericDate(time.Unix(1147483647, 0)),
+			},
+		}, jwt.MapClaims{
+			"sid": "a-session-id",
+			"exp": 1147483647,
+		},
+		nil,
+	)
+
+	ub := mocks.UserBackend{}
+	ub.On("Authenticate", mock.Anything, "testuser", "testpassword").Return(
+		&userv1beta1.User{
+			Id: &userv1beta1.UserId{
+				Idp:      "IdpId",
+				OpaqueId: "OpaqueId",
+			},
+			Username: "testuser",
+			Mail:     "testuser@example.com",
+		},
+		"",
+		nil,
+	)
+	ub.On("Authenticate", mock.Anything, mock.Anything, mock.Anything).Return(nil, "", backend.ErrAccountNotFound)
+
+	BeforeEach(func() {
+		pool.RemoveSelector("GatewaySelector" + "com.owncloud.api.gateway")
+
+		logger := log.NewLogger()
+		authenticators = []Authenticator{
+			BasicAuthenticator{
+				Logger:       logger,
+				UserProvider: &ub,
+			},
+			&OIDCAuthenticator{
+				OIDCIss:       "http://idp.example.com",
+				Logger:        logger,
+				oidcClient:    &oc,
+				userInfoCache: store.NewMemoryStore(),
+				skipUserInfo:  true,
+			},
+			PublicShareAuthenticator{
+				Logger: logger,
+				RevaGatewaySelector: pool.GetSelector[gateway.GatewayAPIClient](
+					"GatewaySelector",
+					"com.owncloud.api.gateway",
+					func(cc *grpc.ClientConn) gateway.GatewayAPIClient {
+						return mockGatewayClient{
+							AuthenticateFunc: func(authType, clientID, clientSecret string) (string, rpcv1beta1.Code) {
+								if authType != "publicshares" {
+									return "", rpcv1beta1.Code_CODE_NOT_FOUND
+								}
+
+								if clientID == "sharetoken" && (clientSecret == "password|examples3cr3t" || clientSecret == "signature|examplesignature|exampleexpiration") {
+									return "exampletoken", rpcv1beta1.Code_CODE_OK
+								}
+
+								if clientID == "sharetoken" && clientSecret == "password|" {
+									return "otherexampletoken", rpcv1beta1.Code_CODE_OK
+								}
+
+								return "", rpcv1beta1.Code_CODE_NOT_FOUND
+							},
+						}
+					},
+				),
+			},
+		}
+	})
+
+	When("the public request must contains correct data", func() {
+		It("ensures the context oidc data when the Bearer authentication is successful", func() {
+			req := httptest.NewRequest("PROPFIND", "http://example.com/remote.php/dav/public-files/", http.NoBody)
+			req = req.WithContext(router.SetRoutingInfo(context.Background(), router.RoutingInfo{}))
+			req.Header.Set(_headerAuthorization, "Bearer jwt.token.sig")
+
+			handler := Authentication(authenticators,
+				EnableBasicAuth(true),
+			)
+			testHandler := handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+				Expect(oidc.FromContext(r.Context())).To(Equal(map[string]interface{}{
+					"sid": "a-session-id",
+					"exp": int64(1147483647),
+				}))
+			}))
+			rr := httptest.NewRecorder()
+			testHandler.ServeHTTP(rr, req)
+			Expect(rr).To(HaveHTTPStatus(http.StatusOK))
+		})
+		It("ensures the context oidc data when user the Basic authentication is successful", func() {
+			req := httptest.NewRequest("PROPFIND", "http://example.com/remote.php/dav/public-files/", http.NoBody)
+			req = req.WithContext(router.SetRoutingInfo(context.Background(), router.RoutingInfo{}))
+			req.SetBasicAuth("testuser", "testpassword")
+
+			handler := Authentication(authenticators,
+				EnableBasicAuth(true),
+			)
+			testHandler := handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+				Expect(oidc.FromContext(r.Context())).To(Equal(map[string]interface{}{
+					"email":              "testuser@example.com",
+					"ownclouduuid":       "OpaqueId",
+					"iss":                "IdpId",
+					"preferred_username": "testuser",
+				}))
+			}))
+			rr := httptest.NewRecorder()
+			testHandler.ServeHTTP(rr, req)
+			Expect(rr).To(HaveHTTPStatus(http.StatusOK))
+		})
+		It("ensures the x-access-token header when public-token URL parameter is set", func() {
+			req := httptest.NewRequest("PROPFIND", "http://example.com/dav/public-files/?public-token=sharetoken", http.NoBody)
+			req = req.WithContext(router.SetRoutingInfo(context.Background(), router.RoutingInfo{}))
+
+			handler := Authentication(authenticators,
+				EnableBasicAuth(true),
+			)
+			testHandler := handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+				Expect(r.Header.Get(_headerRevaAccessToken)).To(Equal("otherexampletoken"))
+			}))
+			rr := httptest.NewRecorder()
+			testHandler.ServeHTTP(rr, req)
+			Expect(rr).To(HaveHTTPStatus(http.StatusOK))
+		})
+		It("ensures the x-access-token header when public-token URL parameter and BasicAuth are set", func() {
+			req := httptest.NewRequest("PROPFIND", "http://example.com/dav/public-files/?public-token=sharetoken", http.NoBody)
+			req.SetBasicAuth("public", "examples3cr3t")
+			req = req.WithContext(router.SetRoutingInfo(context.Background(), router.RoutingInfo{}))
+
+			handler := Authentication(authenticators,
+				EnableBasicAuth(true),
+			)
+			testHandler := handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+				Expect(r.Header.Get(_headerRevaAccessToken)).To(Equal("exampletoken"))
+			}))
+			rr := httptest.NewRecorder()
+			testHandler.ServeHTTP(rr, req)
+			Expect(rr).To(HaveHTTPStatus(http.StatusOK))
+		})
+		It("ensures the x-access-token header when public-token BasicAuth is set", func() {
+			req := httptest.NewRequest("GET", "http://example.com/archiver", http.NoBody)
+			req.Header.Set("public-token", "sharetoken")
+			req = req.WithContext(router.SetRoutingInfo(context.Background(), router.RoutingInfo{}))
+
+			handler := Authentication(authenticators,
+				EnableBasicAuth(true),
+			)
+			testHandler := handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+				Expect(r.Header.Get(_headerRevaAccessToken)).To(Equal("otherexampletoken"))
+			}))
+			rr := httptest.NewRecorder()
+			testHandler.ServeHTTP(rr, req)
+			Expect(rr).To(HaveHTTPStatus(http.StatusOK))
+		})
+	})
+})
diff --git a/services/proxy/pkg/middleware/oidc_auth_test.go b/services/proxy/pkg/middleware/oidc_auth_test.go
index 589cbbc5c6e..eddb5eb72c5 100644
--- a/services/proxy/pkg/middleware/oidc_auth_test.go
+++ b/services/proxy/pkg/middleware/oidc_auth_test.go
@@ -63,5 +63,39 @@ var _ = Describe("Authenticating requests", Label("OIDCAuthenticator"), func() {
 			Expect(valid).To(Equal(true))
 			Expect(req2).ToNot(BeNil())
 		})
+		It("should successfully authenticate", func() {
+			req := httptest.NewRequest(http.MethodGet, "http://example.com/dav/public-files", http.NoBody)
+			req.Header.Set(_headerAuthorization, "Bearer jwt.token.sig")
+
+			req2, valid := authenticator.Authenticate(req)
+
+			Expect(valid).To(Equal(true))
+			Expect(req2).ToNot(BeNil())
+		})
+		It("should skip authenticate if the header ShareToken is set", func() {
+			req := httptest.NewRequest(http.MethodGet, "http://example.com/dav/public-files/", http.NoBody)
+			req.Header.Set(_headerAuthorization, "Bearer jwt.token.sig")
+			req.Header.Set(headerShareToken, "sharetoken")
+
+			req2, valid := authenticator.Authenticate(req)
+
+			// TODO Should the authentication of public path requests is handled by another authenticator?
+			//Expect(valid).To(Equal(false))
+			//Expect(req2).To(BeNil())
+			Expect(valid).To(Equal(true))
+			Expect(req2).ToNot(BeNil())
+		})
+		It("should skip authenticate if the 'public-token' is set", func() {
+			req := httptest.NewRequest(http.MethodGet, "http://example.com/dav/public-files/?public-token=sharetoken", http.NoBody)
+			req.Header.Set(_headerAuthorization, "Bearer jwt.token.sig")
+
+			req2, valid := authenticator.Authenticate(req)
+
+			// TODO Should the authentication of public path requests is handled by another authenticator?
+			//Expect(valid).To(Equal(false))
+			//Expect(req2).To(BeNil())
+			Expect(valid).To(Equal(true))
+			Expect(req2).ToNot(BeNil())
+		})
 	})
 })