Azure: Use SSO settings in plugin context (#112058)

* Bump grafana-azure-sdk-go

* Set override values

* Add Azure settings helper covering SSO cases

* Ensure Azure settings are correctly created

- Add mock for sso settings service
- Add tests
- Update wire

* Minor improvements

* Test updates

* Move fake implementation

* add interface to limit leakage

* rename

* work sync

* Fix wire

* Add fake provider

* Update tests

* Actually fix the workspace

* More go dependency fixes

* Update tests

* Update workspace, again

* Add missing tests

* Fix dependencies

* These dependencies..

* More dependency things

* Okay now dependencies really are fixed

* Lint

* Update pkg/services/pluginsintegration/pluginconfig/request.go

Co-authored-by: Misi <mgyongyosi@users.noreply.github.com>

---------

Co-authored-by: Will Browne <wbrowne@tcd.ie>
Co-authored-by: Misi <mgyongyosi@users.noreply.github.com>
This commit is contained in:
Andreas Christou
2025-10-10 11:46:26 +01:00
committed by GitHub
co-authored by Misi Will Browne
parent 59459560c2
commit fa9d6be255
15 changed files with 652 additions and 75 deletions
@@ -46,7 +46,7 @@ func TestPluginEnvVarsProvider_PluginEnvVars(t *testing.T) {
Features: featuremgmt.WithFeatures(),
}
provider := NewEnvVarsProvider(cfg, licensing)
provider := NewEnvVarsProvider(cfg, licensing, &fakeSSOSettingsProvider{})
envVars := provider.PluginEnvVars(context.Background(), p)
assert.Len(t, envVars, 6)
assert.Equal(t, "GF_VERSION=", envVars[0])
@@ -77,7 +77,7 @@ func TestPluginEnvVarsProvider_skipHostEnvVars(t *testing.T) {
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
require.NoError(t, err)
provider := NewEnvVarsProvider(pCfg, nil)
provider := NewEnvVarsProvider(pCfg, nil, &fakeSSOSettingsProvider{})
envVars := provider.PluginEnvVars(context.Background(), p)
// We want to test that the envvars.Provider does not add any of the host env vars.
@@ -93,7 +93,7 @@ func TestPluginEnvVarsProvider_skipHostEnvVars(t *testing.T) {
cfg := setting.NewCfg()
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
require.NoError(t, err)
provider := NewEnvVarsProvider(pCfg, nil)
provider := NewEnvVarsProvider(pCfg, nil, &fakeSSOSettingsProvider{})
t.Run("should populate allowed host env vars", func(t *testing.T) {
// Set all allowed variables
@@ -418,7 +418,7 @@ func TestPluginEnvVarsProvider_tracingEnvironmentVariables(t *testing.T) {
},
} {
t.Run(tc.name, func(t *testing.T) {
p := NewEnvVarsProvider(tc.cfg, nil)
p := NewEnvVarsProvider(tc.cfg, nil, &fakeSSOSettingsProvider{})
envVars := p.PluginEnvVars(context.Background(), tc.plugin)
tc.exp(t, envVars)
})
@@ -473,7 +473,7 @@ func TestPluginEnvVarsProvider_authEnvVars(t *testing.T) {
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
require.NoError(t, err)
provider := NewEnvVarsProvider(pCfg, nil)
provider := NewEnvVarsProvider(pCfg, nil, &fakeSSOSettingsProvider{})
envVars := provider.PluginEnvVars(context.Background(), p)
assert.Equal(t, "GF_VERSION=", envVars[0])
assert.Equal(t, "GF_APP_URL=https://myorg.com/", envVars[1])
@@ -521,7 +521,7 @@ func TestPluginEnvVarsProvider_awsEnvVars(t *testing.T) {
Features: featuremgmt.WithFeatures(),
}
provider := NewEnvVarsProvider(cfg, nil)
provider := NewEnvVarsProvider(cfg, nil, &fakeSSOSettingsProvider{})
envVars := provider.PluginEnvVars(context.Background(), p)
assert.ElementsMatch(t, tc.expected, envVars)
}
@@ -540,7 +540,7 @@ func TestPluginEnvVarsProvider_featureToggleEnvVar(t *testing.T) {
Features: featuremgmt.WithFeatures(expectedFeatures[0], true, expectedFeatures[1], true),
}
p := NewEnvVarsProvider(cfg, nil)
p := NewEnvVarsProvider(cfg, nil, &fakeSSOSettingsProvider{})
envVars := p.PluginEnvVars(context.Background(), &plugins.Plugin{})
assert.Equal(t, 2, len(envVars))
@@ -591,7 +591,7 @@ func TestPluginEnvVarsProvider_azureEnvVars(t *testing.T) {
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
require.NoError(t, err)
provider := NewEnvVarsProvider(pCfg, nil)
provider := NewEnvVarsProvider(pCfg, nil, &fakeSSOSettingsProvider{})
envVars := provider.PluginEnvVars(context.Background(), &plugins.Plugin{})
assert.ElementsMatch(t, []string{"GF_VERSION=", "GFAZPL_AZURE_CLOUD=AzureCloud", "GFAZPL_AZURE_AUTH_ENABLED=true",
"GFAZPL_MANAGED_IDENTITY_ENABLED=true",
@@ -608,4 +608,113 @@ func TestPluginEnvVarsProvider_azureEnvVars(t *testing.T) {
"GFAZPL_USER_IDENTITY_ASSERTION=username",
}, envVars)
})
t.Run("sets user token endpoint settings from SSO settings for an Azure plugin", func(t *testing.T) {
cfg := &setting.Cfg{
Raw: ini.Empty(),
Azure: &azsettings.AzureSettings{
AzureAuthEnabled: true,
Cloud: azsettings.AzurePublic,
ManagedIdentityEnabled: true,
ManagedIdentityClientId: "mock_managed_identity_client_id",
WorkloadIdentityEnabled: true,
WorkloadIdentitySettings: &azsettings.WorkloadIdentitySettings{
TenantId: "mock_workload_identity_tenant_id",
ClientId: "mock_workload_identity_client_id",
TokenFile: "mock_workload_identity_token_file",
},
UserIdentityEnabled: true,
UserIdentityFallbackCredentialsEnabled: true,
UserIdentityTokenEndpoint: &azsettings.TokenEndpointSettings{
TokenUrl: "mock_user_identity_token_url",
ClientId: "mock_user_identity_client_id",
ClientSecret: "mock_user_identity_client_secret",
UsernameAssertion: true,
},
},
}
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
require.NoError(t, err)
provider := NewEnvVarsProvider(pCfg, nil, &fakeSSOSettingsProvider{
GetForProviderFunc: getAzureSSOSettings,
})
envVars := provider.PluginEnvVars(context.Background(), &plugins.Plugin{})
assert.ElementsMatch(t, []string{"GF_VERSION=", "GFAZPL_AZURE_CLOUD=AzureCloud", "GFAZPL_AZURE_AUTH_ENABLED=true",
"GFAZPL_MANAGED_IDENTITY_ENABLED=true",
"GFAZPL_MANAGED_IDENTITY_CLIENT_ID=mock_managed_identity_client_id",
"GFAZPL_WORKLOAD_IDENTITY_ENABLED=true",
"GFAZPL_WORKLOAD_IDENTITY_TENANT_ID=mock_workload_identity_tenant_id",
"GFAZPL_WORKLOAD_IDENTITY_CLIENT_ID=mock_workload_identity_client_id",
"GFAZPL_WORKLOAD_IDENTITY_TOKEN_FILE=mock_workload_identity_token_file",
"GFAZPL_USER_IDENTITY_ENABLED=true",
"GFAZPL_USER_IDENTITY_FALLBACK_SERVICE_CREDENTIALS_ENABLED=true",
"GFAZPL_USER_IDENTITY_TOKEN_URL=sso_user_identity_token_url",
"GFAZPL_USER_IDENTITY_CLIENT_AUTHENTICATION=sso_user_client_authentication",
"GFAZPL_USER_IDENTITY_CLIENT_ID=sso_user_identity_client_id",
"GFAZPL_USER_IDENTITY_CLIENT_SECRET=sso_user_identity_client_secret",
"GFAZPL_USER_IDENTITY_MANAGED_IDENTITY_CLIENT_ID=sso_user_identity_managed_identity_client_id",
"GFAZPL_USER_IDENTITY_FEDERATED_CREDENTIAL_AUDIENCE=sso_user_identity_federated_credential_audience",
"GFAZPL_USER_IDENTITY_ASSERTION=username",
}, envVars)
})
t.Run("does not use SSO settings if overrides have been set for an Azure plugin", func(t *testing.T) {
cfg := &setting.Cfg{
Raw: ini.Empty(),
Azure: &azsettings.AzureSettings{
AzureAuthEnabled: true,
Cloud: azsettings.AzurePublic,
ManagedIdentityEnabled: true,
ManagedIdentityClientId: "mock_managed_identity_client_id",
WorkloadIdentityEnabled: true,
WorkloadIdentitySettings: &azsettings.WorkloadIdentitySettings{
TenantId: "mock_workload_identity_tenant_id",
ClientId: "mock_workload_identity_client_id",
TokenFile: "mock_workload_identity_token_file",
},
UserIdentityEnabled: true,
UserIdentityFallbackCredentialsEnabled: true,
UserIdentityTokenEndpoint: &azsettings.TokenEndpointSettings{
TokenUrl: "override_user_identity_token_url",
TokenUrlOverride: true,
ClientAuthentication: "override_user_client_authentication",
ClientAuthenticationOverride: true,
ClientId: "override_user_identity_client_id",
ClientIdOverride: true,
ClientSecret: "override_user_identity_client_secret",
ClientSecretOverride: true,
ManagedIdentityClientId: "override_user_identity_managed_identity_client_id",
ManagedIdentityClientIdOverride: true,
FederatedCredentialAudience: "override_user_identity_federated_credential_audience",
FederatedCredentialAudienceOverride: true,
},
},
}
pCfg, err := ProvidePluginInstanceConfig(cfg, setting.ProvideProvider(cfg), featuremgmt.WithFeatures())
require.NoError(t, err)
provider := NewEnvVarsProvider(pCfg, nil, &fakeSSOSettingsProvider{
GetForProviderFunc: getAzureSSOSettings,
})
envVars := provider.PluginEnvVars(context.Background(), &plugins.Plugin{})
assert.ElementsMatch(t, []string{"GF_VERSION=", "GFAZPL_AZURE_CLOUD=AzureCloud", "GFAZPL_AZURE_AUTH_ENABLED=true",
"GFAZPL_MANAGED_IDENTITY_ENABLED=true",
"GFAZPL_MANAGED_IDENTITY_CLIENT_ID=mock_managed_identity_client_id",
"GFAZPL_WORKLOAD_IDENTITY_ENABLED=true",
"GFAZPL_WORKLOAD_IDENTITY_TENANT_ID=mock_workload_identity_tenant_id",
"GFAZPL_WORKLOAD_IDENTITY_CLIENT_ID=mock_workload_identity_client_id",
"GFAZPL_WORKLOAD_IDENTITY_TOKEN_FILE=mock_workload_identity_token_file",
"GFAZPL_USER_IDENTITY_ENABLED=true",
"GFAZPL_USER_IDENTITY_FALLBACK_SERVICE_CREDENTIALS_ENABLED=true",
"GFAZPL_USER_IDENTITY_TOKEN_URL=override_user_identity_token_url",
"GFAZPL_USER_IDENTITY_CLIENT_AUTHENTICATION=override_user_client_authentication",
"GFAZPL_USER_IDENTITY_CLIENT_ID=override_user_identity_client_id",
"GFAZPL_USER_IDENTITY_CLIENT_SECRET=override_user_identity_client_secret",
"GFAZPL_USER_IDENTITY_MANAGED_IDENTITY_CLIENT_ID=override_user_identity_managed_identity_client_id",
"GFAZPL_USER_IDENTITY_FEDERATED_CREDENTIAL_AUDIENCE=override_user_identity_federated_credential_audience",
}, envVars)
})
}