Repository: xanzy/go-gitlab
Pull request #1778 (2023-08-20 09:09:03)

feature: add support for getting and patching project CI/CD job token
Add support for getting and patching project CI/CD job token

Gitlab document: https://docs.gitlab.com/ee/api/project_job_token_scopes.html


Patch:
diff --git a/job_token_scope.go b/job_token_scope.go
index 82dc508..ff96ba6 100644
--- a/job_token_scope.go
+++ b/job_token_scope.go
@@ -26,6 +26,67 @@ type JobTokenScopeService struct {
 	client *Client
 }
 
+// JobTokenAccessSettings represents job token access attributes for this project.
+//
+// GitLab API docs: https://docs.gitlab.com/ee/api/project_job_token_scopes.html
+type JobTokenAccessSettings struct {
+	InboundEnabled  bool `json:"inbound_enabled"`
+	OutboundEnabled bool `json:"outbound_enabled"`
+}
+
+// GetProjectJobTokenAccessSettings fetch the CI/CD job token access settings (job token scope) of a project.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/project_job_token_scopes.html#get-a-projects-cicd-job-token-access-settings
+func (j *JobTokenScopeService) GetProjectJobTokenAccessSettings(pid interface{}, options ...RequestOptionFunc) (*JobTokenAccessSettings, *Response, error) {
+	project, err := parseID(pid)
+	if err != nil {
+		return nil, nil, err
+	}
+	u := fmt.Sprintf(`projects/%s/job_token_scope`, PathEscape(project))
+
+	req, err := j.client.NewRequest(http.MethodGet, u, nil, options)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	jt := new(JobTokenAccessSettings)
+	resp, err := j.client.Do(req, jt)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return jt, resp, err
+}
+
+// PatchProjectJobTokenAccessSettingsOptions represents the available
+// PatchProjectJobTokenAccessSettings() options.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/project_job_token_scopes.html#patch-a-projects-cicd-job-token-access-settings
+type PatchProjectJobTokenAccessSettingsOptions struct {
+	Enabled bool `json:"enabled"`
+}
+
+// PatchProjectJobTokenAccessSettings patch the Limit access to this project setting (job token scope) of a project.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/project_job_token_scopes.html#patch-a-projects-cicd-job-token-access-settings
+func (j *JobTokenScopeService) PatchProjectJobTokenAccessSettings(pid interface{}, opt *PatchProjectJobTokenAccessSettingsOptions, options ...RequestOptionFunc) (*Response, error) {
+	project, err := parseID(pid)
+	if err != nil {
+		return nil, err
+	}
+	u := fmt.Sprintf(`projects/%s/job_token_scope`, PathEscape(project))
+
+	req, err := j.client.NewRequest(http.MethodPatch, u, opt, options)
+	if err != nil {
+		return nil, err
+	}
+
+	return j.client.Do(req, nil)
+}
+
 // JobTokenInboundAllowItem represents a single job token inbound allowlist item.
 //
 // GitLab API docs: https://docs.gitlab.com/ee/api/project_job_token_scopes.html
@@ -95,13 +156,13 @@ func (j *JobTokenScopeService) AddProjectToJobScopeAllowList(pid interface{}, op
 		return nil, nil, err
 	}
 
-	ai := new(JobTokenInboundAllowItem)
-	resp, err := j.client.Do(req, ai)
+	jt := new(JobTokenInboundAllowItem)
+	resp, err := j.client.Do(req, jt)
 	if err != nil {
 		return nil, resp, err
 	}
 
-	return ai, resp, nil
+	return jt, resp, nil
 }
 
 // RemoveProjectFromJobScopeAllowList removes a project from a project's job


Test patch:
diff --git a/job_token_scope_test.go b/job_token_scope_test.go
index 06e116c..0e33f73 100644
--- a/job_token_scope_test.go
+++ b/job_token_scope_test.go
@@ -23,6 +23,64 @@ import (
 	"github.com/stretchr/testify/assert"
 )
 
+func TestGetProjectTokenAccessSettings(t *testing.T) {
+	mux, client := setup(t)
+
+	// Handle project ID 1, and print a result of access settings
+	mux.HandleFunc("/api/v4/projects/1/job_token_scope", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, http.MethodGet)
+
+		// Print on the response
+		fmt.Fprint(w, `{"inbound_enabled":true,"outbound_enabled":false}`)
+	})
+
+	want := &JobTokenAccessSettings{
+		InboundEnabled:  true,
+		OutboundEnabled: false,
+	}
+
+	settings, _, err := client.JobTokenScope.GetProjectJobTokenAccessSettings(1)
+
+	assert.NoError(t, err)
+	assert.Equal(t, want, settings)
+}
+
+func TestPatchProjectJobTokenAccessSettings(t *testing.T) {
+	mux, client := setup(t)
+
+	mux.HandleFunc("/api/v4/projects/1/job_token_scope", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, http.MethodPatch)
+
+		// Read the request to determine which target project is passed in
+		body, err := io.ReadAll(r.Body)
+		if err != nil {
+			t.Fatalf("JobTokenScope.PatchProjectJobTokenAccessSettings failed to read body")
+		}
+
+		// Parse to object to ensure it's sent on the request appropriately.
+		var options PatchProjectJobTokenAccessSettingsOptions
+		err = json.Unmarshal(body, &options)
+		if err != nil {
+			t.Fatalf("JobTokenScope.PatchProjectJobTokenAccessSettings failed to unmarshal body: %v", err)
+		}
+
+		// Ensure we provide the proper response
+		w.WriteHeader(http.StatusNoContent)
+
+		// Print an empty body, since that's what the API provides.
+		fmt.Fprint(w, "")
+	})
+
+	resp, err := client.JobTokenScope.PatchProjectJobTokenAccessSettings(
+		1,
+		&PatchProjectJobTokenAccessSettingsOptions{
+			Enabled: false,
+		},
+	)
+	assert.NoError(t, err)
+	assert.Equal(t, 204, resp.StatusCode)
+}
+
 // This tests that when calling the GetProjectJobTokenInboundAllowList, we get a
 // list of projects back properly. There isn't a "deep" test with every attribute
 // specifieid, because the object returned is a *Project object, which is already