Skip to content

Commit

Permalink
Merge pull request #1894 from Poulpatine/main
Browse files Browse the repository at this point in the history
Add support for groups job token
  • Loading branch information
svanharmelen committed Mar 10, 2024
2 parents c49b7d6 + b6e96f9 commit a603b9d
Show file tree
Hide file tree
Showing 2 changed files with 195 additions and 0 deletions.
98 changes: 98 additions & 0 deletions job_token_scope.go
Expand Up @@ -184,3 +184,101 @@ func (j *JobTokenScopeService) RemoveProjectFromJobScopeAllowList(pid interface{

return j.client.Do(req, nil)
}

// JobTokenAllowlistItem represents a single job token allowlist item.
//
// GitLab API docs: https://docs.gitlab.com/ee/api/project_job_token_scopes.html
type JobTokenAllowlistItem struct {
SourceProjectID int `json:"source_project_id"`
TargetGroupID int `json:"target_group_id"`
}

// GetJobTokenAllowlistGroupsOptions represents the available
// GetJobTokenAllowlistGroups() options.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/project_job_token_scopes.html#get-a-projects-cicd-job-token-allowlist-of-groups
type GetJobTokenAllowlistGroupsOptions struct {
ListOptions
}

// GetJobTokenAllowListGroups fetches the CI/CD job token allowlist groups
// (job token scopes) of a project.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/project_job_token_scopes.html#get-a-projects-cicd-job-token-allowlist-of-groups
func (j *JobTokenScopeService) GetJobTokenAllowlistGroups(pid interface{}, opt *GetJobTokenAllowlistGroupsOptions, options ...RequestOptionFunc) ([]*Group, *Response, error) {
project, err := parseID(pid)
if err != nil {
return nil, nil, err
}
u := fmt.Sprintf(`projects/%s/job_token_scope/groups_allowlist`, PathEscape(project))

req, err := j.client.NewRequest(http.MethodGet, u, opt, options)
if err != nil {
return nil, nil, err
}

var ps []*Group
resp, err := j.client.Do(req, &ps)
if err != nil {
return nil, resp, err
}

return ps, resp, nil
}

// AddGroupToJobTokenAllowlistOptions represents the available
// AddGroupToJobTokenAllowlist() options.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/project_job_token_scopes.html#add-a-group-to-a-cicd-job-token-allowlist
type AddGroupToJobTokenAllowlistOptions struct {
TargetGroupID *int `url:"target_group_id,omitempty" json:"target_group_id,omitempty"`
}

// AddProjectToJobScopeGroupsAllowList adds a new group to a project's job token
// inbound groups allow list.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/project_job_token_scopes.html#add-a-group-to-a-cicd-job-token-allowlist
func (j *JobTokenScopeService) AddGroupToJobTokenAllowlist(pid interface{}, opt *AddGroupToJobTokenAllowlistOptions, options ...RequestOptionFunc) (*JobTokenAllowlistItem, *Response, error) {
project, err := parseID(pid)
if err != nil {
return nil, nil, err
}
u := fmt.Sprintf(`projects/%s/job_token_scope/groups_allowlist`, PathEscape(project))

req, err := j.client.NewRequest(http.MethodPost, u, opt, options)
if err != nil {
return nil, nil, err
}

jt := new(JobTokenAllowlistItem)
resp, err := j.client.Do(req, jt)
if err != nil {
return nil, resp, err
}

return jt, resp, nil
}

// RemoveGroupFromJopTokenAllowlist removes a group from a project's job
// token inbound groups allow list.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/project_job_token_scopes.html#remove-a-group-from-a-cicd-job-token-allowlist
func (j *JobTokenScopeService) RemoveGroupFromJobTokenAllowlist(pid interface{}, targetGroup int, options ...RequestOptionFunc) (*Response, error) {
project, err := parseID(pid)
if err != nil {
return nil, err
}
u := fmt.Sprintf(`projects/%s/job_token_scope/groups_allowlist/%d`, PathEscape(project), targetGroup)

req, err := j.client.NewRequest(http.MethodDelete, u, nil, options)
if err != nil {
return nil, err
}

return j.client.Do(req, nil)
}
97 changes: 97 additions & 0 deletions job_token_scope_test.go
Expand Up @@ -177,3 +177,100 @@ func TestRemoveProjectFromJobScopeAllowList(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, 204, resp.StatusCode)
}

// This tests that when calling the GetJobTokenAllowlistGroups, we get a list
// of groups back. There isn't a "deep" test with every attribute specified,
// because the object returned is a *Group object, which is already tested in
// groups.go.
func TestGetJobTokenAllowlistGroups(t *testing.T) {
mux, client := setup(t)

// Handle project ID 1, and print a result of two groups
mux.HandleFunc("/api/v4/projects/1/job_token_scope/groups_allowlist", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodGet)

// Print on the response
fmt.Fprint(w, `[{"id":1},{"id":2}]`)
})

want := []*Group{{ID: 1}, {ID: 2}}
groups, _, err := client.JobTokenScope.GetJobTokenAllowlistGroups(
1,
&GetJobTokenAllowlistGroupsOptions{},
)

assert.NoError(t, err)
assert.Equal(t, want, groups)
}

func TestAddGroupToJobTokenAllowlist(t *testing.T) {
mux, client := setup(t)

mux.HandleFunc("/api/v4/projects/1/job_token_scope/groups_allowlist", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodPost)

// Read the request to determine which target group is passed in
body, err := io.ReadAll(r.Body)
if err != nil {
t.Fatalf("JobTokenScope.AddGroupToJobTokenAllowlist failed to read body")
}

// Parse to object to ensure it's sent on the request appropriately.
var createTokenRequest AddGroupToJobTokenAllowlistOptions
err = json.Unmarshal(body, &createTokenRequest)
if err != nil {
t.Fatalf("JobTokenScope.AddGroupToJobTokenAllowlist failed to unmarshal body: %v", err)
}

// Ensure we provide the proper response
w.WriteHeader(http.StatusCreated)

// Print on the response with the proper target group
fmt.Fprintf(w, `{
"source_project_id": 1,
"target_group_id": %d
}`, *createTokenRequest.TargetGroupID)
})

want := &JobTokenAllowlistItem{
SourceProjectID: 1,
TargetGroupID: 2,
}

addTokenResponse, resp, err := client.JobTokenScope.AddGroupToJobTokenAllowlist(
1,
&AddGroupToJobTokenAllowlistOptions{TargetGroupID: Ptr(2)},
)
assert.NoError(t, err)
assert.Equal(t, want, addTokenResponse)
assert.Equal(t, 201, resp.StatusCode)
}

func TestRemoveGroupFromJobTokenAllowlist(t *testing.T) {
mux, client := setup(t)

mux.HandleFunc("/api/v4/projects/1/job_token_scope/groups_allowlist/2", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodDelete)

// Read the request to determine which target group is passed in
body, err := io.ReadAll(r.Body)
if err != nil {
t.Fatalf("JobTokenScope.RemoveGroupFromJobTokenAllowlist failed to read body")
}

// The body should be empty since all attributes are passed in the path
if body != nil && string(body) != "" {
t.Fatalf("JobTokenScope.RemoveGroupFromJobTokenAllowlist 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.RemoveGroupFromJobTokenAllowlist(1, 2)
assert.NoError(t, err)
assert.Equal(t, 204, resp.StatusCode)
}

0 comments on commit a603b9d

Please sign in to comment.