Skip to content

Commit

Permalink
role-binding: remove at least one subject requirement (#291)
Browse files Browse the repository at this point in the history
* remove at least one subject requirement

Signed-off-by: Bailin He <[email protected]>

* allow updates to remove all subjects

Signed-off-by: Bailin He <[email protected]>

---------

Signed-off-by: Bailin He <[email protected]>
  • Loading branch information
bailinhe authored Sep 30, 2024
1 parent 98862f9 commit 73e75eb
Show file tree
Hide file tree
Showing 5 changed files with 16 additions and 28 deletions.
4 changes: 0 additions & 4 deletions internal/query/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,6 @@ var (
// request attempts to use a resource that does not support role binding v2
ErrResourceDoesNotSupportRoleBindingV2 = fmt.Errorf("%w: resource does not support role binding v2", ErrInvalidArgument)

// ErrCreateRoleBindingWithNoSubjects represents an error when a role
// binding is created with no subjects
ErrCreateRoleBindingWithNoSubjects = fmt.Errorf("%w: role binding must have at least one subject", ErrInvalidArgument)

// ErrRoleBindingHasNoRelationships represents an internal error when a
// role binding has no relationships
ErrRoleBindingHasNoRelationships = errors.New("role binding has no relationships")
Expand Down
6 changes: 3 additions & 3 deletions internal/query/relations.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,8 +362,8 @@ func (e *engine) CreateRole(ctx context.Context, actor, res types.Resource, role

// diff determines which entities needs to be added and removed.
// If no new entity are provided it is assumed no changes are requested.
func diff(current, incoming []string) ([]string, []string) {
if len(incoming) == 0 {
func diff(current, incoming []string, allowEmptyIncoming bool) ([]string, []string) {
if len(incoming) == 0 && !allowEmptyIncoming {
return nil, nil
}

Expand Down Expand Up @@ -445,7 +445,7 @@ func (e *engine) UpdateRole(ctx context.Context, actor, roleResource types.Resou
newName = role.Name
}

addActions, remActions := diff(role.Actions, newActions)
addActions, remActions := diff(role.Actions, newActions, false)

// If no changes, return existing role with no changes.
if newName == role.Name && len(addActions) == 0 && len(remActions) == 0 {
Expand Down
10 changes: 1 addition & 9 deletions internal/query/rolebindings.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,6 @@ func (e *engine) CreateRoleBinding(
)
defer span.End()

if len(subjects) == 0 {
err := ErrCreateRoleBindingWithNoSubjects
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())

return types.RoleBinding{}, err
}

if err := e.isRoleBindable(ctx, roleResource, resource); err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
Expand Down Expand Up @@ -467,7 +459,7 @@ func (e *engine) UpdateRoleBinding(ctx context.Context, actor, rb types.Resource
newSubjectIDs[i] = subj.SubjectResource.ID
}

add, remove := diff(current, incoming)
add, remove := diff(current, incoming, true)

// return if there are no changes
if (len(add) + len(remove)) == 0 {
Expand Down
22 changes: 11 additions & 11 deletions internal/query/rolebindings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,17 +121,6 @@ func TestCreateRoleBinding(t *testing.T) {
assert.ErrorIs(t, res.Err, ErrRoleNotFound)
},
},
{
Name: "CreateRoleBindingWithNoSubjects",
Input: input{
resource: root,
role: roleRes,
},
CheckFn: func(ctx context.Context, t *testing.T, tr testingx.TestResult[types.RoleBinding]) {
assert.ErrorIs(t, tr.Err, ErrInvalidArgument)
assert.ErrorIs(t, tr.Err, ErrCreateRoleBindingWithNoSubjects)
},
},
{
Name: "CreateRoleBindingSuccess",
Input: input{
Expand Down Expand Up @@ -405,6 +394,17 @@ func TestUpdateRoleBinding(t *testing.T) {
},
Sync: true,
},
{
Name: "UpdateRoleBindingRemoveAllSubjects",
Input: input{
rb: rbRes,
subj: []types.RoleBindingSubject{},
},
CheckFn: func(ctx context.Context, t *testing.T, res testingx.TestResult[types.RoleBinding]) {
assert.NoError(t, res.Err)
assert.Len(t, res.Success.SubjectIDs, 0)
},
},
}

testFn := func(ctx context.Context, in input) testingx.TestResult[types.RoleBinding] {
Expand Down
2 changes: 1 addition & 1 deletion internal/query/roles_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ func (e *engine) UpdateRoleV2(ctx context.Context, actor, roleResource types.Res
newName = role.Name
}

addActions, rmActions := diff(role.Actions, newActions)
addActions, rmActions := diff(role.Actions, newActions, false)

// If no changes, return existing role
if newName == role.Name && len(addActions) == 0 && len(rmActions) == 0 {
Expand Down

0 comments on commit 73e75eb

Please sign in to comment.