Plugins: Automatic service account (and token) setup (#76473)

* Update cue to have an AuthProvider entry

* Cable the new auth provider

* Add feature flag check to the accesscontrol service

* Fix test

* Change the structure of externalServiceRegistration (#76673)
This commit is contained in:
Gabriel MABILLE
2023-10-17 16:21:23 +02:00
committed by GitHub
parent 3bf9f97a89
commit 797a3c57af
15 changed files with 201 additions and 78 deletions

View File

@ -498,12 +498,12 @@ func TestLoader_Load_ExternalRegistration(t *testing.T) {
boolPtr := func(b bool) *bool { return &b }
stringPtr := func(s string) *string { return &s }
t.Run("Load a plugin with external registration", func(t *testing.T) {
t.Run("Load a plugin with oauth client registration", func(t *testing.T) {
cfg := &config.Cfg{
Features: fakes.NewFakeFeatureToggles(featuremgmt.FlagExternalServiceAuth),
PluginsAllowUnsigned: []string{"grafana-test-datasource"},
}
pluginPaths := []string{filepath.Join(testDataDir(t), "external-registration")}
pluginPaths := []string{filepath.Join(testDataDir(t), "oauth-external-registration")}
expected := []*plugins.Plugin{
{JSONData: plugins.JSONData{
ID: "grafana-test-datasource",
@ -539,13 +539,10 @@ func TestLoader_Load_ExternalRegistration(t *testing.T) {
},
},
},
Self: &plugindef.Self{
Enabled: boolPtr(true),
Permissions: []plugindef.Permission{
{
Action: "read",
Scope: stringPtr("datasource"),
},
Permissions: []plugindef.Permission{
{
Action: "read",
Scope: stringPtr("datasource"),
},
},
},
@ -602,6 +599,96 @@ func TestLoader_Load_ExternalRegistration(t *testing.T) {
t.Fatalf("Result mismatch (-want +got):\n%s", cmp.Diff(got, expected, compareOpts...))
}
})
t.Run("Load a plugin with service account registration", func(t *testing.T) {
cfg := &config.Cfg{
Features: fakes.NewFakeFeatureToggles(featuremgmt.FlagExternalServiceAuth),
PluginsAllowUnsigned: []string{"grafana-test-datasource"},
}
pluginPaths := []string{filepath.Join(testDataDir(t), "external-registration")}
expected := []*plugins.Plugin{
{JSONData: plugins.JSONData{
ID: "grafana-test-datasource",
Type: plugins.TypeDataSource,
Name: "Test",
Backend: true,
Executable: "gpx_test_datasource",
Info: plugins.Info{
Author: plugins.InfoLink{
Name: "Grafana Labs",
URL: "https://grafana.com",
},
Version: "1.0.0",
Logos: plugins.Logos{
Small: "/public/plugins/grafana-test-datasource/img/ds.svg",
Large: "/public/plugins/grafana-test-datasource/img/ds.svg",
},
Updated: "2023-08-03",
Screenshots: []plugins.Screenshots{},
},
Dependencies: plugins.Dependencies{
GrafanaVersion: "*",
Plugins: []plugins.Dependency{},
},
ExternalServiceRegistration: &plugindef.ExternalServiceRegistration{
Permissions: []plugindef.Permission{
{
Action: "read",
Scope: stringPtr("datasource"),
},
},
},
},
FS: mustNewStaticFSForTests(t, pluginPaths[0]),
Class: plugins.ClassExternal,
Signature: plugins.SignatureStatusUnsigned,
Module: "/public/plugins/grafana-test-datasource/module.js",
BaseURL: "/public/plugins/grafana-test-datasource",
ExternalService: &auth.ExternalService{
ClientID: "client-id",
ClientSecret: "secretz",
},
},
}
backendFactoryProvider := fakes.NewFakeBackendProcessProvider()
backendFactoryProvider.BackendFactoryFunc = func(ctx context.Context, plugin *plugins.Plugin) backendplugin.PluginFactoryFunc {
return func(pluginID string, logger log.Logger, env func() []string) (backendplugin.Plugin, error) {
require.Equal(t, "grafana-test-datasource", pluginID)
require.Equal(t, []string{"GF_VERSION=", "GF_EDITION=", "GF_ENTERPRISE_LICENSE_PATH=",
"GF_ENTERPRISE_APP_URL=", "GF_ENTERPRISE_LICENSE_TEXT=", "GF_APP_URL=",
"GF_PLUGIN_APP_CLIENT_ID=client-id", "GF_PLUGIN_APP_CLIENT_SECRET=secretz",
"GF_INSTANCE_FEATURE_TOGGLES_ENABLE=externalServiceAuth"}, env())
return &fakes.FakeBackendPlugin{}, nil
}
}
l := newLoaderWithOpts(t, cfg, loaderDepOpts{
authServiceRegistry: &fakes.FakeAuthService{
Result: &auth.ExternalService{
ClientID: "client-id",
ClientSecret: "secretz",
},
},
backendFactoryProvider: backendFactoryProvider,
})
got, err := l.Load(context.Background(), &fakes.FakePluginSource{
PluginClassFunc: func(ctx context.Context) plugins.Class {
return plugins.ClassExternal
},
PluginURIsFunc: func(ctx context.Context) []string {
return pluginPaths
},
DefaultSignatureFunc: func(ctx context.Context) (plugins.Signature, bool) {
return plugins.Signature{}, false
},
})
require.NoError(t, err)
if !cmp.Equal(got, expected, compareOpts...) {
t.Fatalf("Result mismatch (-want +got):\n%s", cmp.Diff(got, expected, compareOpts...))
}
})
}
func TestLoader_Load_CustomSource(t *testing.T) {