diff --git a/examples/meshdirectory/meshdirectory.toml b/examples/meshdirectory/meshdirectory.toml index 1bea8c36e03..8373cefcc62 100644 --- a/examples/meshdirectory/meshdirectory.toml +++ b/examples/meshdirectory/meshdirectory.toml @@ -25,6 +25,7 @@ file = "/var/tmp/reva/shares_server_1.json" [http.services.prometheus] [http.services.ocmd] [http.services.ocmprovider] +[http.services.ocsprovider] [http.services.ocdav] [http.services.ocs] diff --git a/examples/nextcloud-integration/revad.toml b/examples/nextcloud-integration/revad.toml index 97288f5cf88..717ae0d09c9 100644 --- a/examples/nextcloud-integration/revad.toml +++ b/examples/nextcloud-integration/revad.toml @@ -135,6 +135,8 @@ webdav_root = "/remote.php/dav/ocm" enable_webapp = true enable_datatx = true +[http.services.ocsprovider] + [http.services.sciencemesh] mesh_directory_url = 'https://sciencemesh.cesnet.cz/iop/meshdir' provider_domain = 'your-domain.org' diff --git a/examples/ocmd/server-1/ocmd-server-1.toml b/examples/ocmd/server-1/ocmd-server-1.toml index 0d9adbf513c..d2d70b26e78 100644 --- a/examples/ocmd/server-1/ocmd-server-1.toml +++ b/examples/ocmd/server-1/ocmd-server-1.toml @@ -154,6 +154,8 @@ endpoint = "http://localhost:19001" enable_webapp = true enable_datatx = true +[http.services.ocsprovider] + [http.middlewares.providerauthorizer] driver = "json" diff --git a/examples/ocmd/server-2/ocmd-server-2.toml b/examples/ocmd/server-2/ocmd-server-2.toml index 755d00116e0..3e859fffa2b 100644 --- a/examples/ocmd/server-2/ocmd-server-2.toml +++ b/examples/ocmd/server-2/ocmd-server-2.toml @@ -145,6 +145,8 @@ endpoint = "http://localhost:17001" enable_webapp = true enable_datatx = true +[http.services.ocsprovider] + [http.middlewares.providerauthorizer] driver = "json" diff --git a/examples/standalone/standalone.toml b/examples/standalone/standalone.toml index 0b54edd8419..5c069732752 100644 --- a/examples/standalone/standalone.toml +++ b/examples/standalone/standalone.toml @@ -18,5 +18,6 @@ [http.services.prometheus] [http.services.ocmd] [http.services.ocmprovider] +[http.services.ocsprovider] [http.services.ocdav] [http.services.ocs] diff --git a/examples/storage-references/gateway.toml b/examples/storage-references/gateway.toml index 0cbed478ae4..71be7f6e763 100644 --- a/examples/storage-references/gateway.toml +++ b/examples/storage-references/gateway.toml @@ -58,6 +58,7 @@ app_url = "https://your-collabora-server.org:9980" [http.services.prometheus] [http.services.ocmd] [http.services.ocmprovider] +[http.services.ocsprovider] [http.services.ocdav] [http.services.ocs] diff --git a/examples/two-server-setup/gateway-1.toml b/examples/two-server-setup/gateway-1.toml index 6421454da3a..f89a70de873 100644 --- a/examples/two-server-setup/gateway-1.toml +++ b/examples/two-server-setup/gateway-1.toml @@ -101,6 +101,7 @@ endpoint = "http://localhost:19001" enable_webapp = true enable_datatx = true +[http.services.ocsprovider] [http.services.ocdav] [http.services.ocs] [http.services.sciencemesh] diff --git a/examples/two-server-setup/gateway-2.toml b/examples/two-server-setup/gateway-2.toml index 65aa63a30f9..098c36f1391 100644 --- a/examples/two-server-setup/gateway-2.toml +++ b/examples/two-server-setup/gateway-2.toml @@ -102,6 +102,7 @@ enable_webapp = true enable_datatx = true [http.services.ocdav] +[http.services.ocsprovider] [http.services.ocs] [http.services.sciencemesh] diff --git a/internal/http/services/loader/loader.go b/internal/http/services/loader/loader.go index adf1ad02dab..0c1064547bf 100644 --- a/internal/http/services/loader/loader.go +++ b/internal/http/services/loader/loader.go @@ -30,6 +30,7 @@ import ( _ "github.com/cs3org/reva/internal/http/services/metrics" _ "github.com/cs3org/reva/internal/http/services/ocmd" _ "github.com/cs3org/reva/internal/http/services/ocmprovider" + _ "github.com/cs3org/reva/internal/http/services/ocsprovider" _ "github.com/cs3org/reva/internal/http/services/owncloud/ocdav" _ "github.com/cs3org/reva/internal/http/services/owncloud/ocs" _ "github.com/cs3org/reva/internal/http/services/preferences" diff --git a/internal/http/services/ocsprovider/ocsprovider.go b/internal/http/services/ocsprovider/ocsprovider.go new file mode 100644 index 00000000000..0dc5561ce1e --- /dev/null +++ b/internal/http/services/ocsprovider/ocsprovider.go @@ -0,0 +1,124 @@ +// Copyright 2018-2023 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 ocsprovider + +import ( + "encoding/json" + "net/http" + + "github.com/cs3org/reva/pkg/appctx" + "github.com/cs3org/reva/pkg/rhttp/global" + "github.com/mitchellh/mapstructure" + "github.com/rs/zerolog" +) + +func init() { + global.Register("ocsprovider", New) +} + +type config struct { + WebdavRoot string `mapstructure:"webdav_root" docs:"/remote.php/dav/ocm;The root URL of the WebDAV endpoint to serve OCM shares."` +} + +type ocsDiscoveryData struct { + Version int `json:"version"` + Services ocsServices `json:"services"` +} + +type ocsServices struct { + PrivateData map[string]any `json:"PRIVATE_DATA"` + Sharing map[string]any `json:"SHARING"` + FederatedSharing map[string]any `json:"FEDERATED_SHARING"` + Provisioning map[string]any `json:"PROVISIONING"` +} + +type svc struct { + data *ocsDiscoveryData +} + +func (c *config) init() { + if c.WebdavRoot == "" { + // same default as for the /ocm-provider discovery service + c.WebdavRoot = "/remote.php/dav/ocm/" + } + if c.WebdavRoot[len(c.WebdavRoot)-1:] != "/" { + c.WebdavRoot += "/" + } +} + +func (c *config) prepare() *ocsDiscoveryData { + // generates the (static) data structure to be exposed by /ocs-provider: + // here we only populate the federated sharing part and leave the rest empty + var fedSharingData = map[string]any{ + "version": 1, + "endpoints": map[string]string{ + "share": "/ocs/v1.php/apps/files_sharing/api/v1/shares/remote_shares", + "webdav": c.WebdavRoot, + }, + } + d := &ocsDiscoveryData{} + d.Version = 2 + d.Services = ocsServices{ + PrivateData: map[string]any{}, + Sharing: map[string]any{}, + FederatedSharing: fedSharingData, + Provisioning: map[string]any{}, + } + return d +} + +// New returns a new ocsprovider object, that implements +// a minimal OCS discovery endpoint similar to OC10 or NC. +// OCS specs are defined at: +// https://www.freedesktop.org/wiki/Specifications/open-collaboration-services +func New(m map[string]interface{}, log *zerolog.Logger) (global.Service, error) { + conf := &config{} + if err := mapstructure.Decode(m, conf); err != nil { + return nil, err + } + + conf.init() + return &svc{data: conf.prepare()}, nil +} + +// Close performs cleanup. +func (s *svc) Close() error { + return nil +} + +func (s *svc) Prefix() string { + // this is hardcoded as per OCS specifications + return "/ocs-provider" +} + +func (s *svc) Unprotected() []string { + return []string{"/"} +} + +func (s *svc) Handler() http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + log := appctx.GetLogger(r.Context()) + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + indented, _ := json.MarshalIndent(s.data, "", " ") + if _, err := w.Write(indented); err != nil { + log.Err(err).Msg("Error writing to ResponseWriter") + } + }) +}