From 2ed940dbffaebd7a0b415ae9645ccd9eb32853a1 Mon Sep 17 00:00:00 2001 From: Erwan Guyader Date: Thu, 21 Nov 2024 13:33:46 +0100 Subject: [PATCH] WIP --- model/instance/instance_test.go | 7 +++-- model/instance/manager.go | 35 ++++++++++++++------- model/oauth/client_test.go | 4 ++- pkg/config/config/config_test.go | 7 ++++- pkg/config/config/testdata/full_config.yaml | 5 ++- tests/testutils/test_utils.go | 8 ++--- web/apps/apps_test.go | 4 ++- web/auth/confirm.go | 8 ++--- web/settings/context.go | 22 +++++++++++-- web/settings/settings_test.go | 4 ++- 10 files changed, 73 insertions(+), 31 deletions(-) diff --git a/model/instance/instance_test.go b/model/instance/instance_test.go index af18fde7b5d..5d1518cf1e3 100644 --- a/model/instance/instance_test.go +++ b/model/instance/instance_test.go @@ -59,9 +59,11 @@ func TestInstance(t *testing.T) { was := cfg.Contexts defer func() { cfg.Contexts = was }() + cfg.Clouderies["context"] = config.ClouderyConfig{ + API: config.ClouderyAPI{URL: "http://manager.example.org", Token: ""}, + } 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 +175,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..4f24e9d6e48 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 := cloudery(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 := cloudery(inst) + if c == nil { + return nil + } + + api := c.API + if api.URL == "" || api.Token == "" { + return nil + } + + return manager.NewAPIClient(api.URL, api.Token) +} + +func cloudery(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/model/oauth/client_test.go b/model/oauth/client_test.go index e3d7cbb6f7a..5c768b303ca 100644 --- a/model/oauth/client_test.go +++ b/model/oauth/client_test.go @@ -33,7 +33,9 @@ func TestClient(t *testing.T) { config.UseTestFile(t) conf := config.GetConfig() - conf.Contexts[config.DefaultInstanceContext] = map[string]interface{}{"manager_url": "http://manager.example.org"} + conf.Clouderies[config.DefaultInstanceContext] = config.ClouderyConfig{ + API: config.ClouderyAPI{URL: "http://manager.example.org", Token: ""}, + } setup := testutils.NewSetup(t, t.Name()) testInstance := setup.GetTestInstance() 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 66ff3f5b274..16f9b31712a 100644 --- a/tests/testutils/test_utils.go +++ b/tests/testutils/test_utils.go @@ -480,9 +480,9 @@ func WithManager(t *testing.T, inst *instance.Instance) (shouldRemoveUUID bool) config, ok := inst.SettingsContext() require.True(t, ok, "Could not enable test instance manager: could not fetch test instance settings context") - managerURL, ok := config["manager_url"].(string) - require.True(t, ok, "Could not enable test instance manager: manager_url config is required") - require.NotEmpty(t, managerURL, "Could not enable test instance manager: manager_url config is required") + managerURL, err := inst.ManagerURL(instance.ManagerBaseURL) + require.NoError(t, err, "Could not enable test instance manager: cloudery config is required") + require.NotEmpty(t, managerURL, "Could not enable test instance manager: cloudery API URL is required") was := config["enable_premium_links"] config["enable_premium_links"] = true @@ -496,7 +496,7 @@ func WithManager(t *testing.T, inst *instance.Instance) (shouldRemoveUUID bool) } }) - err := instance.Update(inst) + err = instance.Update(inst) require.NoError(t, err, "Could not enable test instance manager") return shouldRemoveUUID diff --git a/web/apps/apps_test.go b/web/apps/apps_test.go index c8b02d83dd8..c2b32b8300d 100644 --- a/web/apps/apps_test.go +++ b/web/apps/apps_test.go @@ -66,7 +66,9 @@ func TestApps(t *testing.T) { Host: "localhost", Path: tempdir, } - cfg.Contexts[config.DefaultInstanceContext] = map[string]interface{}{"manager_url": "http://manager.example.org"} + cfg.Clouderies[config.DefaultInstanceContext] = config.ClouderyConfig{ + API: config.ClouderyAPI{URL: "http://manager.example.org", Token: ""}, + } was := cfg.Subdomains cfg.Subdomains = config.NestedSubdomains defer func() { cfg.Subdomains = was }() 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) } diff --git a/web/settings/settings_test.go b/web/settings/settings_test.go index b476a39dff7..e874bbea6f9 100644 --- a/web/settings/settings_test.go +++ b/web/settings/settings_test.go @@ -73,8 +73,10 @@ func TestSettings(t *testing.T) { config.UseTestFile(t) conf := config.GetConfig() conf.Assets = "../../assets" + conf.Clouderies[config.DefaultInstanceContext] = config.ClouderyConfig{ + API: config.ClouderyAPI{URL: "http://manager.example.org", Token: ""}, + } conf.Contexts[config.DefaultInstanceContext] = map[string]interface{}{ - "manager_url": "http://manager.example.org", "logos": map[string]interface{}{ "home": map[string]interface{}{ "light": []interface{}{