mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Plugins: Rename externalServiceAuthentication
to iam
(#78686)
Plugins: Rename externalServiceAuthentication to iam
This commit is contained in:
parent
0825b63b79
commit
5b70130e6c
@ -478,51 +478,37 @@
|
||||
"type": "boolean",
|
||||
"description": "For data source plugins, if the plugin supports tracing. Used for example to link logs (e.g. Loki logs) with tracing plugins."
|
||||
},
|
||||
"externalServiceRegistration": {
|
||||
"iam": {
|
||||
"type": "object",
|
||||
"description": "Oauth App Service Registration.",
|
||||
"description": "Identity and Access Management.",
|
||||
"properties": {
|
||||
"permissions": {
|
||||
"type": "array",
|
||||
"description": "Permissions are the permissions that the plugin needs its associated service account to have",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string"
|
||||
},
|
||||
"scope": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"impersonation": {
|
||||
"type": "object",
|
||||
"description": "Impersonation describes the permissions that the external service will have on behalf of the user.",
|
||||
"description": "Impersonation describes the permissions that the plugin will be restricted to when acting on behalf of the user.",
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enabled allows the service to request access tokens to impersonate users using the jwtbearer grant"
|
||||
},
|
||||
"groups": {
|
||||
"type": "boolean",
|
||||
"description": "Groups allows the service to list the impersonated user's teams."
|
||||
},
|
||||
"permissions": {
|
||||
"type": "array",
|
||||
"description": "Permissions are the permissions that the external service needs when impersonating a user. The intersection of this set with the impersonated user's permission guarantees that the client will not gain more privileges than the impersonated user has.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string"
|
||||
},
|
||||
"scope": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"self": {
|
||||
"type": "object",
|
||||
"description": "Self describes the permissions that the external service will have on behalf of itself",
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enabled allows the service to request access tokens for itself using the client_credentials grant"
|
||||
},
|
||||
"permissions": {
|
||||
"type": "array",
|
||||
"description": "Permissions are the permissions that the external service needs its associated service account to have",
|
||||
"description": "Permissions are the permissions that the plugin needs when impersonating a user. The intersection of this set with the impersonated user's permission guarantees that the client will not gain more privileges than the impersonated user has.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
|
@ -519,13 +519,13 @@ func (hs *HTTPServer) hasPluginRequestedPermissions(c *contextmodel.ReqContext,
|
||||
}
|
||||
|
||||
// No registration => Early return
|
||||
if plugin.JSONData.ExternalServiceRegistration == nil || len(plugin.JSONData.ExternalServiceRegistration.Permissions) == 0 {
|
||||
if plugin.JSONData.IAM == nil || len(plugin.JSONData.IAM.Permissions) == 0 {
|
||||
hs.log.Debug("plugin did not request permissions on Grafana", "pluginID", pluginID)
|
||||
return
|
||||
}
|
||||
|
||||
hs.log.Debug("check installer's permissions, plugin wants to register an external service")
|
||||
evaluator := evalAllPermissions(plugin.JSONData.ExternalServiceRegistration.Permissions)
|
||||
evaluator := evalAllPermissions(plugin.JSONData.IAM.Permissions)
|
||||
hasAccess := ac.HasGlobalAccess(hs.AccessControl, hs.accesscontrolService, c)
|
||||
if hs.Cfg.RBACSingleOrganization {
|
||||
// In a single organization setup, no need for a global check
|
||||
|
@ -650,7 +650,7 @@ func TestHTTPServer_hasPluginRequestedPermissions(t *testing.T) {
|
||||
pluginReg := pluginstore.Plugin{
|
||||
JSONData: plugins.JSONData{
|
||||
ID: "grafana-test-app",
|
||||
ExternalServiceRegistration: &plugindef.ExternalServiceRegistration{
|
||||
IAM: &plugindef.IAM{
|
||||
Permissions: []plugindef.Permission{{Action: ac.ActionUsersRead, Scope: newStr(ac.ScopeUsersAll)}, {Action: ac.ActionUsersCreate}},
|
||||
},
|
||||
},
|
||||
|
@ -14,6 +14,6 @@ type ExternalService struct {
|
||||
|
||||
type ExternalServiceRegistry interface {
|
||||
HasExternalService(ctx context.Context, pluginID string) (bool, error)
|
||||
RegisterExternalService(ctx context.Context, pluginID string, pType plugindef.Type, svc *plugindef.ExternalServiceRegistration) (*ExternalService, error)
|
||||
RegisterExternalService(ctx context.Context, pluginID string, pType plugindef.Type, svc *plugindef.IAM) (*ExternalService, error)
|
||||
RemoveExternalService(ctx context.Context, pluginID string) error
|
||||
}
|
||||
|
@ -529,8 +529,8 @@ func TestInitializer_authEnvVars(t *testing.T) {
|
||||
t.Run("backend datasource with auth registration", func(t *testing.T) {
|
||||
p := &plugins.Plugin{
|
||||
JSONData: plugins.JSONData{
|
||||
ID: "test",
|
||||
ExternalServiceRegistration: &plugindef.ExternalServiceRegistration{},
|
||||
ID: "test",
|
||||
IAM: &plugindef.IAM{},
|
||||
},
|
||||
ExternalService: &auth.ExternalService{
|
||||
ClientID: "clientID",
|
||||
|
@ -441,7 +441,7 @@ func (f *FakeAuthService) HasExternalService(ctx context.Context, pluginID strin
|
||||
return f.Result != nil, nil
|
||||
}
|
||||
|
||||
func (f *FakeAuthService) RegisterExternalService(ctx context.Context, pluginID string, pType plugindef.Type, svc *plugindef.ExternalServiceRegistration) (*auth.ExternalService, error) {
|
||||
func (f *FakeAuthService) RegisterExternalService(ctx context.Context, pluginID string, pType plugindef.Type, svc *plugindef.IAM) (*auth.ExternalService, error) {
|
||||
return f.Result, nil
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
"updated": "2023-08-03",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"externalServiceRegistration": {
|
||||
"iam": {
|
||||
"permissions" : [
|
||||
{
|
||||
"action": "read",
|
||||
|
@ -17,7 +17,7 @@
|
||||
"updated": "2023-08-03",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"externalServiceRegistration": {
|
||||
"iam": {
|
||||
"impersonation": {
|
||||
"groups" : true,
|
||||
"permissions" : [
|
||||
|
@ -410,12 +410,13 @@ schemas: [{
|
||||
params: [string]: string
|
||||
}
|
||||
|
||||
// External service registration information
|
||||
externalServiceRegistration: #ExternalServiceRegistration
|
||||
// Identity and Access Management information.
|
||||
// Allows the plugin to define the permissions it requires to have on Grafana.
|
||||
iam: #IAM
|
||||
|
||||
// ExternalServiceRegistration allows the service to get a service account token
|
||||
// IAM allows the plugin to get a service account with tailored permissions and a token
|
||||
// (or to use the client_credentials grant if the token provider is the OAuth2 Server)
|
||||
#ExternalServiceRegistration: {
|
||||
#IAM: {
|
||||
// Permissions are the permissions that the external service needs its associated service account to have.
|
||||
permissions?: [...#Permission]
|
||||
|
||||
|
@ -122,15 +122,6 @@ type Dependency struct {
|
||||
// DependencyType defines model for Dependency.Type.
|
||||
type DependencyType string
|
||||
|
||||
// ExternalServiceRegistration allows the service to get a service account token
|
||||
// (or to use the client_credentials grant if the token provider is the OAuth2 Server)
|
||||
type ExternalServiceRegistration struct {
|
||||
Impersonation *Impersonation `json:"impersonation,omitempty"`
|
||||
|
||||
// Permissions are the permissions that the external service needs its associated service account to have.
|
||||
Permissions []Permission `json:"permissions,omitempty"`
|
||||
}
|
||||
|
||||
// Header describes an HTTP header that is forwarded with a proxied request for
|
||||
// a plugin route.
|
||||
type Header struct {
|
||||
@ -138,6 +129,15 @@ type Header struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// IAM allows the plugin to get a service account with tailored permissions and a token
|
||||
// (or to use the client_credentials grant if the token provider is the OAuth2 Server)
|
||||
type IAM struct {
|
||||
Impersonation *Impersonation `json:"impersonation,omitempty"`
|
||||
|
||||
// Permissions are the permissions that the external service needs its associated service account to have.
|
||||
Permissions []Permission `json:"permissions,omitempty"`
|
||||
}
|
||||
|
||||
// Impersonation defines model for Impersonation.
|
||||
type Impersonation struct {
|
||||
// Groups allows the service to list the impersonated user's teams.
|
||||
@ -315,14 +315,14 @@ type PluginDef struct {
|
||||
// https://golang.org/doc/install/source#environment.
|
||||
Executable *string `json:"executable,omitempty"`
|
||||
|
||||
// ExternalServiceRegistration allows the service to get a service account token
|
||||
// (or to use the client_credentials grant if the token provider is the OAuth2 Server)
|
||||
ExternalServiceRegistration ExternalServiceRegistration `json:"externalServiceRegistration"`
|
||||
|
||||
// [internal only] Excludes the plugin from listings in Grafana's UI. Only
|
||||
// allowed for `builtIn` plugins.
|
||||
HideFromList bool `json:"hideFromList"`
|
||||
|
||||
// IAM allows the plugin to get a service account with tailored permissions and a token
|
||||
// (or to use the client_credentials grant if the token provider is the OAuth2 Server)
|
||||
Iam IAM `json:"iam"`
|
||||
|
||||
// Unique name of the plugin. If the plugin is published on
|
||||
// grafana.com, then the plugin `id` has to follow the naming
|
||||
// conventions.
|
||||
|
@ -118,7 +118,7 @@ type JSONData struct {
|
||||
Executable string `json:"executable,omitempty"`
|
||||
|
||||
// App Service Auth Registration
|
||||
ExternalServiceRegistration *plugindef.ExternalServiceRegistration `json:"externalServiceRegistration,omitempty"`
|
||||
IAM *plugindef.IAM `json:"iam,omitempty"`
|
||||
}
|
||||
|
||||
func ReadPluginJSON(reader io.Reader) (JSONData, error) {
|
||||
|
@ -535,7 +535,7 @@ func TestLoader_Load_ExternalRegistration(t *testing.T) {
|
||||
GrafanaVersion: "*",
|
||||
Plugins: []plugins.Dependency{},
|
||||
},
|
||||
ExternalServiceRegistration: &plugindef.ExternalServiceRegistration{
|
||||
IAM: &plugindef.IAM{
|
||||
Impersonation: &plugindef.Impersonation{
|
||||
Groups: boolPtr(true),
|
||||
Permissions: []plugindef.Permission{
|
||||
@ -636,7 +636,7 @@ func TestLoader_Load_ExternalRegistration(t *testing.T) {
|
||||
GrafanaVersion: "*",
|
||||
Plugins: []plugins.Dependency{},
|
||||
},
|
||||
ExternalServiceRegistration: &plugindef.ExternalServiceRegistration{
|
||||
IAM: &plugindef.IAM{
|
||||
Permissions: []plugindef.Permission{
|
||||
{
|
||||
Action: "read",
|
||||
|
@ -39,8 +39,8 @@ func newExternalServiceRegistration(cfg *config.Cfg, serviceRegistry auth.Extern
|
||||
|
||||
// Register registers the external service with the external service registry, if the feature is enabled.
|
||||
func (r *ExternalServiceRegistration) Register(ctx context.Context, p *plugins.Plugin) (*plugins.Plugin, error) {
|
||||
if p.ExternalServiceRegistration != nil {
|
||||
s, err := r.externalServiceRegistry.RegisterExternalService(ctx, p.ID, plugindef.Type(p.Type), p.ExternalServiceRegistration)
|
||||
if p.IAM != nil {
|
||||
s, err := r.externalServiceRegistry.RegisterExternalService(ctx, p.ID, plugindef.Type(p.Type), p.IAM)
|
||||
if err != nil {
|
||||
r.log.Error("Could not register an external service. Initialization skipped", "pluginId", p.ID, "error", err)
|
||||
return nil, err
|
||||
|
@ -41,7 +41,7 @@ func (s *Service) HasExternalService(ctx context.Context, pluginID string) (bool
|
||||
}
|
||||
|
||||
// RegisterExternalService is a simplified wrapper around SaveExternalService for the plugin use case.
|
||||
func (s *Service) RegisterExternalService(ctx context.Context, pluginID string, pType plugindef.Type, svc *plugindef.ExternalServiceRegistration) (*auth.ExternalService, error) {
|
||||
func (s *Service) RegisterExternalService(ctx context.Context, pluginID string, pType plugindef.Type, svc *plugindef.IAM) (*auth.ExternalService, error) {
|
||||
if !s.featureEnabled {
|
||||
s.log.Warn("Skipping External Service Registration. The feature is behind a feature toggle and needs to be enabled.")
|
||||
return nil, nil
|
||||
|
Loading…
Reference in New Issue
Block a user