diff options
author | Patrick Bajao <ebajao@gitlab.com> | 2021-05-18 07:18:15 +0000 |
---|---|---|
committer | Patrick Bajao <ebajao@gitlab.com> | 2021-05-18 07:18:15 +0000 |
commit | 792ff51ca4bcf11d8759ccadff5f8e9f2f876349 (patch) | |
tree | 78ce513357f4719a83e5472b5dccb37edd3f23d5 | |
parent | bc93a437b6cabb64360edfa698dacb4cc3ef02fe (diff) | |
parent | 6851d9f6d6ffa8a3f9d11267a03d99474fd1048a (diff) | |
download | gitlab-shell-792ff51ca4bcf11d8759ccadff5f8e9f2f876349.tar.gz |
Merge branch 'acceptance-tests-simple' into 'main'
Acceptance tests for 2fa_recovery_codes, 2fa_verify, and git-lfs-authenticate
See merge request gitlab-org/gitlab-shell!472
-rw-r--r-- | cmd/gitlab-sshd/acceptance_test.go | 104 | ||||
-rw-r--r-- | internal/testhelper/testdata/testroot/responses/allowed_without_console_messages.json | 22 |
2 files changed, 126 insertions, 0 deletions
diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go index 02d8200..112247b 100644 --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -21,6 +21,7 @@ import ( "github.com/mikesmitty/edkey" "github.com/pires/go-proxyproto" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" "golang.org/x/crypto/ssh" ) @@ -50,6 +51,10 @@ func successAPI(t *testing.T) http.Handler { t.Helper() return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + testDirCleanup, err := testhelper.PrepareTestRootDir() + require.NoError(t, err) + defer testDirCleanup() + t.Logf("gitlab-api-mock: received request: %s %s", r.Method, r.RequestURI) w.Header().Set("Content-Type", "application/json") @@ -60,6 +65,18 @@ func successAPI(t *testing.T) http.Handler { fmt.Fprint(w, `{"id": 1000, "name": "Test User", "username": "test-user"}`) case "/api/v4/internal/personal_access_token": fmt.Fprint(w, `{"success": true, "token": "testtoken", "scopes": ["api"], "expires_at": ""}`) + case "/api/v4/internal/two_factor_recovery_codes": + fmt.Fprint(w, `{"success": true, "recovery_codes": ["code1", "code2"]}`) + case "/api/v4/internal/two_factor_otp_check": + fmt.Fprint(w, `{"success": true}`) + case "/api/v4/internal/allowed": + body, err := ioutil.ReadFile(filepath.Join(testhelper.TestRoot, "responses/allowed_without_console_messages.json")) + require.NoError(t, err) + + _, err = w.Write(body) + require.NoError(t, err) + case "/api/v4/internal/lfs_authenticate": + fmt.Fprint(w, `{"username": "test-user", "lfs_token": "testlfstoken", "repo_path": "foo", "expires_in": 7200}`) default: t.Logf("Unexpected request to successAPI: %s", r.URL.EscapedPath()) t.FailNow() @@ -231,3 +248,90 @@ func TestPersonalAccessTokenSuccess(t *testing.T) { require.NoError(t, err) require.Equal(t, "Token: testtoken\nScopes: api\nExpires: never\n", string(output)) } + +func TestTwoFactorAuthRecoveryCodesSuccess(t *testing.T) { + client := runSSHD(t, successAPI(t)) + + session, err := client.NewSession() + require.NoError(t, err) + defer session.Close() + + stdin, err := session.StdinPipe() + require.NoError(t, err) + + stdout, err := session.StdoutPipe() + require.NoError(t, err) + + reader := bufio.NewReader(stdout) + + err = session.Start("2fa_recovery_codes") + require.NoError(t, err) + + line, err := reader.ReadString('\n') + require.NoError(t, err) + require.Equal(t, "Are you sure you want to generate new two-factor recovery codes?\n", line) + + line, err = reader.ReadString('\n') + require.NoError(t, err) + require.Equal(t, "Any existing recovery codes you saved will be invalidated. (yes/no)\n", line) + + _, err = fmt.Fprintln(stdin, "yes") + require.NoError(t, err) + + output, err := ioutil.ReadAll(stdout) + require.NoError(t, err) + require.Equal(t, ` +Your two-factor authentication recovery codes are: + +code1 +code2 + +During sign in, use one of the codes above when prompted for +your two-factor code. Then, visit your Profile Settings and add +a new device so you do not lose access to your account again. +`, string(output)) +} + +func TwoFactorAuthVerifySuccess(t *testing.T) { + client := runSSHD(t, successAPI(t)) + + session, err := client.NewSession() + require.NoError(t, err) + defer session.Close() + + stdin, err := session.StdinPipe() + require.NoError(t, err) + + stdout, err := session.StdoutPipe() + require.NoError(t, err) + + reader := bufio.NewReader(stdout) + + err = session.Start("2fa_verify") + require.NoError(t, err) + + line, err := reader.ReadString('\n') + require.NoError(t, err) + require.Equal(t, "OTP: ", line) + + _, err = fmt.Fprintln(stdin, "otp123") + require.NoError(t, err) + + output, err := ioutil.ReadAll(stdout) + require.NoError(t, err) + require.Equal(t, "OTP validation successful. Git operations are now allowed.\n", string(output)) +} + +func TestGitLfsAuthenticateSuccess(t *testing.T) { + client := runSSHD(t, successAPI(t)) + + session, err := client.NewSession() + require.NoError(t, err) + defer session.Close() + + output, err := session.Output("git-lfs-authenticate test-user/repo.git download") + + require.NoError(t, err) + require.Equal(t, `{"header":{"Authorization":"Basic dGVzdC11c2VyOnRlc3RsZnN0b2tlbg=="},"href":"/info/lfs","expires_in":7200} +`, string(output)) +} diff --git a/internal/testhelper/testdata/testroot/responses/allowed_without_console_messages.json b/internal/testhelper/testdata/testroot/responses/allowed_without_console_messages.json new file mode 100644 index 0000000..c28ea71 --- /dev/null +++ b/internal/testhelper/testdata/testroot/responses/allowed_without_console_messages.json @@ -0,0 +1,22 @@ +{ + "status": true, + "gl_repository": "project-26", + "gl_project_path": "group/private", + "gl_id": "user-1", + "gl_username": "root", + "git_config_options": ["option"], + "gitaly": { + "repository": { + "storage_name": "default", + "relative_path": "@hashed/5f/9c/5f9c4ab08cac7457e9111a30e4664920607ea2c115a1433d7be98e97e64244ca.git", + "git_object_directory": "path/to/git_object_directory", + "git_alternate_object_directories": ["path/to/git_alternate_object_directory"], + "gl_repository": "project-26", + "gl_project_path": "group/private" + }, + "address": "unix:gitaly.socket", + "token": "token" + }, + "git_protocol": "protocol", + "gl_console_messages": [] +} |