Files
grafana/pkg/services/authz/zanzana/server/server_mutate_rolebindings.go
2025-12-05 13:55:56 +01:00

83 lines
2.6 KiB
Go

package server
import (
"context"
"fmt"
openfgav1 "github.com/openfga/api/proto/openfga/v1"
iamv0 "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1"
authzextv1 "github.com/grafana/grafana/pkg/services/authz/proto/v1"
zanzana "github.com/grafana/grafana/pkg/services/authz/zanzana/common"
)
func (s *Server) mutateRoleBindings(ctx context.Context, store *storeInfo, operations []*authzextv1.MutateOperation) error {
ctx, span := s.tracer.Start(ctx, "server.mutateRoleBindings")
defer span.End()
writeTuples := make([]*openfgav1.TupleKey, 0)
deleteTuples := make([]*openfgav1.TupleKeyWithoutCondition, 0)
for _, operation := range operations {
switch op := operation.Operation.(type) {
case *authzextv1.MutateOperation_CreateRoleBinding:
r := op.CreateRoleBinding
tuple, err := s.getRoleBindingTuple(ctx, r.SubjectKind, r.SubjectName, r.RoleName)
if err != nil {
return err
}
writeTuples = append(writeTuples, tuple)
case *authzextv1.MutateOperation_DeleteRoleBinding:
r := op.DeleteRoleBinding
tuple, err := s.getRoleBindingTuple(ctx, r.SubjectKind, r.SubjectName, r.RoleName)
if err != nil {
return err
}
writeTuple := &openfgav1.TupleKeyWithoutCondition{
User: tuple.User,
Relation: tuple.Relation,
Object: tuple.Object,
}
deleteTuples = append(deleteTuples, writeTuple)
default:
s.logger.Debug("unsupported mutate operation", "operation", op)
}
}
err := s.writeTuples(ctx, store, writeTuples, deleteTuples)
if err != nil {
s.logger.Error("failed to write resource role binding tuples", "error", err)
return err
}
return nil
}
func (s *Server) getRoleBindingTuple(ctx context.Context, subjectKind string, subjectName string, roleName string) (*openfgav1.TupleKey, error) {
zanzanaType := ""
subjectRelation := ""
switch subjectKind {
case string(iamv0.RoleBindingSpecSubjectKindUser):
zanzanaType = zanzana.TypeUser
case string(iamv0.RoleBindingSpecSubjectKindTeam):
zanzanaType = zanzana.TypeTeam
subjectRelation = zanzana.RelationTeamMember
case string(iamv0.RoleBindingSpecSubjectKindServiceAccount):
zanzanaType = zanzana.TypeServiceAccount
case string(iamv0.RoleBindingSpecSubjectKindBasicRole):
zanzanaType = zanzana.TypeRole
subjectRelation = zanzana.RelationAssignee
default:
return nil, fmt.Errorf("invalid subject kind: %s", subjectKind)
}
tuple := &openfgav1.TupleKey{
User: zanzana.NewTupleEntry(zanzanaType, subjectName, subjectRelation),
Relation: zanzana.RelationAssignee,
Object: zanzana.NewTupleEntry(zanzana.TypeRole, roleName, ""),
}
return tuple, nil
}