As we reevaluate how to best support and maintain Staging Ref in the future, we encourage development teams using this environment to highlight their use cases in the following issue: https://gitlab.com/gitlab-com/gl-infra/software-delivery/framework/software-delivery-framework-issue-tracker/-/issues/36.

Skip to content
Snippets Groups Projects
Unverified Commit 2e8cb44b authored by Joe Snyder's avatar Joe Snyder Committed by GitLab
Browse files

Add configuration objects to PAT token

parent 2c2ff10a
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -127,7 +127,9 @@ func Build(args *commandargs.Shell, config *config.Config, readWriter *readwrite
case commandargs.UploadArchive:
return &uploadarchive.Command{Config: config, Args: args, ReadWriter: readWriter}
case commandargs.PersonalAccessToken:
return &personalaccesstoken.Command{Config: config, Args: args, ReadWriter: readWriter}
if config.PATConfig.Enabled {
return &personalaccesstoken.Command{Config: config, Args: args, ReadWriter: readWriter}
}
}
return nil
Loading
Loading
Loading
Loading
@@ -24,7 +24,7 @@ import (
var (
gitlabShellExec = &executable.Executable{Name: executable.GitlabShell}
basicConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket"}
basicConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket", PATConfig: config.PATConfig{Enabled: true}}
)
func TestNew(t *testing.T) {
Loading
Loading
@@ -143,6 +143,47 @@ func TestLFSTransferCommands(t *testing.T) {
})
}
}
func TestPATCommands(t *testing.T) {
testCases := []struct {
desc string
executable *executable.Executable
env sshenv.Env
arguments []string
config *config.Config
expectedType interface{}
errorString string
}{
{
desc: "it returns a PersonalAccessToken command",
executable: gitlabShellExec,
env: buildEnv("personal_access_token"),
config: basicConfig,
expectedType: &personalaccesstoken.Command{},
errorString: "",
},
{
desc: "it does not return a PersonalAccessToken command when config disallows it",
executable: gitlabShellExec,
env: buildEnv("personal_access_token"),
config: &config.Config{GitlabUrl: "http+unix://gitlab.socket", PATConfig: config.PATConfig{Enabled: false}},
expectedType: nil,
errorString: "Disallowed command",
},
}
for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
command, err := cmd.New(tc.arguments, tc.env, tc.config, nil)
if len(tc.errorString) > 0 {
require.Equal(t, err.Error(), tc.errorString)
}
require.IsType(t, tc.expectedType, command)
})
}
}
func TestFailingNew(t *testing.T) {
testCases := []struct {
desc string
Loading
Loading
Loading
Loading
@@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"slices"
"strconv"
"strings"
"time"
Loading
Loading
@@ -60,9 +61,21 @@ func (c *Command) parseTokenArgs() error {
if len(c.Args.SshArgs) < 3 || len(c.Args.SshArgs) > 4 {
return errors.New(usageText)
}
var rectfiedScopes []string
requestedScopes := strings.Split(c.Args.SshArgs[2], ",")
if len(c.Config.PATConfig.AllowedScopes) > 0 {
for _, requestedScope := range requestedScopes {
if slices.Contains(c.Config.PATConfig.AllowedScopes, requestedScope) {
rectfiedScopes = append(rectfiedScopes, requestedScope)
}
}
} else {
rectfiedScopes = requestedScopes
}
c.TokenArgs = &tokenArgs{
Name: c.Args.SshArgs[1],
Scopes: strings.Split(c.Args.SshArgs[2], ","),
Scopes: rectfiedScopes,
}
if len(c.Args.SshArgs) < 4 {
Loading
Loading
Loading
Loading
@@ -6,6 +6,7 @@ import (
"encoding/json"
"io"
"net/http"
"strings"
"testing"
"github.com/stretchr/testify/require"
Loading
Loading
@@ -41,6 +42,14 @@ func setup(t *testing.T) {
json.NewEncoder(w).Encode(body)
case "broken":
w.WriteHeader(http.StatusInternalServerError)
case "invalidscope":
message := "Invalid scope: '" + strings.Join(requestBody.Scopes, ",") + "'."
message += " Valid scopes are: [\"api\", \"create_runner\", \"k8s_proxy\", \"read_api\", \"read_registry\", \"read_repository\", \"read_user\", \"write_registry\", \"write_repository\"]"
body := map[string]interface{}{
"success": false,
"message": message,
}
json.NewEncoder(w).Encode(body)
case "badresponse":
default:
var expiresAt interface{}
Loading
Loading
@@ -73,6 +82,7 @@ func TestExecute(t *testing.T) {
testCases := []struct {
desc string
PATConfig config.PATConfig
arguments *commandargs.Shell
expectedOutput string
expectedError string
Loading
Loading
@@ -154,6 +164,48 @@ func TestExecute(t *testing.T) {
},
expectedError: "who='' is invalid",
},
{
desc: "With restricted scopes",
PATConfig: config.PATConfig{AllowedScopes: []string{"read_api"}},
arguments: &commandargs.Shell{
GitlabKeyId: "default",
SshArgs: []string{cmdname, "newtoken", "read_api,read_repository"},
},
expectedOutput: "Token: YXuxvUgCEmeePY3G1YAa\n" +
"Scopes: read_api\n" +
"Expires: 9001-11-17\n",
},
{
desc: "With unknown configured scopes",
PATConfig: config.PATConfig{AllowedScopes: []string{"read_reposotory"}},
arguments: &commandargs.Shell{
GitlabKeyId: "default",
SshArgs: []string{cmdname, "newtoken", "read_api,read_repository"},
},
expectedOutput: "Token: YXuxvUgCEmeePY3G1YAa\n" +
"Scopes: \n" +
"Expires: 9001-11-17\n",
},
{
desc: "With unknown requested scopes",
PATConfig: config.PATConfig{AllowedScopes: []string{"read_api", "read_repository"}},
arguments: &commandargs.Shell{
GitlabKeyId: "default",
SshArgs: []string{cmdname, "newtoken", "read_api,read_reposotory"},
},
expectedOutput: "Token: YXuxvUgCEmeePY3G1YAa\n" +
"Scopes: read_api\n" +
"Expires: 9001-11-17\n",
},
{
desc: "With matching unknown requested scopes",
PATConfig: config.PATConfig{AllowedScopes: []string{"read_api", "read_reposotory"}},
arguments: &commandargs.Shell{
GitlabKeyId: "invalidscope",
SshArgs: []string{cmdname, "newtoken", "read_reposotory"},
},
expectedError: "Invalid scope: 'read_reposotory'. Valid scopes are: [\"api\", \"create_runner\", \"k8s_proxy\", \"read_api\", \"read_registry\", \"read_repository\", \"read_user\", \"write_registry\", \"write_repository\"]",
},
}
for _, tc := range testCases {
Loading
Loading
@@ -162,7 +214,7 @@ func TestExecute(t *testing.T) {
input := bytes.NewBufferString("")
cmd := &Command{
Config: &config.Config{GitlabUrl: url},
Config: &config.Config{GitlabUrl: url, PATConfig: tc.PATConfig},
Args: tc.arguments,
ReadWriter: &readwriter.ReadWriter{Out: output, In: input},
}
Loading
Loading
Loading
Loading
@@ -65,6 +65,11 @@ type LFSConfig struct {
PureSSHProtocol bool // `yaml:"pure_ssh_protocol"`
}
type PATConfig struct {
Enabled bool `yaml:"enabled,omitempty"`
AllowedScopes []string `yaml:"allowed_scopes,omitempty"`
}
type Config struct {
User string `yaml:"user,omitempty"`
RootDir string
Loading
Loading
@@ -81,6 +86,7 @@ type Config struct {
HttpSettings HttpSettingsConfig `yaml:"http_settings"`
Server ServerConfig `yaml:"sshd"`
LFSConfig LFSConfig `yaml:"lfs"`
PATConfig PATConfig `yaml:"pat"`
httpClient *client.HTTPClient
httpClientErr error
Loading
Loading
@@ -97,6 +103,7 @@ var (
LogLevel: "info",
Server: DefaultServerConfig,
User: "git",
PATConfig: DefaultPATConfig,
}
DefaultServerConfig = ServerConfig{
Loading
Loading
@@ -115,6 +122,10 @@ var (
"/run/secrets/ssh-hostkeys/ssh_host_ed25519_key",
},
}
DefaultPATConfig = PATConfig{
Enabled: true,
}
)
func (d *YamlDuration) UnmarshalYAML(unmarshal func(interface{}) error) error {
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment