diff --git a/model/instance/instance_test.go b/model/instance/instance_test.go index af18fde7b5d..d2c8837c56c 100644 --- a/model/instance/instance_test.go +++ b/model/instance/instance_test.go @@ -61,7 +61,6 @@ func TestInstance(t *testing.T) { cfg.Contexts = map[string]interface{}{ "context": map[string]interface{}{ - "manager_url": "http://manager.example.org", "logos": map[string]interface{}{ "coachco2": map[string]interface{}{ "light": []interface{}{ @@ -173,8 +172,7 @@ func TestInstance(t *testing.T) { } ] } - }, - "manager_url": "http://manager.example.org" + } }` assert.Equal(t, expected, string(bytes)) }) diff --git a/model/instance/manager.go b/model/instance/manager.go index ebfe579baac..61bdc61054f 100644 --- a/model/instance/manager.go +++ b/model/instance/manager.go @@ -19,22 +19,24 @@ const ( ManagerPremiumURL // ManagerBlockedURL is the kind for a redirection of a blocked instance. ManagerBlockedURL + // ManagerBaseURL is the kind for building other manager URLs + ManagerBaseURL ) // ManagerURL returns an external string for the given ManagerURL kind. It is // used for redirecting the user to a manager URL. func (i *Instance) ManagerURL(k ManagerURLKind) (string, error) { - if i.UUID == "" { + c := clouderyConfig(i) + if c == nil { return "", nil } - config, ok := i.SettingsContext() - if !ok { + if i.UUID == "" { return "", nil } - base, ok := config["manager_url"].(string) - if !ok { + base := c.API.URL + if base == "" { return "", nil } @@ -51,6 +53,8 @@ func (i *Instance) ManagerURL(k ManagerURLKind) (string, error) { path = fmt.Sprintf("/cozy/instances/%s/tos", url.PathEscape(i.UUID)) case ManagerBlockedURL: path = fmt.Sprintf("/cozy/instances/%s/blocked", url.PathEscape(i.UUID)) + case ManagerBaseURL: + path = "" default: panic("unknown ManagerURLKind") } @@ -61,6 +65,20 @@ func (i *Instance) ManagerURL(k ManagerURLKind) (string, error) { // APIManagerClient returns a client to talk to the manager via its API. func APIManagerClient(inst *Instance) *manager.APIClient { + c := clouderyConfig(inst) + if c == nil { + return nil + } + + api := c.API + if api.URL == "" || api.Token == "" { + return nil + } + + return manager.NewAPIClient(api.URL, api.Token) +} + +func clouderyConfig(inst *Instance) *config.ClouderyConfig { clouderies := config.GetConfig().Clouderies if clouderies == nil { return nil @@ -75,10 +93,5 @@ func APIManagerClient(inst *Instance) *manager.APIClient { return nil } - api := cloudery.API - if api.URL == "" || api.Token == "" { - return nil - } - - return manager.NewAPIClient(api.URL, api.Token) + return &cloudery } diff --git a/pkg/config/config/config_test.go b/pkg/config/config/config_test.go index de8c219a796..c3af112285b 100644 --- a/pkg/config/config/config_test.go +++ b/pkg/config/config/config_test.go @@ -116,7 +116,6 @@ func TestConfigUnmarshal(t *testing.T) { // Contexts assert.EqualValues(t, map[string]interface{}{ "my-context": map[string]interface{}{ - "manager_url": "https://manager-url", "onboarded_redirection": "home/intro", "default_redirection": "home/", "help_link": "https://cozy.io/fr/support", @@ -216,6 +215,12 @@ func TestConfigUnmarshal(t *testing.T) { Token: "some-token", }, }, + "my-context": { + API: ClouderyAPI{ + URL: "https://manager-url", + Token: "manager-token", + }, + }, }, cfg.Clouderies) // CSPs diff --git a/pkg/config/config/testdata/full_config.yaml b/pkg/config/config/testdata/full_config.yaml index d827a587f0c..ab753424ab6 100644 --- a/pkg/config/config/testdata/full_config.yaml +++ b/pkg/config/config/testdata/full_config.yaml @@ -109,6 +109,10 @@ clouderies: api: url: https://some-url token: some-token + my-context: + api: + url: https://manager-url + token: manager-token password_reset_interval: 1h @@ -163,7 +167,6 @@ log: contexts: my-context: - manager_url: https://manager-url onboarded_redirection: home/intro default_redirection: home/ help_link: https://cozy.io/fr/support diff --git a/tests/testutils/test_utils.go b/tests/testutils/test_utils.go index 34ca8db5f98..e792f445a7c 100644 --- a/tests/testutils/test_utils.go +++ b/tests/testutils/test_utils.go @@ -488,6 +488,13 @@ func WithManager(t *testing.T, inst *instance.Instance, managerConfig ManagerCon cfg := config.GetConfig() originalCfg, _ := json.Marshal(cfg) + if cfg.Clouderies == nil { + cfg.Clouderies = map[string]config.ClouderyConfig{} + } + cloudery, contextName := getCloudery(inst, cfg) + cloudery.API = config.ClouderyAPI{URL: managerConfig.URL, Token: ""} + cfg.Clouderies[contextName] = cloudery + if cfg.Contexts == nil { cfg.Contexts = map[string]interface{}{} } @@ -511,6 +518,19 @@ func WithManager(t *testing.T, inst *instance.Instance, managerConfig ManagerCon return shouldRemoveUUID } +// getCloudery returns the most relevant cloudery config depending on the +// instance context name or creates a new one if none exist. +// It also returns the name of the context associated with the config. +func getCloudery(inst *instance.Instance, cfg *config.Config) (config.ClouderyConfig, string) { + if cloudery, ok := cfg.Clouderies[inst.ContextName]; ok { + return cloudery, inst.ContextName + } + if cloudery, ok := cfg.Clouderies[config.DefaultInstanceContext]; ok { + return cloudery, config.DefaultInstanceContext + } + return config.ClouderyConfig{}, config.DefaultInstanceContext +} + // getContext returns the most relevant context config depending on the // instance context name or creates a new one if none exist. // It also returns the name of the context associated with the config. diff --git a/web/auth/confirm.go b/web/auth/confirm.go index 0a2c64ffe4a..895db8479da 100644 --- a/web/auth/confirm.go +++ b/web/auth/confirm.go @@ -149,12 +149,8 @@ func checkRedirectToAuthorized(c echo.Context) (*url.URL, error) { } func checkRedirectToManager(inst *instance.Instance, redirect *url.URL) bool { - config, ok := inst.SettingsContext() - if !ok { - return false - } - managerURL, ok := config["manager_url"].(string) - if !ok { + managerURL, err := inst.ManagerURL(instance.ManagerBaseURL) + if err != nil { return false } manager, err := url.Parse(managerURL) diff --git a/web/settings/context.go b/web/settings/context.go index fc036e06d3b..2af737d9f6c 100644 --- a/web/settings/context.go +++ b/web/settings/context.go @@ -4,6 +4,7 @@ import ( "encoding/json" "net/http" + "github.com/cozy/cozy-stack/model/instance" "github.com/cozy/cozy-stack/model/instance/lifecycle" "github.com/cozy/cozy-stack/pkg/consts" "github.com/cozy/cozy-stack/pkg/couchdb" @@ -78,6 +79,23 @@ func (h *HTTPHandler) context(c echo.Context) error { } i := middlewares.GetInstance(c) - doc := &apiContext{i.GetContextWithSponsorships()} - return jsonapi.Data(c, http.StatusOK, doc, nil) + context := &apiContext{i.GetContextWithSponsorships()} + + managerURL, err := i.ManagerURL(instance.ManagerBaseURL) + if err != nil { + return err + } + if managerURL != "" { + // XXX: The manager URL used to be stored in the config in + // `context..manager_url`. It's now stored in + // `clouderies..api.url` and can be retrieved via a call + // to `instance.ManagerURL()`. + // + // However, some external apps and clients (e.g. `cozy-client`) still + // expect to find the `manager_url` attribute in the context document + // so we add it back for backwards compatibility. + context.doc["manager_url"] = managerURL + } + + return jsonapi.Data(c, http.StatusOK, context, nil) }