Skip to content

Commit

Permalink
test: add test cases for service account provider
Browse files Browse the repository at this point in the history
  • Loading branch information
rahmatrhd committed Aug 14, 2023
1 parent cd341ff commit cb5d72b
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 16 deletions.
26 changes: 14 additions & 12 deletions plugins/providers/gcloudiam/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ func (p *Provider) GetResources(pc *domain.ProviderConfig) ([]*domain.Resource,
return nil, fmt.Errorf("listing service accounts: %w", err)
}

// TODO: filter

for _, sa := range serviceAccounts {
resources = append(resources, &domain.Resource{
ProviderType: pc.Type,
Expand All @@ -116,7 +118,7 @@ func (p *Provider) GetResources(pc *domain.ProviderConfig) ([]*domain.Resource,
return resources, nil
}

func (p *Provider) GrantAccess(pc *domain.ProviderConfig, a domain.Grant) error {
func (p *Provider) GrantAccess(pc *domain.ProviderConfig, g domain.Grant) error {
// TODO: validate provider config and appeal

var creds Credentials
Expand All @@ -129,10 +131,10 @@ func (p *Provider) GrantAccess(pc *domain.ProviderConfig, a domain.Grant) error
return err
}

switch a.Resource.Type {
switch g.Resource.Type {
case ResourceTypeProject, ResourceTypeOrganization:
for _, p := range a.Permissions {
if err := client.GrantAccess(a.AccountType, a.AccountID, p); err != nil {
for _, p := range g.Permissions {
if err := client.GrantAccess(g.AccountType, g.AccountID, p); err != nil {
if !errors.Is(err, ErrPermissionAlreadyExists) {
return err
}
Expand All @@ -141,8 +143,8 @@ func (p *Provider) GrantAccess(pc *domain.ProviderConfig, a domain.Grant) error
return nil

case ResourceTypeServiceAccount:
for _, p := range a.Permissions {
if err := client.GrantServiceAccountAccess(context.TODO(), a.Resource.URN, a.AccountType, a.AccountID, p); err != nil {
for _, p := range g.Permissions {
if err := client.GrantServiceAccountAccess(context.TODO(), g.Resource.URN, g.AccountType, g.AccountID, p); err != nil {
if !errors.Is(err, ErrPermissionAlreadyExists) {
return err
}
Expand All @@ -155,7 +157,7 @@ func (p *Provider) GrantAccess(pc *domain.ProviderConfig, a domain.Grant) error
}
}

func (p *Provider) RevokeAccess(pc *domain.ProviderConfig, a domain.Grant) error {
func (p *Provider) RevokeAccess(pc *domain.ProviderConfig, g domain.Grant) error {
var creds Credentials
if err := mapstructure.Decode(pc.Credentials, &creds); err != nil {
return err
Expand All @@ -166,10 +168,10 @@ func (p *Provider) RevokeAccess(pc *domain.ProviderConfig, a domain.Grant) error
return err
}

switch a.Resource.Type {
switch g.Resource.Type {
case ResourceTypeProject, ResourceTypeOrganization:
for _, p := range a.Permissions {
if err := client.RevokeAccess(a.AccountType, a.AccountID, p); err != nil {
for _, p := range g.Permissions {
if err := client.RevokeAccess(g.AccountType, g.AccountID, p); err != nil {
if !errors.Is(err, ErrPermissionNotFound) {
return err
}
Expand All @@ -178,8 +180,8 @@ func (p *Provider) RevokeAccess(pc *domain.ProviderConfig, a domain.Grant) error
return nil

case ResourceTypeServiceAccount:
for _, p := range a.Permissions {
if err := client.RevokeServiceAccountAccess(context.TODO(), a.Resource.URN, a.AccountType, a.AccountID, p); err != nil {
for _, p := range g.Permissions {
if err := client.RevokeServiceAccountAccess(context.TODO(), g.Resource.URN, g.AccountType, g.AccountID, p); err != nil {
if !errors.Is(err, ErrPermissionNotFound) {
return err
}
Expand Down
128 changes: 124 additions & 4 deletions plugins/providers/gcloudiam/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ func TestGetResources(t *testing.T) {
providerURN: client,
}

gCloudRolesList := []*iam.Role{
projectRoles := []*iam.Role{
{
Name: "roles/bigquery.admin",
Title: "BigQuery Admin",
Expand All @@ -326,9 +326,29 @@ func TestGetResources(t *testing.T) {
Description: "Read-only access to ApiGateway and related resources",
},
}
saRoles := []*iam.Role{
{
Name: "roles/workstations.serviceAgent",
Title: "Workstations Service Agent",
Description: "Grants the Workstations Service Account access to manage resources in consumer project.",
},
}
client.EXPECT().
GetGrantableRoles(mock.AnythingOfType("*context.emptyCtx"), gcloudiam.ResourceTypeProject).
Return(gCloudRolesList, nil).Once()
Return(projectRoles, nil).Once()
client.EXPECT().
GetGrantableRoles(mock.AnythingOfType("*context.emptyCtx"), gcloudiam.ResourceTypeServiceAccount).
Return(saRoles, nil).Once()

expectedServiceAccounts := []*iam.ServiceAccount{
{
Name: "sa-name",
DisplayName: "sa-display-name",
},
}
client.EXPECT().
ListServiceAccounts(mock.AnythingOfType("*context.emptyCtx")).
Return(expectedServiceAccounts, nil).Once()

pc := &domain.ProviderConfig{
Type: domain.ProviderTypeGCloudIAM,
Expand All @@ -353,6 +373,15 @@ func TestGetResources(t *testing.T) {
},
},
},
{
Type: gcloudiam.ResourceTypeServiceAccount,
Roles: []*domain.Role{
{
ID: "role-1",
Permissions: []interface{}{"roles/workstations.serviceAgent"},
},
},
},
},
}

Expand All @@ -364,6 +393,13 @@ func TestGetResources(t *testing.T) {
URN: "project/test-resource-name",
Name: "project/test-resource-name - GCP IAM",
},
{
ProviderType: pc.Type,
ProviderURN: pc.URN,
Type: gcloudiam.ResourceTypeServiceAccount,
URN: "sa-name",
Name: "sa-display-name",
},
}

actualResources, actualError := p.GetResources(pc)
Expand Down Expand Up @@ -562,7 +598,7 @@ func TestGrantAccess(t *testing.T) {
},
URN: providerURN,
}
a := domain.Grant{
g := domain.Grant{
Resource: &domain.Resource{
Type: gcloudiam.ResourceTypeProject,
URN: "test-role",
Expand All @@ -575,10 +611,52 @@ func TestGrantAccess(t *testing.T) {
Permissions: []string{"roles/bigquery.admin"},
}

actualError := p.GrantAccess(pc, a)
actualError := p.GrantAccess(pc, g)

assert.Nil(t, actualError)
})

t.Run("successful grant access to a service account", func(t *testing.T) {
providerURN := "test-provider-urn"
crypto := new(mocks.Encryptor)
client := new(mocks.GcloudIamClient)
p := gcloudiam.NewProvider("", crypto)
p.Clients = map[string]gcloudiam.GcloudIamClient{
providerURN: client,
}

pc := &domain.ProviderConfig{
URN: providerURN,
Resources: []*domain.ResourceConfig{
{
Type: gcloudiam.ResourceTypeServiceAccount,
Roles: []*domain.Role{
{
ID: "test-role",
Permissions: []interface{}{"test-permission"},
},
},
},
},
}
g := domain.Grant{
Resource: &domain.Resource{
Type: gcloudiam.ResourceTypeServiceAccount,
URN: "sa-urn",
},
Role: "test-role",
AccountType: "test-account-type",
AccountID: "test-account-id",
Permissions: []string{"test-permission"},
}

client.EXPECT().
GrantServiceAccountAccess(mock.AnythingOfType("*context.emptyCtx"), g.Resource.URN, g.AccountType, g.AccountID, g.Permissions[0]).
Return(nil).Once()

err := p.GrantAccess(pc, g)
assert.NoError(t, err)
})
}

func TestRevokeAccess(t *testing.T) {
Expand Down Expand Up @@ -708,6 +786,48 @@ func TestRevokeAccess(t *testing.T) {

assert.Nil(t, actualError)
})

t.Run("successful revoke access to a service account", func(t *testing.T) {
providerURN := "test-provider-urn"
crypto := new(mocks.Encryptor)
client := new(mocks.GcloudIamClient)
p := gcloudiam.NewProvider("", crypto)
p.Clients = map[string]gcloudiam.GcloudIamClient{
providerURN: client,
}

pc := &domain.ProviderConfig{
URN: providerURN,
Resources: []*domain.ResourceConfig{
{
Type: gcloudiam.ResourceTypeServiceAccount,
Roles: []*domain.Role{
{
ID: "test-role",
Permissions: []interface{}{"test-permission"},
},
},
},
},
}
g := domain.Grant{
Resource: &domain.Resource{
Type: gcloudiam.ResourceTypeServiceAccount,
URN: "sa-urn",
},
Role: "test-role",
AccountType: "test-account-type",
AccountID: "test-account-id",
Permissions: []string{"test-permission"},
}

client.EXPECT().
RevokeServiceAccountAccess(mock.AnythingOfType("*context.emptyCtx"), g.Resource.URN, g.AccountType, g.AccountID, g.Permissions[0]).
Return(nil).Once()

err := p.RevokeAccess(pc, g)
assert.NoError(t, err)
})
}

func TestGetRoles(t *testing.T) {
Expand Down

0 comments on commit cb5d72b

Please sign in to comment.