diff --git a/changelog/unreleased/public-share-auth-provider.md b/changelog/unreleased/public-share-auth-provider.md new file mode 100644 index 0000000000..1354686f37 --- /dev/null +++ b/changelog/unreleased/public-share-auth-provider.md @@ -0,0 +1,5 @@ +Enhancement: add public share auth provider + +Add a public share auth middleware + +https://github.com/cs3org/reva/pull/3056 diff --git a/internal/http/interceptors/auth/auth.go b/internal/http/interceptors/auth/auth.go index 822f26dce3..1a10d4fccc 100644 --- a/internal/http/interceptors/auth/auth.go +++ b/internal/http/interceptors/auth/auth.go @@ -100,7 +100,7 @@ func New(m map[string]interface{}, unprotected []string) (global.Middleware, err } if len(conf.CredentialChain) == 0 { - conf.CredentialChain = []string{"basic", "bearer"} + conf.CredentialChain = []string{"basic", "bearer", "publicshares"} } if conf.CredentialsByUserAgent == nil { diff --git a/internal/http/interceptors/auth/credential/loader/loader.go b/internal/http/interceptors/auth/credential/loader/loader.go index d67ab160bd..af503c1967 100644 --- a/internal/http/interceptors/auth/credential/loader/loader.go +++ b/internal/http/interceptors/auth/credential/loader/loader.go @@ -22,5 +22,6 @@ import ( // Load core authentication strategies. _ "github.com/cs3org/reva/internal/http/interceptors/auth/credential/strategy/basic" _ "github.com/cs3org/reva/internal/http/interceptors/auth/credential/strategy/bearer" + _ "github.com/cs3org/reva/internal/http/interceptors/auth/credential/strategy/publicshares" // Add your own here. ) diff --git a/internal/http/interceptors/auth/credential/strategy/publicshares/publicshares.go b/internal/http/interceptors/auth/credential/strategy/publicshares/publicshares.go new file mode 100644 index 0000000000..e39289dfd0 --- /dev/null +++ b/internal/http/interceptors/auth/credential/strategy/publicshares/publicshares.go @@ -0,0 +1,65 @@ +// Copyright 2018-2021 CERN +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// In applying this license, CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +package publicshares + +import ( + "fmt" + "net/http" + + "github.com/cs3org/reva/internal/http/interceptors/auth/credential/registry" + "github.com/cs3org/reva/pkg/auth" +) + +func init() { + registry.Register("publicshares", New) +} + +const ( + headerShareToken = "public-token" + basicAuthPasswordPrefix = "password|" +) + +type strategy struct{} + +// New returns a new auth strategy that handles public share verification +func New(m map[string]interface{}) (auth.CredentialStrategy, error) { + return &strategy{}, nil +} + +func (s *strategy) GetCredentials(w http.ResponseWriter, r *http.Request) (*auth.Credentials, error) { + token := r.Header.Get(headerShareToken) + if token == "" { + token = r.URL.Query().Get(headerShareToken) + } + if token == "" { + return nil, fmt.Errorf("no public token provided") + } + + // We can ignore the username since it is always set to "public" in public shares. + sharePassword := basicAuthPasswordPrefix + _, password, ok := r.BasicAuth() + if ok { + sharePassword += password + } + return &auth.Credentials{Type: "publicshares", ClientID: token, ClientSecret: sharePassword}, nil +} + +func (s *strategy) AddWWWAuthenticate(w http.ResponseWriter, r *http.Request, realm string) { + // TODO read realm from forwarded header? +}