Skip to content

Commit

Permalink
Restrict request params of Create to known subset (#1017)
Browse files Browse the repository at this point in the history
Fixes #1014.
  • Loading branch information
gmlewis authored Sep 26, 2018
1 parent 429a78b commit 02e358b
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 18 deletions.
51 changes: 49 additions & 2 deletions github/repos.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ type Repository struct {
AllowSquashMerge *bool `json:"allow_squash_merge,omitempty"`
AllowMergeCommit *bool `json:"allow_merge_commit,omitempty"`
Topics []string `json:"topics,omitempty"`
Archived *bool `json:"archived,omitempty"`

// Only provided when using RepositoriesService.Get while in preview
License *License `json:"license,omitempty"`
Expand All @@ -69,7 +70,6 @@ type Repository struct {
HasDownloads *bool `json:"has_downloads,omitempty"`
LicenseTemplate *string `json:"license_template,omitempty"`
GitignoreTemplate *string `json:"gitignore_template,omitempty"`
Archived *bool `json:"archived,omitempty"`

// Creating an organization repository. Required for non-owners.
TeamID *int64 `json:"team_id,omitempty"`
Expand Down Expand Up @@ -259,10 +259,40 @@ func (s *RepositoriesService) ListAll(ctx context.Context, opt *RepositoryListAl
return repos, resp, nil
}

// createRepoRequest is a subset of Repository and is used internally
// by Create to pass only the known fields for the endpoint.
//
// See https://github.com/google/go-github/issues/1014 for more
// information.
type createRepoRequest struct {
// Name is required when creating a repo.
Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
Homepage *string `json:"homepage,omitempty"`

Private *bool `json:"private,omitempty"`
HasIssues *bool `json:"has_issues,omitempty"`
HasProjects *bool `json:"has_projects,omitempty"`
HasWiki *bool `json:"has_wiki,omitempty"`

// Creating an organization repository. Required for non-owners.
TeamID *int64 `json:"team_id,omitempty"`

AutoInit *bool `json:"auto_init,omitempty"`
GitignoreTemplate *string `json:"gitignore_template,omitempty"`
LicenseTemplate *string `json:"license_template,omitempty"`
AllowSquashMerge *bool `json:"allow_squash_merge,omitempty"`
AllowMergeCommit *bool `json:"allow_merge_commit,omitempty"`
AllowRebaseMerge *bool `json:"allow_rebase_merge,omitempty"`
}

// Create a new repository. If an organization is specified, the new
// repository will be created under that org. If the empty string is
// specified, it will be created for the authenticated user.
//
// Note that only a subset of the repo fields are used and repo must
// not be nil.
//
// GitHub API docs: https://developer.github.com/v3/repos/#create
func (s *RepositoriesService) Create(ctx context.Context, org string, repo *Repository) (*Repository, *Response, error) {
var u string
Expand All @@ -272,7 +302,24 @@ func (s *RepositoriesService) Create(ctx context.Context, org string, repo *Repo
u = "user/repos"
}

req, err := s.client.NewRequest("POST", u, repo)
repoReq := &createRepoRequest{
Name: repo.Name,
Description: repo.Description,
Homepage: repo.Homepage,
Private: repo.Private,
HasIssues: repo.HasIssues,
HasProjects: repo.HasProjects,
HasWiki: repo.HasWiki,
TeamID: repo.TeamID,
AutoInit: repo.AutoInit,
GitignoreTemplate: repo.GitignoreTemplate,
LicenseTemplate: repo.LicenseTemplate,
AllowSquashMerge: repo.AllowSquashMerge,
AllowMergeCommit: repo.AllowMergeCommit,
AllowRebaseMerge: repo.AllowRebaseMerge,
}

req, err := s.client.NewRequest("POST", u, repoReq)
if err != nil {
return nil, nil, err
}
Expand Down
32 changes: 16 additions & 16 deletions github/repos_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,15 +172,19 @@ func TestRepositoriesService_Create_user(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

input := &Repository{Name: String("n")}
input := &Repository{
Name: String("n"),
Archived: Bool(true), // not passed along.
}

mux.HandleFunc("/user/repos", func(w http.ResponseWriter, r *http.Request) {
v := new(Repository)
v := new(createRepoRequest)
json.NewDecoder(r.Body).Decode(v)

testMethod(t, r, "POST")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
want := &createRepoRequest{Name: String("n")}
if !reflect.DeepEqual(v, want) {
t.Errorf("Request body = %+v, want %+v", v, want)
}

fmt.Fprint(w, `{"id":1}`)
Expand All @@ -201,15 +205,19 @@ func TestRepositoriesService_Create_org(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

input := &Repository{Name: String("n")}
input := &Repository{
Name: String("n"),
Archived: Bool(true), // not passed along.
}

mux.HandleFunc("/orgs/o/repos", func(w http.ResponseWriter, r *http.Request) {
v := new(Repository)
v := new(createRepoRequest)
json.NewDecoder(r.Body).Decode(v)

testMethod(t, r, "POST")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
want := &createRepoRequest{Name: String("n")}
if !reflect.DeepEqual(v, want) {
t.Errorf("Request body = %+v, want %+v", v, want)
}

fmt.Fprint(w, `{"id":1}`)
Expand All @@ -226,14 +234,6 @@ func TestRepositoriesService_Create_org(t *testing.T) {
}
}

func TestRepositoriesService_Create_invalidOrg(t *testing.T) {
client, _, _, teardown := setup()
defer teardown()

_, _, err := client.Repositories.Create(context.Background(), "%", nil)
testURLParseError(t, err)
}

func TestRepositoriesService_Get(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135 h1:zLTLjkaOFEFIOxY5BWLFLwh+cL8vOBW4XJ2aqLE/Tf0=
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac h1:7d7lG9fHOLdL6jZPtnV4LpI41SbohIJ1Atq7U991dMg=
golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
Expand Down

0 comments on commit 02e358b

Please sign in to comment.