grafana/pkg/services/pluginsintegration/serviceregistration/serviceregistration.go
Gabriel MABILLE 83e9088314
AuthN: Set oauth client grant_types based on plugin state (#77248)
* Disable plugin service account

* Fix bug seen by linoman 💯

Co-authored-by: linoman <2051016+linoman@users.noreply.github.com>

* Account for PR feedback

Co-authored-by: linoman <2051016+linoman@users.noreply.github.com>

* Fix test data

* Enable datasource plugins by default

Co-authored-by: Andres Martinez Gotor <andres.martinez@grafana.com>

* Update pkg/services/extsvcauth/oauthserver/oasimpl/service.go

* Handle error differently

* Fix service reg

---------

Co-authored-by: linoman <2051016+linoman@users.noreply.github.com>
Co-authored-by: Andres Martinez Gotor <andres.martinez@grafana.com>
2023-10-27 14:45:04 +02:00

101 lines
2.9 KiB
Go

package serviceregistration
import (
"context"
"errors"
"github.com/grafana/grafana/pkg/plugins/auth"
"github.com/grafana/grafana/pkg/plugins/plugindef"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/extsvcauth"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings"
)
type Service struct {
reg extsvcauth.ExternalServiceRegistry
settingsSvc pluginsettings.Service
}
func ProvideService(reg extsvcauth.ExternalServiceRegistry, settingsSvc pluginsettings.Service) *Service {
s := &Service{
reg: reg,
settingsSvc: settingsSvc,
}
return s
}
// RegisterExternalService is a simplified wrapper around SaveExternalService for the plugin use case.
func (s *Service) RegisterExternalService(ctx context.Context, svcName string, pType plugindef.Type, svc *plugindef.ExternalServiceRegistration) (*auth.ExternalService, error) {
// Datasource plugins can only be enabled
enabled := true
// App plugins can be disabled
if pType == plugindef.TypeApp {
settings, err := s.settingsSvc.GetPluginSettingByPluginID(ctx, &pluginsettings.GetByPluginIDArgs{PluginID: svcName})
if err != nil && !errors.Is(err, pluginsettings.ErrPluginSettingNotFound) {
return nil, err
}
enabled = (settings != nil) && settings.Enabled
}
impersonation := extsvcauth.ImpersonationCfg{}
if svc.Impersonation != nil {
impersonation.Permissions = toAccessControlPermissions(svc.Impersonation.Permissions)
impersonation.Enabled = enabled
if svc.Impersonation.Groups != nil {
impersonation.Groups = *svc.Impersonation.Groups
} else {
impersonation.Groups = true
}
}
self := extsvcauth.SelfCfg{}
self.Enabled = enabled
if len(svc.Permissions) > 0 {
self.Permissions = toAccessControlPermissions(svc.Permissions)
}
registration := &extsvcauth.ExternalServiceRegistration{
Name: svcName,
Impersonation: impersonation,
Self: self,
}
// Default authProvider now is ServiceAccounts
registration.AuthProvider = extsvcauth.ServiceAccounts
if svc.Impersonation != nil {
registration.AuthProvider = extsvcauth.OAuth2Server
registration.OAuthProviderCfg = &extsvcauth.OAuthProviderCfg{Key: &extsvcauth.KeyOption{Generate: true}}
}
extSvc, err := s.reg.SaveExternalService(ctx, registration)
if err != nil || extSvc == nil {
return nil, err
}
privateKey := ""
if extSvc.OAuthExtra != nil {
privateKey = extSvc.OAuthExtra.KeyResult.PrivatePem
}
return &auth.ExternalService{
ClientID: extSvc.ID,
ClientSecret: extSvc.Secret,
PrivateKey: privateKey}, 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
}