diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 71ab258..b9d876d 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -6,11 +6,35 @@ builds: mod_timestamp: '{{ .CommitTimestamp }}' flags: - -trimpath + goos: + - windows + - linux + - darwin + - illumos + goarch: + - amd64 + - "386" + - arm + - arm64 + ignore: + - goos: darwin + goarch: "386" + id: g16x + binary: '{{ .ProjectName }}16x_v{{ .Version }}' ldflags: - - '-s -w' - - "-X 'github.com/ilijamt/vault-plugin-secrets-gitlab.Version=v{{ .Version }}'" - - "-X 'github.com/ilijamt/vault-plugin-secrets-gitlab.FullCommit={{ .FullCommit }}'" - - "-X 'github.com/ilijamt/vault-plugin-secrets-gitlab.BuildDate={{ .Date }}'" + - -s -w + - -X 'github.com/ilijamt/vault-plugin-secrets-gitlab.Version=v{{ .Version }}' + - -X 'github.com/ilijamt/vault-plugin-secrets-gitlab.FullCommit={{ .FullCommit }}' + - -X 'github.com/ilijamt/vault-plugin-secrets-gitlab.BuildDate={{ .Date }}' + - -X 'github.com/ilijamt/vault-plugin-secrets-gitlab.VersionTarget=g16x' + tags: + - g16x + - env: + - CGO_ENABLED=0 + main: ./cmd/vault-plugin-secrets-gitlab/main.go + mod_timestamp: '{{ .CommitTimestamp }}' + flags: + - -trimpath goos: - windows - linux @@ -18,16 +42,24 @@ builds: - illumos goarch: - amd64 - - '386' + - "386" - arm - arm64 ignore: - goos: darwin - goarch: '386' - binary: '{{ .ProjectName }}_v{{ .Version }}' + goarch: "386" + id: g17x + binary: '{{ .ProjectName }}17x_v{{ .Version }}' + ldflags: + - -s -w + - -X 'github.com/ilijamt/vault-plugin-secrets-gitlab.Version=v{{ .Version }}' + - -X 'github.com/ilijamt/vault-plugin-secrets-gitlab.FullCommit={{ .FullCommit }}' + - -X 'github.com/ilijamt/vault-plugin-secrets-gitlab.BuildDate={{ .Date }}' + - -X 'github.com/ilijamt/vault-plugin-secrets-gitlab.VersionTarget=g17x' archives: - - formats: [ 'tar.gz' ] - name_template: >- + - formats: + - tar.gz + name_template: |- {{ .ProjectName }}_ {{- .Os }}_ {{- if eq .Arch "amd64" }}x86_64 @@ -36,7 +68,8 @@ archives: {{- if .Arm }}v{{ .Arm }}{{ end }} format_overrides: - goos: windows - formats: [ 'zip' ] + formats: + - zip report_sizes: true sboms: - artifacts: archive @@ -50,7 +83,7 @@ changelog: exclude: - '^docs:' - '^test:' - - "merge conflict" + - merge conflict - Merge pull request - Merge remote-tracking branch - Merge branch diff --git a/entry_role.go b/entry_role.go index a5b086e..4680422 100644 --- a/entry_role.go +++ b/entry_role.go @@ -6,18 +6,20 @@ import ( "time" "github.com/hashicorp/vault/sdk/logical" + + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/access" ) type EntryRole struct { - RoleName string `json:"role_name" structs:"role_name" mapstructure:"role_name"` - TTL time.Duration `json:"ttl" structs:"ttl" mapstructure:"ttl"` - Path string `json:"path" structs:"path" mapstructure:"path"` - Name string `json:"name" structs:"name" mapstructure:"name"` - Scopes []string `json:"scopes" structs:"scopes" mapstructure:"scopes"` - AccessLevel AccessLevel `json:"access_level" structs:"access_level" mapstructure:"access_level,omitempty"` - TokenType TokenType `json:"token_type" structs:"token_type" mapstructure:"token_type"` - GitlabRevokesTokens bool `json:"gitlab_revokes_token" structs:"gitlab_revokes_token" mapstructure:"gitlab_revokes_token"` - ConfigName string `json:"config_name" structs:"config_name" mapstructure:"config_name"` + RoleName string `json:"role_name" structs:"role_name" mapstructure:"role_name"` + TTL time.Duration `json:"ttl" structs:"ttl" mapstructure:"ttl"` + Path string `json:"path" structs:"path" mapstructure:"path"` + Name string `json:"name" structs:"name" mapstructure:"name"` + Scopes []string `json:"scopes" structs:"scopes" mapstructure:"scopes"` + AccessLevel access.AccessLevel `json:"access_level" structs:"access_level" mapstructure:"access_level,omitempty"` + TokenType TokenType `json:"token_type" structs:"token_type" mapstructure:"token_type"` + GitlabRevokesTokens bool `json:"gitlab_revokes_token" structs:"gitlab_revokes_token" mapstructure:"gitlab_revokes_token"` + ConfigName string `json:"config_name" structs:"config_name" mapstructure:"config_name"` } func (e EntryRole) LogicalResponseData() map[string]any { diff --git a/gitlab_client.go b/gitlab_client.go index a35d7aa..0196e40 100644 --- a/gitlab_client.go +++ b/gitlab_client.go @@ -14,6 +14,8 @@ import ( "github.com/hashicorp/vault/sdk/helper/logging" g "gitlab.com/gitlab-org/api/client-go" "golang.org/x/time/rate" + + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/access" ) var ( @@ -28,8 +30,8 @@ type Client interface { CurrentTokenInfo(ctx context.Context) (*TokenConfig, error) RotateCurrentToken(ctx context.Context) (newToken *TokenConfig, oldToken *TokenConfig, err error) CreatePersonalAccessToken(ctx context.Context, username string, userId int, name string, expiresAt time.Time, scopes []string) (*TokenPersonal, error) - CreateGroupAccessToken(ctx context.Context, groupId string, name string, expiresAt time.Time, scopes []string, accessLevel AccessLevel) (*TokenGroup, error) - CreateProjectAccessToken(ctx context.Context, projectId string, name string, expiresAt time.Time, scopes []string, accessLevel AccessLevel) (*TokenProject, error) + CreateGroupAccessToken(ctx context.Context, groupId string, name string, expiresAt time.Time, scopes []string, accessLevel access.AccessLevel) (*TokenGroup, error) + CreateProjectAccessToken(ctx context.Context, projectId string, name string, expiresAt time.Time, scopes []string, accessLevel access.AccessLevel) (*TokenProject, error) RevokePersonalAccessToken(ctx context.Context, tokenId int) error RevokeProjectAccessToken(ctx context.Context, tokenId int, projectId string) error RevokeGroupAccessToken(ctx context.Context, tokenId int, groupId string) error @@ -449,7 +451,7 @@ func (gc *gitlabClient) CreatePersonalAccessToken(ctx context.Context, username return et, err } -func (gc *gitlabClient) CreateGroupAccessToken(ctx context.Context, groupId string, name string, expiresAt time.Time, scopes []string, accessLevel AccessLevel) (et *TokenGroup, err error) { +func (gc *gitlabClient) CreateGroupAccessToken(ctx context.Context, groupId string, name string, expiresAt time.Time, scopes []string, accessLevel access.AccessLevel) (et *TokenGroup, err error) { var at *g.GroupAccessToken defer func() { gc.logger.Debug("Create group access token", "gat", at, "et", et, "groupId", groupId, "name", name, "expiresAt", expiresAt, "scopes", scopes, "accessLevel", accessLevel, "error", err) @@ -482,7 +484,7 @@ func (gc *gitlabClient) CreateGroupAccessToken(ctx context.Context, groupId stri return et, err } -func (gc *gitlabClient) CreateProjectAccessToken(ctx context.Context, projectId string, name string, expiresAt time.Time, scopes []string, accessLevel AccessLevel) (et *TokenProject, err error) { +func (gc *gitlabClient) CreateProjectAccessToken(ctx context.Context, projectId string, name string, expiresAt time.Time, scopes []string, accessLevel access.AccessLevel) (et *TokenProject, err error) { var at *g.ProjectAccessToken defer func() { gc.logger.Debug("Create project access token", "gat", at, "et", et, "projectId", projectId, "name", name, "expiresAt", expiresAt, "scopes", scopes, "accessLevel", accessLevel, "error", err) diff --git a/gitlab_client_test.go b/gitlab_client_test.go index a49ec3c..9c83348 100644 --- a/gitlab_client_test.go +++ b/gitlab_client_test.go @@ -13,6 +13,8 @@ import ( "github.com/stretchr/testify/require" gitlab "github.com/ilijamt/vault-plugin-secrets-gitlab" + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/access" + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/token" ) func TestGitlabClient(t *testing.T) { @@ -87,11 +89,11 @@ func TestGitlabClient_InvalidToken(t *testing.T) { _, err = client.GetUserIdByUsername(ctx, "username") require.Error(t, err) - gatToken, err := client.CreateGroupAccessToken(ctx, "groupId", "name", timeExpiresAt, []string{"scope"}, gitlab.AccessLevelUnknown) + gatToken, err := client.CreateGroupAccessToken(ctx, "groupId", "name", timeExpiresAt, []string{"scope"}, access.AccessLevelUnknown) require.Error(t, err) require.Nil(t, gatToken) - prjAtToken, err := client.CreateProjectAccessToken(ctx, "projectId", "name", timeExpiresAt, []string{"scope"}, gitlab.AccessLevelUnknown) + prjAtToken, err := client.CreateProjectAccessToken(ctx, "projectId", "name", timeExpiresAt, []string{"scope"}, access.AccessLevelUnknown) require.Error(t, err) require.Nil(t, prjAtToken) @@ -255,8 +257,8 @@ func TestGitlabClient_CreateAccessToken_And_Revoke(t *testing.T) { "example", "name", timeExpiresAt, - []string{gitlab.TokenScopeReadApi.String()}, - gitlab.AccessLevelGuestPermissions, + []string{token.TokenScopeReadApi.String()}, + access.AccessLevelGuestPermissions, ) require.NoError(t, err) require.NotNil(t, gatToken) @@ -269,8 +271,8 @@ func TestGitlabClient_CreateAccessToken_And_Revoke(t *testing.T) { "example/example", "name", timeExpiresAt, - []string{gitlab.TokenScopeReadApi.String()}, - gitlab.AccessLevelDeveloperPermissions, + []string{token.TokenScopeReadApi.String()}, + access.AccessLevelDeveloperPermissions, ) require.NoError(t, err) require.NotNil(t, prjatToken) @@ -284,7 +286,7 @@ func TestGitlabClient_CreateAccessToken_And_Revoke(t *testing.T) { 1, "name", timeExpiresAt, - []string{gitlab.TokenScopeReadApi.String()}, + []string{token.TokenScopeReadApi.String()}, ) require.NoError(t, err) require.NotNil(t, patToken) diff --git a/goreleaser.cue b/goreleaser.cue new file mode 100644 index 0000000..e1c28c6 --- /dev/null +++ b/goreleaser.cue @@ -0,0 +1,114 @@ +package goreleaser + +import "list" + +_base: { + env: [ + "CGO_ENABLED=0", + ] + main: "./cmd/vault-plugin-secrets-gitlab/main.go" + mod_timestamp: "{{ .CommitTimestamp }}" + flags: [ + "-trimpath", + ] + goos: [ + "windows", + "linux", + "darwin", + "illumos", + ] + goarch: [ + "amd64", + "386", + "arm", + "arm64", + ] + ignore: [ + { + goos: "darwin" + goarch: "386" + }, + ] +} + +_commonLdflags: [ + "-s -w", + "-X 'github.com/ilijamt/vault-plugin-secrets-gitlab.Version=v{{ .Version }}'", + "-X 'github.com/ilijamt/vault-plugin-secrets-gitlab.FullCommit={{ .FullCommit }}'", + "-X 'github.com/ilijamt/vault-plugin-secrets-gitlab.BuildDate={{ .Date }}'", +] + +version: 2 + +builds: [ + { + _base + id: "g16x" + binary: "{{ .ProjectName }}16x_v{{ .Version }}" + ldflags: list.Concat([ + _commonLdflags, + ["-X 'github.com/ilijamt/vault-plugin-secrets-gitlab.VersionTarget=g16x'"] + ]) + tags: [ + "g16x" + ] + }, + { + _base + id: "g17x" + binary: "{{ .ProjectName }}17x_v{{ .Version }}" + ldflags: list.Concat([ + _commonLdflags, + ["-X 'github.com/ilijamt/vault-plugin-secrets-gitlab.VersionTarget=g17x'"] + ]) + }, +] + +archives: [ + { + formats: ["tar.gz"] + name_template: """ + {{ .ProjectName }}_ + {{- .Os }}_ + {{- if eq .Arch "amd64" }}x86_64 + {{- else if eq .Arch "386" }}i386 + {{- else }}{{ .Arch }}{{ end }} + {{- if .Arm }}v{{ .Arm }}{{ end }} + """ + format_overrides: [ + { + goos: "windows" + formats: ["zip"] + }, + ] + }, +] + +report_sizes: true + +sboms: [ + { + artifacts: "archive" + }, +] + +checksum: { + name_template: "{{ .ProjectName }}_{{ .Version }}_SHA256SUMS" + algorithm: "sha256" +} + +changelog: { + sort: "asc" + use: "github" + filters: { + exclude: [ + "^docs:", + "^test:", + "merge conflict", + "Merge pull request", + "Merge remote-tracking branch", + "Merge branch", + "go mod tidy", + ] + } +} \ No newline at end of file diff --git a/helpers_test.go b/helpers_test.go index 32c26c0..97f20cc 100644 --- a/helpers_test.go +++ b/helpers_test.go @@ -27,6 +27,7 @@ import ( g "gitlab.com/gitlab-org/api/client-go" gitlab "github.com/ilijamt/vault-plugin-secrets-gitlab" + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/access" ) var _ gitlab.Client = new(inMemoryClient) @@ -465,7 +466,7 @@ func (i *inMemoryClient) CreatePersonalAccessToken(ctx context.Context, username return entryToken, nil } -func (i *inMemoryClient) CreateGroupAccessToken(ctx context.Context, groupId string, name string, expiresAt time.Time, scopes []string, accessLevel gitlab.AccessLevel) (*gitlab.TokenGroup, error) { +func (i *inMemoryClient) CreateGroupAccessToken(ctx context.Context, groupId string, name string, expiresAt time.Time, scopes []string, accessLevel access.AccessLevel) (*gitlab.TokenGroup, error) { i.muLock.Lock() defer i.muLock.Unlock() if i.groupAccessTokenCreateError { @@ -493,7 +494,7 @@ func (i *inMemoryClient) CreateGroupAccessToken(ctx context.Context, groupId str return entryToken, nil } -func (i *inMemoryClient) CreateProjectAccessToken(ctx context.Context, projectId string, name string, expiresAt time.Time, scopes []string, accessLevel gitlab.AccessLevel) (*gitlab.TokenProject, error) { +func (i *inMemoryClient) CreateProjectAccessToken(ctx context.Context, projectId string, name string, expiresAt time.Time, scopes []string, accessLevel access.AccessLevel) (*gitlab.TokenProject, error) { i.muLock.Lock() defer i.muLock.Unlock() if i.projectAccessTokenCreateError { diff --git a/type_access_level.go b/internal/access/level.go similarity index 99% rename from type_access_level.go rename to internal/access/level.go index 53e1d18..4c420c8 100644 --- a/type_access_level.go +++ b/internal/access/level.go @@ -1,4 +1,4 @@ -package gitlab +package access import ( "errors" diff --git a/internal/access/level_g16x.go b/internal/access/level_g16x.go new file mode 100644 index 0000000..665a9e5 --- /dev/null +++ b/internal/access/level_g16x.go @@ -0,0 +1,3 @@ +//go:build g16x + +package access diff --git a/internal/access/level_g17x.go b/internal/access/level_g17x.go new file mode 100644 index 0000000..e92dc64 --- /dev/null +++ b/internal/access/level_g17x.go @@ -0,0 +1,3 @@ +//go:build !g16x + +package access diff --git a/internal/access/level_test.go b/internal/access/level_test.go new file mode 100644 index 0000000..258fc74 --- /dev/null +++ b/internal/access/level_test.go @@ -0,0 +1,66 @@ +//go:build unit + +package access_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/access" +) + +func TestAccessLevel(t *testing.T) { + var tests = []struct { + expected access.AccessLevel + input string + err bool + }{ + { + expected: access.AccessLevelOwnerPermissions, + input: access.AccessLevelOwnerPermissions.String(), + }, + { + expected: access.AccessLevelReporterPermissions, + input: access.AccessLevelReporterPermissions.String(), + }, + { + expected: access.AccessLevelMaintainerPermissions, + input: access.AccessLevelMaintainerPermissions.String(), + }, + { + expected: access.AccessLevelDeveloperPermissions, + input: access.AccessLevelDeveloperPermissions.String(), + }, + { + expected: access.AccessLevelGuestPermissions, + input: access.AccessLevelGuestPermissions.String(), + }, + { + expected: access.AccessLevelNoPermissions, + input: access.AccessLevelNoPermissions.String(), + }, + { + expected: access.AccessLevelMinimalAccessPermissions, + input: access.AccessLevelMinimalAccessPermissions.String(), + }, + { + expected: access.AccessLevelUnknown, + input: "unknown", + err: true, + }, + } + + for _, test := range tests { + t.Logf("assert parse(%s) = %s (err: %v)", test.input, test.expected, test.err) + val, err := access.AccessLevelParse(test.input) + assert.EqualValues(t, test.expected, val) + if test.err { + assert.ErrorIs(t, err, access.ErrUnknownAccessLevel) + assert.Less(t, val.Value(), 0) + } else { + assert.NoError(t, err) + assert.GreaterOrEqual(t, val.Value(), 0) + } + } +} diff --git a/type_token_scope.go b/internal/token/scope.go similarity index 82% rename from type_token_scope.go rename to internal/token/scope.go index 7687777..2460f79 100644 --- a/type_token_scope.go +++ b/internal/token/scope.go @@ -1,4 +1,4 @@ -package gitlab +package token import ( "errors" @@ -6,54 +6,54 @@ import ( "slices" ) -type TokenScope string +type Scope string const ( // TokenScopeApi grants complete read/write access to the API, including all groups and projects, the container registry, the dependency proxy, and the package registry. Also grants complete read/write access to the registry and repository using Git over HTTP - TokenScopeApi = TokenScope("api") + TokenScopeApi = Scope("api") // TokenScopeReadApi grants read access to the scoped group and related project API, including the Package Registry - TokenScopeReadApi = TokenScope("read_api") + TokenScopeReadApi = Scope("read_api") // TokenScopeReadRegistry grants read access (pull) to the Container Registry images if any project within expected group is private and authorization is required. - TokenScopeReadRegistry = TokenScope("read_registry") + TokenScopeReadRegistry = Scope("read_registry") // TokenScopeWriteRegistry grants write access (push) to the Container Registry. - TokenScopeWriteRegistry = TokenScope("write_registry") + TokenScopeWriteRegistry = Scope("write_registry") // TokenScopeReadRepository grants read access (pull) to the Container Registry images if any project within expected group is private and authorization is required - TokenScopeReadRepository = TokenScope("read_repository") + TokenScopeReadRepository = Scope("read_repository") // TokenScopeWriteRepository grants read and write access (pull and push) to all repositories within expected group - TokenScopeWriteRepository = TokenScope("write_repository") + TokenScopeWriteRepository = Scope("write_repository") // TokenScopeReadPackageRegistry Allows read-only access to the package registry. - TokenScopeReadPackageRegistry = TokenScope("read_package_registry") + TokenScopeReadPackageRegistry = Scope("read_package_registry") // TokenScopeWritePackageRegistry Allows read and write access to the package registry. - TokenScopeWritePackageRegistry = TokenScope("write_package_registry") + TokenScopeWritePackageRegistry = Scope("write_package_registry") // TokenScopeCreateRunner grants permission to create runners in expected group - TokenScopeCreateRunner = TokenScope("create_runner") + TokenScopeCreateRunner = Scope("create_runner") // TokenScopeManageRunner grants permission to manage runners in expected group - TokenScopeManageRunner = TokenScope("manage_runner") + TokenScopeManageRunner = Scope("manage_runner") // TokenScopeReadUser grants read-only access to the authenticated user’s profile through the /user API endpoint, which includes username, public email, and full name. Also grants access to read-only API endpoints under /users. - TokenScopeReadUser = TokenScope("read_user") + TokenScopeReadUser = Scope("read_user") // TokenScopeSudo grants permission to perform API actions as any user in the system, when authenticated as an administrator. - TokenScopeSudo = TokenScope("sudo") + TokenScopeSudo = Scope("sudo") // TokenScopeAdminMode grants permission to perform API actions as an administrator, when Admin Mode is enabled. - TokenScopeAdminMode = TokenScope("admin_mode") + TokenScopeAdminMode = Scope("admin_mode") // TokenScopeAiFeatures grants permission to perform API actions for GitLab Duo. This scope is designed to work with the GitLab Duo Plugin for JetBrains. For all other extensions, see scope requirements. - TokenScopeAiFeatures = TokenScope("ai_features") + TokenScopeAiFeatures = Scope("ai_features") // TokenScopeK8SProxy grants permission to perform Kubernetes API calls using the agent for Kubernetes. - TokenScopeK8SProxy = TokenScope("k8s_proxy") + TokenScopeK8SProxy = Scope("k8s_proxy") // TokenScopeReadServicePing grant access to download Service Ping payload through the API when authenticated as an admin use. - TokenScopeReadServicePing = TokenScope("read_service_ping") + TokenScopeReadServicePing = Scope("read_service_ping") // TokenScopeSelfRotate grants permission to rotate this token using the personal access token API. Does not allow rotation of other tokens. - TokenScopeSelfRotate = TokenScope("self_rotate") + TokenScopeSelfRotate = Scope("self_rotate") // TokenScopeReadVirtualRegistry if a project is private and authorization is required, grants read-only (pull) access to container images through the dependency proxy. Available only when the dependency proxy is enabled. - TokenScopeReadVirtualRegistry = TokenScope("read_virtual_registry") + TokenScopeReadVirtualRegistry = Scope("read_virtual_registry") // TokenScopeWriteVirtualRegistry if a project is private and authorization is required, grants read (pull), write (push), and delete access to container images through the dependency proxy. Available only when the dependency proxy is enabled. - TokenScopeWriteVirtualRegistry = TokenScope("write_virtual_registry") + TokenScopeWriteVirtualRegistry = Scope("write_virtual_registry") - TokenScopeUnknown = TokenScope("") + TokenScopeUnknown = Scope("") ) var ( @@ -137,15 +137,15 @@ var ( } ) -func (i TokenScope) String() string { +func (i Scope) String() string { return string(i) } -func (i TokenScope) Value() string { +func (i Scope) Value() string { return i.String() } -func TokenScopeParse(value string) (TokenScope, error) { +func ParseScope(value string) (Scope, error) { if slices.Contains(ValidGroupTokenScopes, value) || slices.Contains(ValidPipelineProjectTokenScopes, value) || slices.Contains(ValidGroupDeployTokenScopes, value) || @@ -154,7 +154,7 @@ func TokenScopeParse(value string) (TokenScope, error) { slices.Contains(ValidProjectTokenScopes, value) || slices.Contains(ValidUserServiceAccountTokenScopes, value) || slices.Contains(ValidGroupServiceAccountTokenScopes, value) { - return TokenScope(value), nil + return Scope(value), nil } return TokenScopeUnknown, fmt.Errorf("failed to parse '%s': %w", value, ErrUnknownTokenScope) } diff --git a/internal/token/scope_g16x.go b/internal/token/scope_g16x.go new file mode 100644 index 0000000..4202136 --- /dev/null +++ b/internal/token/scope_g16x.go @@ -0,0 +1,3 @@ +//go:build g16x + +package token diff --git a/internal/token/scope_g17x.go b/internal/token/scope_g17x.go new file mode 100644 index 0000000..25cfa61 --- /dev/null +++ b/internal/token/scope_g17x.go @@ -0,0 +1,3 @@ +//go:build !g16x + +package token diff --git a/internal/token/scope_test.go b/internal/token/scope_test.go new file mode 100644 index 0000000..0992894 --- /dev/null +++ b/internal/token/scope_test.go @@ -0,0 +1,90 @@ +//go:build unit + +package token_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/token" +) + +func TestScope(t *testing.T) { + var tests = []struct { + expected token.Scope + input string + err bool + }{ + { + expected: token.TokenScopeApi, + input: token.TokenScopeApi.String(), + }, + { + expected: token.TokenScopeReadApi, + input: token.TokenScopeReadApi.String(), + }, + { + expected: token.TokenScopeReadRegistry, + input: token.TokenScopeReadRegistry.String(), + }, + { + expected: token.TokenScopeWriteRegistry, + input: token.TokenScopeWriteRegistry.String(), + }, + { + expected: token.TokenScopeReadRepository, + input: token.TokenScopeReadRepository.String(), + }, + { + expected: token.TokenScopeWriteRepository, + input: token.TokenScopeWriteRepository.String(), + }, + { + expected: token.TokenScopeCreateRunner, + input: token.TokenScopeCreateRunner.String(), + }, + { + expected: token.TokenScopeReadUser, + input: token.TokenScopeReadUser.String(), + }, + { + expected: token.TokenScopeSudo, + input: token.TokenScopeSudo.String(), + }, + { + expected: token.TokenScopeAdminMode, + input: token.TokenScopeAdminMode.String(), + }, + { + expected: token.TokenScopeReadPackageRegistry, + input: token.TokenScopeReadPackageRegistry.String(), + }, + { + expected: token.TokenScopeWritePackageRegistry, + input: token.TokenScopeWritePackageRegistry.String(), + }, + { + expected: token.TokenScopeUnknown, + input: "what", + err: true, + }, + { + expected: token.TokenScopeUnknown, + input: "unknown", + err: true, + }, + } + + for _, test := range tests { + t.Logf("assert parse(%s) = %s (err: %v)", test.input, test.expected, test.err) + val, err := token.ParseScope(test.input) + assert.EqualValues(t, test.expected, val) + assert.EqualValues(t, test.expected.Value(), test.expected.String()) + if test.err { + assert.ErrorIs(t, err, token.ErrUnknownTokenScope) + } else { + assert.NoError(t, err) + } + } +} diff --git a/internal/token/type_g16x.go b/internal/token/type_g16x.go new file mode 100644 index 0000000..4202136 --- /dev/null +++ b/internal/token/type_g16x.go @@ -0,0 +1,3 @@ +//go:build g16x + +package token diff --git a/internal/token/type_g17x.go b/internal/token/type_g17x.go new file mode 100644 index 0000000..25cfa61 --- /dev/null +++ b/internal/token/type_g17x.go @@ -0,0 +1,3 @@ +//go:build !g16x + +package token diff --git a/name_tpl_rand_string_test.go b/name_tpl_rand_string_test.go index f079f87..f280f32 100644 --- a/name_tpl_rand_string_test.go +++ b/name_tpl_rand_string_test.go @@ -9,6 +9,8 @@ import ( "github.com/stretchr/testify/require" g "github.com/ilijamt/vault-plugin-secrets-gitlab" + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/access" + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/token" ) func TestTokenNameGenerator_RandString(t *testing.T) { @@ -18,8 +20,8 @@ func TestTokenNameGenerator_RandString(t *testing.T) { TTL: time.Hour, Path: "/path", Name: "{{ randHexString 8 }}", - Scopes: []string{g.TokenScopeApi.String()}, - AccessLevel: g.AccessLevelNoPermissions, + Scopes: []string{token.TokenScopeApi.String()}, + AccessLevel: access.AccessLevelNoPermissions, TokenType: g.TokenTypePersonal, GitlabRevokesTokens: false, }, diff --git a/name_tpl_test.go b/name_tpl_test.go index dd534b8..5c197dd 100644 --- a/name_tpl_test.go +++ b/name_tpl_test.go @@ -10,6 +10,8 @@ import ( "github.com/stretchr/testify/assert" g "github.com/ilijamt/vault-plugin-secrets-gitlab" + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/access" + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/token" ) func TestTokenNameGenerator(t *testing.T) { @@ -27,8 +29,8 @@ func TestTokenNameGenerator(t *testing.T) { TTL: time.Hour, Path: "/path", Name: "{{ .role_name", - Scopes: []string{g.TokenScopeApi.String()}, - AccessLevel: g.AccessLevelNoPermissions, + Scopes: []string{token.TokenScopeApi.String()}, + AccessLevel: access.AccessLevelNoPermissions, TokenType: g.TokenTypePersonal, GitlabRevokesTokens: true, }, @@ -43,8 +45,8 @@ func TestTokenNameGenerator(t *testing.T) { TTL: time.Hour, Path: "/path", Name: "{{ .role_name }}-{{ .token_type }}-access-token-{{ yesNoBool .gitlab_revokes_token }}", - Scopes: []string{g.TokenScopeApi.String()}, - AccessLevel: g.AccessLevelNoPermissions, + Scopes: []string{token.TokenScopeApi.String()}, + AccessLevel: access.AccessLevelNoPermissions, TokenType: g.TokenTypePersonal, GitlabRevokesTokens: true, }, @@ -59,8 +61,8 @@ func TestTokenNameGenerator(t *testing.T) { TTL: time.Hour, Path: "/path", Name: "{{ .role_name }}-{{ .token_type }}-{{ stringsJoin .scopes \"-\" }}-{{ yesNoBool .gitlab_revokes_token }}", - Scopes: []string{g.TokenScopeApi.String(), g.TokenScopeSudo.String()}, - AccessLevel: g.AccessLevelNoPermissions, + Scopes: []string{token.TokenScopeApi.String(), token.TokenScopeSudo.String()}, + AccessLevel: access.AccessLevelNoPermissions, TokenType: g.TokenTypePersonal, GitlabRevokesTokens: false, }, @@ -75,8 +77,8 @@ func TestTokenNameGenerator(t *testing.T) { TTL: time.Hour, Path: "/path", Name: "{{ .role_name }}-{{ .token_type }}-{{ timeNowFormat \"2006-01\" }}", - Scopes: []string{g.TokenScopeApi.String(), g.TokenScopeSudo.String()}, - AccessLevel: g.AccessLevelNoPermissions, + Scopes: []string{token.TokenScopeApi.String(), token.TokenScopeSudo.String()}, + AccessLevel: access.AccessLevelNoPermissions, TokenType: g.TokenTypePersonal, GitlabRevokesTokens: false, }, diff --git a/name_tpl_unix_timestamp_test.go b/name_tpl_unix_timestamp_test.go index 7579786..f3e2eff 100644 --- a/name_tpl_unix_timestamp_test.go +++ b/name_tpl_unix_timestamp_test.go @@ -10,6 +10,8 @@ import ( "github.com/stretchr/testify/require" g "github.com/ilijamt/vault-plugin-secrets-gitlab" + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/access" + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/token" ) func TestTokenNameGenerator_UnixTimeStamp(t *testing.T) { @@ -20,8 +22,8 @@ func TestTokenNameGenerator_UnixTimeStamp(t *testing.T) { TTL: time.Hour, Path: "/path", Name: "{{ .unix_timestamp_utc }}", - Scopes: []string{g.TokenScopeApi.String()}, - AccessLevel: g.AccessLevelNoPermissions, + Scopes: []string{token.TokenScopeApi.String()}, + AccessLevel: access.AccessLevelNoPermissions, TokenType: g.TokenTypePersonal, GitlabRevokesTokens: false, }, diff --git a/path_role.go b/path_role.go index 584b1d8..7eb3225 100644 --- a/path_role.go +++ b/path_role.go @@ -14,6 +14,9 @@ import ( "github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/helper/locksutil" "github.com/hashicorp/vault/sdk/logical" + + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/access" + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/token" ) const ( @@ -54,7 +57,7 @@ var ( DisplayAttrs: &framework.DisplayAttributes{ Name: "Scopes", }, - AllowedValues: allowedValues(ValidPersonalTokenScopes...), + AllowedValues: allowedValues(token.ValidPersonalTokenScopes...), }, "ttl": { Type: framework.TypeDurationSecond, @@ -71,7 +74,7 @@ var ( DisplayAttrs: &framework.DisplayAttributes{ Name: "Access Level", }, - AllowedValues: allowedValues(ValidAccessLevels...), + AllowedValues: allowedValues(access.ValidAccessLevels...), }, "token_type": { Type: framework.TypeString, @@ -200,7 +203,7 @@ func (b *Backend) pathRolesWrite(ctx context.Context, req *logical.Request, data var err error var warnings []string var tokenType TokenType - var accessLevel AccessLevel + var accessLevel access.AccessLevel var configName = cmp.Or(data.Get("config_name").(string), TypeConfigDefault) b.lockClientMutex.RLock() @@ -215,7 +218,7 @@ func (b *Backend) pathRolesWrite(ctx context.Context, req *logical.Request, data } tokenType, _ = TokenTypeParse(data.Get("token_type").(string)) - accessLevel, _ = AccessLevelParse(data.Get("access_level").(string)) + accessLevel, _ = access.AccessLevelParse(data.Get("access_level").(string)) var role = EntryRole{ RoleName: roleName, @@ -247,43 +250,43 @@ func (b *Backend) pathRolesWrite(ctx context.Context, req *logical.Request, data switch tokenType { case TokenTypePersonal: - validAccessLevels = ValidPersonalAccessLevels - validScopes = ValidPersonalTokenScopes + validAccessLevels = access.ValidPersonalAccessLevels + validScopes = token.ValidPersonalTokenScopes noEmptyScopes = false skipFields = []string{"config_name", "access_level"} case TokenTypeGroup: - validAccessLevels = ValidGroupAccessLevels - validScopes = ValidGroupTokenScopes + validAccessLevels = access.ValidGroupAccessLevels + validScopes = token.ValidGroupTokenScopes noEmptyScopes = false skipFields = []string{"config_name"} case TokenTypeProject: - validAccessLevels = ValidProjectAccessLevels - validScopes = ValidProjectTokenScopes + validAccessLevels = access.ValidProjectAccessLevels + validScopes = token.ValidProjectTokenScopes noEmptyScopes = false skipFields = []string{"config_name"} case TokenTypeUserServiceAccount: - validAccessLevels = ValidUserServiceAccountAccessLevels - validScopes = ValidUserServiceAccountTokenScopes + validAccessLevels = access.ValidUserServiceAccountAccessLevels + validScopes = token.ValidUserServiceAccountTokenScopes noEmptyScopes = false skipFields = []string{"config_name", "access_level"} case TokenTypeGroupServiceAccount: - validAccessLevels = ValidGroupServiceAccountAccessLevels - validScopes = ValidGroupServiceAccountTokenScopes + validAccessLevels = access.ValidGroupServiceAccountAccessLevels + validScopes = token.ValidGroupServiceAccountTokenScopes noEmptyScopes = false skipFields = []string{"config_name", "access_level"} case TokenTypePipelineProjectTrigger: - validAccessLevels = ValidPipelineProjectTriggerAccessLevels + validAccessLevels = access.ValidPipelineProjectTriggerAccessLevels validScopes = []string{} noEmptyScopes = false skipFields = []string{"config_name", "access_level", "scopes"} case TokenTypeProjectDeploy: - validAccessLevels = ValidProjectDeployAccessLevels - validScopes = ValidProjectDeployTokenScopes + validAccessLevels = access.ValidProjectDeployAccessLevels + validScopes = token.ValidProjectDeployTokenScopes noEmptyScopes = true skipFields = []string{"config_name", "access_level"} case TokenTypeGroupDeploy: - validAccessLevels = ValidGroupDeployAccessLevels - validScopes = ValidGroupDeployTokenScopes + validAccessLevels = access.ValidGroupDeployAccessLevels + validScopes = token.ValidGroupDeployTokenScopes noEmptyScopes = true skipFields = []string{"config_name", "access_level"} } diff --git a/path_role_deploy_tokens_test.go b/path_role_deploy_tokens_test.go index 198ddcc..0031200 100644 --- a/path_role_deploy_tokens_test.go +++ b/path_role_deploy_tokens_test.go @@ -15,6 +15,8 @@ import ( "github.com/stretchr/testify/require" gitlab "github.com/ilijamt/vault-plugin-secrets-gitlab" + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/access" + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/token" ) func TestPathRolesDeployTokens(t *testing.T) { @@ -26,7 +28,7 @@ func TestPathRolesDeployTokens(t *testing.T) { var tests = []struct { tokenType gitlab.TokenType - accessLevel gitlab.AccessLevel + accessLevel access.AccessLevel scopes []string ttl string path string @@ -35,12 +37,12 @@ func TestPathRolesDeployTokens(t *testing.T) { { tokenType: gitlab.TokenTypeProjectDeploy, path: "example/example", - scopes: []string{gitlab.TokenScopeReadRepository.String()}, + scopes: []string{token.TokenScopeReadRepository.String()}, }, { tokenType: gitlab.TokenTypeGroupDeploy, path: "test/test1", - scopes: []string{gitlab.TokenScopeReadRepository.String()}, + scopes: []string{token.TokenScopeReadRepository.String()}, }, } @@ -56,7 +58,7 @@ func TestPathRolesDeployTokens(t *testing.T) { Data: map[string]any{ "path": tt.path, "name": tt.name, - "access_level": cmp.Or(tt.accessLevel, gitlab.AccessLevelUnknown).String(), + "access_level": cmp.Or(tt.accessLevel, access.AccessLevelUnknown).String(), "token_type": tt.tokenType.String(), "scopes": tt.scopes, "ttl": cmp.Or(tt.ttl, "1h"), @@ -76,7 +78,7 @@ func TestPathRolesDeployTokens(t *testing.T) { Data: map[string]any{ "path": tt.path, "name": tt.name, - "access_level": gitlab.AccessLevelNoPermissions.String(), + "access_level": access.AccessLevelNoPermissions.String(), "token_type": tt.tokenType.String(), "ttl": cmp.Or(tt.ttl, "1h"), "scopes": []string{}, diff --git a/path_role_pipeline_project_trigger_token_test.go b/path_role_pipeline_project_trigger_token_test.go index 6728c43..838730a 100644 --- a/path_role_pipeline_project_trigger_token_test.go +++ b/path_role_pipeline_project_trigger_token_test.go @@ -15,6 +15,8 @@ import ( "github.com/stretchr/testify/require" gitlab "github.com/ilijamt/vault-plugin-secrets-gitlab" + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/access" + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/token" ) func TestPathRolesPipelineProjectTrigger(t *testing.T) { @@ -34,9 +36,9 @@ func TestPathRolesPipelineProjectTrigger(t *testing.T) { Data: map[string]any{ "path": "user", "name": "Example user personal token", - "access_level": gitlab.AccessLevelNoPermissions.String(), + "access_level": access.AccessLevelNoPermissions.String(), "token_type": gitlab.TokenTypePipelineProjectTrigger.String(), - "scopes": []string{gitlab.TokenScopeApi.String()}, + "scopes": []string{token.TokenScopeApi.String()}, "ttl": "1h", }, }) @@ -56,7 +58,7 @@ func TestPathRolesPipelineProjectTrigger(t *testing.T) { Data: map[string]any{ "path": "user", "name": "Example user personal token", - "access_level": gitlab.AccessLevelUnknown.String(), + "access_level": access.AccessLevelUnknown.String(), "token_type": gitlab.TokenTypePipelineProjectTrigger.String(), "scopes": []string{}, "ttl": "1h", @@ -77,7 +79,7 @@ func TestPathRolesPipelineProjectTrigger(t *testing.T) { Data: map[string]any{ "path": "user", "name": "Example user personal token", - "access_level": gitlab.AccessLevelUnknown.String(), + "access_level": access.AccessLevelUnknown.String(), "token_type": gitlab.TokenTypePipelineProjectTrigger.String(), "scopes": []string{}, }, diff --git a/path_role_test.go b/path_role_test.go index 4d084bd..0678421 100644 --- a/path_role_test.go +++ b/path_role_test.go @@ -15,6 +15,8 @@ import ( "github.com/stretchr/testify/require" gitlab "github.com/ilijamt/vault-plugin-secrets-gitlab" + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/access" + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/token" ) func TestPathRolesList(t *testing.T) { @@ -80,7 +82,7 @@ func TestPathRoles(t *testing.T) { "name": gitlab.TokenTypePersonal.String(), "token_type": gitlab.TokenTypePersonal.String(), "ttl": gitlab.DefaultAccessTokenMinTTL, - "scopes": gitlab.ValidPersonalTokenScopes, + "scopes": token.ValidPersonalTokenScopes, "gitlab_revokes_token": false, }, }) @@ -99,10 +101,10 @@ func TestPathRoles(t *testing.T) { Data: map[string]any{ "path": "user", "name": gitlab.TokenTypePersonal.String(), - "access_level": gitlab.AccessLevelOwnerPermissions.String(), + "access_level": access.AccessLevelOwnerPermissions.String(), "token_type": gitlab.TokenTypePersonal.String(), "ttl": gitlab.DefaultAccessTokenMinTTL, - "scopes": gitlab.ValidPersonalTokenScopes, + "scopes": token.ValidPersonalTokenScopes, "gitlab_revokes_token": false, }, }) @@ -125,7 +127,7 @@ func TestPathRoles(t *testing.T) { "name": gitlab.TokenTypeProject.String(), "token_type": gitlab.TokenTypeProject.String(), "ttl": gitlab.DefaultAccessTokenMinTTL, - "scopes": gitlab.ValidProjectTokenScopes, + "scopes": token.ValidProjectTokenScopes, "gitlab_revokes_token": false, }, }) @@ -143,10 +145,10 @@ func TestPathRoles(t *testing.T) { Data: map[string]any{ "path": "user", "name": gitlab.TokenTypeProject.String(), - "access_level": gitlab.AccessLevelOwnerPermissions.String(), + "access_level": access.AccessLevelOwnerPermissions.String(), "token_type": gitlab.TokenTypeProject.String(), "ttl": gitlab.DefaultAccessTokenMinTTL, - "scopes": gitlab.ValidProjectTokenScopes, + "scopes": token.ValidProjectTokenScopes, "gitlab_revokes_token": false, }, }) @@ -170,7 +172,7 @@ func TestPathRoles(t *testing.T) { "name": gitlab.TokenTypeGroup.String(), "token_type": gitlab.TokenTypeGroup.String(), "ttl": gitlab.DefaultAccessTokenMinTTL, - "scopes": gitlab.ValidGroupTokenScopes, + "scopes": token.ValidGroupTokenScopes, "gitlab_revokes_token": false, }, }) @@ -188,10 +190,10 @@ func TestPathRoles(t *testing.T) { Data: map[string]any{ "path": "user", "name": gitlab.TokenTypeGroup.String(), - "access_level": gitlab.AccessLevelOwnerPermissions.String(), + "access_level": access.AccessLevelOwnerPermissions.String(), "token_type": gitlab.TokenTypeGroup.String(), "ttl": gitlab.DefaultAccessTokenMinTTL, - "scopes": gitlab.ValidGroupTokenScopes, + "scopes": token.ValidGroupTokenScopes, "gitlab_revokes_token": false, }, }) @@ -234,7 +236,7 @@ func TestPathRoles(t *testing.T) { "name": "{{ . } invalid template", "token_type": gitlab.TokenTypePersonal.String(), "ttl": gitlab.DefaultAccessTokenMinTTL, - "scopes": gitlab.ValidPersonalTokenScopes, + "scopes": token.ValidPersonalTokenScopes, "gitlab_revokes_token": false, }, }) @@ -255,10 +257,10 @@ func TestPathRoles(t *testing.T) { Data: map[string]any{ "path": "user", "name": "Example user personal token", - "access_level": gitlab.AccessLevelOwnerPermissions.String(), + "access_level": access.AccessLevelOwnerPermissions.String(), "ttl": "48h", "token_type": gitlab.TokenTypeProject.String(), - "scopes": gitlab.ValidProjectTokenScopes, + "scopes": token.ValidProjectTokenScopes, }, }) require.NoError(t, err) @@ -276,10 +278,10 @@ func TestPathRoles(t *testing.T) { Data: map[string]any{ "path": "user", "name": "Example project personal token", - "access_level": gitlab.AccessLevelOwnerPermissions.String(), + "access_level": access.AccessLevelOwnerPermissions.String(), "token_type": gitlab.TokenTypeProject.String(), "ttl": "48h", - "scopes": gitlab.ValidPersonalTokenScopes, + "scopes": token.ValidPersonalTokenScopes, "gitlab_revokes_token": false, }, }) @@ -303,7 +305,7 @@ func TestPathRoles(t *testing.T) { "name": "Example user personal token", "ttl": "48h", "token_type": gitlab.TokenTypePersonal.String(), - "scopes": gitlab.ValidPersonalTokenScopes, + "scopes": token.ValidPersonalTokenScopes, }, }) require.NoError(t, err) @@ -346,9 +348,9 @@ func TestPathRoles(t *testing.T) { "path": "user", "name": "Example user personal token", "ttl": "48h", - "access_level": gitlab.AccessLevelOwnerPermissions.String(), + "access_level": access.AccessLevelOwnerPermissions.String(), "token_type": gitlab.TokenTypeGroup.String(), - "scopes": gitlab.ValidProjectTokenScopes, + "scopes": token.ValidProjectTokenScopes, }, }) require.NoError(t, err) @@ -366,9 +368,9 @@ func TestPathRoles(t *testing.T) { Data: map[string]any{ "path": "user", "name": "Example user personal token", - "access_level": gitlab.AccessLevelOwnerPermissions.String(), + "access_level": access.AccessLevelOwnerPermissions.String(), "token_type": gitlab.TokenTypeGroup.String(), - "scopes": gitlab.ValidPersonalTokenScopes, + "scopes": token.ValidPersonalTokenScopes, }, }) require.Error(t, err) @@ -421,8 +423,8 @@ func TestPathRoles(t *testing.T) { "ttl": int64((5 * 24 * time.Hour).Seconds()), "gitlab_revokes_token": false, "scopes": []string{ - gitlab.TokenScopeApi.String(), - gitlab.TokenScopeReadRegistry.String(), + token.TokenScopeApi.String(), + token.TokenScopeReadRegistry.String(), }, } diff --git a/path_role_ttl_test.go b/path_role_ttl_test.go index 313a242..06e1b63 100644 --- a/path_role_ttl_test.go +++ b/path_role_ttl_test.go @@ -14,6 +14,7 @@ import ( "github.com/stretchr/testify/require" gitlab "github.com/ilijamt/vault-plugin-secrets-gitlab" + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/token" ) func TestPathRolesTTL(t *testing.T) { @@ -29,8 +30,8 @@ func TestPathRolesTTL(t *testing.T) { "name": "Example user personal token", "token_type": gitlab.TokenTypePersonal.String(), "scopes": []string{ - gitlab.TokenScopeApi.String(), - gitlab.TokenScopeReadRegistry.String(), + token.TokenScopeApi.String(), + token.TokenScopeReadRegistry.String(), }, "gitlab_revokes_token": false, } @@ -90,8 +91,8 @@ func TestPathRolesTTL(t *testing.T) { "name": "Example user personal token", "token_type": gitlab.TokenTypePersonal.String(), "scopes": []string{ - gitlab.TokenScopeApi.String(), - gitlab.TokenScopeReadRegistry.String(), + token.TokenScopeApi.String(), + token.TokenScopeReadRegistry.String(), }, "gitlab_revokes_token": false, } @@ -152,8 +153,8 @@ func TestPathRolesTTL(t *testing.T) { "name": "Example user personal token", "token_type": gitlab.TokenTypePersonal.String(), "scopes": []string{ - gitlab.TokenScopeApi.String(), - gitlab.TokenScopeReadRegistry.String(), + token.TokenScopeApi.String(), + token.TokenScopeReadRegistry.String(), }, "gitlab_revokes_token": true, } diff --git a/path_token_role_multiple_config_test.go b/path_token_role_multiple_config_test.go index f09a794..97f790c 100644 --- a/path_token_role_multiple_config_test.go +++ b/path_token_role_multiple_config_test.go @@ -11,6 +11,8 @@ import ( g "gitlab.com/gitlab-org/api/client-go" gitlab "github.com/ilijamt/vault-plugin-secrets-gitlab" + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/access" + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/token" ) func TestPathTokenRolesMultipleConfigs(t *testing.T) { @@ -45,7 +47,7 @@ func TestPathTokenRolesMultipleConfigs(t *testing.T) { type roleData struct { roleName, path, tokenName string tokenType gitlab.TokenType - accessLevel gitlab.AccessLevel + accessLevel access.AccessLevel scopes []string } var roles = map[string][]roleData{ @@ -54,14 +56,14 @@ func TestPathTokenRolesMultipleConfigs(t *testing.T) { roleName: "root-root", path: "root", tokenType: gitlab.TokenTypePersonal, - scopes: []string{gitlab.TokenScopeApi.String(), gitlab.TokenScopeSelfRotate.String()}, + scopes: []string{token.TokenScopeApi.String(), token.TokenScopeSelfRotate.String()}, tokenName: "admin_user_root", }, { roleName: "root-normal-user", path: "normal-user", tokenType: gitlab.TokenTypePersonal, - scopes: []string{gitlab.TokenScopeApi.String(), gitlab.TokenScopeSelfRotate.String()}, + scopes: []string{token.TokenScopeApi.String(), token.TokenScopeSelfRotate.String()}, tokenName: "admin_user_root", }, }, @@ -70,8 +72,8 @@ func TestPathTokenRolesMultipleConfigs(t *testing.T) { roleName: "admin-example-example", path: "example/example", tokenType: gitlab.TokenTypeProject, - accessLevel: gitlab.AccessLevelGuestPermissions, - scopes: []string{gitlab.TokenScopeApi.String(), gitlab.TokenScopeSelfRotate.String()}, + accessLevel: access.AccessLevelGuestPermissions, + scopes: []string{token.TokenScopeApi.String(), token.TokenScopeSelfRotate.String()}, tokenName: "admin_user_initial_token", }, }, @@ -80,8 +82,8 @@ func TestPathTokenRolesMultipleConfigs(t *testing.T) { roleName: "normal-example", path: "example", tokenType: gitlab.TokenTypeGroup, - accessLevel: gitlab.AccessLevelGuestPermissions, - scopes: []string{gitlab.TokenScopeApi.String(), gitlab.TokenScopeSelfRotate.String()}, + accessLevel: access.AccessLevelGuestPermissions, + scopes: []string{token.TokenScopeApi.String(), token.TokenScopeSelfRotate.String()}, tokenName: "normal_user_initial_token", }, }, diff --git a/path_token_role_test.go b/path_token_role_test.go index 7b9769e..5440a4a 100644 --- a/path_token_role_test.go +++ b/path_token_role_test.go @@ -13,6 +13,7 @@ import ( "github.com/stretchr/testify/require" gitlab "github.com/ilijamt/vault-plugin-secrets-gitlab" + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/access" ) func TestPathTokenRoles(t *testing.T) { @@ -35,7 +36,7 @@ func TestPathTokenRoles(t *testing.T) { require.ErrorIs(t, err, gitlab.ErrRoleNotFound) }) - var generalTokenCreation = func(t *testing.T, tokenType gitlab.TokenType, level gitlab.AccessLevel, gitlabRevokesToken bool) { + var generalTokenCreation = func(t *testing.T, tokenType gitlab.TokenType, level access.AccessLevel, gitlabRevokesToken bool) { t.Logf("token creation, token type: %s, level: %s, gitlab revokes token: %t", tokenType, level, gitlabRevokesToken) ctx := getCtxGitlabClient(t, "unit") client := newInMemoryClient(true) @@ -150,17 +151,17 @@ func TestPathTokenRoles(t *testing.T) { } t.Run("personal access token", func(t *testing.T) { - generalTokenCreation(t, gitlab.TokenTypePersonal, gitlab.AccessLevelUnknown, false) - generalTokenCreation(t, gitlab.TokenTypePersonal, gitlab.AccessLevelUnknown, true) + generalTokenCreation(t, gitlab.TokenTypePersonal, access.AccessLevelUnknown, false) + generalTokenCreation(t, gitlab.TokenTypePersonal, access.AccessLevelUnknown, true) }) t.Run("project access token", func(t *testing.T) { - generalTokenCreation(t, gitlab.TokenTypeProject, gitlab.AccessLevelGuestPermissions, false) - generalTokenCreation(t, gitlab.TokenTypeProject, gitlab.AccessLevelGuestPermissions, true) + generalTokenCreation(t, gitlab.TokenTypeProject, access.AccessLevelGuestPermissions, false) + generalTokenCreation(t, gitlab.TokenTypeProject, access.AccessLevelGuestPermissions, true) }) t.Run("group access token", func(t *testing.T) { - generalTokenCreation(t, gitlab.TokenTypeGroup, gitlab.AccessLevelGuestPermissions, false) - generalTokenCreation(t, gitlab.TokenTypeGroup, gitlab.AccessLevelGuestPermissions, true) + generalTokenCreation(t, gitlab.TokenTypeGroup, access.AccessLevelGuestPermissions, false) + generalTokenCreation(t, gitlab.TokenTypeGroup, access.AccessLevelGuestPermissions, true) }) } diff --git a/token_with_scopes_and_access_level.go b/token_with_scopes_and_access_level.go index 6aacc72..f893a3b 100644 --- a/token_with_scopes_and_access_level.go +++ b/token_with_scopes_and_access_level.go @@ -3,13 +3,15 @@ package gitlab import ( "maps" "strings" + + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/access" ) type TokenWithScopesAndAccessLevel struct { Token `json:",inline"` - Scopes []string `json:"scopes"` - AccessLevel AccessLevel `json:"access_level"` + Scopes []string `json:"scopes"` + AccessLevel access.AccessLevel `json:"access_level"` } func (t *TokenWithScopesAndAccessLevel) Internal() (d map[string]any) { diff --git a/type_access_level_test.go b/type_access_level_test.go deleted file mode 100644 index d5cab4c..0000000 --- a/type_access_level_test.go +++ /dev/null @@ -1,66 +0,0 @@ -//go:build unit - -package gitlab_test - -import ( - "testing" - - "github.com/stretchr/testify/assert" - - gitlab "github.com/ilijamt/vault-plugin-secrets-gitlab" -) - -func TestAccessLevel(t *testing.T) { - var tests = []struct { - expected gitlab.AccessLevel - input string - err bool - }{ - { - expected: gitlab.AccessLevelOwnerPermissions, - input: gitlab.AccessLevelOwnerPermissions.String(), - }, - { - expected: gitlab.AccessLevelReporterPermissions, - input: gitlab.AccessLevelReporterPermissions.String(), - }, - { - expected: gitlab.AccessLevelMaintainerPermissions, - input: gitlab.AccessLevelMaintainerPermissions.String(), - }, - { - expected: gitlab.AccessLevelDeveloperPermissions, - input: gitlab.AccessLevelDeveloperPermissions.String(), - }, - { - expected: gitlab.AccessLevelGuestPermissions, - input: gitlab.AccessLevelGuestPermissions.String(), - }, - { - expected: gitlab.AccessLevelNoPermissions, - input: gitlab.AccessLevelNoPermissions.String(), - }, - { - expected: gitlab.AccessLevelMinimalAccessPermissions, - input: gitlab.AccessLevelMinimalAccessPermissions.String(), - }, - { - expected: gitlab.AccessLevelUnknown, - input: "unknown", - err: true, - }, - } - - for _, test := range tests { - t.Logf("assert parse(%s) = %s (err: %v)", test.input, test.expected, test.err) - val, err := gitlab.AccessLevelParse(test.input) - assert.EqualValues(t, test.expected, val) - if test.err { - assert.ErrorIs(t, err, gitlab.ErrUnknownAccessLevel) - assert.Less(t, val.Value(), 0) - } else { - assert.NoError(t, err) - assert.GreaterOrEqual(t, val.Value(), 0) - } - } -} diff --git a/type_token_scope_test.go b/type_token_scope_test.go deleted file mode 100644 index fa0614c..0000000 --- a/type_token_scope_test.go +++ /dev/null @@ -1,90 +0,0 @@ -//go:build unit - -package gitlab_test - -import ( - "testing" - - "github.com/stretchr/testify/assert" - - gitlab "github.com/ilijamt/vault-plugin-secrets-gitlab" -) - -func TestTokenScope(t *testing.T) { - var tests = []struct { - expected gitlab.TokenScope - input string - err bool - }{ - { - expected: gitlab.TokenScopeApi, - input: gitlab.TokenScopeApi.String(), - }, - { - expected: gitlab.TokenScopeReadApi, - input: gitlab.TokenScopeReadApi.String(), - }, - { - expected: gitlab.TokenScopeReadRegistry, - input: gitlab.TokenScopeReadRegistry.String(), - }, - { - expected: gitlab.TokenScopeWriteRegistry, - input: gitlab.TokenScopeWriteRegistry.String(), - }, - { - expected: gitlab.TokenScopeReadRepository, - input: gitlab.TokenScopeReadRepository.String(), - }, - { - expected: gitlab.TokenScopeWriteRepository, - input: gitlab.TokenScopeWriteRepository.String(), - }, - { - expected: gitlab.TokenScopeCreateRunner, - input: gitlab.TokenScopeCreateRunner.String(), - }, - { - expected: gitlab.TokenScopeReadUser, - input: gitlab.TokenScopeReadUser.String(), - }, - { - expected: gitlab.TokenScopeSudo, - input: gitlab.TokenScopeSudo.String(), - }, - { - expected: gitlab.TokenScopeAdminMode, - input: gitlab.TokenScopeAdminMode.String(), - }, - { - expected: gitlab.TokenScopeReadPackageRegistry, - input: gitlab.TokenScopeReadPackageRegistry.String(), - }, - { - expected: gitlab.TokenScopeWritePackageRegistry, - input: gitlab.TokenScopeWritePackageRegistry.String(), - }, - { - expected: gitlab.TokenScopeUnknown, - input: "what", - err: true, - }, - { - expected: gitlab.TokenScopeUnknown, - input: "unknown", - err: true, - }, - } - - for _, test := range tests { - t.Logf("assert parse(%s) = %s (err: %v)", test.input, test.expected, test.err) - val, err := gitlab.TokenScopeParse(test.input) - assert.EqualValues(t, test.expected, val) - assert.EqualValues(t, test.expected.Value(), test.expected.String()) - if test.err { - assert.ErrorIs(t, err, gitlab.ErrUnknownTokenScope) - } else { - assert.NoError(t, err) - } - } -} diff --git a/version.go b/version.go index 1c84a94..35a7f12 100644 --- a/version.go +++ b/version.go @@ -3,3 +3,4 @@ package gitlab var Version string = "v0.0.0-dev" var FullCommit string var BuildDate string +var VersionTarget string diff --git a/with_admin_user_pat_gitlab_revokes_token_test.go b/with_admin_user_pat_gitlab_revokes_token_test.go index eb19798..3bf4e47 100644 --- a/with_admin_user_pat_gitlab_revokes_token_test.go +++ b/with_admin_user_pat_gitlab_revokes_token_test.go @@ -15,6 +15,7 @@ import ( g "gitlab.com/gitlab-org/api/client-go" gitlab "github.com/ilijamt/vault-plugin-secrets-gitlab" + token2 "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/token" ) func TestWithAdminUser_PAT_AdminUser_GitlabRevokesToken(t *testing.T) { @@ -58,7 +59,7 @@ func TestWithAdminUser_PAT_AdminUser_GitlabRevokesToken(t *testing.T) { "gitlab_revokes_token": strconv.FormatBool(true), "scopes": strings.Join( []string{ - gitlab.TokenScopeReadApi.String(), + token2.TokenScopeReadApi.String(), }, ","), }, diff --git a/with_admin_user_pat_vault_revokes_token_test.go b/with_admin_user_pat_vault_revokes_token_test.go index 187b617..0b850da 100644 --- a/with_admin_user_pat_vault_revokes_token_test.go +++ b/with_admin_user_pat_vault_revokes_token_test.go @@ -15,6 +15,7 @@ import ( g "gitlab.com/gitlab-org/api/client-go" gitlab "github.com/ilijamt/vault-plugin-secrets-gitlab" + token2 "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/token" ) func TestWithAdminUser_PAT_AdminUser_VaultRevokesToken(t *testing.T) { @@ -57,7 +58,7 @@ func TestWithAdminUser_PAT_AdminUser_VaultRevokesToken(t *testing.T) { "token_type": gitlab.TokenTypePersonal.String(), "scopes": strings.Join( []string{ - gitlab.TokenScopeReadApi.String(), + token2.TokenScopeReadApi.String(), }, ","), "ttl": time.Hour, diff --git a/with_group_deploy_token_test.go b/with_group_deploy_token_test.go index ab5863d..dbd4cfa 100644 --- a/with_group_deploy_token_test.go +++ b/with_group_deploy_token_test.go @@ -13,6 +13,7 @@ import ( g "gitlab.com/gitlab-org/api/client-go" gitlab "github.com/ilijamt/vault-plugin-secrets-gitlab" + token2 "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/token" ) func TestWithGroupDeployToken(t *testing.T) { @@ -54,7 +55,7 @@ func TestWithGroupDeployToken(t *testing.T) { "token_type": gitlab.TokenTypeGroupDeploy.String(), "gitlab_revokes_token": strconv.FormatBool(false), "ttl": 120 * time.Hour, - "scopes": []string{gitlab.TokenScopeReadRepository.String()}, + "scopes": []string{token2.TokenScopeReadRepository.String()}, }, }) require.NoError(t, err) diff --git a/with_normal_user_gat_test.go b/with_normal_user_gat_test.go index acbcd83..09bbe2e 100644 --- a/with_normal_user_gat_test.go +++ b/with_normal_user_gat_test.go @@ -15,6 +15,8 @@ import ( g "gitlab.com/gitlab-org/api/client-go" gitlab "github.com/ilijamt/vault-plugin-secrets-gitlab" + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/access" + token2 "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/token" ) func TestWithNormalUser_GAT(t *testing.T) { @@ -55,8 +57,8 @@ func TestWithNormalUser_GAT(t *testing.T) { "token_type": gitlab.TokenTypeGroup.String(), "ttl": time.Hour * 120, "gitlab_revokes_token": strconv.FormatBool(false), - "access_level": gitlab.AccessLevelMaintainerPermissions.String(), - "scopes": strings.Join([]string{gitlab.TokenScopeReadApi.String()}, ","), + "access_level": access.AccessLevelMaintainerPermissions.String(), + "scopes": strings.Join([]string{token2.TokenScopeReadApi.String()}, ","), }, }) require.NoError(t, err) diff --git a/with_normal_user_personal_at_fails_test.go b/with_normal_user_personal_at_fails_test.go index 0ad1a3a..6b4d341 100644 --- a/with_normal_user_personal_at_fails_test.go +++ b/with_normal_user_personal_at_fails_test.go @@ -13,6 +13,7 @@ import ( "github.com/stretchr/testify/require" gitlab "github.com/ilijamt/vault-plugin-secrets-gitlab" + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/token" ) func TestWithNormalUser_PersonalAT_Fails(t *testing.T) { @@ -52,7 +53,7 @@ func TestWithNormalUser_PersonalAT_Fails(t *testing.T) { "gitlab_revokes_token": strconv.FormatBool(true), "scopes": strings.Join( []string{ - gitlab.TokenScopeReadApi.String(), + token.TokenScopeReadApi.String(), }, ","), }, diff --git a/with_normal_user_project_at_test.go b/with_normal_user_project_at_test.go index 52fb5bd..c8fdd03 100644 --- a/with_normal_user_project_at_test.go +++ b/with_normal_user_project_at_test.go @@ -15,6 +15,8 @@ import ( g "gitlab.com/gitlab-org/api/client-go" gitlab "github.com/ilijamt/vault-plugin-secrets-gitlab" + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/access" + token2 "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/token" ) func TestWithNormalUser_ProjectAT(t *testing.T) { @@ -56,10 +58,10 @@ func TestWithNormalUser_ProjectAT(t *testing.T) { "token_type": gitlab.TokenTypeProject.String(), "ttl": time.Hour * 120, "gitlab_revokes_token": strconv.FormatBool(false), - "access_level": gitlab.AccessLevelMaintainerPermissions.String(), + "access_level": access.AccessLevelMaintainerPermissions.String(), "scopes": strings.Join( []string{ - gitlab.TokenScopeReadApi.String(), + token2.TokenScopeReadApi.String(), }, ","), }, diff --git a/with_project_deploy_token_test.go b/with_project_deploy_token_test.go index 357eddf..1f6e874 100644 --- a/with_project_deploy_token_test.go +++ b/with_project_deploy_token_test.go @@ -13,6 +13,7 @@ import ( g "gitlab.com/gitlab-org/api/client-go" gitlab "github.com/ilijamt/vault-plugin-secrets-gitlab" + token2 "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/token" ) func TestWithProjectDeployToken(t *testing.T) { @@ -54,7 +55,7 @@ func TestWithProjectDeployToken(t *testing.T) { "token_type": gitlab.TokenTypeProjectDeploy.String(), "gitlab_revokes_token": strconv.FormatBool(false), "ttl": 120 * time.Hour, - "scopes": []string{gitlab.TokenScopeReadRepository.String()}, + "scopes": []string{token2.TokenScopeReadRepository.String()}, }, }) require.NoError(t, err) diff --git a/with_service_account_fail_test.go b/with_service_account_fail_test.go index a4a9fa5..67cf700 100644 --- a/with_service_account_fail_test.go +++ b/with_service_account_fail_test.go @@ -11,6 +11,7 @@ import ( g "gitlab.com/gitlab-org/api/client-go" gitlab "github.com/ilijamt/vault-plugin-secrets-gitlab" + "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/token" ) func TestWithServiceAccountUserFail(t *testing.T) { @@ -58,7 +59,7 @@ func TestWithServiceAccountUserFail(t *testing.T) { "name": fmt.Sprintf(`user-service-account-%s`, usr.Username), "token_type": gitlab.TokenTypeUserServiceAccount.String(), "ttl": gitlab.DefaultAccessTokenMinTTL, - "scopes": gitlab.ValidUserServiceAccountTokenScopes, + "scopes": token.ValidUserServiceAccountTokenScopes, "gitlab_revokes_token": false, }, }) diff --git a/with_service_account_group_test.go b/with_service_account_group_test.go index f4bdc2d..988a734 100644 --- a/with_service_account_group_test.go +++ b/with_service_account_group_test.go @@ -13,6 +13,7 @@ import ( g "gitlab.com/gitlab-org/api/client-go" gitlab "github.com/ilijamt/vault-plugin-secrets-gitlab" + token2 "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/token" ) func TestWithServiceAccountGroup(t *testing.T) { @@ -63,7 +64,7 @@ func TestWithServiceAccountGroup(t *testing.T) { "name": `vault-generated-{{ .token_type }}-token`, "token_type": gitlab.TokenTypeGroupServiceAccount.String(), "ttl": gitlab.DefaultAccessTokenMinTTL, - "scopes": gitlab.ValidGroupServiceAccountTokenScopes, + "scopes": token2.ValidGroupServiceAccountTokenScopes, "gitlab_revokes_token": false, }, }) diff --git a/with_service_account_user_test.go b/with_service_account_user_test.go index be515e0..f145c64 100644 --- a/with_service_account_user_test.go +++ b/with_service_account_user_test.go @@ -12,6 +12,7 @@ import ( g "gitlab.com/gitlab-org/api/client-go" gitlab "github.com/ilijamt/vault-plugin-secrets-gitlab" + token2 "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/token" ) func TestWithServiceAccountUser(t *testing.T) { @@ -61,7 +62,7 @@ func TestWithServiceAccountUser(t *testing.T) { "name": `vault-generated-{{ .token_type }}-token`, "token_type": gitlab.TokenTypeUserServiceAccount.String(), "ttl": gitlab.DefaultAccessTokenMinTTL, - "scopes": gitlab.ValidUserServiceAccountTokenScopes, + "scopes": token2.ValidUserServiceAccountTokenScopes, "gitlab_revokes_token": false, }, })