From 86f24cd28c75387c212e6a466c94806fdf8e7bae Mon Sep 17 00:00:00 2001 From: Sergiu Ghitea <28300158+sergiught@users.noreply.github.com> Date: Mon, 17 Apr 2023 18:32:40 +0200 Subject: [PATCH] wip 6 --- internal/cli/cli.go | 22 +- internal/cli/login.go | 8 - internal/config/config.go | 50 ++- internal/config/config_test.go | 610 +++++++++++++++++++++++++++++++++ 4 files changed, 648 insertions(+), 42 deletions(-) diff --git a/internal/cli/cli.go b/internal/cli/cli.go index d8dbf244d..b0332ad9d 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -56,10 +56,14 @@ type cli struct { func (c *cli) setup(ctx context.Context) error { cobra.EnableCommandSorting = false - if err := c.initializeAndValidateConfig(); err != nil { + if err := c.Config.VerifyAuthentication(); err != nil { return err } + if c.tenant == "" { + c.tenant = c.Config.DefaultTenant + } + c.configureRenderer() tenant, err := c.ensureTenantAccessTokenIsUpdated(ctx) @@ -82,22 +86,6 @@ func (c *cli) setup(ctx context.Context) error { return nil } -func (c *cli) initializeAndValidateConfig() error { - if err := c.Config.Initialize(); err != nil { - return err - } - - if err := c.Config.Validate(); err != nil { - return err - } - - if c.tenant == "" { - c.tenant = c.Config.DefaultTenant - } - - return nil -} - func (c *cli) configureRenderer() { c.renderer.Tenant = c.tenant diff --git a/internal/cli/login.go b/internal/cli/login.go index fe7a1df39..6e7531a1e 100644 --- a/internal/cli/login.go +++ b/internal/cli/login.go @@ -221,10 +221,6 @@ func RunLoginAsUser(ctx context.Context, cli *cli, additionalScopes []string) (c return config.Tenant{}, fmt.Errorf("Failed to add the tenant to the config: %w", err) } - if err := cli.Config.AssignInstallID(); err != nil { - return config.Tenant{}, fmt.Errorf("Failed to update the config: %w", err) - } - cli.tracker.TrackFirstLogin(cli.Config.InstallID) if cli.Config.DefaultTenant != result.Domain { @@ -298,10 +294,6 @@ func RunLoginAsMachine(ctx context.Context, inputs LoginInputs, cli *cli, cmd *c cli.renderer.Infof("Successfully logged in.") cli.renderer.Infof("Tenant: %s", inputs.Domain) - if err := cli.Config.AssignInstallID(); err != nil { - return fmt.Errorf("failed to update the config: %w", err) - } - cli.tracker.TrackFirstLogin(cli.Config.InstallID) return nil diff --git a/internal/config/config.go b/internal/config/config.go index e808d2bd3..0d08a6294 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -40,33 +40,28 @@ func (c *Config) Initialize() error { return c.initError } -// Validate checks to see if the config is not corrupted, +// VerifyAuthentication checks to see if the config is not corrupted, // and we have an authenticated tenant saved. // If we have at least one tenant saved but the DefaultTenant // is empty, it will attempt to set the first available // tenant as the DefaultTenant and save to disk. -func (c *Config) Validate() error { - if len(c.Tenants) == 0 { - return ErrNoAuthenticatedTenants +func (c *Config) VerifyAuthentication() error { + if err := c.Initialize(); err != nil { + return err } - if c.DefaultTenant == "" { - for tenant := range c.Tenants { - c.DefaultTenant = tenant - break // Pick first tenant and exit. - } + if len(c.Tenants) == 0 { + return ErrNoAuthenticatedTenants } - return c.saveToDisk() -} - -// AssignInstallID assigns and saves the installation ID to the config. -func (c *Config) AssignInstallID() error { - if c.InstallID != "" { + if c.DefaultTenant != "" { return nil } - c.InstallID = uuid.NewString() + for tenant := range c.Tenants { + c.DefaultTenant = tenant + break // Pick first tenant and exit. + } return c.saveToDisk() } @@ -77,12 +72,16 @@ func (c *Config) IsLoggedInWithTenant(tenantName string) bool { // be not logged in yet. _ = c.Initialize() + if tenantName == "" { + tenantName = c.DefaultTenant + } + tenant, ok := c.Tenants[tenantName] if !ok { return false } - token, err := jwt.ParseString(tenant.AccessToken) + token, err := jwt.ParseString(tenant.GetAccessToken()) if err != nil { return false } @@ -119,6 +118,8 @@ func (c *Config) AddTenant(tenant Tenant) error { // logging in the first time. _ = c.Initialize() + c.ensureInstallIDAssigned() + if c.DefaultTenant == "" { c.DefaultTenant = tenant.Domain } @@ -154,6 +155,8 @@ func (c *Config) RemoveTenant(tenant string) error { delete(c.Tenants, tenant) if c.DefaultTenant == tenant { + c.DefaultTenant = "" + for otherTenant := range c.Tenants { c.DefaultTenant = otherTenant break // Pick first tenant and exit as we called delete above. @@ -179,7 +182,12 @@ func (c *Config) ListAllTenants() ([]Tenant, error) { // SaveNewDefaultTenant saves the new default tenant to the disk. func (c *Config) SaveNewDefaultTenant(tenant string) error { + if err := c.Initialize(); err != nil { + return err + } + c.DefaultTenant = tenant + return c.saveToDisk() } @@ -196,6 +204,14 @@ func (c *Config) SaveNewDefaultAppIDForTenant(tenantName, appID string) error { return c.saveToDisk() } +func (c *Config) ensureInstallIDAssigned() { + if c.InstallID != "" { + return + } + + c.InstallID = uuid.NewString() +} + func (c *Config) loadFromDisk() error { if c.Path == "" { c.Path = defaultPath() diff --git a/internal/config/config_test.go b/internal/config/config_test.go index c51720b80..3247d6374 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -201,6 +201,608 @@ func TestConfig_SaveToDisk(t *testing.T) { }) } +func TestConfig_GetTenant(t *testing.T) { + t.Run("it can successfully retrieve a logged in tenant", func(t *testing.T) { + tempFile := createTempConfigFile(t, []byte(` + { + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "auth0-cli.eu.auth0.com", + "tenants": { + "auth0-cli.eu.auth0.com": { + "name": "auth0-cli", + "domain": "auth0-cli.eu.auth0.com", + "access_token": "eyfSaswe", + "expires_at": "2023-04-18T11:18:07.998809Z", + "client_id": "secret" + } + } + } + `)) + + expectedTenant := Tenant{ + Name: "auth0-cli", + Domain: "auth0-cli.eu.auth0.com", + AccessToken: "eyfSaswe", + ExpiresAt: time.Date(2023, time.April, 18, 11, 18, 7, 998809000, time.UTC), + ClientID: "secret", + } + + config := &Config{Path: tempFile} + actualTenant, err := config.GetTenant("auth0-cli.eu.auth0.com") + + assert.NoError(t, err) + assert.Equal(t, expectedTenant, actualTenant) + }) + + t.Run("it throws an error if the tenant can't be found", func(t *testing.T) { + tempFile := createTempConfigFile(t, []byte(` + { + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "", + "tenants": {} + } + `)) + + config := &Config{Path: tempFile} + _, err := config.GetTenant("auth0-cli.eu.auth0.com") + + assert.EqualError(t, err, "failed to find tenant: auth0-cli.eu.auth0.com. Run 'auth0 tenants use' to see your configured tenants or run 'auth0 login' to configure a new tenant") + }) + + t.Run("it throws an error if the config can't be initialized", func(t *testing.T) { + config := &Config{Path: "non-existent-config.json"} + _, err := config.GetTenant("auth0-cli.eu.auth0.com") + + assert.EqualError(t, err, "config.json file is missing") + }) +} + +func TestConfig_AddTenant(t *testing.T) { + t.Run("it can successfully add a tenant and create the config.json file", func(t *testing.T) { + tmpDir, err := os.MkdirTemp("", "") + require.NoError(t, err) + t.Cleanup(func() { + err := os.RemoveAll(tmpDir) + require.NoError(t, err) + }) + + config := &Config{ + InstallID: "6122fd48-a634-447e-88b0-0580d41b7fb6", + Path: path.Join(tmpDir, "auth0", "config.json"), + } + + tenant := Tenant{ + Name: "auth0-cli", + Domain: "auth0-cli.eu.auth0.com", + AccessToken: "eyfSaswe", + ExpiresAt: time.Date(2023, time.April, 18, 11, 18, 7, 998809000, time.UTC), + ClientID: "secret", + } + + err = config.AddTenant(tenant) + assert.NoError(t, err) + + expectedOutput := `{ + "install_id": "6122fd48-a634-447e-88b0-0580d41b7fb6", + "default_tenant": "auth0-cli.eu.auth0.com", + "tenants": { + "auth0-cli.eu.auth0.com": { + "name": "auth0-cli", + "domain": "auth0-cli.eu.auth0.com", + "access_token": "eyfSaswe", + "expires_at": "2023-04-18T11:18:07.998809Z", + "client_id": "secret" + } + } +}` + + assertConfigFileMatches(t, config.Path, expectedOutput) + }) + + t.Run("it can successfully add another tenant to the config", func(t *testing.T) { + tempFile := createTempConfigFile(t, []byte(` + { + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "auth0-cli.eu.auth0.com", + "tenants": { + "auth0-cli.eu.auth0.com": { + "name": "auth0-cli", + "domain": "auth0-cli.eu.auth0.com", + "access_token": "eyfSaswe", + "expires_at": "2023-04-18T11:18:07.998809Z", + "client_id": "secret" + } + } + } + `)) + + config := &Config{ + Path: tempFile, + } + + tenant := Tenant{ + Name: "auth0-mega-cli", + Domain: "auth0-mega-cli.eu.auth0.com", + AccessToken: "eyfSaswe", + ExpiresAt: time.Date(2023, time.April, 18, 11, 18, 7, 998809000, time.UTC), + ClientID: "secret", + } + + err := config.AddTenant(tenant) + assert.NoError(t, err) + + expectedOutput := `{ + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "auth0-cli.eu.auth0.com", + "tenants": { + "auth0-cli.eu.auth0.com": { + "name": "auth0-cli", + "domain": "auth0-cli.eu.auth0.com", + "access_token": "eyfSaswe", + "expires_at": "2023-04-18T11:18:07.998809Z", + "client_id": "secret" + }, + "auth0-mega-cli.eu.auth0.com": { + "name": "auth0-mega-cli", + "domain": "auth0-mega-cli.eu.auth0.com", + "access_token": "eyfSaswe", + "expires_at": "2023-04-18T11:18:07.998809Z", + "client_id": "secret" + } + } +}` + + assertConfigFileMatches(t, config.Path, expectedOutput) + }) +} + +func TestConfig_RemoveTenant(t *testing.T) { + var testCases = []struct { + name string + givenConfig string + givenTenant string + expectedConfig string + }{ + { + name: "it can successfully remove a tenant from the config", + givenTenant: "auth0-mega-cli.eu.auth0.com", + givenConfig: createTempConfigFile(t, []byte(`{ + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "auth0-cli.eu.auth0.com", + "tenants": { + "auth0-cli.eu.auth0.com": { + "name": "auth0-cli", + "domain": "auth0-cli.eu.auth0.com", + "access_token": "eyfSaswe", + "expires_at": "2023-04-18T11:18:07.998809Z", + "client_id": "secret" + }, + "auth0-mega-cli.eu.auth0.com": { + "name": "auth0-mega-cli", + "domain": "auth0-mega-cli.eu.auth0.com", + "access_token": "eyfSaswe", + "expires_at": "2023-04-18T11:18:07.998809Z", + "client_id": "secret" + } + } + }`)), + expectedConfig: `{ + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "auth0-cli.eu.auth0.com", + "tenants": { + "auth0-cli.eu.auth0.com": { + "name": "auth0-cli", + "domain": "auth0-cli.eu.auth0.com", + "access_token": "eyfSaswe", + "expires_at": "2023-04-18T11:18:07.998809Z", + "client_id": "secret" + } + } +}`, + }, + { + name: "it can successfully remove the default tenant from the config", + givenTenant: "auth0-cli.eu.auth0.com", + givenConfig: createTempConfigFile(t, []byte(`{ + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "auth0-cli.eu.auth0.com", + "tenants": { + "auth0-cli.eu.auth0.com": { + "name": "auth0-cli", + "domain": "auth0-cli.eu.auth0.com", + "access_token": "eyfSaswe", + "expires_at": "2023-04-18T11:18:07.998809Z", + "client_id": "secret" + }, + "auth0-mega-cli.eu.auth0.com": { + "name": "auth0-mega-cli", + "domain": "auth0-mega-cli.eu.auth0.com", + "access_token": "eyfSaswe", + "expires_at": "2023-04-18T11:18:07.998809Z", + "client_id": "secret" + } + } + }`)), + expectedConfig: `{ + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "auth0-mega-cli.eu.auth0.com", + "tenants": { + "auth0-mega-cli.eu.auth0.com": { + "name": "auth0-mega-cli", + "domain": "auth0-mega-cli.eu.auth0.com", + "access_token": "eyfSaswe", + "expires_at": "2023-04-18T11:18:07.998809Z", + "client_id": "secret" + } + } +}`, + }, + { + name: "it can successfully remove the last tenant from the config", + givenTenant: "auth0-cli.eu.auth0.com", + givenConfig: createTempConfigFile(t, []byte(`{ + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "auth0-cli.eu.auth0.com", + "tenants": { + "auth0-cli.eu.auth0.com": { + "name": "auth0-cli", + "domain": "auth0-cli.eu.auth0.com", + "access_token": "eyfSaswe", + "expires_at": "2023-04-18T11:18:07.998809Z", + "client_id": "secret" + } + } + }`)), + expectedConfig: `{ + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "", + "tenants": {} +}`, + }, + { + name: "it doesn't do anything if config file has no logged in tenants", + givenTenant: "auth0-cli.eu.auth0.com", + givenConfig: createTempConfigFile(t, []byte(`{ + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "", + "tenants": {} +}`)), + expectedConfig: `{ + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "", + "tenants": {} +}`, + }, + { + name: "it sets the default tenant to empty if no logged in tenants are registered", + givenTenant: "auth0-cli.eu.auth0.com", + givenConfig: createTempConfigFile(t, []byte(`{ + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "auth0-cli.eu.auth0.com", + "tenants": {} +}`)), + expectedConfig: `{ + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "", + "tenants": {} +}`, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + config := &Config{Path: testCase.givenConfig} + + err := config.RemoveTenant(testCase.givenTenant) + assert.NoError(t, err) + + assertConfigFileMatches(t, config.Path, testCase.expectedConfig) + }) + } + + t.Run("it doesn't throw an error if config file is missing", func(t *testing.T) { + config := &Config{ + Path: "i-dont-exist.json", + } + + err := config.RemoveTenant("auth0-cli.eu.auth0.com") + assert.NoError(t, err) + }) +} + +func TestConfig_ListAllTenants(t *testing.T) { + t.Run("it can successfully list all tenants", func(t *testing.T) { + tempFile := createTempConfigFile(t, []byte(`{ + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "auth0-cli.eu.auth0.com", + "tenants": { + "auth0-cli.eu.auth0.com": { + "name": "auth0-cli", + "domain": "auth0-cli.eu.auth0.com", + "access_token": "eyfSaswe", + "expires_at": "2023-04-18T11:18:07.998809Z", + "client_id": "secret" + }, + "auth0-mega-cli.eu.auth0.com": { + "name": "auth0-mega-cli", + "domain": "auth0-mega-cli.eu.auth0.com", + "access_token": "eyfSaswe", + "expires_at": "2023-04-18T11:18:07.998809Z", + "client_id": "secret" + } + } + }`)) + + expectedTenants := []Tenant{ + { + Name: "auth0-cli", + Domain: "auth0-cli.eu.auth0.com", + AccessToken: "eyfSaswe", + ExpiresAt: time.Date(2023, time.April, 18, 11, 18, 7, 998809000, time.UTC), + ClientID: "secret", + }, + { + Name: "auth0-mega-cli", + Domain: "auth0-mega-cli.eu.auth0.com", + AccessToken: "eyfSaswe", + ExpiresAt: time.Date(2023, time.April, 18, 11, 18, 7, 998809000, time.UTC), + ClientID: "secret", + }, + } + + config := &Config{Path: tempFile} + actualTenants, err := config.ListAllTenants() + + assert.NoError(t, err) + assert.Len(t, actualTenants, 2) + assert.Equal(t, expectedTenants, actualTenants) + }) + + t.Run("it throws an error if there's an issue with the config file", func(t *testing.T) { + config := &Config{Path: "i-dont-exist.json"} + + _, err := config.ListAllTenants() + assert.EqualError(t, err, "config.json file is missing") + }) +} + +func TestConfig_SaveNewDefaultTenant(t *testing.T) { + t.Run("it can successfully save a new tenant default", func(t *testing.T) { + tempFile := createTempConfigFile(t, []byte(`{ + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "auth0-cli.eu.auth0.com", + "tenants": { + "auth0-cli.eu.auth0.com": { + "name": "auth0-cli", + "domain": "auth0-cli.eu.auth0.com", + "access_token": "eyfSaswe", + "expires_at": "2023-04-18T11:18:07.998809Z", + "client_id": "secret" + }, + "auth0-mega-cli.eu.auth0.com": { + "name": "auth0-mega-cli", + "domain": "auth0-mega-cli.eu.auth0.com", + "access_token": "eyfSaswe", + "expires_at": "2023-04-18T11:18:07.998809Z", + "client_id": "secret" + } + } + }`)) + + expectedConfig := `{ + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "auth0-mega-cli.eu.auth0.com", + "tenants": { + "auth0-cli.eu.auth0.com": { + "name": "auth0-cli", + "domain": "auth0-cli.eu.auth0.com", + "access_token": "eyfSaswe", + "expires_at": "2023-04-18T11:18:07.998809Z", + "client_id": "secret" + }, + "auth0-mega-cli.eu.auth0.com": { + "name": "auth0-mega-cli", + "domain": "auth0-mega-cli.eu.auth0.com", + "access_token": "eyfSaswe", + "expires_at": "2023-04-18T11:18:07.998809Z", + "client_id": "secret" + } + } +}` + + config := &Config{Path: tempFile} + err := config.SaveNewDefaultTenant("auth0-mega-cli.eu.auth0.com") + assert.NoError(t, err) + assertConfigFileMatches(t, config.Path, expectedConfig) + }) + + t.Run("it throws an error if there's an issue with the config file", func(t *testing.T) { + config := &Config{Path: "i-dont-exist.json"} + + err := config.SaveNewDefaultTenant("tenant") + assert.EqualError(t, err, "config.json file is missing") + }) +} + +func TestConfig_SaveNewDefaultAppIDForTenant(t *testing.T) { + t.Run("it successfully saves a new default app id for the tenant", func(t *testing.T) { + tempFile := createTempConfigFile(t, []byte(`{ + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "auth0-cli.eu.auth0.com", + "tenants": { + "auth0-cli.eu.auth0.com": { + "name": "auth0-cli", + "domain": "auth0-cli.eu.auth0.com", + "access_token": "eyfSaswe", + "expires_at": "2023-04-18T11:18:07.998809Z", + "client_id": "secret" + } + } + }`)) + + expectedConfig := `{ + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "auth0-cli.eu.auth0.com", + "tenants": { + "auth0-cli.eu.auth0.com": { + "name": "auth0-cli", + "domain": "auth0-cli.eu.auth0.com", + "access_token": "eyfSaswe", + "expires_at": "2023-04-18T11:18:07.998809Z", + "default_app_id": "appID123456", + "client_id": "secret" + } + } +}` + + config := &Config{Path: tempFile} + err := config.SaveNewDefaultAppIDForTenant("auth0-cli.eu.auth0.com", "appID123456") + assert.NoError(t, err) + assertConfigFileMatches(t, config.Path, expectedConfig) + }) + + t.Run("it throws an error if there's an issue with the config file", func(t *testing.T) { + config := &Config{Path: "i-dont-exist.json"} + + err := config.SaveNewDefaultAppIDForTenant("tenant", "appID123456") + assert.EqualError(t, err, "config.json file is missing") + }) +} + +func TestConfig_IsLoggedInWithTenant(t *testing.T) { + t.Run("it returns true when we are logged in", func(t *testing.T) { + tempFile := createTempConfigFile(t, []byte(`{ + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "auth0-cli.eu.auth0.com", + "tenants": { + "auth0-cli.eu.auth0.com": { + "name": "auth0-cli", + "domain": "auth0-cli.eu.auth0.com", + "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2F1dGgwLmF1dGgwLmNvbS8iLCJpYXQiOjE2ODExNDcwNjAsImV4cCI6OTY4MTgzMzQ2MH0.DsEpQkL0MIWcGJOIfEY8vr3MVS_E0GYsachNLQwBu5Q", + "expires_at": "2023-04-18T11:18:07.998809Z", + "client_id": "secret" + } + } + }`)) + + config := &Config{Path: tempFile} + assert.True(t, config.IsLoggedInWithTenant("auth0-cli.eu.auth0.com")) + }) + + t.Run("it returns false when we are not logged in", func(t *testing.T) { + config := &Config{Path: "i-dont-exist.json"} + assert.False(t, config.IsLoggedInWithTenant("auth0-cli.eu.auth0.com")) + }) + + t.Run("it returns false when we are logged in but the token is expired", func(t *testing.T) { + tempFile := createTempConfigFile(t, []byte(`{ + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "auth0-cli.eu.auth0.com", + "tenants": { + "auth0-cli.eu.auth0.com": { + "name": "auth0-cli", + "domain": "auth0-cli.eu.auth0.com", + "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2F1dGgwLmF1dGgwLmNvbS8iLCJpYXQiOjE2ODExNDcwNjAsImV4cCI6MTY4MTEzMzQ2MH0.dG481CD7v8VCzSsBHdApTiRDUuCZXBgk5LO__q4r2Fg", + "expires_at": "2023-04-10T11:18:07.998809Z", + "client_id": "secret" + } + } + }`)) + + config := &Config{Path: tempFile} + assert.False(t, config.IsLoggedInWithTenant("auth0-cli.eu.auth0.com")) + }) + + t.Run("it returns false when we are logged in but the token is malformed", func(t *testing.T) { + tempFile := createTempConfigFile(t, []byte(`{ + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "auth0-cli.eu.auth0.com", + "tenants": { + "auth0-cli.eu.auth0.com": { + "name": "auth0-cli", + "domain": "auth0-cli.eu.auth0.com", + "access_token": "dG481CD7v8VCzSsBHdApTiRDUuCZXBgk5LO__q4r2Fg", + "expires_at": "2023-04-10T11:18:07.998809Z", + "client_id": "secret" + } + } + }`)) + + config := &Config{Path: tempFile} + assert.False(t, config.IsLoggedInWithTenant("")) + }) +} + +func TestConfig_VerifyAuthentication(t *testing.T) { + t.Run("it successfully verifies that we are authenticated", func(t *testing.T) { + tempFile := createTempConfigFile(t, []byte(`{ + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "auth0-cli.eu.auth0.com", + "tenants": { + "auth0-cli.eu.auth0.com": { + "name": "auth0-cli", + "domain": "auth0-cli.eu.auth0.com", + "access_token": "eyfSaswe", + "expires_at": "2023-04-18T11:18:07.998809Z", + "client_id": "secret" + } + } + }`)) + + config := &Config{Path: tempFile} + err := config.VerifyAuthentication() + assert.NoError(t, err) + }) + + t.Run("it throws an error if we are not authenticated with any tenant", func(t *testing.T) { + tempFile := createTempConfigFile(t, []byte(`{ + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "auth0-cli.eu.auth0.com", + "tenants": {} + }`)) + + config := &Config{Path: tempFile} + err := config.VerifyAuthentication() + assert.EqualError(t, err, "Not logged in. Try `auth0 login`.") + }) + + t.Run("it fixes the default tenant if there are tenant entries and the default is empty", func(t *testing.T) { + tempFile := createTempConfigFile(t, []byte(`{ + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "", + "tenants": { + "auth0-cli.eu.auth0.com": { + "name": "auth0-cli", + "domain": "auth0-cli.eu.auth0.com", + "access_token": "eyfSaswe", + "expires_at": "2023-04-18T11:18:07.998809Z", + "client_id": "secret" + } + } + }`)) + + config := &Config{Path: tempFile} + err := config.VerifyAuthentication() + assert.NoError(t, err) + + expectedConfig := `{ + "install_id": "3998b053-dd7f-4bfe-bb10-c4f3a96a0180", + "default_tenant": "auth0-cli.eu.auth0.com", + "tenants": { + "auth0-cli.eu.auth0.com": { + "name": "auth0-cli", + "domain": "auth0-cli.eu.auth0.com", + "access_token": "eyfSaswe", + "expires_at": "2023-04-18T11:18:07.998809Z", + "client_id": "secret" + } + } +}` + + assertConfigFileMatches(t, config.Path, expectedConfig) + }) +} + func createTempConfigFile(t *testing.T, data []byte) string { t.Helper() @@ -217,3 +819,11 @@ func createTempConfigFile(t *testing.T, data []byte) string { return tempFile.Name() } + +func assertConfigFileMatches(t *testing.T, actualConfigPath, expectedConfig string) { + t.Helper() + + fileContent, err := os.ReadFile(actualConfigPath) + assert.NoError(t, err) + assert.Equal(t, expectedConfig, string(fileContent)) +}