mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Service account: Ensure that you can revert only service accounts which you can access (#52626)
* Service account: Ensure that you can revert only service accounts which you can access * Remove prettier messup with docs * Remove prettier messup with docs * Prettier run
This commit is contained in:
@@ -463,7 +463,7 @@ func (s *ServiceAccountsStoreImpl) CreateServiceAccountFromApikey(ctx context.Co
|
||||
}
|
||||
|
||||
// RevertApiKey converts service account token to old API key
|
||||
func (s *ServiceAccountsStoreImpl) RevertApiKey(ctx context.Context, keyId int64) error {
|
||||
func (s *ServiceAccountsStoreImpl) RevertApiKey(ctx context.Context, saId int64, keyId int64) error {
|
||||
query := models.GetApiKeyByIdQuery{ApiKeyId: keyId}
|
||||
if err := s.sqlStore.GetApiKeyById(ctx, &query); err != nil {
|
||||
return err
|
||||
@@ -474,6 +474,10 @@ func (s *ServiceAccountsStoreImpl) RevertApiKey(ctx context.Context, keyId int64
|
||||
return fmt.Errorf("API key is not service account token")
|
||||
}
|
||||
|
||||
if *key.ServiceAccountId != saId {
|
||||
return ErrServiceAccountAndTokenMismatch
|
||||
}
|
||||
|
||||
tokens, err := s.ListTokens(ctx, key.OrgId, *key.ServiceAccountId)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot revert token: %w", err)
|
||||
|
||||
@@ -2,6 +2,7 @@ package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/kvstore"
|
||||
@@ -270,15 +271,22 @@ func TestStore_MigrateAllApiKeys(t *testing.T) {
|
||||
|
||||
func TestStore_RevertApiKey(t *testing.T) {
|
||||
cases := []struct {
|
||||
desc string
|
||||
key tests.TestApiKey
|
||||
expectedErr error
|
||||
desc string
|
||||
key tests.TestApiKey
|
||||
forceMismatchServiceAccount bool
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
desc: "service account token should be reverted to api key",
|
||||
key: tests.TestApiKey{Name: "Test1", Role: models.ROLE_EDITOR, OrgId: 1},
|
||||
expectedErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "should fail reverting to api key when the token is assigned to a different service account",
|
||||
key: tests.TestApiKey{Name: "Test1", Role: models.ROLE_EDITOR, OrgId: 1},
|
||||
forceMismatchServiceAccount: true,
|
||||
expectedErr: ErrServiceAccountAndTokenMismatch,
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
@@ -291,9 +299,23 @@ func TestStore_RevertApiKey(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
key := tests.SetupApiKey(t, db, c.key)
|
||||
err = store.MigrateApiKey(context.Background(), key.OrgId, key.Id)
|
||||
err = store.CreateServiceAccountFromApikey(context.Background(), key)
|
||||
require.NoError(t, err)
|
||||
err = store.RevertApiKey(context.Background(), key.Id)
|
||||
|
||||
var saId int64
|
||||
if c.forceMismatchServiceAccount {
|
||||
saId = rand.Int63()
|
||||
} else {
|
||||
serviceAccounts, err := store.SearchOrgServiceAccounts(context.Background(), key.OrgId, "", "all", 1, 50, &models.SignedInUser{UserId: 1, OrgId: 1, Permissions: map[int64]map[string][]string{
|
||||
key.OrgId: {
|
||||
"serviceaccounts:read": {"serviceaccounts:id:*"},
|
||||
},
|
||||
}})
|
||||
require.NoError(t, err)
|
||||
saId = serviceAccounts.ServiceAccounts[0].Id
|
||||
}
|
||||
|
||||
err = store.RevertApiKey(context.Background(), saId, key.Id)
|
||||
|
||||
if c.expectedErr != nil {
|
||||
require.ErrorIs(t, err, c.expectedErr)
|
||||
|
||||
@@ -5,8 +5,9 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrServiceAccountAlreadyExists = errors.New("service account already exists")
|
||||
ErrServiceAccountTokenNotFound = errors.New("service account token not found")
|
||||
ErrInvalidTokenExpiration = errors.New("invalid SecondsToLive value")
|
||||
ErrDuplicateToken = errors.New("service account token with given name already exists in the organization")
|
||||
ErrServiceAccountAlreadyExists = errors.New("service account already exists")
|
||||
ErrServiceAccountTokenNotFound = errors.New("service account token not found")
|
||||
ErrInvalidTokenExpiration = errors.New("invalid SecondsToLive value")
|
||||
ErrDuplicateToken = errors.New("service account token with given name already exists in the organization")
|
||||
ErrServiceAccountAndTokenMismatch = errors.New("API token does not belong to the given service account")
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user