From 7ebd698a2163accf1269333aec790e9283856d07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Penteado?= <4219131+joaopenteado@users.noreply.github.com> Date: Wed, 5 Jul 2023 20:21:57 +0900 Subject: [PATCH 1/4] Added support for the personal access tokens request review API --- github/orgs_personal_access_tokens.go | 30 ++++++++++++ github/orgs_personal_access_tokens_test.go | 57 ++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 github/orgs_personal_access_tokens.go create mode 100644 github/orgs_personal_access_tokens_test.go diff --git a/github/orgs_personal_access_tokens.go b/github/orgs_personal_access_tokens.go new file mode 100644 index 00000000000..4fbb4cd2eff --- /dev/null +++ b/github/orgs_personal_access_tokens.go @@ -0,0 +1,30 @@ +package github + +import ( + "context" + "fmt" + "net/http" +) + +// Approves or denies a pending request to access organization resources via a fine-grained personal access token. +// Only GitHub Apps can call this API, using the `organization_personal_access_token_requests: write` permission. +// `action` can be one of `approve` or `deny`. +// +// GitHub API docs: https://docs.github.com/en/rest/orgs/personal-access-tokens?apiVersion=2022-11-28#review-a-request-to-access-organization-resources-with-a-fine-grained-personal-access-token +func (s *OrganizationsService) ReviewPersonalAccessTokenRequest(ctx context.Context, org, requestID, action, reason string) (*Response, error) { + u := fmt.Sprintf("orgs/%v/personal-access-token-requests/%v", org, requestID) + body := struct { + Action string `json:"action"` + Reason string `json:"reason,omitempty"` + }{ + Action: action, + Reason: reason, + } + + req, err := s.client.NewRequest(http.MethodPost, u, &body) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} diff --git a/github/orgs_personal_access_tokens_test.go b/github/orgs_personal_access_tokens_test.go new file mode 100644 index 00000000000..1abaa69de06 --- /dev/null +++ b/github/orgs_personal_access_tokens_test.go @@ -0,0 +1,57 @@ +package github + +import ( + "context" + "encoding/json" + "net/http" + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestOrganizationsService_ReviewPersonalAccessTokenRequest(t *testing.T) { + type body struct { + Action string `json:"action"` + Reason string `json:"reason,omitempty"` + } + + client, mux, _, teardown := setup() + defer teardown() + + input := &body{ + Action: "a", + Reason: "r", + } + + mux.HandleFunc("/orgs/o/personal-access-token-requests/r", func(w http.ResponseWriter, r *http.Request) { + v := new(body) + json.NewDecoder(r.Body).Decode(v) + + testMethod(t, r, http.MethodPost) + if !cmp.Equal(v, input) { + t.Errorf("Request body = %+v, want %+v", v, input) + } + + w.WriteHeader(http.StatusNoContent) + }) + + ctx := context.Background() + res, err := client.Organizations.ReviewPersonalAccessTokenRequest(ctx, "o", "r", input.Action, input.Reason) + if err != nil { + t.Errorf("Organizations.ReviewPersonalAccessTokenRequest returned error: %v", err) + } + + if res.StatusCode != http.StatusNoContent { + t.Errorf("Organizations.ReviewPersonalAccessTokenRequest returned %v, want %v", res.StatusCode, http.StatusNoContent) + } + + const methodName = "ReviewPersonalAccessTokenRequest" + testBadOptions(t, methodName, func() (err error) { + _, err = client.Organizations.ReviewPersonalAccessTokenRequest(ctx, "\n", "", "", "") + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + return client.Organizations.ReviewPersonalAccessTokenRequest(ctx, "o", "r", input.Action, input.Reason) + }) +} From 567111db4862b75aba1e36f39b0e28ffb1723997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Penteado?= <4219131+joaopenteado@users.noreply.github.com> Date: Wed, 5 Jul 2023 23:47:25 +0900 Subject: [PATCH 2/4] Added package comment headers and fixed godoc comments Co-authored-by: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> --- github/orgs_personal_access_tokens.go | 7 ++++++- github/orgs_personal_access_tokens_test.go | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/github/orgs_personal_access_tokens.go b/github/orgs_personal_access_tokens.go index 4fbb4cd2eff..e9277875352 100644 --- a/github/orgs_personal_access_tokens.go +++ b/github/orgs_personal_access_tokens.go @@ -1,3 +1,8 @@ +// Copyright 2023 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package github import ( @@ -6,7 +11,7 @@ import ( "net/http" ) -// Approves or denies a pending request to access organization resources via a fine-grained personal access token. +// ReviewPersonalAccessTokenRequest approves or denies a pending request to access organization resources via a fine-grained personal access token. // Only GitHub Apps can call this API, using the `organization_personal_access_token_requests: write` permission. // `action` can be one of `approve` or `deny`. // diff --git a/github/orgs_personal_access_tokens_test.go b/github/orgs_personal_access_tokens_test.go index 1abaa69de06..d0e4c7abfec 100644 --- a/github/orgs_personal_access_tokens_test.go +++ b/github/orgs_personal_access_tokens_test.go @@ -1,3 +1,8 @@ +// Copyright 2023 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package github import ( From b96882dc47fd33ab07415ea3102549795235ed77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Penteado?= <4219131+joaopenteado@users.noreply.github.com> Date: Thu, 6 Jul 2023 11:52:39 +0900 Subject: [PATCH 3/4] Conformed the `ReviewPersonalAccessTokenRequest` method to the existing API --- github/github-accessors.go | 8 +++++ github/github-accessors_test.go | 10 +++++++ github/orgs_personal_access_tokens.go | 17 +++++------ github/orgs_personal_access_tokens_test.go | 35 ++++++++++++++-------- 4 files changed, 49 insertions(+), 21 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 41cd582c1a1..c7089951a34 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -18806,6 +18806,14 @@ func (r *ReviewersRequest) GetNodeID() string { return *r.NodeID } +// GetReason returns the Reason field if it's non-nil, zero value otherwise. +func (r *ReviewPersonalAccessTokenRequestOptions) GetReason() string { + if r == nil || r.Reason == nil { + return "" + } + return *r.Reason +} + // GetDescription returns the Description field if it's non-nil, zero value otherwise. func (r *Rule) GetDescription() string { if r == nil || r.Description == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 993a12484b9..7d151331cbb 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -21933,6 +21933,16 @@ func TestReviewersRequest_GetNodeID(tt *testing.T) { r.GetNodeID() } +func TestReviewPersonalAccessTokenRequestOptions_GetReason(tt *testing.T) { + var zeroValue string + r := &ReviewPersonalAccessTokenRequestOptions{Reason: &zeroValue} + r.GetReason() + r = &ReviewPersonalAccessTokenRequestOptions{} + r.GetReason() + r = nil + r.GetReason() +} + func TestRule_GetDescription(tt *testing.T) { var zeroValue string r := &Rule{Description: &zeroValue} diff --git a/github/orgs_personal_access_tokens.go b/github/orgs_personal_access_tokens.go index e9277875352..2691ff2f7dd 100644 --- a/github/orgs_personal_access_tokens.go +++ b/github/orgs_personal_access_tokens.go @@ -11,22 +11,21 @@ import ( "net/http" ) +// ReviewPersonalAccessTokenRequestOptions specifies the parameters to the ReviewPersonalAccessTokenRequest method. +type ReviewPersonalAccessTokenRequestOptions struct { + Action string `json:"action"` + Reason *string `json:"reason,omitempty"` +} + // ReviewPersonalAccessTokenRequest approves or denies a pending request to access organization resources via a fine-grained personal access token. // Only GitHub Apps can call this API, using the `organization_personal_access_token_requests: write` permission. // `action` can be one of `approve` or `deny`. // // GitHub API docs: https://docs.github.com/en/rest/orgs/personal-access-tokens?apiVersion=2022-11-28#review-a-request-to-access-organization-resources-with-a-fine-grained-personal-access-token -func (s *OrganizationsService) ReviewPersonalAccessTokenRequest(ctx context.Context, org, requestID, action, reason string) (*Response, error) { +func (s *OrganizationsService) ReviewPersonalAccessTokenRequest(ctx context.Context, org, requestID string, opts ReviewPersonalAccessTokenRequestOptions) (*Response, error) { u := fmt.Sprintf("orgs/%v/personal-access-token-requests/%v", org, requestID) - body := struct { - Action string `json:"action"` - Reason string `json:"reason,omitempty"` - }{ - Action: action, - Reason: reason, - } - req, err := s.client.NewRequest(http.MethodPost, u, &body) + req, err := s.client.NewRequest(http.MethodPost, u, &opts) if err != nil { return nil, err } diff --git a/github/orgs_personal_access_tokens_test.go b/github/orgs_personal_access_tokens_test.go index d0e4c7abfec..7e5c5b29d91 100644 --- a/github/orgs_personal_access_tokens_test.go +++ b/github/orgs_personal_access_tokens_test.go @@ -15,25 +15,20 @@ import ( ) func TestOrganizationsService_ReviewPersonalAccessTokenRequest(t *testing.T) { - type body struct { - Action string `json:"action"` - Reason string `json:"reason,omitempty"` - } - client, mux, _, teardown := setup() defer teardown() - input := &body{ + input := ReviewPersonalAccessTokenRequestOptions{ Action: "a", - Reason: "r", + Reason: String("r"), } mux.HandleFunc("/orgs/o/personal-access-token-requests/r", func(w http.ResponseWriter, r *http.Request) { - v := new(body) + v := new(ReviewPersonalAccessTokenRequestOptions) json.NewDecoder(r.Body).Decode(v) testMethod(t, r, http.MethodPost) - if !cmp.Equal(v, input) { + if !cmp.Equal(v, &input) { t.Errorf("Request body = %+v, want %+v", v, input) } @@ -41,7 +36,7 @@ func TestOrganizationsService_ReviewPersonalAccessTokenRequest(t *testing.T) { }) ctx := context.Background() - res, err := client.Organizations.ReviewPersonalAccessTokenRequest(ctx, "o", "r", input.Action, input.Reason) + res, err := client.Organizations.ReviewPersonalAccessTokenRequest(ctx, "o", "r", input) if err != nil { t.Errorf("Organizations.ReviewPersonalAccessTokenRequest returned error: %v", err) } @@ -52,11 +47,27 @@ func TestOrganizationsService_ReviewPersonalAccessTokenRequest(t *testing.T) { const methodName = "ReviewPersonalAccessTokenRequest" testBadOptions(t, methodName, func() (err error) { - _, err = client.Organizations.ReviewPersonalAccessTokenRequest(ctx, "\n", "", "", "") + _, err = client.Organizations.ReviewPersonalAccessTokenRequest(ctx, "\n", "", input) return err }) testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - return client.Organizations.ReviewPersonalAccessTokenRequest(ctx, "o", "r", input.Action, input.Reason) + return client.Organizations.ReviewPersonalAccessTokenRequest(ctx, "o", "r", input) }) } + +func TestReviewPersonalAccessTokenRequestOptions_Marshal(t *testing.T) { + testJSONMarshal(t, &ReviewPersonalAccessTokenRequestOptions{}, "{}") + + u := &ReviewPersonalAccessTokenRequestOptions{ + Action: "a", + Reason: String("r"), + } + + want := `{ + "action": "a", + "reason": "r" + }` + + testJSONMarshal(t, u, want) +} From c5f2b2744d43439bedc7d679f3ba8012349787c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Penteado?= <4219131+joaopenteado@users.noreply.github.com> Date: Fri, 7 Jul 2023 17:49:05 +0900 Subject: [PATCH 4/4] Changed `ReviewPersonalAccessTokenRequest` function signature for type safety --- github/orgs_personal_access_tokens.go | 2 +- github/orgs_personal_access_tokens_test.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/github/orgs_personal_access_tokens.go b/github/orgs_personal_access_tokens.go index 2691ff2f7dd..c30ff2843ee 100644 --- a/github/orgs_personal_access_tokens.go +++ b/github/orgs_personal_access_tokens.go @@ -22,7 +22,7 @@ type ReviewPersonalAccessTokenRequestOptions struct { // `action` can be one of `approve` or `deny`. // // GitHub API docs: https://docs.github.com/en/rest/orgs/personal-access-tokens?apiVersion=2022-11-28#review-a-request-to-access-organization-resources-with-a-fine-grained-personal-access-token -func (s *OrganizationsService) ReviewPersonalAccessTokenRequest(ctx context.Context, org, requestID string, opts ReviewPersonalAccessTokenRequestOptions) (*Response, error) { +func (s *OrganizationsService) ReviewPersonalAccessTokenRequest(ctx context.Context, org string, requestID int64, opts ReviewPersonalAccessTokenRequestOptions) (*Response, error) { u := fmt.Sprintf("orgs/%v/personal-access-token-requests/%v", org, requestID) req, err := s.client.NewRequest(http.MethodPost, u, &opts) diff --git a/github/orgs_personal_access_tokens_test.go b/github/orgs_personal_access_tokens_test.go index 7e5c5b29d91..93ee1b3db93 100644 --- a/github/orgs_personal_access_tokens_test.go +++ b/github/orgs_personal_access_tokens_test.go @@ -23,7 +23,7 @@ func TestOrganizationsService_ReviewPersonalAccessTokenRequest(t *testing.T) { Reason: String("r"), } - mux.HandleFunc("/orgs/o/personal-access-token-requests/r", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/orgs/o/personal-access-token-requests/1", func(w http.ResponseWriter, r *http.Request) { v := new(ReviewPersonalAccessTokenRequestOptions) json.NewDecoder(r.Body).Decode(v) @@ -36,7 +36,7 @@ func TestOrganizationsService_ReviewPersonalAccessTokenRequest(t *testing.T) { }) ctx := context.Background() - res, err := client.Organizations.ReviewPersonalAccessTokenRequest(ctx, "o", "r", input) + res, err := client.Organizations.ReviewPersonalAccessTokenRequest(ctx, "o", 1, input) if err != nil { t.Errorf("Organizations.ReviewPersonalAccessTokenRequest returned error: %v", err) } @@ -47,12 +47,12 @@ func TestOrganizationsService_ReviewPersonalAccessTokenRequest(t *testing.T) { const methodName = "ReviewPersonalAccessTokenRequest" testBadOptions(t, methodName, func() (err error) { - _, err = client.Organizations.ReviewPersonalAccessTokenRequest(ctx, "\n", "", input) + _, err = client.Organizations.ReviewPersonalAccessTokenRequest(ctx, "\n", 0, input) return err }) testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - return client.Organizations.ReviewPersonalAccessTokenRequest(ctx, "o", "r", input) + return client.Organizations.ReviewPersonalAccessTokenRequest(ctx, "o", 1, input) }) }