mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
auth: implement feature flag for service account proxy (#77129)
* add FlagExternalServiceAccounts to proxy service * add FlagExternalServiceAccounts value to tests --------- Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com>
This commit is contained in:
parent
5f2fd8935d
commit
dff7403b29
@ -2,11 +2,11 @@ package proxy
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/services/apikey"
|
"github.com/grafana/grafana/pkg/services/apikey"
|
||||||
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/services/serviceaccounts"
|
"github.com/grafana/grafana/pkg/services/serviceaccounts"
|
||||||
"github.com/grafana/grafana/pkg/services/serviceaccounts/extsvcaccounts"
|
"github.com/grafana/grafana/pkg/services/serviceaccounts/extsvcaccounts"
|
||||||
"github.com/grafana/grafana/pkg/services/serviceaccounts/manager"
|
"github.com/grafana/grafana/pkg/services/serviceaccounts/manager"
|
||||||
@ -19,14 +19,17 @@ import (
|
|||||||
type ServiceAccountsProxy struct {
|
type ServiceAccountsProxy struct {
|
||||||
log log.Logger
|
log log.Logger
|
||||||
proxiedService serviceaccounts.Service
|
proxiedService serviceaccounts.Service
|
||||||
|
isProxyEnabled bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProvideServiceAccountsProxy(
|
func ProvideServiceAccountsProxy(
|
||||||
|
features *featuremgmt.FeatureManager,
|
||||||
proxiedService *manager.ServiceAccountsService,
|
proxiedService *manager.ServiceAccountsService,
|
||||||
) (*ServiceAccountsProxy, error) {
|
) (*ServiceAccountsProxy, error) {
|
||||||
s := &ServiceAccountsProxy{
|
s := &ServiceAccountsProxy{
|
||||||
log: log.New("serviceaccounts.proxy"),
|
log: log.New("serviceaccounts.proxy"),
|
||||||
proxiedService: proxiedService,
|
proxiedService: proxiedService,
|
||||||
|
isProxyEnabled: features.IsEnabled(featuremgmt.FlagExternalServiceAccounts) || features.IsEnabled(featuremgmt.FlagExternalServiceAuth),
|
||||||
}
|
}
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
@ -34,55 +37,59 @@ func ProvideServiceAccountsProxy(
|
|||||||
var _ serviceaccounts.Service = (*ServiceAccountsProxy)(nil)
|
var _ serviceaccounts.Service = (*ServiceAccountsProxy)(nil)
|
||||||
|
|
||||||
func (s *ServiceAccountsProxy) AddServiceAccountToken(ctx context.Context, serviceAccountID int64, cmd *serviceaccounts.AddServiceAccountTokenCommand) (*apikey.APIKey, error) {
|
func (s *ServiceAccountsProxy) AddServiceAccountToken(ctx context.Context, serviceAccountID int64, cmd *serviceaccounts.AddServiceAccountTokenCommand) (*apikey.APIKey, error) {
|
||||||
sa, err := s.proxiedService.RetrieveServiceAccount(ctx, cmd.OrgId, serviceAccountID)
|
if s.isProxyEnabled {
|
||||||
if err != nil {
|
sa, err := s.proxiedService.RetrieveServiceAccount(ctx, cmd.OrgId, serviceAccountID)
|
||||||
return nil, err
|
if err != nil {
|
||||||
}
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
if isExternalServiceAccount(sa.Login) {
|
if isExternalServiceAccount(sa.Login) {
|
||||||
s.log.Error("unable to create tokens for external service accounts", "serviceAccountID", serviceAccountID)
|
s.log.Error("unable to create tokens for external service accounts", "serviceAccountID", serviceAccountID)
|
||||||
return nil, extsvcaccounts.ErrCannotCreateToken
|
return nil, extsvcaccounts.ErrCannotCreateToken
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.proxiedService.AddServiceAccountToken(ctx, serviceAccountID, cmd)
|
return s.proxiedService.AddServiceAccountToken(ctx, serviceAccountID, cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ServiceAccountsProxy) CreateServiceAccount(ctx context.Context, orgID int64, saForm *serviceaccounts.CreateServiceAccountForm) (*serviceaccounts.ServiceAccountDTO, error) {
|
func (s *ServiceAccountsProxy) CreateServiceAccount(ctx context.Context, orgID int64, saForm *serviceaccounts.CreateServiceAccountForm) (*serviceaccounts.ServiceAccountDTO, error) {
|
||||||
if !isNameValid(saForm.Name) {
|
if s.isProxyEnabled {
|
||||||
s.log.Error("Unable to create service account with a protected name", "name", saForm.Name)
|
if !isNameValid(saForm.Name) {
|
||||||
return nil, extsvcaccounts.ErrInvalidName
|
s.log.Error("Unable to create service account with a protected name", "name", saForm.Name)
|
||||||
|
return nil, extsvcaccounts.ErrInvalidName
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return s.proxiedService.CreateServiceAccount(ctx, orgID, saForm)
|
return s.proxiedService.CreateServiceAccount(ctx, orgID, saForm)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ServiceAccountsProxy) DeleteServiceAccount(ctx context.Context, orgID, serviceAccountID int64) error {
|
func (s *ServiceAccountsProxy) DeleteServiceAccount(ctx context.Context, orgID, serviceAccountID int64) error {
|
||||||
sa, err := s.proxiedService.RetrieveServiceAccount(ctx, orgID, serviceAccountID)
|
if s.isProxyEnabled {
|
||||||
if err != nil {
|
sa, err := s.proxiedService.RetrieveServiceAccount(ctx, orgID, serviceAccountID)
|
||||||
return err
|
if err != nil {
|
||||||
}
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if isExternalServiceAccount(sa.Login) {
|
if isExternalServiceAccount(sa.Login) {
|
||||||
s.log.Error("unable to delete external service accounts", "serviceAccountID", serviceAccountID)
|
s.log.Error("unable to delete external service accounts", "serviceAccountID", serviceAccountID)
|
||||||
return extsvcaccounts.ErrCannotBeDeleted
|
return extsvcaccounts.ErrCannotBeDeleted
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.proxiedService.DeleteServiceAccount(ctx, orgID, serviceAccountID)
|
return s.proxiedService.DeleteServiceAccount(ctx, orgID, serviceAccountID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ServiceAccountsProxy) DeleteServiceAccountToken(ctx context.Context, orgID int64, serviceAccountID int64, tokenID int64) error {
|
func (s *ServiceAccountsProxy) DeleteServiceAccountToken(ctx context.Context, orgID int64, serviceAccountID int64, tokenID int64) error {
|
||||||
sa, err := s.proxiedService.RetrieveServiceAccount(ctx, 0, serviceAccountID)
|
if s.isProxyEnabled {
|
||||||
if err != nil {
|
sa, err := s.proxiedService.RetrieveServiceAccount(ctx, orgID, serviceAccountID)
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if isExternalServiceAccount(sa.Login) {
|
||||||
|
s.log.Error("unable to delete tokens for external service accounts", "serviceAccountID", serviceAccountID)
|
||||||
|
return extsvcaccounts.ErrCannotDeleteToken
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return s.proxiedService.DeleteServiceAccountToken(ctx, orgID, serviceAccountID, tokenID)
|
||||||
fmt.Println("sa.Login: ", sa.Login)
|
|
||||||
|
|
||||||
if isExternalServiceAccount(sa.Login) {
|
|
||||||
s.log.Error("unable to delete tokens for external service accounts", "serviceAccountID", serviceAccountID)
|
|
||||||
return extsvcaccounts.ErrCannotDeleteToken
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.proxiedService.DeleteServiceAccountToken(ctx, sa.OrgId, serviceAccountID, tokenID)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ServiceAccountsProxy) ListTokens(ctx context.Context, query *serviceaccounts.GetSATokensQuery) ([]apikey.APIKey, error) {
|
func (s *ServiceAccountsProxy) ListTokens(ctx context.Context, query *serviceaccounts.GetSATokensQuery) ([]apikey.APIKey, error) {
|
||||||
@ -103,7 +110,9 @@ func (s *ServiceAccountsProxy) RetrieveServiceAccount(ctx context.Context, orgID
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sa.IsExternal = isExternalServiceAccount(sa.Login)
|
if s.isProxyEnabled {
|
||||||
|
sa.IsExternal = isExternalServiceAccount(sa.Login)
|
||||||
|
}
|
||||||
|
|
||||||
return sa, nil
|
return sa, nil
|
||||||
}
|
}
|
||||||
@ -113,17 +122,19 @@ func (s *ServiceAccountsProxy) RetrieveServiceAccountIdByName(ctx context.Contex
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *ServiceAccountsProxy) UpdateServiceAccount(ctx context.Context, orgID, serviceAccountID int64, saForm *serviceaccounts.UpdateServiceAccountForm) (*serviceaccounts.ServiceAccountProfileDTO, error) {
|
func (s *ServiceAccountsProxy) UpdateServiceAccount(ctx context.Context, orgID, serviceAccountID int64, saForm *serviceaccounts.UpdateServiceAccountForm) (*serviceaccounts.ServiceAccountProfileDTO, error) {
|
||||||
if !isNameValid(*saForm.Name) {
|
if s.isProxyEnabled {
|
||||||
s.log.Error("Invalid service account name", "name", *saForm.Name)
|
if !isNameValid(*saForm.Name) {
|
||||||
return nil, extsvcaccounts.ErrInvalidName
|
s.log.Error("Invalid service account name", "name", *saForm.Name)
|
||||||
}
|
return nil, extsvcaccounts.ErrInvalidName
|
||||||
sa, err := s.proxiedService.RetrieveServiceAccount(ctx, orgID, serviceAccountID)
|
}
|
||||||
if err != nil {
|
sa, err := s.proxiedService.RetrieveServiceAccount(ctx, orgID, serviceAccountID)
|
||||||
return nil, err
|
if err != nil {
|
||||||
}
|
return nil, err
|
||||||
if isExternalServiceAccount(sa.Login) {
|
}
|
||||||
s.log.Error("unable to update external service accounts", "serviceAccountID", serviceAccountID)
|
if isExternalServiceAccount(sa.Login) {
|
||||||
return nil, extsvcaccounts.ErrCannotBeUpdated
|
s.log.Error("unable to update external service accounts", "serviceAccountID", serviceAccountID)
|
||||||
|
return nil, extsvcaccounts.ErrCannotBeUpdated
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.proxiedService.UpdateServiceAccount(ctx, orgID, serviceAccountID, saForm)
|
return s.proxiedService.UpdateServiceAccount(ctx, orgID, serviceAccountID, saForm)
|
||||||
@ -135,8 +146,10 @@ func (s *ServiceAccountsProxy) SearchOrgServiceAccounts(ctx context.Context, que
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range sa.ServiceAccounts {
|
if s.isProxyEnabled {
|
||||||
sa.ServiceAccounts[i].IsExternal = isExternalServiceAccount(sa.ServiceAccounts[i].Login)
|
for i := range sa.ServiceAccounts {
|
||||||
|
sa.ServiceAccounts[i].IsExternal = isExternalServiceAccount(sa.ServiceAccounts[i].Login)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return sa, nil
|
return sa, nil
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ func TestProvideServiceAccount_crudServiceAccount(t *testing.T) {
|
|||||||
svc := ServiceAccountsProxy{
|
svc := ServiceAccountsProxy{
|
||||||
log.New("test"),
|
log.New("test"),
|
||||||
serviceMock,
|
serviceMock,
|
||||||
|
true,
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run("should create service account", func(t *testing.T) {
|
t.Run("should create service account", func(t *testing.T) {
|
||||||
|
Loading…
Reference in New Issue
Block a user