Files
grafana/pkg/registry/apis/iam/serviceaccount/validate.go
MisiandGabriel MABILLE 29551a6edf IAM: Implement Delete in Service Account API (#110584)
* wip

* IAM: Create Service Account

* Add dual writer

* Update openapi_test.go

* Add integration tests

* Add sql tests

* Add Role to SA spec, add validation, add DBTime, add tests

* Format, update test

* Fixes

* Add check for External

* wip

* Fix merge

* wip

* Use plugin name instead of title for ext svc account login

Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com>

* Remove OrgID from DeleteUserCommand

* Use the new authorizer

* Fix tests

* cleanup

* Move test to enterprise

* Revert unnecessary change

* Address feedback

* Revert "Address feedback"

This reverts commit 8ab9559076.

---------

Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com>
2025-09-16 15:39:01 +02:00

59 lines
1.8 KiB
Go

package serviceaccount
import (
"context"
"fmt"
"strings"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"github.com/grafana/authlib/types"
iamv0alpha1 "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/services/serviceaccounts"
)
func ValidateOnCreate(ctx context.Context, obj *iamv0alpha1.ServiceAccount) error {
if obj.Spec.Title == "" {
return apierrors.NewBadRequest("service account must have a title")
}
requester, err := identity.GetRequester(ctx)
if err != nil {
return apierrors.NewUnauthorized("no identity found")
}
requestedRole := identity.RoleType(obj.Spec.Role)
if !requestedRole.IsValid() {
return apierrors.NewBadRequest(fmt.Sprintf("invalid role: %s", requestedRole))
}
if obj.Spec.Plugin != "" {
if !strings.HasPrefix(obj.Spec.Title, serviceaccounts.ExtSvcPrefix) {
return apierrors.NewBadRequest("title of external service accounts must start with " + serviceaccounts.ExtSvcPrefix)
}
if !strings.HasSuffix(obj.Spec.Title, strings.ToLower(obj.Spec.Plugin)) {
return apierrors.NewBadRequest("title of external service accounts must end with " + strings.ToLower(obj.Spec.Plugin))
}
if !requester.IsIdentityType(types.TypeAccessPolicy) {
return apierrors.NewForbidden(iamv0alpha1.ServiceAccountResourceInfo.GroupResource(),
obj.Name,
fmt.Errorf("only service identities can create external service accounts"))
}
if obj.Spec.Role != iamv0alpha1.ServiceAccountOrgRoleNone {
return apierrors.NewBadRequest("external service accounts must have role None")
}
}
if !requester.HasRole(requestedRole) {
return apierrors.NewForbidden(iamv0alpha1.ServiceAccountResourceInfo.GroupResource(),
obj.Name,
fmt.Errorf("cannot assign a role higher than user's role"))
}
return nil
}