mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Service accounts: Creation logic simplification (#63884)
* SA creation improvements * PR feedback - put salt and rand back in and remove an unneeded line:
This commit is contained in:
@@ -16,7 +16,6 @@ import (
|
||||
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/serviceaccounts"
|
||||
"github.com/grafana/grafana/pkg/services/serviceaccounts/database"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
@@ -133,7 +132,7 @@ func (api *ServiceAccountsAPI) CreateServiceAccount(c *contextmodel.ReqContext)
|
||||
|
||||
serviceAccount, err := api.service.CreateServiceAccount(c.Req.Context(), c.OrgID, &cmd)
|
||||
switch {
|
||||
case errors.Is(err, database.ErrServiceAccountAlreadyExists):
|
||||
case errors.Is(err, serviceaccounts.ErrServiceAccountAlreadyExists):
|
||||
return response.Error(http.StatusBadRequest, "Failed to create service account", err)
|
||||
case err != nil:
|
||||
return response.Error(http.StatusInternalServerError, "Failed to create service account", err)
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/apikey"
|
||||
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
||||
"github.com/grafana/grafana/pkg/services/serviceaccounts"
|
||||
"github.com/grafana/grafana/pkg/services/serviceaccounts/database"
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
)
|
||||
|
||||
@@ -177,10 +176,10 @@ func (api *ServiceAccountsAPI) CreateToken(c *contextmodel.ReqContext) response.
|
||||
|
||||
apiKey, err := api.service.AddServiceAccountToken(c.Req.Context(), saID, &cmd)
|
||||
if err != nil {
|
||||
if errors.Is(err, database.ErrInvalidTokenExpiration) {
|
||||
if errors.Is(err, serviceaccounts.ErrInvalidTokenExpiration) {
|
||||
return response.Error(http.StatusBadRequest, err.Error(), nil)
|
||||
}
|
||||
if errors.Is(err, database.ErrDuplicateToken) {
|
||||
if errors.Is(err, serviceaccounts.ErrDuplicateToken) {
|
||||
return response.Error(http.StatusConflict, err.Error(), nil)
|
||||
}
|
||||
return response.Error(http.StatusInternalServerError, "Failed to add service account token", err)
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
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")
|
||||
ErrServiceAccountAndTokenMismatch = errors.New("API token does not belong to the given service account")
|
||||
)
|
||||
@@ -3,7 +3,6 @@ package database
|
||||
//nolint:goimports
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -55,40 +54,17 @@ func (s *ServiceAccountsStoreImpl) CreateServiceAccount(ctx context.Context, org
|
||||
if saForm.Role != nil {
|
||||
role = *saForm.Role
|
||||
}
|
||||
var newSA *user.User
|
||||
createErr := s.sqlStore.WithTransactionalDbSession(ctx, func(sess *db.Session) (err error) {
|
||||
var errUser error
|
||||
newSA, errUser = s.userService.CreateServiceAccount(ctx, &user.CreateUserCommand{
|
||||
Login: generatedLogin,
|
||||
OrgID: orgId,
|
||||
Name: saForm.Name,
|
||||
IsDisabled: isDisabled,
|
||||
IsServiceAccount: true,
|
||||
SkipOrgSetup: true,
|
||||
})
|
||||
if errUser != nil {
|
||||
return errUser
|
||||
}
|
||||
|
||||
errAddOrgUser := s.orgService.AddOrgUser(ctx, &org.AddOrgUserCommand{
|
||||
Role: role,
|
||||
OrgID: orgId,
|
||||
UserID: newSA.ID,
|
||||
AllowAddingServiceAccount: true,
|
||||
})
|
||||
if errAddOrgUser != nil {
|
||||
return errAddOrgUser
|
||||
}
|
||||
|
||||
return nil
|
||||
newSA, err := s.userService.CreateServiceAccount(ctx, &user.CreateUserCommand{
|
||||
Login: generatedLogin,
|
||||
OrgID: orgId,
|
||||
Name: saForm.Name,
|
||||
IsDisabled: isDisabled,
|
||||
IsServiceAccount: true,
|
||||
DefaultOrgRole: string(role),
|
||||
})
|
||||
|
||||
if createErr != nil {
|
||||
if errors.Is(createErr, user.ErrUserAlreadyExists) {
|
||||
return nil, ErrServiceAccountAlreadyExists
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("failed to create service account: %w", createErr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create service account: %w", err)
|
||||
}
|
||||
|
||||
return &serviceaccounts.ServiceAccountDTO{
|
||||
@@ -473,7 +449,7 @@ func (s *ServiceAccountsStoreImpl) RevertApiKey(ctx context.Context, saId int64,
|
||||
}
|
||||
|
||||
if *key.ServiceAccountId != saId {
|
||||
return ErrServiceAccountAndTokenMismatch
|
||||
return serviceaccounts.ErrServiceAccountAndTokenMismatch
|
||||
}
|
||||
|
||||
tokens, err := s.ListTokens(ctx, &serviceaccounts.GetSATokensQuery{
|
||||
|
||||
@@ -328,7 +328,7 @@ func TestStore_RevertApiKey(t *testing.T) {
|
||||
desc: "should fail reverting to api key when the token is assigned to a different service account",
|
||||
key: tests.TestApiKey{Name: "Test1", Role: org.RoleEditor, OrgId: 1},
|
||||
forceMismatchServiceAccount: true,
|
||||
expectedErr: ErrServiceAccountAndTokenMismatch,
|
||||
expectedErr: serviceaccounts.ErrServiceAccountAndTokenMismatch,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -58,9 +58,9 @@ func (s *ServiceAccountsStoreImpl) AddServiceAccountToken(ctx context.Context, s
|
||||
if err := s.apiKeyService.AddAPIKey(ctx, addKeyCmd); err != nil {
|
||||
switch {
|
||||
case errors.Is(err, apikey.ErrDuplicate):
|
||||
return ErrDuplicateToken
|
||||
return serviceaccounts.ErrDuplicateToken
|
||||
case errors.Is(err, apikey.ErrInvalidExpiration):
|
||||
return ErrInvalidTokenExpiration
|
||||
return serviceaccounts.ErrInvalidTokenExpiration
|
||||
}
|
||||
|
||||
return err
|
||||
@@ -81,7 +81,7 @@ func (s *ServiceAccountsStoreImpl) DeleteServiceAccountToken(ctx context.Context
|
||||
}
|
||||
affected, err := result.RowsAffected()
|
||||
if affected == 0 {
|
||||
return ErrServiceAccountTokenNotFound
|
||||
return serviceaccounts.ErrServiceAccountTokenNotFound
|
||||
}
|
||||
|
||||
return err
|
||||
@@ -98,7 +98,7 @@ func (s *ServiceAccountsStoreImpl) RevokeServiceAccountToken(ctx context.Context
|
||||
}
|
||||
affected, err := result.RowsAffected()
|
||||
if affected == 0 {
|
||||
return ErrServiceAccountTokenNotFound
|
||||
return serviceaccounts.ErrServiceAccountTokenNotFound
|
||||
}
|
||||
|
||||
return err
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/util/errutil"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -22,6 +23,14 @@ const (
|
||||
ActionPermissionsWrite = "serviceaccounts.permissions:write"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrServiceAccountAlreadyExists = errutil.NewBase(errutil.StatusBadRequest, "serviceaccounts.ErrAlreadyExists", errutil.WithPublicMessage("service account already exists"))
|
||||
ErrServiceAccountTokenNotFound = errutil.NewBase(errutil.StatusNotFound, "serviceaccounts.ErrTokenNotFound", errutil.WithPublicMessage("service account token not found"))
|
||||
ErrInvalidTokenExpiration = errutil.NewBase(errutil.StatusValidationFailed, "serviceaccounts.ErrInvalidInput", errutil.WithPublicMessage("invalid SecondsToLive value"))
|
||||
ErrDuplicateToken = errutil.NewBase(errutil.StatusBadRequest, "serviceaccounts.ErrTokenAlreadyExists", errutil.WithPublicMessage("service account token with given name already exists in the organization"))
|
||||
ErrServiceAccountAndTokenMismatch = errutil.NewBase(errutil.StatusBadRequest, "serviceaccounts.ErrToeknMismatch", errutil.WithPublicMessage("API token does not belong to the given service account"))
|
||||
)
|
||||
|
||||
type ServiceAccount struct {
|
||||
Id int64
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user