IAM: Add the implementation of the Update User API (#112054)
* wip * Add validate, wire mutate, add tests * Address copilot's feedback * Address feedback
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
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"
|
||||
)
|
||||
@@ -27,5 +28,75 @@ func ValidateOnCreate(ctx context.Context, obj *iamv0alpha1.User) error {
|
||||
return apierrors.NewBadRequest("user must have either login or email")
|
||||
}
|
||||
|
||||
err = validateRole(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateRole(obj *iamv0alpha1.User) error {
|
||||
if obj.Spec.Role == "" {
|
||||
return apierrors.NewBadRequest("role is required")
|
||||
}
|
||||
|
||||
if !identity.RoleType(obj.Spec.Role).IsValid() {
|
||||
return apierrors.NewBadRequest(fmt.Sprintf("invalid role '%s'", obj.Spec.Role))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ValidateOnUpdate(ctx context.Context, oldObj, newObj *iamv0alpha1.User) error {
|
||||
requester, err := identity.GetRequester(ctx)
|
||||
if err != nil {
|
||||
return apierrors.NewUnauthorized("no identity found")
|
||||
}
|
||||
|
||||
isGrafanaAdmin := requester.GetIsGrafanaAdmin()
|
||||
isServiceUser := requester.IsIdentityType(types.TypeAccessPolicy)
|
||||
|
||||
if !isGrafanaAdmin {
|
||||
if newObj.Spec.Disabled != oldObj.Spec.Disabled {
|
||||
return apierrors.NewForbidden(iamv0alpha1.UserResourceInfo.GroupResource(),
|
||||
newObj.Name,
|
||||
fmt.Errorf("only grafana admins can disable or enable a user"))
|
||||
}
|
||||
if newObj.Spec.GrafanaAdmin != oldObj.Spec.GrafanaAdmin {
|
||||
return apierrors.NewForbidden(iamv0alpha1.UserResourceInfo.GroupResource(),
|
||||
newObj.Name,
|
||||
fmt.Errorf("only grafana admins can change grafana admin status"))
|
||||
}
|
||||
}
|
||||
|
||||
if !newObj.Spec.Provisioned && oldObj.Spec.Provisioned {
|
||||
return apierrors.NewForbidden(iamv0alpha1.UserResourceInfo.GroupResource(),
|
||||
newObj.Name,
|
||||
fmt.Errorf("provisioned user cannot be un-provisioned"))
|
||||
}
|
||||
|
||||
if !isServiceUser {
|
||||
if newObj.Spec.Provisioned && !oldObj.Spec.Provisioned {
|
||||
return apierrors.NewForbidden(iamv0alpha1.UserResourceInfo.GroupResource(),
|
||||
newObj.Name,
|
||||
fmt.Errorf("only service users can provision a user"))
|
||||
}
|
||||
if newObj.Spec.EmailVerified && !oldObj.Spec.EmailVerified {
|
||||
return apierrors.NewForbidden(iamv0alpha1.UserResourceInfo.GroupResource(),
|
||||
newObj.Name,
|
||||
fmt.Errorf("only service users can verify email"))
|
||||
}
|
||||
}
|
||||
|
||||
if newObj.Spec.Login == "" && newObj.Spec.Email == "" {
|
||||
return apierrors.NewBadRequest("user must have either login or email")
|
||||
}
|
||||
|
||||
err = validateRole(newObj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user