diff --git a/changelog/unreleased/ocm-discovery.md b/changelog/unreleased/ocm-discovery.md new file mode 100644 index 0000000000..7fc0da8a4f --- /dev/null +++ b/changelog/unreleased/ocm-discovery.md @@ -0,0 +1,6 @@ +Enhancement: new OCM discovery endpoint + +This PR implements the new OCM v1.1 specifications +for the /ocm-provider endpoint. + +https://github.com/cs3org/reva/pull/3772 diff --git a/examples/nextcloud-integration/revad.toml b/examples/nextcloud-integration/revad.toml index fda4fe6428..f44a43f4fa 100644 --- a/examples/nextcloud-integration/revad.toml +++ b/examples/nextcloud-integration/revad.toml @@ -127,6 +127,10 @@ user_layout = "{{.Username}}" [http.services.ocmd] prefix = "ocm" +provider = "Reva-Nextcloud" +endpoint = "http://localhost" +enable_webapp = true +enable_datatx = true [http.middlewares.providerauthorizer] driver = "json" diff --git a/examples/oc-phoenix/ocmd.toml b/examples/oc-phoenix/ocmd.toml index 37ad659d12..1814c6157f 100644 --- a/examples/oc-phoenix/ocmd.toml +++ b/examples/oc-phoenix/ocmd.toml @@ -34,6 +34,7 @@ address = "0.0.0.0:13001" [http.services.ocmd] prefix = "ocm" +endpoint = "http://localhost:13001" [http.middlewares.providerauthorizer] driver = "json" diff --git a/examples/ocmd/server-1/ocmd-server-1.toml b/examples/ocmd/server-1/ocmd-server-1.toml index 8f6132d29c..7f826f3da8 100644 --- a/examples/ocmd/server-1/ocmd-server-1.toml +++ b/examples/ocmd/server-1/ocmd-server-1.toml @@ -122,6 +122,10 @@ user_layout = "{{.Username}}" [http.services.ocmd] prefix = "ocm" +provider = "reva@cern" +endpoint = "http://localhost:19001" +enable_webapp = true +enable_datatx = true [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 99eac947f8..745c46eefa 100644 --- a/examples/ocmd/server-2/ocmd-server-2.toml +++ b/examples/ocmd/server-2/ocmd-server-2.toml @@ -113,6 +113,10 @@ user_layout = "{{.Username}}" [http.services.ocmd] prefix = "ocm" +provider = "reva@cesnet" +endpoint = "http://localhost:17001" +enable_webapp = true +enable_datatx = true [http.middlewares.providerauthorizer] driver = "json" diff --git a/examples/two-server-setup/gateway-1.toml b/examples/two-server-setup/gateway-1.toml index 6b7051d80e..912b24d043 100644 --- a/examples/two-server-setup/gateway-1.toml +++ b/examples/two-server-setup/gateway-1.toml @@ -54,6 +54,11 @@ address = "0.0.0.0:19001" [http.services.datagateway] [http.services.prometheus] [http.services.ocmd] +provider = "Reva-Server-1" +endpoint = "http://localhost:19001" +enable_webapp = true +enable_datatx = true + [http.services.ocdav] [http.services.ocs] diff --git a/examples/two-server-setup/gateway-2.toml b/examples/two-server-setup/gateway-2.toml index e3379e93eb..04186a7e5b 100644 --- a/examples/two-server-setup/gateway-2.toml +++ b/examples/two-server-setup/gateway-2.toml @@ -69,6 +69,11 @@ address = "0.0.0.0:29001" [http.services.datagateway] [http.services.prometheus] [http.services.ocmd] +provider = "Reva-Server-2" +endpoint = "http://localhost:29001" +enable_webapp = true +enable_datatx = true + [http.services.ocdav] [http.services.ocs] diff --git a/internal/http/services/ocmd/config.go b/internal/http/services/ocmd/discovery.go similarity index 52% rename from internal/http/services/ocmd/config.go rename to internal/http/services/ocmd/discovery.go index a8666e53f1..891f914cf9 100644 --- a/internal/http/services/ocmd/config.go +++ b/internal/http/services/ocmd/discovery.go @@ -26,62 +26,55 @@ import ( "github.com/cs3org/reva/pkg/appctx" ) -type configData struct { +type discoveryData struct { Enabled bool `json:"enabled" xml:"enabled"` APIVersion string `json:"apiVersion" xml:"apiVersion"` - Host string `json:"host" xml:"host"` Endpoint string `json:"endPoint" xml:"endPoint"` Provider string `json:"provider" xml:"provider"` ResourceTypes []resourceTypes `json:"resourceTypes" xml:"resourceTypes"` + Capabilities []string `json:"capabilities" xml:"capabilities"` } type resourceTypes struct { - Name string `json:"name"` - ShareTypes []string `json:"shareTypes"` - Protocols resourceTypesProtocols `json:"protocols"` + Name string `json:"name"` + ShareTypes []string `json:"shareTypes"` + Protocols map[string]string `json:"protocols"` } -type resourceTypesProtocols struct { - Webdav string `json:"webdav"` +type discoHandler struct { + d discoveryData } -type configHandler struct { - c configData -} - -func (h *configHandler) init(c *config) { - h.c = c.Config - if h.c.APIVersion == "" { - h.c.APIVersion = "1.0-proposal1" - } - if h.c.Host == "" { - h.c.Host = "localhost" - } - if h.c.Provider == "" { - h.c.Provider = "cernbox" +func (h *discoHandler) init(c *config) { + h.d.Enabled = true + h.d.APIVersion = "1.1.0" + h.d.Endpoint = fmt.Sprintf("%s/%s", c.Endpoint, c.Prefix) + h.d.Provider = c.Provider + rtProtos := map[string]string{} + // webdav is always enabled + rtProtos["webdav"] = fmt.Sprintf("%s/remote.php/dav/%s", c.Endpoint, c.Prefix) + if c.EnableWebApp { + rtProtos["webapp"] = fmt.Sprintf("%s/external/sciencemesh", c.Endpoint) } - h.c.Enabled = true - if len(c.Prefix) > 0 { - h.c.Endpoint = fmt.Sprintf("https://%s/%s", h.c.Host, c.Prefix) - } else { - h.c.Endpoint = fmt.Sprintf("https://%s", h.c.Host) + if c.EnableDataTx { + rtProtos["datatx"] = fmt.Sprintf("%s/remote.php/dav/%s", c.Endpoint, c.Prefix) } - h.c.ResourceTypes = []resourceTypes{{ - Name: "file", - ShareTypes: []string{"user"}, - Protocols: resourceTypesProtocols{ - Webdav: fmt.Sprintf("/%s/ocm_webdav", h.c.Provider), - }, + h.d.ResourceTypes = []resourceTypes{{ + Name: "file", // so far we only support `file` + ShareTypes: []string{"user"}, // so far we only support `user` + Protocols: rtProtos, // expose the protocols as per configuration }} + // for now we hardcode the capabilities, as this is currently only advisory + h.d.Capabilities = []string{"/invite-accepted"} } -// Send sends the configuration to the caller. -func (h *configHandler) Send(w http.ResponseWriter, r *http.Request) { +// Send sends the discovery info to the caller. +func (h *discoHandler) Send(w http.ResponseWriter, r *http.Request) { log := appctx.GetLogger(r.Context()) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - indentedConf, _ := json.MarshalIndent(h.c, "", " ") + indentedConf, _ := json.MarshalIndent(h.d, "", " ") if _, err := w.Write(indentedConf); err != nil { log.Err(err).Msg("Error writing to ResponseWriter") } diff --git a/internal/http/services/ocmd/ocm.go b/internal/http/services/ocmd/ocm.go index f998db52da..f91f29c4ae 100644 --- a/internal/http/services/ocmd/ocm.go +++ b/internal/http/services/ocmd/ocm.go @@ -34,10 +34,13 @@ func init() { } type config struct { - Prefix string `mapstructure:"prefix"` - GatewaySvc string `mapstructure:"gatewaysvc"` - Config configData `mapstructure:"config"` - ExposeRecipientDisplayName bool `mapstructure:"expose_recipient_display_name"` + Prefix string `mapstructure:"prefix"` + GatewaySvc string `mapstructure:"gatewaysvc"` + Endpoint string `mapstructure:"endpoint"` + Provider string `mapstructure:"provider"` + EnableWebApp bool `mapstructure:"enable_webapp"` + EnableDataTx bool `mapstructure:"enable_datatx"` + ExposeRecipientDisplayName bool `mapstructure:"expose_recipient_display_name"` } func (c *config) init() { @@ -46,6 +49,12 @@ func (c *config) init() { if c.Prefix == "" { c.Prefix = "ocm" } + if c.Endpoint == "" { + c.Endpoint = "http://localhost" + } + if c.Provider == "" { + c.Provider = "reva" + } } type svc struct { @@ -76,12 +85,12 @@ func New(m map[string]interface{}, log *zerolog.Logger) (global.Service, error) } func (s *svc) routerInit() error { - configHandler := new(configHandler) + discoHandler := new(discoHandler) sharesHandler := new(sharesHandler) notificationsHandler := new(notificationsHandler) invitesHandler := new(invitesHandler) - configHandler.init(s.Conf) + discoHandler.init(s.Conf) if err := sharesHandler.init(s.Conf); err != nil { return err } @@ -90,7 +99,7 @@ func (s *svc) routerInit() error { return err } - s.router.Get("/ocm-provider", configHandler.Send) // FIXME: where this endpoint is documented? + s.router.Get("/ocm-provider", discoHandler.Send) s.router.Post("/shares", sharesHandler.CreateShare) s.router.Post("/notifications", notificationsHandler.SendNotification) s.router.Post("/invite-accepted", invitesHandler.AcceptInvite)