Skip to content

Commit

Permalink
Added tests for deploy tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
ilijamt committed Dec 18, 2024
1 parent 8877a1a commit 0202dd4
Show file tree
Hide file tree
Showing 10 changed files with 1,529 additions and 21 deletions.
12 changes: 12 additions & 0 deletions helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -530,3 +530,15 @@ func ctxTestTime(ctx context.Context, tn string) (_ context.Context, t time.Time
}
return gitlab.WithStaticTime(ctx, t), t
}

func filterSlice[T any, Slice ~[]T](collection Slice, predicate func(item T, index int) bool) Slice {
result := make(Slice, 0, len(collection))

for i := range collection {
if predicate(collection[i], i) {
result = append(result, collection[i])
}
}

return result
}
38 changes: 18 additions & 20 deletions path_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,29 +243,43 @@ func (b *Backend) pathRolesWrite(ctx context.Context, req *logical.Request, data

// validate access level and which fields to skip for validation
var validAccessLevels []string
var invalidScopes []string
var validScopes []string
var noEmptyScopes bool

switch tokenType {
case TokenTypePersonal:
validAccessLevels = ValidPersonalAccessLevels
validScopes = slices.Concat(validTokenScopes, ValidPersonalTokenScopes)
skipFields = append(skipFields, "access_level")
case TokenTypeGroup:
validAccessLevels = ValidGroupAccessLevels
validScopes = validTokenScopes
case TokenTypeProject:
validAccessLevels = ValidProjectAccessLevels
validScopes = validTokenScopes
case TokenTypeUserServiceAccount:
validAccessLevels = ValidUserServiceAccountAccessLevels
validScopes = slices.Concat(validTokenScopes, ValidPersonalTokenScopes, ValidUserServiceAccountTokenScopes)
skipFields = append(skipFields, "access_level")
case TokenTypeGroupServiceAccount:
validAccessLevels = ValidGroupServiceAccountAccessLevels
validScopes = slices.Concat(validTokenScopes, ValidPersonalTokenScopes, ValidGroupServiceAccountTokenScopes)
skipFields = append(skipFields, "access_level")
case TokenTypePipelineProjectTrigger:
validAccessLevels = ValidPipelineProjectTriggerAccessLevels
validScopes = []string{}
skipFields = append(skipFields, "access_level", "scopes")
case TokenTypeProjectDeploy:
validAccessLevels = ValidProjectDeployAccessLevels
validScopes = ValidProjectDeployTokenScopes
skipFields = append(skipFields, "access_level")
noEmptyScopes = true
case TokenTypeGroupDeploy:
validAccessLevels = ValidGroupDeployAccessLevels
validScopes = ValidGroupDeployTokenScopes
skipFields = append(skipFields, "access_level")
noEmptyScopes = true
}

// check if all required fields are set
Expand Down Expand Up @@ -308,26 +322,6 @@ func (b *Backend) pathRolesWrite(ctx context.Context, req *logical.Request, data
err = multierror.Append(err, fmt.Errorf("access_level='%s', should be one of %v: %w", data.Get("access_level").(string), validAccessLevels, ErrFieldInvalidValue))
}

// validate scopes
var invalidScopes []string
var validScopes = validTokenScopes
if tokenType == TokenTypePersonal || tokenType == TokenTypeUserServiceAccount || tokenType == TokenTypeGroupServiceAccount {
validScopes = append(validScopes, ValidPersonalTokenScopes...)
}

switch tokenType {
case TokenTypeUserServiceAccount:
validScopes = append(validScopes, ValidUserServiceAccountTokenScopes...)
case TokenTypeGroupServiceAccount:
validScopes = append(validScopes, ValidGroupServiceAccountTokenScopes...)
case TokenTypePipelineProjectTrigger:
validScopes = []string{}
case TokenTypeProjectDeploy:
validScopes = ValidProjectDeployTokenScopes
case TokenTypeGroupDeploy:
validScopes = ValidGroupDeployTokenScopes
}

for _, scope := range role.Scopes {
if !slices.Contains(validScopes, scope) {
invalidScopes = append(invalidScopes, scope)
Expand All @@ -338,6 +332,10 @@ func (b *Backend) pathRolesWrite(ctx context.Context, req *logical.Request, data
err = multierror.Append(err, fmt.Errorf("scopes='%v', should be one or more of '%v': %w", invalidScopes, validScopes, ErrFieldInvalidValue))
}

if noEmptyScopes && len(role.Scopes) == 0 {
err = multierror.Append(err, fmt.Errorf("should be one or more of '%v': %w", validScopes, ErrFieldInvalidValue))
}

if tokenType == TokenTypeUserServiceAccount && (config.Type == TypeSaaS || config.Type == TypeDedicated) {
err = multierror.Append(err, fmt.Errorf("cannot create %s with %s: %w", tokenType, config.Type, ErrInvalidValue))
}
Expand Down
24 changes: 24 additions & 0 deletions path_role_deploy_tokens_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import (
"testing"
"time"

"github.com/hashicorp/go-multierror"
"github.com/hashicorp/vault/sdk/logical"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

gitlab "github.com/ilijamt/vault-plugin-secrets-gitlab"
Expand Down Expand Up @@ -63,6 +65,28 @@ func TestPathRolesDeployTokens(t *testing.T) {
require.NoError(t, err)
require.NotNil(t, resp)
})

t.Run("fail to create role due to missing scopes and wrong access level", func(t *testing.T) {
ctx := getCtxGitlabClient(t, "unit")
var b, l, err = getBackendWithConfig(ctx, defaultConfig)
require.NoError(t, err)
resp, err := b.HandleRequest(ctx, &logical.Request{
Operation: logical.CreateOperation,
Path: fmt.Sprintf("%s/%d", gitlab.PathRoleStorage, time.Now().UnixNano()), Storage: l,
Data: map[string]any{
"path": tt.path,
"name": tt.name,
"access_level": gitlab.AccessLevelNoPermissions.String(),
"token_type": tt.tokenType.String(),
"ttl": cmp.Or(tt.ttl, "1h"),
"scopes": []string{},
},
})
require.Error(t, err)
require.NotNil(t, resp)
var errorMap = countErrByName(err.(*multierror.Error))
assert.EqualValues(t, 2, errorMap[gitlab.ErrFieldInvalidValue.Error()])
})
})
}
}
2 changes: 1 addition & 1 deletion secret_access_tokens.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func (b *Backend) secretAccessTokenRevoke(ctx context.Context, req *logical.Requ
case TokenTypeGroupDeploy:
var groupId int
if groupId, err = strconv.Atoi(parentId); err == nil {
err = client.RevokeProjectDeployToken(ctx, groupId, tokenId)
err = client.RevokeGroupDeployToken(ctx, groupId, tokenId)
}
case TokenTypeProjectDeploy:
var projectId int
Expand Down
Loading

0 comments on commit 0202dd4

Please sign in to comment.