diff --git a/job_token_scope.go b/job_token_scope.go index 82dc50819..ff96ba698 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 diff --git a/job_token_scope_test.go b/job_token_scope_test.go index 06e116c34..0e33f73e9 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