Skip to content

Commit

Permalink
feat(iampolicy): add AddBinding and RemoveBinding helpers
Browse files Browse the repository at this point in the history
Reference implementation for adding and removing bindings.
  • Loading branch information
odsod committed May 6, 2021
1 parent 448f43d commit 2ef94be
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 0 deletions.
28 changes: 28 additions & 0 deletions iampolicy/add.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package iampolicy

import "google.golang.org/genproto/googleapis/iam/v1"

// AddBinding adds the provided role and member binding to the policy.
// If the role and member already exists, no updates are made.
// No validation on the role or member is performed.
func AddBinding(policy *iam.Policy, role, member string) {
// Add binding to policy.
var added bool
for _, binding := range policy.Bindings {
if binding.Role == role {
for _, bindingMember := range binding.Members {
if bindingMember == member {
return // already have this policy binding
}
}
binding.Members = append(binding.Members, member)
added = true
}
}
if !added {
policy.Bindings = append(policy.Bindings, &iam.Binding{
Role: role,
Members: []string{member},
})
}
}
36 changes: 36 additions & 0 deletions iampolicy/remove.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package iampolicy

import "google.golang.org/genproto/googleapis/iam/v1"

// RemoveBinding removes the provided role and member binding from the policy.
// If a binding of the the role and member don't exist, no updates are made.
// No validation on the role or member is performed.
func RemoveBinding(policy *iam.Policy, role, member string) {
for _, binding := range policy.Bindings {
if binding.Role == role {
binding.Members = removeMember(binding.Members, member)
if len(binding.Members) == 0 {
policy.Bindings = removeRole(policy.Bindings, role)
}
return
}
}
}

func removeMember(members []string, member string) []string {
for i, candidate := range members {
if candidate == member {
return append(members[:i], members[i+1:]...)
}
}
return members
}

func removeRole(bindings []*iam.Binding, role string) []*iam.Binding {
for i, binding := range bindings {
if binding.Role == role {
return append(bindings[:i], bindings[i+1:]...)
}
}
return bindings
}
40 changes: 40 additions & 0 deletions iampolicy/remove_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package iampolicy

import (
"testing"

"google.golang.org/genproto/googleapis/iam/v1"
"google.golang.org/protobuf/testing/protocmp"
"gotest.tools/v3/assert"
)

func TestRemoveBinding(t *testing.T) {
t.Run("ok", func(t *testing.T) {
actual := &iam.Policy{
Bindings: []*iam.Binding{
{
Role: "roles/test",
Members: []string{"foo", "bar"},
},
{
Role: "roles/test2",
Members: []string{"foo", "bar"},
},
},
}
RemoveBinding(actual, "roles/test2", "bar")
expected := &iam.Policy{
Bindings: []*iam.Binding{
{
Role: "roles/test",
Members: []string{"foo", "bar"},
},
{
Role: "roles/test2",
Members: []string{"foo"},
},
},
}
assert.DeepEqual(t, expected, actual, protocmp.Transform())
})
}

0 comments on commit 2ef94be

Please sign in to comment.