Grant management added to Roles API and SDK (#185)

* Adding grants related methods to Roles.

* Adding grants back after the merge of Principals.

* Adding tests for Grant related custom methods.

* Improving api handler methods.

* Fixing tests and sdk field.

* Adding todos for adding principals and grants to List and Update Role responses.

* Fix up Set* tests and fix SetPrincipals bug.

* Making AddPrincipals and RemovePrincipals similar to the tests for AddGrants and RemoveGrants.

* Add JSON grants to output (#187)

I also changed canonical_grants to grants_canonical and used
grants_json. I believe that when members are simply different formats of
other members this is the preferred way to have it in the API. Let me
know if you disagree and we can dig in more.

* Regenerate the API role resource.

Co-authored-by: Jeff Mitchell <jeffrey.mitchell@gmail.com>
This commit is contained in:
Todd KnightandJeff Mitchell authored and GitHub committed 2020-07-10 17:42:47 -07:00
1 parent 260703febe
commit 847ca1cc78
19 files changed
+3321 -732

No files matched your search

+96
View File
@@ -105,3 +105,99 @@ func (s Role) RemovePrincipals(ctx context.Context, groups, users []string) (*Ro
return target, apiErr, nil
}
func (s Role) AddGrants(ctx context.Context, grants []string) (*Role, *api.Error, error) {
if s.Client == nil {
return nil, nil, fmt.Errorf("nil client in AddGrants request")
}
// We assume that the client provided has the org and optionally the project id of the request.
body := map[string]interface{}{
"grants": grants,
"version": s.Version,
}
req, err := s.Client.NewRequest(ctx, "POST", fmt.Sprintf("roles/%s:add-grants", s.Id), body)
if err != nil {
return nil, nil, fmt.Errorf("error creating AddGrants request: %w", err)
}
resp, err := s.Client.Do(req)
if err != nil {
return nil, nil, fmt.Errorf("error performing client request during AddGrants call: %w", err)
}
target := new(Role)
apiErr, err := resp.Decode(target)
if err != nil {
return nil, nil, fmt.Errorf("error decoding AddGrants repsonse: %w", err)
}
target.Client = s.Client
return target, apiErr, nil
}
func (s Role) SetGrants(ctx context.Context, grants []string) (*Role, *api.Error, error) {
if s.Client == nil {
return nil, nil, fmt.Errorf("nil client in SetGrants request")
}
// We assume that the client provided has the org and optionally the project id of the request.
body := map[string]interface{}{
"grants": grants,
"version": s.Version,
}
req, err := s.Client.NewRequest(ctx, "POST", fmt.Sprintf("roles/%s:set-grants", s.Id), body)
if err != nil {
return nil, nil, fmt.Errorf("error creating SetGrants request: %w", err)
}
resp, err := s.Client.Do(req)
if err != nil {
return nil, nil, fmt.Errorf("error performing client request during SetGrants call: %w", err)
}
target := new(Role)
apiErr, err := resp.Decode(target)
if err != nil {
return nil, nil, fmt.Errorf("error decoding SetGrants repsonse: %w", err)
}
target.Client = s.Client
return target, apiErr, nil
}
func (s Role) RemoveGrants(ctx context.Context, grants []string) (*Role, *api.Error, error) {
if s.Client == nil {
return nil, nil, fmt.Errorf("nil client in RemoveGrants request")
}
// We assume that the client provided has the org and optionally the project id of the request.
body := map[string]interface{}{
"grants": grants,
"version": s.Version,
}
req, err := s.Client.NewRequest(ctx, "POST", fmt.Sprintf("roles/%s:remove-grants", s.Id), body)
if err != nil {
return nil, nil, fmt.Errorf("error creating RemoveGrants request: %w", err)
}
resp, err := s.Client.Do(req)
if err != nil {
return nil, nil, fmt.Errorf("error performing client request during RemoveGrants call: %w", err)
}
target := new(Role)
apiErr, err := resp.Decode(target)
if err != nil {
return nil, nil, fmt.Errorf("error decoding RemoveGrants repsonse: %w", err)
}
target.Client = s.Client
return target, apiErr, nil
}
+6
View File
@@ -49,6 +49,12 @@ type Role struct {
// The grants that this role provides for it's principals.
// Output only.
Grants []string `json:"grants,omitempty"`
// The canonical version of the grants in the grants field with the same index.
// Output only.
GrantsCanonical []string `json:"grants_canonical,omitempty"`
// The JSON version of the grants in the grants field with the same index.
// Output only.
GrantsJson []string `json:"grants_json,omitempty"`
}
func (s *Role) SetDefault(key string) {
+21
View File
@@ -92,6 +92,27 @@ func TestCustom(t *testing.T) {
assert.Equal(t, *updatedRole.Version, (*r.Version)+1)
assert.Empty(t, updatedRole.GroupIds)
assert.Empty(t, updatedRole.UserIds)
r = updatedRole
updatedRole, apiErr, err = r.AddGrants(ctx, []string{"id=*;actions=read"})
require.NoError(err)
require.Nil(apiErr, "Got error ", errorMessage(apiErr))
assert.Equal(t, *updatedRole.Version, (*r.Version)+1)
assert.Contains(t, updatedRole.Grants, "id=*;actions=read")
r = updatedRole
updatedRole, apiErr, err = r.SetGrants(ctx, []string{"id=*;actions=*"})
require.NoError(err)
require.Nil(apiErr, "Got error ", errorMessage(apiErr))
assert.Equal(t, *updatedRole.Version, (*r.Version)+1)
assert.Contains(t, updatedRole.Grants, "id=*;actions=*")
r = updatedRole
updatedRole, apiErr, err = r.RemoveGrants(ctx, []string{"id=*;actions=*"})
require.NoError(err)
require.Nil(apiErr, "Got error ", errorMessage(apiErr))
assert.Equal(t, *updatedRole.Version, (*r.Version)+1)
assert.Empty(t, updatedRole.Grants)
})
}
}