From 0fb51b4c35b0832438e7aafbe0d33b9aa966b07a Mon Sep 17 00:00:00 2001 From: Will Norris Date: Mon, 6 Jul 2015 12:25:16 -0700 Subject: [PATCH] update team membership APIs for new permissions - AddTeamMembership and ListTeamMembers both take new Option structs to specify role. (BREAKING CHANGE). - Add Role to ListMembersOptions - update Permission and Role docs Ref #187 --- github/orgs_members.go | 24 ++++++++++++++++- github/orgs_members_test.go | 3 +++ github/orgs_teams.go | 53 ++++++++++++++++++++++++++++++++----- github/orgs_teams_test.go | 10 ++++--- 4 files changed, 80 insertions(+), 10 deletions(-) diff --git a/github/orgs_members.go b/github/orgs_members.go index 64dcfcc..01a78c0 100644 --- a/github/orgs_members.go +++ b/github/orgs_members.go @@ -15,7 +15,16 @@ type Membership struct { // Possible values are: "active", "pending" State *string `json:"state,omitempty"` - // TODO(willnorris): add docs + // Role identifies the user's role within the organization or team. + // Possible values for organization membership: + // member - non-owner organization member + // admin - organization owner + // + // Possible values for team membership are: + // member - a normal member of the team + // maintainer - a team maintainer. Able to add/remove other team + // members, promote other team members to team + // maintainer, and edit the team’s name and description Role *string `json:"role,omitempty"` // For organization membership, the API URL of the organization. @@ -43,6 +52,15 @@ type ListMembersOptions struct { // 2fa_disabled, all. Default is "all". Filter string `url:"filter,omitempty"` + // Role filters memebers returned by their role in the organization. + // Possible values are: + // all - all members of the organization, regardless of role + // admin - organization owners + // member - non-organization members + // + // Default is "all". + Role string `url:"role,omitempty"` + ListOptions } @@ -68,6 +86,10 @@ func (s *OrganizationsService) ListMembers(org string, opt *ListMembersOptions) return nil, nil, err } + if opt != nil && opt.Role != "" { + req.Header.Set("Accept", mediaTypeOrgPermissionPreview) + } + members := new([]User) resp, err := s.client.Do(req, members) if err != nil { diff --git a/github/orgs_members_test.go b/github/orgs_members_test.go index 493488a..2bec813 100644 --- a/github/orgs_members_test.go +++ b/github/orgs_members_test.go @@ -19,8 +19,10 @@ func TestOrganizationsService_ListMembers(t *testing.T) { mux.HandleFunc("/orgs/o/members", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeOrgPermissionPreview) testFormValues(t, r, values{ "filter": "2fa_disabled", + "role": "admin", "page": "2", }) fmt.Fprint(w, `[{"id":1}]`) @@ -29,6 +31,7 @@ func TestOrganizationsService_ListMembers(t *testing.T) { opt := &ListMembersOptions{ PublicOnly: false, Filter: "2fa_disabled", + Role: "admin", ListOptions: ListOptions{Page: 2}, } members, _, err := client.Organizations.ListMembers("o", opt) diff --git a/github/orgs_teams.go b/github/orgs_teams.go index f1434d0..85de2b7 100644 --- a/github/orgs_teams.go +++ b/github/orgs_teams.go @@ -140,11 +140,21 @@ func (s *OrganizationsService) DeleteTeam(team int) (*Response, error) { return s.client.Do(req, nil) } +// OrganizationListTeamMembersOptions specifies the optional parameters to the +// OrganizationsService.ListTeamMembers method. +type OrganizationListTeamMembersOptions struct { + // Role filters members returned by their role in the team. Possible + // values are "all", "member", "maintainer". Default is "all". + Role string `url:"role,omitempty"` + + ListOptions +} + // ListTeamMembers lists all of the users who are members of the specified // team. // // GitHub API docs: http://developer.github.com/v3/orgs/teams/#list-team-members -func (s *OrganizationsService) ListTeamMembers(team int, opt *ListOptions) ([]User, *Response, error) { +func (s *OrganizationsService) ListTeamMembers(team int, opt *OrganizationListTeamMembersOptions) ([]User, *Response, error) { u := fmt.Sprintf("teams/%v/members", team) u, err := addOptions(u, opt) if err != nil { @@ -156,6 +166,10 @@ func (s *OrganizationsService) ListTeamMembers(team int, opt *ListOptions) ([]Us return nil, nil, err } + if opt != nil && opt.Role != "" { + req.Header.Set("Accept", mediaTypeOrgPermissionPreview) + } + members := new([]User) resp, err := s.client.Do(req, members) if err != nil { @@ -230,10 +244,14 @@ func (s *OrganizationsService) IsTeamRepo(team int, owner string, repo string) ( // OrganizationAddTeamRepoOptions specifies the optional parameters to the // OrganizationsService.AddTeamRepo method. type OrganizationAddTeamRepoOptions struct { - // Permission specifies the permission to grant the team on this - // repository. Possible values are: pull, push, admin. If not - // specified, the team's permission attribute will be used. - Permission string `url:"permission"` + // Permission specifies the permission to grant the team on this repository. + // Possible values are: + // pull - team members can pull, but not push to or administer this repository + // push - team members can pull and push, but not administer this repository + // admin - team members can pull, push and administer this repository + // + // If not specified, the team's permission attribute will be used. + Permission string `url:"permission,omitempty"` } // AddTeamRepo adds a repository to be managed by the specified team. The @@ -317,6 +335,20 @@ func (s *OrganizationsService) GetTeamMembership(team int, user string) (*Member return t, resp, err } +// OrganizationAddTeamMembershipOptions does stuff specifies the optional +// parameters to the OrganizationsService.AddTeamMembership method. +type OrganizationAddTeamMembershipOptions struct { + // Role specifies the role the user should have in the team. Possible + // values are: + // member - a normal member of the team + // maintainer - a team maintainer. Able to add/remove other team + // members, promote other team members to team + // maintainer, and edit the team’s name and description + // + // Default value is "member". + Role string `url:"role,omitempty"` +} + // AddTeamMembership adds or invites a user to a team. // // In order to add a membership between a user and a team, the authenticated @@ -335,13 +367,22 @@ func (s *OrganizationsService) GetTeamMembership(team int, user string) (*Member // added as a member of the team. // // GitHub API docs: https://developer.github.com/v3/orgs/teams/#add-team-membership -func (s *OrganizationsService) AddTeamMembership(team int, user string) (*Membership, *Response, error) { +func (s *OrganizationsService) AddTeamMembership(team int, user string, opt *OrganizationAddTeamMembershipOptions) (*Membership, *Response, error) { u := fmt.Sprintf("teams/%v/memberships/%v", team, user) + u, err := addOptions(u, opt) + if err != nil { + return nil, nil, err + } + req, err := s.client.NewRequest("PUT", u, nil) if err != nil { return nil, nil, err } + if opt != nil { + req.Header.Set("Accept", mediaTypeOrgPermissionPreview) + } + t := new(Membership) resp, err := s.client.Do(req, t) if err != nil { diff --git a/github/orgs_teams_test.go b/github/orgs_teams_test.go index e8c4280..57bb840 100644 --- a/github/orgs_teams_test.go +++ b/github/orgs_teams_test.go @@ -145,11 +145,12 @@ func TestOrganizationsService_ListTeamMembers(t *testing.T) { mux.HandleFunc("/teams/1/members", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testFormValues(t, r, values{"page": "2"}) + testHeader(t, r, "Accept", mediaTypeOrgPermissionPreview) + testFormValues(t, r, values{"role": "member", "page": "2"}) fmt.Fprint(w, `[{"id":1}]`) }) - opt := &ListOptions{Page: 2} + opt := &OrganizationListTeamMembersOptions{Role: "member", ListOptions: ListOptions{Page: 2}} members, _, err := client.Organizations.ListTeamMembers(1, opt) if err != nil { t.Errorf("Organizations.ListTeamMembers returned error: %v", err) @@ -436,10 +437,13 @@ func TestOrganizationsService_AddTeamMembership(t *testing.T) { mux.HandleFunc("/teams/1/memberships/u", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "PUT") + testFormValues(t, r, values{"role": "maintainer"}) + testHeader(t, r, "Accept", mediaTypeOrgPermissionPreview) fmt.Fprint(w, `{"url":"u", "state":"pending"}`) }) - membership, _, err := client.Organizations.AddTeamMembership(1, "u") + opt := &OrganizationAddTeamMembershipOptions{Role: "maintainer"} + membership, _, err := client.Organizations.AddTeamMembership(1, "u", opt) if err != nil { t.Errorf("Organizations.AddTeamMembership returned error: %v", err) }