mirror of
https://github.com/grafana/grafana.git
synced 2025-02-11 16:15:42 -06:00
Chore: Update plugin schema with service registration info (#70692)
This commit is contained in:
parent
e03f61fe26
commit
025465e611
@ -477,6 +477,68 @@
|
||||
"tracing": {
|
||||
"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": {
|
||||
"type": "object",
|
||||
"description": "Oauth App Service Registration.",
|
||||
"properties": {
|
||||
"impersonation": {
|
||||
"type": "object",
|
||||
"description": "Impersonation describes the permissions that the external service will have 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",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string"
|
||||
},
|
||||
"scope": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/plugins/config"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/fakes"
|
||||
"github.com/grafana/grafana/pkg/plugins/oauth"
|
||||
"github.com/grafana/grafana/pkg/plugins/plugindef"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
@ -312,7 +313,7 @@ func TestInitializer_oauthEnvVars(t *testing.T) {
|
||||
p := &plugins.Plugin{
|
||||
JSONData: plugins.JSONData{
|
||||
ID: "test",
|
||||
ExternalServiceRegistration: &oauth.ExternalServiceRegistration{},
|
||||
ExternalServiceRegistration: &plugindef.ExternalServiceRegistration{},
|
||||
},
|
||||
ExternalService: &oauth.ExternalService{
|
||||
ClientID: "clientID",
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/plugins/backendplugin"
|
||||
"github.com/grafana/grafana/pkg/plugins/log"
|
||||
"github.com/grafana/grafana/pkg/plugins/oauth"
|
||||
"github.com/grafana/grafana/pkg/plugins/plugindef"
|
||||
"github.com/grafana/grafana/pkg/plugins/repo"
|
||||
"github.com/grafana/grafana/pkg/plugins/storage"
|
||||
)
|
||||
@ -428,6 +429,6 @@ type FakeOauthService struct {
|
||||
Result *oauth.ExternalService
|
||||
}
|
||||
|
||||
func (f *FakeOauthService) RegisterExternalService(ctx context.Context, name string, svc *oauth.ExternalServiceRegistration) (*oauth.ExternalService, error) {
|
||||
func (f *FakeOauthService) RegisterExternalService(ctx context.Context, name string, svc *plugindef.ExternalServiceRegistration) (*oauth.ExternalService, error) {
|
||||
return f.Result, nil
|
||||
}
|
||||
|
@ -3,29 +3,9 @@ package oauth
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/plugins/plugindef"
|
||||
)
|
||||
|
||||
// SelfCfg is a subset of oauthserver.SelfCfg making some fields optional
|
||||
type SelfCfg struct {
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
Permissions []accesscontrol.Permission `json:"permissions,omitempty"`
|
||||
}
|
||||
|
||||
// ImpersonationCfg is a subset of oauthserver.ImpersonationCfg making some fields optional
|
||||
type ImpersonationCfg struct {
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
Groups *bool `json:"groups,omitempty"`
|
||||
Permissions []accesscontrol.Permission `json:"permissions,omitempty"`
|
||||
}
|
||||
|
||||
// PluginExternalServiceRegistration is a subset of oauthserver.ExternalServiceRegistration
|
||||
// simplified for the plugin use case.
|
||||
type ExternalServiceRegistration struct {
|
||||
Impersonation *ImpersonationCfg `json:"impersonation,omitempty"`
|
||||
Self *SelfCfg `json:"self,omitempty"`
|
||||
}
|
||||
|
||||
type ExternalService struct {
|
||||
ClientID string `json:"clientId"`
|
||||
ClientSecret string `json:"clientSecret"`
|
||||
@ -33,5 +13,5 @@ type ExternalService struct {
|
||||
}
|
||||
|
||||
type ExternalServiceRegistry interface {
|
||||
RegisterExternalService(ctx context.Context, name string, svc *ExternalServiceRegistration) (*ExternalService, error)
|
||||
RegisterExternalService(ctx context.Context, name string, svc *plugindef.ExternalServiceRegistration) (*ExternalService, error)
|
||||
}
|
||||
|
@ -405,6 +405,37 @@ schemas: [{
|
||||
// Parameters for the JWT token authentication request.
|
||||
params: [string]: string
|
||||
}
|
||||
|
||||
// External service registration information
|
||||
externalServiceRegistration: #ExternalServiceRegistration
|
||||
|
||||
#ExternalServiceRegistration: {
|
||||
// Impersonation describes the permissions that the external service will have on behalf of the user
|
||||
impersonation?: #Impersonation
|
||||
// Self describes the permissions that the external service will have on behalf of itself
|
||||
self?: #Self
|
||||
}
|
||||
|
||||
#Impersonation: {
|
||||
// Enabled allows the service to request access tokens to impersonate users using the jwtbearer grant
|
||||
// Defaults to true.
|
||||
enabled?: bool
|
||||
// Groups allows the service to list the impersonated user's teams.
|
||||
// Defaults to true.
|
||||
groups?: bool
|
||||
// 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.
|
||||
permissions?: [...#Permission]
|
||||
}
|
||||
|
||||
#Self: {
|
||||
// Enabled allows the service to request access tokens for itself using the client_credentials grant
|
||||
// Defaults to true.
|
||||
enabled?: bool
|
||||
// Permissions are the permissions that the external service needs its associated service account to have.
|
||||
permissions?: [...#Permission]
|
||||
}
|
||||
}
|
||||
}]
|
||||
lenses: []
|
||||
|
@ -122,6 +122,12 @@ type Dependency struct {
|
||||
// DependencyType defines model for Dependency.Type.
|
||||
type DependencyType string
|
||||
|
||||
// ExternalServiceRegistration defines model for ExternalServiceRegistration.
|
||||
type ExternalServiceRegistration struct {
|
||||
Impersonation *Impersonation `json:"impersonation,omitempty"`
|
||||
Self *Self `json:"self,omitempty"`
|
||||
}
|
||||
|
||||
// Header describes an HTTP header that is forwarded with a proxied request for
|
||||
// a plugin route.
|
||||
type Header struct {
|
||||
@ -129,6 +135,22 @@ type Header struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// Impersonation defines model for Impersonation.
|
||||
type Impersonation struct {
|
||||
// Enabled allows the service to request access tokens to impersonate users using the jwtbearer grant
|
||||
// Defaults to true.
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
|
||||
// Groups allows the service to list the impersonated user's teams.
|
||||
// Defaults to true.
|
||||
Groups *bool `json:"groups,omitempty"`
|
||||
|
||||
// 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.
|
||||
Permissions []Permission `json:"permissions,omitempty"`
|
||||
}
|
||||
|
||||
// A resource to be included in a plugin.
|
||||
type Include struct {
|
||||
// RBAC action the user must have to access the route
|
||||
@ -288,7 +310,8 @@ type PluginDef struct {
|
||||
// $GOARCH><.exe for Windows>`, e.g. `plugin_linux_amd64`.
|
||||
// Combination of $GOOS and $GOARCH can be found here:
|
||||
// https://golang.org/doc/install/source#environment.
|
||||
Executable *string `json:"executable,omitempty"`
|
||||
Executable *string `json:"executable,omitempty"`
|
||||
ExternalServiceRegistration ExternalServiceRegistration `json:"externalServiceRegistration"`
|
||||
|
||||
// [internal only] Excludes the plugin from listings in Grafana's UI. Only
|
||||
// allowed for `builtIn` plugins.
|
||||
@ -445,6 +468,16 @@ type Route struct {
|
||||
UrlParams []URLParam `json:"urlParams,omitempty"`
|
||||
}
|
||||
|
||||
// Self defines model for Self.
|
||||
type Self struct {
|
||||
// Enabled allows the service to request access tokens for itself using the client_credentials grant
|
||||
// Defaults to true.
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
|
||||
// Permissions are the permissions that the external service needs its associated service account to have.
|
||||
Permissions []Permission `json:"permissions,omitempty"`
|
||||
}
|
||||
|
||||
// TODO docs
|
||||
type TokenAuth struct {
|
||||
// Parameters for the token authentication request.
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/plugins/backendplugin/secretsmanagerplugin"
|
||||
"github.com/grafana/grafana/pkg/plugins/log"
|
||||
"github.com/grafana/grafana/pkg/plugins/oauth"
|
||||
"github.com/grafana/grafana/pkg/plugins/plugindef"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
@ -155,7 +156,7 @@ type JSONData struct {
|
||||
Executable string `json:"executable,omitempty"`
|
||||
|
||||
// Oauth App Service Registration
|
||||
ExternalServiceRegistration *oauth.ExternalServiceRegistration `json:"externalServiceRegistration,omitempty"`
|
||||
ExternalServiceRegistration *plugindef.ExternalServiceRegistration `json:"externalServiceRegistration,omitempty"`
|
||||
}
|
||||
|
||||
func ReadPluginJSON(reader io.Reader) (JSONData, error) {
|
||||
|
@ -4,6 +4,8 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins/oauth"
|
||||
"github.com/grafana/grafana/pkg/plugins/plugindef"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/oauthserver"
|
||||
)
|
||||
|
||||
@ -19,10 +21,10 @@ func ProvideService(os oauthserver.OAuth2Server) *Service {
|
||||
}
|
||||
|
||||
// RegisterExternalService is a simplified wrapper around SaveExternalService for the plugin use case.
|
||||
func (s *Service) RegisterExternalService(ctx context.Context, svcName string, svc *oauth.ExternalServiceRegistration) (*oauth.ExternalService, error) {
|
||||
func (s *Service) RegisterExternalService(ctx context.Context, svcName string, svc *plugindef.ExternalServiceRegistration) (*oauth.ExternalService, error) {
|
||||
impersonation := oauthserver.ImpersonationCfg{}
|
||||
if svc.Impersonation != nil {
|
||||
impersonation.Permissions = svc.Impersonation.Permissions
|
||||
impersonation.Permissions = toAccessControlPermissions(svc.Impersonation.Permissions)
|
||||
if svc.Impersonation.Enabled != nil {
|
||||
impersonation.Enabled = *svc.Impersonation.Enabled
|
||||
} else {
|
||||
@ -37,7 +39,7 @@ func (s *Service) RegisterExternalService(ctx context.Context, svcName string, s
|
||||
|
||||
self := oauthserver.SelfCfg{}
|
||||
if svc.Self != nil {
|
||||
self.Permissions = svc.Self.Permissions
|
||||
self.Permissions = toAccessControlPermissions(svc.Self.Permissions)
|
||||
if svc.Self.Enabled != nil {
|
||||
self.Enabled = *svc.Self.Enabled
|
||||
} else {
|
||||
@ -60,3 +62,18 @@ func (s *Service) RegisterExternalService(ctx context.Context, svcName string, s
|
||||
PrivateKey: extSvc.KeyResult.PrivatePem,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func toAccessControlPermissions(ps []plugindef.Permission) []accesscontrol.Permission {
|
||||
res := make([]accesscontrol.Permission, 0, len(ps))
|
||||
for _, p := range ps {
|
||||
scope := ""
|
||||
if p.Scope != nil {
|
||||
scope = *p.Scope
|
||||
}
|
||||
res = append(res, accesscontrol.Permission{
|
||||
Action: p.Action,
|
||||
Scope: scope,
|
||||
})
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user