Skip to content

Commit

Permalink
Add support for groups job token
Browse files Browse the repository at this point in the history
  • Loading branch information
Poulpatine committed Mar 9, 2024
1 parent c49b7d6 commit 7c17faf
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
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,101 @@ func (j *JobTokenScopeService) RemoveProjectFromJobScopeAllowList(pid interface{

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

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

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

// GetProjectJobTokenInboundGroupsAllowList fetches the CI/CD job token inbound
// groups allowlist (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-allowlist-of-groups
func (j *JobTokenScopeService) GetProjectJobTokenInboundGroupsAllowList(pid interface{}, opt *GetJobTokenInboundGroupsAllowListOptions, 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
}

// AddProjectToJobScopeGroupsAllowListOptions represents the available
// AddProjectToJobScopeGroupsAllowList() 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 JobTokenInboundGroupsAllowOptions 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) AddGroupToJobScopeGroupsAllowList(pid interface{}, opt *JobTokenInboundGroupsAllowOptions, options ...RequestOptionFunc) (*JobTokenInboundGroupsAllowItem, *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(JobTokenInboundGroupsAllowItem)
resp, err := j.client.Do(req, jt)
if err != nil {
return nil, resp, err
}

return jt, resp, nil
}

// RemoveGroupFromJobScopeAllowList 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) RemoveGroupFromJobScopeGroupsAllowList(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
Original file line number Diff line number Diff line change
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 GetProjectJobTokenInboundGroupsAllowList, we
// get a list of groups back properly. 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 TestGetProjectJobTokenInboundGroupsAllowList(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.GetProjectJobTokenInboundGroupsAllowList(
1,
&GetJobTokenInboundGroupsAllowListOptions{},
)

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

func TestAddGroupToJobScopeGroupsAllowList(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.AddGroupToJobScopeGroupsAllowList failed to read body")
}

// Parse to object to ensure it's sent on the request appropriately.
var createTokenRequest JobTokenInboundGroupsAllowOptions
err = json.Unmarshal(body, &createTokenRequest)
if err != nil {
t.Fatalf("JobTokenScope.AddGroupToJobScopeGroupsAllowList 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 := &JobTokenInboundGroupsAllowItem{
SourceProjectID: 1,
TargetGroupID: 2,
}

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

func TestRemoveGroupFromJobScopeGroupsAllowList(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.RemoveGroupFromJobScopeGroupsAllowList 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.RemoveGroupFromJobScopeGroupsAllowList 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.RemoveGroupFromJobScopeGroupsAllowList(1, 2)
assert.NoError(t, err)
assert.Equal(t, 204, resp.StatusCode)
}

0 comments on commit 7c17faf

Please sign in to comment.