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

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • idrozdov/gitlab-shell
  • mmj/gitlab-shell
2 results
Show changes
Commits on Source (129)
Showing
with 181 additions and 99 deletions
Loading
@@ -3,7 +3,6 @@ include:
Loading
@@ -3,7 +3,6 @@ include:
- template: Security/SAST.gitlab-ci.yml - template: Security/SAST.gitlab-ci.yml
- template: Security/Dependency-Scanning.gitlab-ci.yml - template: Security/Dependency-Scanning.gitlab-ci.yml
- template: Security/Secret-Detection.gitlab-ci.yml - template: Security/Secret-Detection.gitlab-ci.yml
- component: ${CI_SERVER_FQDN}/gitlab-org/components/danger-review/danger-review@1.4.1
stages: stages:
- prepare - prepare
Loading
@@ -16,16 +15,16 @@ variables:
Loading
@@ -16,16 +15,16 @@ variables:
TRANSFER_METER_FREQUENCY: "1s" TRANSFER_METER_FREQUENCY: "1s"
DOCKER_VERSION: "20.10.15" DOCKER_VERSION: "20.10.15"
BUNDLE_FROZEN: "true" BUNDLE_FROZEN: "true"
GO_VERSION: "golang-1.22" GO_VERSION: "1.23"
GOPATH: $CI_PROJECT_DIR/.GOPATH GOPATH: $CI_PROJECT_DIR/.GOPATH
DEBIAN_VERSION: "bookworm" DEBIAN_VERSION: "bookworm"
RUBY_VERSION: "3.2.4" RUBY_VERSION: "3.2.5"
BUNDLE_PATH: vendor/ruby BUNDLE_PATH: vendor/ruby
POLICY: pull POLICY: pull
CI_DEBUG_SERVICES: 'true' CI_DEBUG_SERVICES: 'true'
RUST_VERSION: "rust-1.73" RUST_VERSION: "1.73"
UBI_VERSION: "8.6" UBI_VERSION: "8.6"
IMAGE_TAG: "rubygems-3.4-git-2.36-exiftool-12.60" IMAGE_TAG: "rubygems-3.5-git-2.45-exiftool-12.60"
GITLAB_ADVANCED_SAST_ENABLED: 'true' GITLAB_ADVANCED_SAST_ENABLED: 'true'
workflow: workflow:
Loading
@@ -37,8 +36,15 @@ workflow:
Loading
@@ -37,8 +36,15 @@ workflow:
# For tags, create a pipeline. # For tags, create a pipeline.
- if: '$CI_COMMIT_TAG' - if: '$CI_COMMIT_TAG'
.rules:go-changes:
rules:
- changes:
- 'go.mod'
- 'go.sum'
- '**/*.go'
default: default:
image: registry.gitlab.com/gitlab-org/gitlab-build-images/debian-${DEBIAN_VERSION}-ruby-${RUBY_VERSION}-${GO_VERSION}-${RUST_VERSION}:${IMAGE_TAG} image: registry.gitlab.com/gitlab-org/gitlab-build-images/debian-${DEBIAN_VERSION}-ruby-${RUBY_VERSION}-golang-${GO_VERSION}-rust-${RUST_VERSION}:${IMAGE_TAG}
tags: tags:
- gitlab-org - gitlab-org
Loading
@@ -52,7 +58,7 @@ default:
Loading
@@ -52,7 +58,7 @@ default:
.cached-go: &cached_go .cached-go: &cached_go
- key: - key:
prefix: $GO_VERSION-cache prefix: "golang-${GO_VERSION}-cache"
files: files:
- go.mod - go.mod
- go.sum - go.sum
Loading
@@ -87,7 +93,7 @@ default:
Loading
@@ -87,7 +93,7 @@ default:
.go-matrix-job: .go-matrix-job:
parallel: parallel:
matrix: matrix:
- GO_VERSION: ["golang-1.21", "golang-1.22"] - GO_VERSION: ["1.22", "1.23"]
################################################################################ ################################################################################
# Prepare jobs # Prepare jobs
Loading
@@ -117,6 +123,7 @@ modules:download:
Loading
@@ -117,6 +123,7 @@ modules:download:
.test-job: .test-job:
needs: ['bundle:install', 'modules:download'] needs: ['bundle:install', 'modules:download']
rules: !reference [".rules:go-changes", rules]
variables: variables:
GITALY_CONNECTION_INFO: '{"address":"tcp://gitaly:8075", "storage":"default"}' GITALY_CONNECTION_INFO: '{"address":"tcp://gitaly:8075", "storage":"default"}'
before_script: before_script:
Loading
@@ -159,7 +166,7 @@ tests_without_cgo:
Loading
@@ -159,7 +166,7 @@ tests_without_cgo:
- make verify test_fancy - make verify test_fancy
tests:fips: tests:fips:
image: registry.gitlab.com/gitlab-org/gitlab-build-images/ubi-${UBI_VERSION}-ruby-${RUBY_VERSION}-${GO_VERSION}-${RUST_VERSION}:${IMAGE_TAG} image: registry.gitlab.com/gitlab-org/gitlab-build-images/ubi-${UBI_VERSION}-ruby-${RUBY_VERSION}-golang-${GO_VERSION}-rust-${RUST_VERSION}:${IMAGE_TAG}
extends: extends:
- .cached-job - .cached-job
- .test-job - .test-job
Loading
@@ -267,6 +274,7 @@ lint:
Loading
@@ -267,6 +274,7 @@ lint:
nilaway: nilaway:
stage: lint stage: lint
rules: !reference [".rules:go-changes", rules]
before_script: before_script:
- go install go.uber.org/nilaway/cmd/nilaway@latest - go install go.uber.org/nilaway/cmd/nilaway@latest
script: script:
Loading
Loading
Loading
@@ -61,6 +61,8 @@ output:
Loading
@@ -61,6 +61,8 @@ output:
# print linter name in the end of issue text, default is true # print linter name in the end of issue text, default is true
print-linter-name: true print-linter-name: true
sort-results: true
# all available settings of specific linters # all available settings of specific linters
linters-settings: linters-settings:
errcheck: errcheck:
Loading
@@ -262,11 +264,11 @@ linters:
Loading
@@ -262,11 +264,11 @@ linters:
disable-all: true disable-all: true
enable: enable:
- bodyclose - bodyclose
- copyloopvar
- depguard - depguard
- dogsled - dogsled
- dupl - dupl
- errcheck - errcheck
- exportloopref
- funlen - funlen
- gocognit - gocognit
- goconst - goconst
Loading
Loading
ruby 3.3.4 ruby 3.3.5
golang 1.23.0 golang 1.23.2
Loading
@@ -2,7 +2,7 @@ source 'https://rubygems.org'
Loading
@@ -2,7 +2,7 @@ source 'https://rubygems.org'
group :development, :test do group :development, :test do
gem 'rspec', '~> 3.13.0' gem 'rspec', '~> 3.13.0'
gem 'webrick', '~> 1.8', '>= 1.8.1' gem 'webrick', '~> 1.8', '>= 1.8.2'
end end
group :development, :danger do group :development, :danger do
Loading
Loading
Loading
@@ -91,7 +91,7 @@ GEM
Loading
@@ -91,7 +91,7 @@ GEM
unicode-display_width (>= 1.1.1, < 3) unicode-display_width (>= 1.1.1, < 3)
unicode-display_width (2.5.0) unicode-display_width (2.5.0)
uri (0.13.0) uri (0.13.0)
webrick (1.8.1) webrick (1.8.2)
PLATFORMS PLATFORMS
ruby ruby
Loading
@@ -99,7 +99,7 @@ PLATFORMS
Loading
@@ -99,7 +99,7 @@ PLATFORMS
DEPENDENCIES DEPENDENCIES
gitlab-dangerfiles (~> 4.8.0) gitlab-dangerfiles (~> 4.8.0)
rspec (~> 3.13.0) rspec (~> 3.13.0)
webrick (~> 1.8, >= 1.8.1) webrick (~> 1.8, >= 1.8.2)
BUNDLED WITH BUNDLED WITH
2.5.11 2.5.11
Loading
@@ -9,10 +9,10 @@ GO_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver
Loading
@@ -9,10 +9,10 @@ GO_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver
ARCH ?= $(shell uname -m | sed -e 's/x86_64/amd64/' | sed -e 's/aarch64/arm64/') ARCH ?= $(shell uname -m | sed -e 's/x86_64/amd64/' | sed -e 's/aarch64/arm64/')
GOTESTSUM_VERSION := 1.11.0 GOTESTSUM_VERSION := 1.12.0
GOTESTSUM_FILE := support/bin/gotestsum-${GOTESTSUM_VERSION} GOTESTSUM_FILE := support/bin/gotestsum-${GOTESTSUM_VERSION}
GOLANGCI_LINT_VERSION := 1.60.1 GOLANGCI_LINT_VERSION := 1.60.3
GOLANGCI_LINT_FILE := support/bin/golangci-lint-${GOLANGCI_LINT_VERSION} GOLANGCI_LINT_FILE := support/bin/golangci-lint-${GOLANGCI_LINT_VERSION}
export GOFLAGS := -mod=readonly export GOFLAGS := -mod=readonly
Loading
@@ -86,13 +86,15 @@ coverage: coverage_golang
Loading
@@ -86,13 +86,15 @@ coverage: coverage_golang
coverage_golang: coverage_golang:
[ -f cover.out ] && go tool cover -func cover.out [ -f cover.out ] && go tool cover -func cover.out
lint: ${GOLANGCI_LINT_FILE} lint:
${GOLANGCI_LINT_FILE} --version @support/lint.sh ./...
${GOLANGCI_LINT_FILE} run --issues-exit-code 0 --print-issued-lines=false ${GOLANGCI_LINT_ARGS}
golangci: ${GOLANGCI_LINT_FILE}
@${GOLANGCI_LINT_FILE} run --issues-exit-code 0 --print-issued-lines=false ${GOLANGCI_LINT_ARGS}
${GOLANGCI_LINT_FILE}: ${GOLANGCI_LINT_FILE}:
mkdir -p $(shell dirname ${GOLANGCI_LINT_FILE}) @mkdir -p $(shell dirname ${GOLANGCI_LINT_FILE})
curl -L https://github.com/golangci/golangci-lint/releases/download/v${GOLANGCI_LINT_VERSION}/golangci-lint-${GOLANGCI_LINT_VERSION}-${OS}-${ARCH}.tar.gz | tar --strip-components 1 -zOxf - golangci-lint-${GOLANGCI_LINT_VERSION}-${OS}-${ARCH}/golangci-lint > ${GOLANGCI_LINT_FILE} && chmod +x ${GOLANGCI_LINT_FILE} @curl -L https://github.com/golangci/golangci-lint/releases/download/v${GOLANGCI_LINT_VERSION}/golangci-lint-${GOLANGCI_LINT_VERSION}-${OS}-${ARCH}.tar.gz | tar --strip-components 1 -zOxf - golangci-lint-${GOLANGCI_LINT_VERSION}-${OS}-${ARCH}/golangci-lint > ${GOLANGCI_LINT_FILE} && chmod +x ${GOLANGCI_LINT_FILE}
setup: make_necessary_dirs bin/gitlab-shell setup: make_necessary_dirs bin/gitlab-shell
Loading
Loading
Loading
@@ -4,10 +4,48 @@ group: Source Code
Loading
@@ -4,10 +4,48 @@ group: Source Code
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
--- ---
# GitLab Shell documentation has moved
[![pipeline status](https://gitlab.com/gitlab-org/gitlab-shell/badges/main/pipeline.svg)](https://gitlab.com/gitlab-org/gitlab-shell/-/pipelines?ref=main) [![pipeline status](https://gitlab.com/gitlab-org/gitlab-shell/badges/main/pipeline.svg)](https://gitlab.com/gitlab-org/gitlab-shell/-/pipelines?ref=main)
[![coverage report](https://gitlab.com/gitlab-org/gitlab-shell/badges/main/coverage.svg)](https://gitlab.com/gitlab-org/gitlab-shell/-/pipelines?ref=main) [![coverage report](https://gitlab.com/gitlab-org/gitlab-shell/badges/main/coverage.svg)](https://gitlab.com/gitlab-org/gitlab-shell/-/pipelines?ref=main)
[![Code Climate](https://codeclimate.com/github/gitlabhq/gitlab-shell.svg)](https://codeclimate.com/github/gitlabhq/gitlab-shell) [![Code Climate](https://codeclimate.com/github/gitlabhq/gitlab-shell.svg)](https://codeclimate.com/github/gitlabhq/gitlab-shell)
The documentation for GitLab Shell [has moved into the `gitlab` repository](https://docs.gitlab.com/ee/development/gitlab_shell/). # GitLab Shell
GitLab Shell handles Git SSH sessions for GitLab and modifies the list of
authorized keys. GitLab Shell is not a Unix shell nor a replacement for Bash or Zsh.
GitLab supports Git LFS authentication through SSH.
## Development Documentation
Development documentation for GitLab Shell [has moved into the `gitlab` repository](https://docs.gitlab.com/ee/development/gitlab_shell/).
## Project structure
| Directory | Description |
|-----------|-------------|
| `cmd/` | 'Commands' that will ultimately be compiled into binaries. |
| `internal/` | Internal Go source code that is not intended to be used outside of the project/module. |
| `client/` | HTTP and GitLab client logic that is used internally and by other modules, e.g. Gitaly. |
| `bin/` | Compiled binaries are created here. |
| `support/` | Scripts and tools that assist in development and/or testing. |
| `spec/` | Ruby based integration tests. |
## Building
Run `make` or `make build`.
## Testing
Run `make test`.
## Release Process
1. Create a `gitlab-org/gitlab-shell` MR to update [`VERSION`](https://gitlab.com/gitlab-org/gitlab-shell/-/blob/main/VERSION) and [`CHANGELOG`](https://gitlab.com/gitlab-org/gitlab-shell/-/blob/main/CHANGELOG) files, e.g. [Release v14.39.0](https://gitlab.com/gitlab-org/gitlab-shell/-/merge_requests/1123).
2. Once `gitlab-org/gitlab-shell` MR is merged, create the corresponding git tag, e.g. https://gitlab.com/gitlab-org/gitlab-shell/-/tags/v14.39.0.
3. Create a `gitlab-org/gitlab` MR to update [`GITLAB_SHELL_VERSION`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/GITLAB_SHELL_VERSION) to the proposed tag, e.g. [Bump GitLab Shell to 14.39.0](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/162661).
4. Announce in `#gitlab-shell` a new version has been created.
## Licensing
See the `LICENSE` file for licensing information as it pertains to files in
this repository.
Loading
@@ -13,6 +13,7 @@ import (
Loading
@@ -13,6 +13,7 @@ import (
"time" "time"
"github.com/golang-jwt/jwt/v5" "github.com/golang-jwt/jwt/v5"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver"
Loading
@@ -36,31 +37,31 @@ func TestClients(t *testing.T) {
Loading
@@ -36,31 +37,31 @@ func TestClients(t *testing.T) {
}{ }{
{ {
desc: "Socket client", desc: "Socket client",
server: testserver.StartSocketHttpServer, server: testserver.StartSocketHTTPServer,
secret: secret, secret: secret,
}, },
{ {
desc: "Socket client with a relative URL at /", desc: "Socket client with a relative URL at /",
relativeURLRoot: "/", relativeURLRoot: "/",
server: testserver.StartSocketHttpServer, server: testserver.StartSocketHTTPServer,
secret: secret, secret: secret,
}, },
{ {
desc: "Socket client with relative URL at /gitlab", desc: "Socket client with relative URL at /gitlab",
relativeURLRoot: "/gitlab", relativeURLRoot: "/gitlab",
server: testserver.StartSocketHttpServer, server: testserver.StartSocketHTTPServer,
secret: secret, secret: secret,
}, },
{ {
desc: "Http client", desc: "Http client",
server: testserver.StartHttpServer, server: testserver.StartHTTPServer,
secret: secret, secret: secret,
}, },
{ {
desc: "Https client", desc: "Https client",
caFile: path.Join(testRoot, "certs/valid/server.crt"), caFile: path.Join(testRoot, "certs/valid/server.crt"),
server: func(t *testing.T, handlers []testserver.TestRequestHandler) string { server: func(t *testing.T, handlers []testserver.TestRequestHandler) string {
return testserver.StartHttpsServer(t, handlers, "") return testserver.StartHTTPSServer(t, handlers, "")
}, },
secret: secret, secret: secret,
}, },
Loading
@@ -68,13 +69,13 @@ func TestClients(t *testing.T) {
Loading
@@ -68,13 +69,13 @@ func TestClients(t *testing.T) {
desc: "Secret with newlines", desc: "Secret with newlines",
caFile: path.Join(testRoot, "certs/valid/server.crt"), caFile: path.Join(testRoot, "certs/valid/server.crt"),
server: func(t *testing.T, handlers []testserver.TestRequestHandler) string { server: func(t *testing.T, handlers []testserver.TestRequestHandler) string {
return testserver.StartHttpsServer(t, handlers, "") return testserver.StartHTTPSServer(t, handlers, "")
}, },
secret: "\n" + secret + "\n", secret: "\n" + secret + "\n",
}, },
{ {
desc: "Retry client", desc: "Retry client",
server: testserver.StartRetryHttpServer, server: testserver.StartRetryHTTPServer,
secret: secret, secret: secret,
}, },
} }
Loading
@@ -240,7 +241,7 @@ func buildRequests(t *testing.T, relativeURLRoot string) []testserver.TestReques
Loading
@@ -240,7 +241,7 @@ func buildRequests(t *testing.T, relativeURLRoot string) []testserver.TestReques
{ {
Path: "/api/v4/internal/hello", Path: "/api/v4/internal/hello",
Handler: func(w http.ResponseWriter, r *http.Request) { Handler: func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, http.MethodGet, r.Method) assert.Equal(t, http.MethodGet, r.Method)
fmt.Fprint(w, "Hello") fmt.Fprint(w, "Hello")
}, },
Loading
@@ -248,12 +249,12 @@ func buildRequests(t *testing.T, relativeURLRoot string) []testserver.TestReques
Loading
@@ -248,12 +249,12 @@ func buildRequests(t *testing.T, relativeURLRoot string) []testserver.TestReques
{ {
Path: "/api/v4/internal/post_endpoint", Path: "/api/v4/internal/post_endpoint",
Handler: func(w http.ResponseWriter, r *http.Request) { Handler: func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, http.MethodPost, r.Method) assert.Equal(t, http.MethodPost, r.Method)
b, err := io.ReadAll(r.Body) b, err := io.ReadAll(r.Body)
defer r.Body.Close() defer r.Body.Close()
require.NoError(t, err) assert.NoError(t, err)
fmt.Fprint(w, "Echo: "+string(b)) fmt.Fprint(w, "Echo: "+string(b))
}, },
Loading
Loading
Loading
@@ -10,6 +10,7 @@ import (
Loading
@@ -10,6 +10,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver"
) )
Loading
@@ -34,7 +35,7 @@ func TestBasicAuthSettings(t *testing.T) {
Loading
@@ -34,7 +35,7 @@ func TestBasicAuthSettings(t *testing.T) {
{ {
Path: "/api/v4/internal/get_endpoint", Path: "/api/v4/internal/get_endpoint",
Handler: func(w http.ResponseWriter, r *http.Request) { Handler: func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, http.MethodGet, r.Method) assert.Equal(t, http.MethodGet, r.Method)
fmt.Fprint(w, r.Header.Get("Authorization")) fmt.Fprint(w, r.Header.Get("Authorization"))
}, },
Loading
@@ -42,7 +43,7 @@ func TestBasicAuthSettings(t *testing.T) {
Loading
@@ -42,7 +43,7 @@ func TestBasicAuthSettings(t *testing.T) {
{ {
Path: "/api/v4/internal/post_endpoint", Path: "/api/v4/internal/post_endpoint",
Handler: func(w http.ResponseWriter, r *http.Request) { Handler: func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, http.MethodPost, r.Method) assert.Equal(t, http.MethodPost, r.Method)
fmt.Fprint(w, r.Header.Get("Authorization")) fmt.Fprint(w, r.Header.Get("Authorization"))
}, },
Loading
@@ -82,7 +83,7 @@ func TestEmptyBasicAuthSettings(t *testing.T) {
Loading
@@ -82,7 +83,7 @@ func TestEmptyBasicAuthSettings(t *testing.T) {
{ {
Path: "/api/v4/internal/empty_basic_auth", Path: "/api/v4/internal/empty_basic_auth",
Handler: func(_ http.ResponseWriter, r *http.Request) { Handler: func(_ http.ResponseWriter, r *http.Request) {
require.Equal(t, "", r.Header.Get("Authorization")) assert.Equal(t, "", r.Header.Get("Authorization"))
}, },
}, },
} }
Loading
@@ -100,13 +101,13 @@ func TestRequestWithUserAgent(t *testing.T) {
Loading
@@ -100,13 +101,13 @@ func TestRequestWithUserAgent(t *testing.T) {
{ {
Path: "/api/v4/internal/default_user_agent", Path: "/api/v4/internal/default_user_agent",
Handler: func(_ http.ResponseWriter, r *http.Request) { Handler: func(_ http.ResponseWriter, r *http.Request) {
require.Equal(t, defaultUserAgent, r.UserAgent()) assert.Equal(t, defaultUserAgent, r.UserAgent())
}, },
}, },
{ {
Path: "/api/v4/internal/override_user_agent", Path: "/api/v4/internal/override_user_agent",
Handler: func(_ http.ResponseWriter, r *http.Request) { Handler: func(_ http.ResponseWriter, r *http.Request) {
require.Equal(t, gitalyUserAgent, r.UserAgent()) assert.Equal(t, gitalyUserAgent, r.UserAgent())
}, },
}, },
} }
Loading
@@ -125,7 +126,7 @@ func TestRequestWithUserAgent(t *testing.T) {
Loading
@@ -125,7 +126,7 @@ func TestRequestWithUserAgent(t *testing.T) {
} }
func setup(t *testing.T, username, password string, requests []testserver.TestRequestHandler) *GitlabNetClient { func setup(t *testing.T, username, password string, requests []testserver.TestRequestHandler) *GitlabNetClient {
url := testserver.StartHttpServer(t, requests) url := testserver.StartHTTPServer(t, requests)
httpClient, err := NewHTTPClientWithOpts(url, "", "", "", 1, nil) httpClient, err := NewHTTPClientWithOpts(url, "", "", "", 1, nil)
require.NoError(t, err) require.NoError(t, err)
Loading
Loading
Loading
@@ -8,6 +8,7 @@ import (
Loading
@@ -8,6 +8,7 @@ import (
"path" "path"
"testing" "testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper"
Loading
@@ -116,14 +117,14 @@ func setupWithRequests(t *testing.T, caFile, caPath, clientCAPath, clientCertPat
Loading
@@ -116,14 +117,14 @@ func setupWithRequests(t *testing.T, caFile, caPath, clientCAPath, clientCertPat
{ {
Path: "/api/v4/internal/hello", Path: "/api/v4/internal/hello",
Handler: func(w http.ResponseWriter, r *http.Request) { Handler: func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, http.MethodGet, r.Method) assert.Equal(t, http.MethodGet, r.Method)
fmt.Fprint(w, "Hello") fmt.Fprint(w, "Hello")
}, },
}, },
} }
url := testserver.StartHttpsServer(t, requests, clientCAPath) url := testserver.StartHTTPSServer(t, requests, clientCAPath)
opts := defaultHttpOpts opts := defaultHttpOpts
if clientCertPath != "" && clientKeyPath != "" { if clientCertPath != "" && clientKeyPath != "" {
Loading
Loading
Loading
@@ -22,7 +22,8 @@ type TestRequestHandler struct {
Loading
@@ -22,7 +22,8 @@ type TestRequestHandler struct {
Handler func(w http.ResponseWriter, r *http.Request) Handler func(w http.ResponseWriter, r *http.Request)
} }
func StartSocketHttpServer(t *testing.T, handlers []TestRequestHandler) string { // StartSocketHTTPServer starts a socket based HTTP server
func StartSocketHTTPServer(t *testing.T, handlers []TestRequestHandler) string {
t.Helper() t.Helper()
// We can't use t.TempDir() here because it will create a directory that // We can't use t.TempDir() here because it will create a directory that
Loading
@@ -55,7 +56,8 @@ func StartSocketHttpServer(t *testing.T, handlers []TestRequestHandler) string {
Loading
@@ -55,7 +56,8 @@ func StartSocketHttpServer(t *testing.T, handlers []TestRequestHandler) string {
return url return url
} }
func StartHttpServer(t *testing.T, handlers []TestRequestHandler) string { // StartHTTPServer starts a TCP based HTTP server
func StartHTTPServer(t *testing.T, handlers []TestRequestHandler) string {
t.Helper() t.Helper()
server := httptest.NewServer(buildHandler(handlers)) server := httptest.NewServer(buildHandler(handlers))
Loading
@@ -64,7 +66,8 @@ func StartHttpServer(t *testing.T, handlers []TestRequestHandler) string {
Loading
@@ -64,7 +66,8 @@ func StartHttpServer(t *testing.T, handlers []TestRequestHandler) string {
return server.URL return server.URL
} }
func StartRetryHttpServer(t *testing.T, handlers []TestRequestHandler) string { // StartRetryHTTPServer starts a TCP based HTTP server with retry capabilities
func StartRetryHTTPServer(t *testing.T, handlers []TestRequestHandler) string {
attempts := map[string]int{} attempts := map[string]int{}
retryMiddileware := func(next func(w http.ResponseWriter, r *http.Request)) http.Handler { retryMiddileware := func(next func(w http.ResponseWriter, r *http.Request)) http.Handler {
Loading
@@ -92,7 +95,8 @@ func StartRetryHttpServer(t *testing.T, handlers []TestRequestHandler) string {
Loading
@@ -92,7 +95,8 @@ func StartRetryHttpServer(t *testing.T, handlers []TestRequestHandler) string {
return server.URL return server.URL
} }
func StartHttpsServer(t *testing.T, handlers []TestRequestHandler, clientCAPath string) string { // StartHTTPSServer starts a TCP based HTTPS capable server
func StartHTTPSServer(t *testing.T, handlers []TestRequestHandler, clientCAPath string) string {
t.Helper() t.Helper()
testRoot := testhelper.PrepareTestRootDir(t) testRoot := testhelper.PrepareTestRootDir(t)
Loading
Loading
// Package client provides an HTTP client with enhanced logging, tracing, and correlation handling.
package client package client
import ( import (
Loading
@@ -13,6 +14,7 @@ type transport struct {
Loading
@@ -13,6 +14,7 @@ type transport struct {
next http.RoundTripper next http.RoundTripper
} }
// RoundTrip executes a single HTTP transaction, adding logging and tracing capabilities.
func (rt *transport) RoundTrip(request *http.Request) (*http.Response, error) { func (rt *transport) RoundTrip(request *http.Request) (*http.Response, error) {
ctx := request.Context() ctx := request.Context()
Loading
@@ -55,10 +57,12 @@ func (rt *transport) RoundTrip(request *http.Request) (*http.Response, error) {
Loading
@@ -55,10 +57,12 @@ func (rt *transport) RoundTrip(request *http.Request) (*http.Response, error) {
return response, nil return response, nil
} }
// DefaultTransport returns a clone of the default HTTP transport.
func DefaultTransport() http.RoundTripper { func DefaultTransport() http.RoundTripper {
return http.DefaultTransport.(*http.Transport).Clone() return http.DefaultTransport.(*http.Transport).Clone()
} }
// NewTransport creates a new transport with logging, tracing, and correlation handling.
func NewTransport(next http.RoundTripper) http.RoundTripper { func NewTransport(next http.RoundTripper) http.RoundTripper {
t := &transport{next: next} t := &transport{next: next}
return correlation.NewInstrumentedRoundTripper(tracing.NewRoundTripper(t)) return correlation.NewInstrumentedRoundTripper(tracing.NewRoundTripper(t))
Loading
Loading
// Package command handles command creation and initialization in GitLab Shell.
package command package command
import ( import (
Loading
@@ -9,6 +10,7 @@ import (
Loading
@@ -9,6 +10,7 @@ import (
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config"
) )
// New creates a new command based on provided arguments, config, and I/O.
func New(arguments []string, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { func New(arguments []string, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) {
args, err := Parse(arguments) args, err := Parse(arguments)
if err != nil { if err != nil {
Loading
@@ -22,6 +24,7 @@ func New(arguments []string, config *config.Config, readWriter *readwriter.ReadW
Loading
@@ -22,6 +24,7 @@ func New(arguments []string, config *config.Config, readWriter *readwriter.ReadW
return nil, disallowedcommand.Error return nil, disallowedcommand.Error
} }
// Parse parses command-line arguments into a CommandArgs structure.
func Parse(arguments []string) (*commandargs.AuthorizedPrincipals, error) { func Parse(arguments []string) (*commandargs.AuthorizedPrincipals, error) {
args := &commandargs.AuthorizedPrincipals{Arguments: arguments} args := &commandargs.AuthorizedPrincipals{Arguments: arguments}
Loading
Loading
Loading
@@ -58,7 +58,7 @@ func TestParseSuccess(t *testing.T) {
Loading
@@ -58,7 +58,7 @@ func TestParseSuccess(t *testing.T) {
desc: "It parses authorized-principals command", desc: "It parses authorized-principals command",
executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck},
arguments: []string{"key", "principal-1", "principal-2"}, arguments: []string{"key", "principal-1", "principal-2"},
expectedArgs: &commandargs.AuthorizedPrincipals{Arguments: []string{"key", "principal-1", "principal-2"}, KeyId: "key", Principals: []string{"principal-1", "principal-2"}}, expectedArgs: &commandargs.AuthorizedPrincipals{Arguments: []string{"key", "principal-1", "principal-2"}, KeyID: "key", Principals: []string{"principal-1", "principal-2"}},
}, },
} }
Loading
Loading
// Package main is the entry point for the GitLab Shell authorized principals check command.
package main package main
import ( import (
Loading
@@ -21,6 +22,10 @@ var (
Loading
@@ -21,6 +22,10 @@ var (
) )
func main() { func main() {
os.Exit(run())
}
func run() int {
command.CheckForVersionFlag(os.Args, Version, BuildTime) command.CheckForVersionFlag(os.Args, Version, BuildTime)
readWriter := &readwriter.ReadWriter{ readWriter := &readwriter.ReadWriter{
Loading
@@ -31,32 +36,33 @@ func main() {
Loading
@@ -31,32 +36,33 @@ func main() {
executable, err := executable.New(executable.AuthorizedPrincipalsCheck) executable, err := executable.New(executable.AuthorizedPrincipalsCheck)
if err != nil { if err != nil {
fmt.Fprintln(readWriter.ErrOut, "Failed to determine executable, exiting") _, _ = fmt.Fprintln(readWriter.ErrOut, "Failed to determine executable, exiting")
os.Exit(1) return 1
} }
config, err := config.NewFromDirExternal(executable.RootDir) config, err := config.NewFromDirExternal(executable.RootDir)
if err != nil { if err != nil {
fmt.Fprintln(readWriter.ErrOut, "Failed to read config, exiting") _, _ = fmt.Fprintln(readWriter.ErrOut, "Failed to read config, exiting:", err)
os.Exit(1) return 1
} }
logCloser := logger.Configure(config) logCloser := logger.Configure(config)
defer logCloser.Close() defer logCloser.Close() //nolint:errcheck
cmd, err := cmd.New(os.Args[1:], config, readWriter) cmd, err := cmd.New(os.Args[1:], config, readWriter)
if err != nil { if err != nil {
// For now this could happen if `SSH_CONNECTION` is not set on // For now this could happen if `SSH_CONNECTION` is not set on
// the environment // the environment
fmt.Fprintf(readWriter.ErrOut, "%v\n", err) _, _ = fmt.Fprintf(readWriter.ErrOut, "%v\n", err)
os.Exit(1) return 1
} }
ctx, finished := command.Setup(executable.Name, config) ctx, finished := command.Setup(executable.Name, config)
defer finished() defer finished()
if ctx, err = cmd.Execute(ctx); err != nil { if _, err = cmd.Execute(ctx); err != nil {
console.DisplayWarningMessage(err.Error(), readWriter.ErrOut) console.DisplayWarningMessage(err.Error(), readWriter.ErrOut)
os.Exit(1) return 1
} }
return 0
} }
// Package main is the entry point for the GitLab Shell health check command.
package main package main
import ( import (
Loading
@@ -20,6 +21,10 @@ var (
Loading
@@ -20,6 +21,10 @@ var (
) )
func main() { func main() {
os.Exit(run())
}
func run() int {
command.CheckForVersionFlag(os.Args, Version, BuildTime) command.CheckForVersionFlag(os.Args, Version, BuildTime)
readWriter := &readwriter.ReadWriter{ readWriter := &readwriter.ReadWriter{
Loading
@@ -28,32 +33,38 @@ func main() {
Loading
@@ -28,32 +33,38 @@ func main() {
ErrOut: os.Stderr, ErrOut: os.Stderr,
} }
exitOnError := func(err error, message string) int {
if err != nil {
_, _ = fmt.Fprintf(readWriter.ErrOut, "%s: %v\n", message, err)
return 1
}
return 0
}
executable, err := executable.New(executable.Healthcheck) executable, err := executable.New(executable.Healthcheck)
if err != nil { if code := exitOnError(err, "Failed to determine executable, exiting"); code != 0 {
fmt.Fprintln(readWriter.ErrOut, "Failed to determine executable, exiting") return code
os.Exit(1)
} }
config, err := config.NewFromDirExternal(executable.RootDir) config, err := config.NewFromDirExternal(executable.RootDir)
if err != nil { if code := exitOnError(err, "Failed to read config, exiting"); code != 0 {
fmt.Fprintln(readWriter.ErrOut, "Failed to read config, exiting") return code
os.Exit(1)
} }
logCloser := logger.Configure(config) logCloser := logger.Configure(config)
defer logCloser.Close() defer logCloser.Close() //nolint:errcheck
cmd, err := checkCmd.New(config, readWriter) cmd, err := checkCmd.New(config, readWriter)
if err != nil { if code := exitOnError(err, "Failed to create command"); code != 0 {
fmt.Fprintf(readWriter.ErrOut, "%v\n", err) return code
os.Exit(1)
} }
ctx, finished := command.Setup(executable.Name, config) ctx, finished := command.Setup(executable.Name, config)
defer finished() defer finished()
if ctx, err = cmd.Execute(ctx); err != nil { if _, err = cmd.Execute(ctx); err != nil {
fmt.Fprintf(readWriter.ErrOut, "%v\n", err) _, _ = fmt.Fprintf(readWriter.ErrOut, "%v\n", err)
os.Exit(1) return 1
} }
return 0
} }
Loading
@@ -41,7 +41,7 @@ func NewWithKey(gitlabKeyID string, env sshenv.Env, config *config.Config, readW
Loading
@@ -41,7 +41,7 @@ func NewWithKey(gitlabKeyID string, env sshenv.Env, config *config.Config, readW
return nil, err return nil, err
} }
args.GitlabKeyId = gitlabKeyID args.GitlabKeyID = gitlabKeyID
if cmd := Build(args, config, readWriter); cmd != nil { if cmd := Build(args, config, readWriter); cmd != nil {
return cmd, nil return cmd, nil
} }
Loading
@@ -71,7 +71,7 @@ func NewWithUsername(gitlabUsername string, env sshenv.Env, config *config.Confi
Loading
@@ -71,7 +71,7 @@ func NewWithUsername(gitlabUsername string, env sshenv.Env, config *config.Confi
return nil, err return nil, err
} }
// When 1.21+ only Golang is supported, it can be refactored by using slices.Contains // FIXME: When 1.21+ only Golang is supported, it can be refactored by using slices.Contains
if env.NamespacePath != "" { if env.NamespacePath != "" {
exists := false exists := false
for _, gitCmd := range commandargs.GitCommands { for _, gitCmd := range commandargs.GitCommands {
Loading
Loading
Loading
@@ -256,112 +256,112 @@ func TestParseSuccess(t *testing.T) {
Loading
@@ -256,112 +256,112 @@ func TestParseSuccess(t *testing.T) {
executable: &executable.Executable{Name: executable.GitlabShell}, executable: &executable.Executable{Name: executable.GitlabShell},
env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"},
arguments: []string{}, arguments: []string{},
expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{}, CommandType: commandargs.Discover, Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, expectedArgs: &commandargs.Shell{Arguments: []string{}, SSHArgs: []string{}, CommandType: commandargs.Discover, Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}},
}, },
{ {
desc: "It finds the key id in any passed arguments", desc: "It finds the key id in any passed arguments",
executable: &executable.Executable{Name: executable.GitlabShell}, executable: &executable.Executable{Name: executable.GitlabShell},
env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"},
arguments: []string{"hello", "key-123"}, arguments: []string{"hello", "key-123"},
expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "key-123"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabKeyId: "123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "key-123"}, SSHArgs: []string{}, CommandType: commandargs.Discover, GitlabKeyID: "123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}},
}, },
{ {
desc: "It finds the key id only if the argument is of <key-id> format", desc: "It finds the key id only if the argument is of <key-id> format",
executable: &executable.Executable{Name: executable.GitlabShell}, executable: &executable.Executable{Name: executable.GitlabShell},
env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"},
arguments: []string{"hello", "username-key-123"}, arguments: []string{"hello", "username-key-123"},
expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "username-key-123"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "key-123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "username-key-123"}, SSHArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "key-123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}},
}, },
{ {
desc: "It finds the key id if the key is listed as the last argument", desc: "It finds the key id if the key is listed as the last argument",
executable: &executable.Executable{Name: executable.GitlabShell}, executable: &executable.Executable{Name: executable.GitlabShell},
env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"},
arguments: []string{"hello", "gitlab-shell -c key-123"}, arguments: []string{"hello", "gitlab-shell -c key-123"},
expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "gitlab-shell -c key-123"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabKeyId: "123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "gitlab-shell -c key-123"}, SSHArgs: []string{}, CommandType: commandargs.Discover, GitlabKeyID: "123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}},
}, },
{ {
desc: "It finds the username if the username is listed as the last argument", desc: "It finds the username if the username is listed as the last argument",
executable: &executable.Executable{Name: executable.GitlabShell}, executable: &executable.Executable{Name: executable.GitlabShell},
env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"},
arguments: []string{"hello", "gitlab-shell -c username-jane-doe"}, arguments: []string{"hello", "gitlab-shell -c username-jane-doe"},
expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "gitlab-shell -c username-jane-doe"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "jane-doe", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "gitlab-shell -c username-jane-doe"}, SSHArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "jane-doe", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}},
}, },
{ {
desc: "It finds the key id only if the last argument is of <key-id> format", desc: "It finds the key id only if the last argument is of <key-id> format",
executable: &executable.Executable{Name: executable.GitlabShell}, executable: &executable.Executable{Name: executable.GitlabShell},
env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"},
arguments: []string{"hello", "gitlab-shell -c username-key-123"}, arguments: []string{"hello", "gitlab-shell -c username-key-123"},
expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "gitlab-shell -c username-key-123"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "key-123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "gitlab-shell -c username-key-123"}, SSHArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "key-123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}},
}, },
{ {
desc: "It finds the username in any passed arguments", desc: "It finds the username in any passed arguments",
executable: &executable.Executable{Name: executable.GitlabShell}, executable: &executable.Executable{Name: executable.GitlabShell},
env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"},
arguments: []string{"hello", "username-jane-doe"}, arguments: []string{"hello", "username-jane-doe"},
expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "username-jane-doe"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "jane-doe", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "username-jane-doe"}, SSHArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "jane-doe", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}},
}, },
{ {
desc: "It parses 2fa_recovery_codes command", desc: "It parses 2fa_recovery_codes command",
executable: &executable.Executable{Name: executable.GitlabShell}, executable: &executable.Executable{Name: executable.GitlabShell},
env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "2fa_recovery_codes"}, env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "2fa_recovery_codes"},
arguments: []string{}, arguments: []string{},
expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"2fa_recovery_codes"}, CommandType: commandargs.TwoFactorRecover, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "2fa_recovery_codes"}}, expectedArgs: &commandargs.Shell{Arguments: []string{}, SSHArgs: []string{"2fa_recovery_codes"}, CommandType: commandargs.TwoFactorRecover, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "2fa_recovery_codes"}},
}, },
{ {
desc: "It parses git-receive-pack command", desc: "It parses git-receive-pack command",
executable: &executable.Executable{Name: executable.GitlabShell}, executable: &executable.Executable{Name: executable.GitlabShell},
env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack group/repo"}, env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack group/repo"},
arguments: []string{}, arguments: []string{},
expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: commandargs.ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack group/repo"}}, expectedArgs: &commandargs.Shell{Arguments: []string{}, SSHArgs: []string{"git-receive-pack", "group/repo"}, CommandType: commandargs.ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack group/repo"}},
}, },
{ {
desc: "It parses git-receive-pack command and a project with single quotes", desc: "It parses git-receive-pack command and a project with single quotes",
executable: &executable.Executable{Name: executable.GitlabShell}, executable: &executable.Executable{Name: executable.GitlabShell},
env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack 'group/repo'"}, env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack 'group/repo'"},
arguments: []string{}, arguments: []string{},
expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: commandargs.ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack 'group/repo'"}}, expectedArgs: &commandargs.Shell{Arguments: []string{}, SSHArgs: []string{"git-receive-pack", "group/repo"}, CommandType: commandargs.ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack 'group/repo'"}},
}, },
{ {
desc: `It parses "git receive-pack" command`, desc: `It parses "git receive-pack" command`,
executable: &executable.Executable{Name: executable.GitlabShell}, executable: &executable.Executable{Name: executable.GitlabShell},
env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack "group/repo"`}, env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack "group/repo"`},
arguments: []string{}, arguments: []string{},
expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: commandargs.ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack "group/repo"`}}, expectedArgs: &commandargs.Shell{Arguments: []string{}, SSHArgs: []string{"git-receive-pack", "group/repo"}, CommandType: commandargs.ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack "group/repo"`}},
}, },
{ {
desc: `It parses a command followed by control characters`, desc: `It parses a command followed by control characters`,
executable: &executable.Executable{Name: executable.GitlabShell}, executable: &executable.Executable{Name: executable.GitlabShell},
env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack group/repo; any command`}, env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack group/repo; any command`},
arguments: []string{}, arguments: []string{},
expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: commandargs.ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack group/repo; any command`}}, expectedArgs: &commandargs.Shell{Arguments: []string{}, SSHArgs: []string{"git-receive-pack", "group/repo"}, CommandType: commandargs.ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack group/repo; any command`}},
}, },
{ {
desc: "It parses git-upload-pack command", desc: "It parses git-upload-pack command",
executable: &executable.Executable{Name: executable.GitlabShell}, executable: &executable.Executable{Name: executable.GitlabShell},
env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git upload-pack "group/repo"`}, env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git upload-pack "group/repo"`},
arguments: []string{}, arguments: []string{},
expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-upload-pack", "group/repo"}, CommandType: commandargs.UploadPack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git upload-pack "group/repo"`}}, expectedArgs: &commandargs.Shell{Arguments: []string{}, SSHArgs: []string{"git-upload-pack", "group/repo"}, CommandType: commandargs.UploadPack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git upload-pack "group/repo"`}},
}, },
{ {
desc: "It parses git-upload-archive command", desc: "It parses git-upload-archive command",
executable: &executable.Executable{Name: executable.GitlabShell}, executable: &executable.Executable{Name: executable.GitlabShell},
env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-upload-archive 'group/repo'"}, env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-upload-archive 'group/repo'"},
arguments: []string{}, arguments: []string{},
expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-upload-archive", "group/repo"}, CommandType: commandargs.UploadArchive, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-upload-archive 'group/repo'"}}, expectedArgs: &commandargs.Shell{Arguments: []string{}, SSHArgs: []string{"git-upload-archive", "group/repo"}, CommandType: commandargs.UploadArchive, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-upload-archive 'group/repo'"}},
}, },
{ {
desc: "It parses git-lfs-authenticate command", desc: "It parses git-lfs-authenticate command",
executable: &executable.Executable{Name: executable.GitlabShell}, executable: &executable.Executable{Name: executable.GitlabShell},
env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-lfs-authenticate 'group/repo' download"}, env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-lfs-authenticate 'group/repo' download"},
arguments: []string{}, arguments: []string{},
expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-lfs-authenticate", "group/repo", "download"}, CommandType: commandargs.LfsAuthenticate, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-lfs-authenticate 'group/repo' download"}}, expectedArgs: &commandargs.Shell{Arguments: []string{}, SSHArgs: []string{"git-lfs-authenticate", "group/repo", "download"}, CommandType: commandargs.LfsAuthenticate, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-lfs-authenticate 'group/repo' download"}},
}, },
{ {
desc: "It parses git-lfs-transfer command", desc: "It parses git-lfs-transfer command",
executable: &executable.Executable{Name: executable.GitlabShell}, executable: &executable.Executable{Name: executable.GitlabShell},
env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-lfs-transfer 'group/repo' download"}, env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-lfs-transfer 'group/repo' download"},
arguments: []string{}, arguments: []string{},
expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-lfs-transfer", "group/repo", "download"}, CommandType: commandargs.LfsTransfer, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-lfs-transfer 'group/repo' download"}}, expectedArgs: &commandargs.Shell{Arguments: []string{}, SSHArgs: []string{"git-lfs-transfer", "group/repo", "download"}, CommandType: commandargs.LfsTransfer, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-lfs-transfer 'group/repo' download"}},
}, },
} }
Loading
@@ -427,7 +427,7 @@ func TestNewWithUsername(t *testing.T) {
Loading
@@ -427,7 +427,7 @@ func TestNewWithUsername(t *testing.T) {
Args: &commandargs.Shell{ Args: &commandargs.Shell{
CommandType: commandargs.ReceivePack, CommandType: commandargs.ReceivePack,
GitlabUsername: "username", GitlabUsername: "username",
SshArgs: []string{"git-receive-pack", "group/repo"}, SSHArgs: []string{"git-receive-pack", "group/repo"},
Env: sshenv.Env{ Env: sshenv.Env{
IsSSHConnection: true, IsSSHConnection: true,
OriginalCommand: "git-receive-pack 'group/repo'", OriginalCommand: "git-receive-pack 'group/repo'",
Loading
@@ -442,7 +442,7 @@ func TestNewWithUsername(t *testing.T) {
Loading
@@ -442,7 +442,7 @@ func TestNewWithUsername(t *testing.T) {
Args: &commandargs.Shell{ Args: &commandargs.Shell{
CommandType: commandargs.TwoFactorRecover, CommandType: commandargs.TwoFactorRecover,
GitlabUsername: "username", GitlabUsername: "username",
SshArgs: []string{"2fa_recovery_codes"}, SSHArgs: []string{"2fa_recovery_codes"},
Env: sshenv.Env{ Env: sshenv.Env{
IsSSHConnection: true, IsSSHConnection: true,
OriginalCommand: "2fa_recovery_codes", OriginalCommand: "2fa_recovery_codes",
Loading
@@ -463,7 +463,7 @@ func TestNewWithUsername(t *testing.T) {
Loading
@@ -463,7 +463,7 @@ func TestNewWithUsername(t *testing.T) {
Args: &commandargs.Shell{ Args: &commandargs.Shell{
CommandType: commandargs.ReceivePack, CommandType: commandargs.ReceivePack,
GitlabUsername: "username", GitlabUsername: "username",
SshArgs: []string{"git-receive-pack", "group/repo"}, SSHArgs: []string{"git-receive-pack", "group/repo"},
Env: sshenv.Env{ Env: sshenv.Env{
IsSSHConnection: true, IsSSHConnection: true,
OriginalCommand: "git-receive-pack 'group/repo'", OriginalCommand: "git-receive-pack 'group/repo'",
Loading
Loading
Loading
@@ -45,7 +45,7 @@ func main() {
Loading
@@ -45,7 +45,7 @@ func main() {
config, err := config.NewFromDirExternal(executable.RootDir) config, err := config.NewFromDirExternal(executable.RootDir)
if err != nil { if err != nil {
fmt.Fprintln(readWriter.ErrOut, "Failed to read config, exiting") fmt.Fprintln(readWriter.ErrOut, "Failed to read config, exiting:", err)
os.Exit(1) os.Exit(1)
} }
Loading
Loading
Loading
@@ -21,6 +21,7 @@ import (
Loading
@@ -21,6 +21,7 @@ import (
"github.com/mikesmitty/edkey" "github.com/mikesmitty/edkey"
"github.com/pires/go-proxyproto" "github.com/pires/go-proxyproto"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
gitalyClient "gitlab.com/gitlab-org/gitaly/v16/client" gitalyClient "gitlab.com/gitlab-org/gitaly/v16/client"
pb "gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb" pb "gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
Loading
@@ -112,7 +113,7 @@ func startGitOverHTTPServer(t *testing.T) string {
Loading
@@ -112,7 +113,7 @@ func startGitOverHTTPServer(t *testing.T) string {
switch r.URL.Query().Get("service") { switch r.URL.Query().Get("service") {
case "git-receive-pack": case "git-receive-pack":
stream, err := client.InfoRefsReceivePack(ctx, rpcRequest) stream, err := client.InfoRefsReceivePack(ctx, rpcRequest)
require.NoError(t, err) assert.NoError(t, err)
reader = streamio.NewReader(func() ([]byte, error) { reader = streamio.NewReader(func() ([]byte, error) {
resp, err := stream.Recv() resp, err := stream.Recv()
return resp.GetData(), err return resp.GetData(), err
Loading
@@ -122,22 +123,22 @@ func startGitOverHTTPServer(t *testing.T) string {
Loading
@@ -122,22 +123,22 @@ func startGitOverHTTPServer(t *testing.T) string {
} }
_, err := io.Copy(w, reader) _, err := io.Copy(w, reader)
require.NoError(t, err) assert.NoError(t, err)
}, },
}, },
{ {
Path: "/git-receive-pack", Path: "/git-receive-pack",
Handler: func(_ http.ResponseWriter, r *http.Request) { Handler: func(_ http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body) body, err := io.ReadAll(r.Body)
require.NoError(t, err) assert.NoError(t, err)
defer r.Body.Close() defer r.Body.Close()
require.Equal(t, "0000", string(body)) assert.Equal(t, "0000", string(body))
}, },
}, },
} }
return testserver.StartHttpServer(t, requests) return testserver.StartHTTPServer(t, requests)
} }
func buildAllowedResponse(t *testing.T, filename string) string { func buildAllowedResponse(t *testing.T, filename string) string {
Loading
@@ -185,7 +186,7 @@ func successAPI(t *testing.T, handlers ...customHandler) http.Handler {
Loading
@@ -185,7 +186,7 @@ func successAPI(t *testing.T, handlers ...customHandler) http.Handler {
response := buildAllowedResponse(t, "responses/allowed_without_console_messages.json") response := buildAllowedResponse(t, "responses/allowed_without_console_messages.json")
_, err := fmt.Fprint(w, response) _, err := fmt.Fprint(w, response)
require.NoError(t, err) assert.NoError(t, err)
case "/api/v4/internal/shellhorse/git_audit_event": case "/api/v4/internal/shellhorse/git_audit_event":
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
return return
Loading
@@ -495,7 +496,7 @@ func TestGeoGitReceivePackSuccess(t *testing.T) {
Loading
@@ -495,7 +496,7 @@ func TestGeoGitReceivePackSuccess(t *testing.T) {
w.WriteHeader(300) w.WriteHeader(300)
_, err := fmt.Fprint(w, response) _, err := fmt.Fprint(w, response)
require.NoError(t, err) assert.NoError(t, err)
}, },
} }
client := runSSHD(t, successAPI(t, handler)) client := runSSHD(t, successAPI(t, handler))
Loading
Loading