@@ -26,6 +26,16 @@ func setupMockGitLabRunnersAPI(t *testing.T) string {
2626 w .Write ([]byte (`[{"id":123,"name":"test-project"}]` ))
2727 })
2828
29+ // Repository files endpoint for creating .gitlab-ci.yml
30+ mux .HandleFunc ("/api/v4/projects/999/repository/files/.gitlab-ci.yml" , func (w http.ResponseWriter , r * http.Request ) {
31+ if r .Method == http .MethodPost {
32+ w .WriteHeader (http .StatusCreated )
33+ w .Write ([]byte (`{"file_path":".gitlab-ci.yml","branch":"main"}` ))
34+ return
35+ }
36+ w .WriteHeader (http .StatusOK )
37+ })
38+
2939 // Project runners endpoint
3040 mux .HandleFunc ("/api/v4/projects/123/runners" , func (w http.ResponseWriter , r * http.Request ) {
3141 w .WriteHeader (http .StatusOK )
@@ -105,7 +115,7 @@ func TestGLRunnersExploit_DryRun(t *testing.T) {
105115 "--gitlab" , apiURL ,
106116 "--token" , "mock-token" ,
107117 "--tags" , "docker,shell" ,
108- "--dry" , " true" ,
118+ "--dry= true" ,
109119 }, nil , 10 * time .Second )
110120
111121 assert .Nil (t , exitErr , "Runners exploit dry run should succeed" )
@@ -114,6 +124,33 @@ func TestGLRunnersExploit_DryRun(t *testing.T) {
114124 assert .NotContains (t , stderr , "fatal" )
115125}
116126
127+ func TestGLRunnersExploit_DryRun_WithoutTokenAndGitlab (t * testing.T ) {
128+ stdout , stderr , exitErr := testutil .RunCLI (t , []string {
129+ "gl" , "runners" , "exploit" ,
130+ "--dry=true" ,
131+ "--tags" , "docker,shell" ,
132+ }, nil , 10 * time .Second )
133+
134+ assert .Nil (t , exitErr , "Runners exploit dry run should succeed without token and gitlab flags" )
135+ assert .Contains (t , stdout , ".gitlab-ci.yml" , "Should show CI/CD YAML output" )
136+ assert .Contains (t , stdout , "docker" , "Should include docker tag in YAML" )
137+ assert .NotContains (t , stderr , "fatal" )
138+ }
139+
140+ func TestGLRunnersExploit_NonDryRun_WithoutTokenAndGitlab (t * testing.T ) {
141+ stdout , stderr , exitErr := testutil .RunCLI (t , []string {
142+ "gl" , "runners" , "exploit" ,
143+ "--dry=false" ,
144+ }, nil , 10 * time .Second )
145+
146+ assert .NotNil (t , exitErr , "Should fail without token and gitlab flags when not in dry-run mode" )
147+ output := stdout + stderr
148+ assert .Contains (t , output , "required configuration missing" , "Should mention missing required configuration" )
149+ assert .Contains (t , output , "gitlab.url" , "Should mention gitlab.url is missing" )
150+ assert .Contains (t , output , "gitlab.token" , "Should mention gitlab.token is missing" )
151+ }
152+
153+
117154func TestGLRunnersExploit_WithRepoCreation (t * testing.T ) {
118155 apiURL := setupMockGitLabRunnersAPI (t )
119156 stdout , stderr , exitErr := testutil .RunCLI (t , []string {
@@ -122,8 +159,8 @@ func TestGLRunnersExploit_WithRepoCreation(t *testing.T) {
122159 "--token" , "mock-token" ,
123160 "--tags" , "docker" ,
124161 "--repo-name" , "test-exploit-repo" ,
125- "--dry" , " false" ,
126- "--shell" , " false" ,
162+ "--dry= false" ,
163+ "--shell= false" ,
127164 }, nil , 15 * time .Second )
128165
129166 assert .Nil (t , exitErr , "Runners exploit should succeed" )
@@ -140,13 +177,15 @@ func TestGLRunnersExploit_Unauthorized(t *testing.T) {
140177 server := httptest .NewServer (mux )
141178 defer server .Close ()
142179
143- stdout , _ , _ := testutil .RunCLI (t , []string {
180+ stdout , stderr , exitErr := testutil .RunCLI (t , []string {
144181 "gl" , "runners" , "exploit" ,
145182 "--gitlab" , server .URL ,
146183 "--token" , "invalid-token" ,
147- "--dry" , " false" ,
184+ "--dry= false" ,
148185 }, nil , 10 * time .Second )
149186
150- // Exploit command generates YAML in dry mode regardless
151- assert .Contains (t , stdout , "Done, Bye Bye" , "Should complete with generated YAML" )
187+ // Should fail with unauthorized error when creating project
188+ assert .NotNil (t , exitErr , "Should fail with unauthorized error" )
189+ output := stdout + stderr
190+ assert .Contains (t , output , "401" , "Should mention 401 error" )
152191}
0 commit comments