diff --git a/acceptance/cmd/auth/logout/stale-account-id-workspace-host/out.test.toml b/acceptance/cmd/auth/logout/stale-account-id-workspace-host/out.test.toml new file mode 100644 index 0000000000..d560f1de04 --- /dev/null +++ b/acceptance/cmd/auth/logout/stale-account-id-workspace-host/out.test.toml @@ -0,0 +1,5 @@ +Local = true +Cloud = false + +[EnvMatrix] + DATABRICKS_BUNDLE_ENGINE = ["terraform", "direct"] diff --git a/acceptance/cmd/auth/logout/stale-account-id-workspace-host/output.txt b/acceptance/cmd/auth/logout/stale-account-id-workspace-host/output.txt new file mode 100644 index 0000000000..2404b2d591 --- /dev/null +++ b/acceptance/cmd/auth/logout/stale-account-id-workspace-host/output.txt @@ -0,0 +1,42 @@ + +=== Profiles before logout — logfood should be valid + +>>> [CLI] auth profiles +Name Host Valid +logfood (Default) [DATABRICKS_URL] YES + +=== Token cache keys before logout +[ + "[DATABRICKS_URL]", + "logfood" +] + +=== Logout without --delete +>>> [CLI] auth logout --profile logfood --force +Logged out of profile "logfood". Use --delete to also remove it from the config file. + +=== Config after logout — profile should still exist +; The profile defined in the DEFAULT section is to be used as a fallback when no profile is explicitly specified. +[DEFAULT] + +[logfood] +host = [DATABRICKS_URL] +account_id = stale-account +auth_type = databricks-cli + +[__settings__] +default_profile = logfood + +=== Token cache keys after logout — both entries should be removed +[] + +=== Profiles after logout — logfood should be invalid + +>>> [CLI] auth profiles +Name Host Valid +logfood (Default) [DATABRICKS_URL] NO + +=== Logged out profile should no longer return a token + +>>> musterr [CLI] auth token --profile logfood +Error: cache: databricks OAuth is not configured for this host. Try logging in again with `databricks auth login --profile logfood` before retrying. If this fails, please report this issue to the Databricks CLI maintainers at https://github.com/databricks/cli/issues/new diff --git a/acceptance/cmd/auth/logout/stale-account-id-workspace-host/script b/acceptance/cmd/auth/logout/stale-account-id-workspace-host/script new file mode 100644 index 0000000000..5e29abe544 --- /dev/null +++ b/acceptance/cmd/auth/logout/stale-account-id-workspace-host/script @@ -0,0 +1,52 @@ +sethome "./home" + +cat > "./home/.databrickscfg" < "./home/.databricks/token-cache.json" < as the cache key and match on both host and -// account ID; workspace profiles use just the host. +// account ID. Workspace profiles use just the host, even if the profile still +// carries stale account metadata from an earlier login. func hostCacheKeyAndMatchFn(p profile.Profile) (string, profile.ProfileMatchFunction) { - host := (&config.Config{Host: p.Host}).CanonicalHostName() + cfg := &config.Config{ + Host: p.Host, + AccountID: p.AccountID, + WorkspaceID: p.WorkspaceID, + Experimental_IsUnifiedHost: p.IsUnifiedHost, + } + host := cfg.CanonicalHostName() if host == "" { return "", nil } - if p.AccountID != "" { + switch cfg.HostType() { + case config.AccountHost, config.UnifiedHost: + if p.AccountID == "" { + return "", nil + } return host + "/oidc/accounts/" + p.AccountID, profile.WithHostAndAccountID(host, p.AccountID) + default: + return host, profile.WithHost(host) } - - return host, profile.WithHost(host) } // resolveLogoutArg resolves a positional argument to a profile name. It first diff --git a/cmd/auth/logout_test.go b/cmd/auth/logout_test.go index 7468a0779b..ad7dd96711 100644 --- a/cmd/auth/logout_test.go +++ b/cmd/auth/logout_test.go @@ -26,6 +26,11 @@ auth_type = databricks-cli host = https://my-unique-workspace.cloud.databricks.com auth_type = databricks-cli +[my-workspace-stale-account] +host = https://stale-account.cloud.databricks.com +account_id = stale-account +auth_type = databricks-cli + [my-account] host = https://accounts.cloud.databricks.com account_id = abc123 @@ -43,13 +48,15 @@ token = dev-token ` var logoutTestTokensCacheConfig = map[string]*oauth2.Token{ - "my-workspace": {AccessToken: "shared-workspace-token"}, - "shared-workspace": {AccessToken: "shared-workspace-token"}, - "my-unique-workspace": {AccessToken: "my-unique-workspace-token"}, - "my-account": {AccessToken: "my-account-token"}, - "my-unified": {AccessToken: "my-unified-token"}, + "my-workspace": {AccessToken: "shared-workspace-token"}, + "shared-workspace": {AccessToken: "shared-workspace-token"}, + "my-unique-workspace": {AccessToken: "my-unique-workspace-token"}, + "my-workspace-stale-account": {AccessToken: "stale-account-token"}, + "my-account": {AccessToken: "my-account-token"}, + "my-unified": {AccessToken: "my-unified-token"}, "https://my-workspace.cloud.databricks.com": {AccessToken: "shared-workspace-host-token"}, "https://my-unique-workspace.cloud.databricks.com": {AccessToken: "unique-workspace-host-token"}, + "https://stale-account.cloud.databricks.com": {AccessToken: "stale-account-host-token"}, "https://accounts.cloud.databricks.com/oidc/accounts/abc123": {AccessToken: "account-host-token"}, "https://unified.cloud.databricks.com/oidc/accounts/def456": {AccessToken: "unified-host-token"}, "my-m2m": {AccessToken: "m2m-service-token"}, @@ -96,6 +103,13 @@ func TestLogout(t *testing.T) { isSharedKey: false, force: true, }, + { + name: "existing workspace profile with stale account id", + profileName: "my-workspace-stale-account", + hostBasedKey: "https://stale-account.cloud.databricks.com", + isSharedKey: false, + force: true, + }, { name: "existing account profile", profileName: "my-account",