本站源代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

458 lines
15KB

  1. // Copyright 2018 The go-github AUTHORS. All rights reserved.
  2. //
  3. // Use of this source code is governed by a BSD-style
  4. // license that can be found in the LICENSE file.
  5. package github
  6. import (
  7. "context"
  8. "fmt"
  9. "strings"
  10. "time"
  11. )
  12. // TeamsService provides access to the team-related functions
  13. // in the GitHub API.
  14. //
  15. // GitHub API docs: https://developer.github.com/v3/teams/
  16. type TeamsService service
  17. // Team represents a team within a GitHub organization. Teams are used to
  18. // manage access to an organization's repositories.
  19. type Team struct {
  20. ID *int64 `json:"id,omitempty"`
  21. Name *string `json:"name,omitempty"`
  22. Description *string `json:"description,omitempty"`
  23. URL *string `json:"url,omitempty"`
  24. Slug *string `json:"slug,omitempty"`
  25. // Permission specifies the default permission for repositories owned by the team.
  26. Permission *string `json:"permission,omitempty"`
  27. // Privacy identifies the level of privacy this team should have.
  28. // Possible values are:
  29. // secret - only visible to organization owners and members of this team
  30. // closed - visible to all members of this organization
  31. // Default is "secret".
  32. Privacy *string `json:"privacy,omitempty"`
  33. MembersCount *int `json:"members_count,omitempty"`
  34. ReposCount *int `json:"repos_count,omitempty"`
  35. Organization *Organization `json:"organization,omitempty"`
  36. MembersURL *string `json:"members_url,omitempty"`
  37. RepositoriesURL *string `json:"repositories_url,omitempty"`
  38. Parent *Team `json:"parent,omitempty"`
  39. // LDAPDN is only available in GitHub Enterprise and when the team
  40. // membership is synchronized with LDAP.
  41. LDAPDN *string `json:"ldap_dn,omitempty"`
  42. }
  43. func (t Team) String() string {
  44. return Stringify(t)
  45. }
  46. // Invitation represents a team member's invitation status.
  47. type Invitation struct {
  48. ID *int64 `json:"id,omitempty"`
  49. Login *string `json:"login,omitempty"`
  50. Email *string `json:"email,omitempty"`
  51. // Role can be one of the values - 'direct_member', 'admin', 'billing_manager', 'hiring_manager', or 'reinstate'.
  52. Role *string `json:"role,omitempty"`
  53. CreatedAt *time.Time `json:"created_at,omitempty"`
  54. Inviter *User `json:"inviter,omitempty"`
  55. TeamCount *int `json:"team_count,omitempty"`
  56. InvitationTeamURL *string `json:"invitation_team_url,omitempty"`
  57. }
  58. func (i Invitation) String() string {
  59. return Stringify(i)
  60. }
  61. // ListTeams lists all of the teams for an organization.
  62. //
  63. // GitHub API docs: https://developer.github.com/v3/teams/#list-teams
  64. func (s *TeamsService) ListTeams(ctx context.Context, org string, opt *ListOptions) ([]*Team, *Response, error) {
  65. u := fmt.Sprintf("orgs/%v/teams", org)
  66. u, err := addOptions(u, opt)
  67. if err != nil {
  68. return nil, nil, err
  69. }
  70. req, err := s.client.NewRequest("GET", u, nil)
  71. if err != nil {
  72. return nil, nil, err
  73. }
  74. // TODO: remove custom Accept header when this API fully launches.
  75. req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
  76. var teams []*Team
  77. resp, err := s.client.Do(ctx, req, &teams)
  78. if err != nil {
  79. return nil, resp, err
  80. }
  81. return teams, resp, nil
  82. }
  83. // GetTeam fetches a team by ID.
  84. //
  85. // GitHub API docs: https://developer.github.com/v3/teams/#get-team
  86. func (s *TeamsService) GetTeam(ctx context.Context, team int64) (*Team, *Response, error) {
  87. u := fmt.Sprintf("teams/%v", team)
  88. req, err := s.client.NewRequest("GET", u, nil)
  89. if err != nil {
  90. return nil, nil, err
  91. }
  92. // TODO: remove custom Accept header when this API fully launches.
  93. req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
  94. t := new(Team)
  95. resp, err := s.client.Do(ctx, req, t)
  96. if err != nil {
  97. return nil, resp, err
  98. }
  99. return t, resp, nil
  100. }
  101. // NewTeam represents a team to be created or modified.
  102. type NewTeam struct {
  103. Name string `json:"name"` // Name of the team. (Required.)
  104. Description *string `json:"description,omitempty"`
  105. Maintainers []string `json:"maintainers,omitempty"`
  106. RepoNames []string `json:"repo_names,omitempty"`
  107. ParentTeamID *int64 `json:"parent_team_id,omitempty"`
  108. // Deprecated: Permission is deprecated when creating or editing a team in an org
  109. // using the new GitHub permission model. It no longer identifies the
  110. // permission a team has on its repos, but only specifies the default
  111. // permission a repo is initially added with. Avoid confusion by
  112. // specifying a permission value when calling AddTeamRepo.
  113. Permission *string `json:"permission,omitempty"`
  114. // Privacy identifies the level of privacy this team should have.
  115. // Possible values are:
  116. // secret - only visible to organization owners and members of this team
  117. // closed - visible to all members of this organization
  118. // Default is "secret".
  119. Privacy *string `json:"privacy,omitempty"`
  120. // LDAPDN may be used in GitHub Enterprise when the team membership
  121. // is synchronized with LDAP.
  122. LDAPDN *string `json:"ldap_dn,omitempty"`
  123. }
  124. func (s NewTeam) String() string {
  125. return Stringify(s)
  126. }
  127. // CreateTeam creates a new team within an organization.
  128. //
  129. // GitHub API docs: https://developer.github.com/v3/teams/#create-team
  130. func (s *TeamsService) CreateTeam(ctx context.Context, org string, team NewTeam) (*Team, *Response, error) {
  131. u := fmt.Sprintf("orgs/%v/teams", org)
  132. req, err := s.client.NewRequest("POST", u, team)
  133. if err != nil {
  134. return nil, nil, err
  135. }
  136. // TODO: remove custom Accept header when this API fully launches.
  137. req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
  138. t := new(Team)
  139. resp, err := s.client.Do(ctx, req, t)
  140. if err != nil {
  141. return nil, resp, err
  142. }
  143. return t, resp, nil
  144. }
  145. // EditTeam edits a team.
  146. //
  147. // GitHub API docs: https://developer.github.com/v3/teams/#edit-team
  148. func (s *TeamsService) EditTeam(ctx context.Context, id int64, team NewTeam) (*Team, *Response, error) {
  149. u := fmt.Sprintf("teams/%v", id)
  150. req, err := s.client.NewRequest("PATCH", u, team)
  151. if err != nil {
  152. return nil, nil, err
  153. }
  154. // TODO: remove custom Accept header when this API fully launches.
  155. req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
  156. t := new(Team)
  157. resp, err := s.client.Do(ctx, req, t)
  158. if err != nil {
  159. return nil, resp, err
  160. }
  161. return t, resp, nil
  162. }
  163. // DeleteTeam deletes a team.
  164. //
  165. // GitHub API docs: https://developer.github.com/v3/teams/#delete-team
  166. func (s *TeamsService) DeleteTeam(ctx context.Context, team int64) (*Response, error) {
  167. u := fmt.Sprintf("teams/%v", team)
  168. req, err := s.client.NewRequest("DELETE", u, nil)
  169. if err != nil {
  170. return nil, err
  171. }
  172. req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
  173. return s.client.Do(ctx, req, nil)
  174. }
  175. // ListChildTeams lists child teams for a team.
  176. //
  177. // GitHub API docs: https://developer.github.com/v3/teams/#list-child-teams
  178. func (s *TeamsService) ListChildTeams(ctx context.Context, teamID int64, opt *ListOptions) ([]*Team, *Response, error) {
  179. u := fmt.Sprintf("teams/%v/teams", teamID)
  180. u, err := addOptions(u, opt)
  181. if err != nil {
  182. return nil, nil, err
  183. }
  184. req, err := s.client.NewRequest("GET", u, nil)
  185. if err != nil {
  186. return nil, nil, err
  187. }
  188. req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
  189. var teams []*Team
  190. resp, err := s.client.Do(ctx, req, &teams)
  191. if err != nil {
  192. return nil, resp, err
  193. }
  194. return teams, resp, nil
  195. }
  196. // ListTeamRepos lists the repositories that the specified team has access to.
  197. //
  198. // GitHub API docs: https://developer.github.com/v3/teams/#list-team-repos
  199. func (s *TeamsService) ListTeamRepos(ctx context.Context, team int64, opt *ListOptions) ([]*Repository, *Response, error) {
  200. u := fmt.Sprintf("teams/%v/repos", team)
  201. u, err := addOptions(u, opt)
  202. if err != nil {
  203. return nil, nil, err
  204. }
  205. req, err := s.client.NewRequest("GET", u, nil)
  206. if err != nil {
  207. return nil, nil, err
  208. }
  209. // TODO: remove custom Accept header when topics API fully launches.
  210. headers := []string{mediaTypeTopicsPreview, mediaTypeNestedTeamsPreview}
  211. req.Header.Set("Accept", strings.Join(headers, ", "))
  212. var repos []*Repository
  213. resp, err := s.client.Do(ctx, req, &repos)
  214. if err != nil {
  215. return nil, resp, err
  216. }
  217. return repos, resp, nil
  218. }
  219. // IsTeamRepo checks if a team manages the specified repository. If the
  220. // repository is managed by team, a Repository is returned which includes the
  221. // permissions team has for that repo.
  222. //
  223. // GitHub API docs: https://developer.github.com/v3/teams/#check-if-a-team-manages-a-repository
  224. func (s *TeamsService) IsTeamRepo(ctx context.Context, team int64, owner string, repo string) (*Repository, *Response, error) {
  225. u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo)
  226. req, err := s.client.NewRequest("GET", u, nil)
  227. if err != nil {
  228. return nil, nil, err
  229. }
  230. headers := []string{mediaTypeOrgPermissionRepo, mediaTypeNestedTeamsPreview}
  231. req.Header.Set("Accept", strings.Join(headers, ", "))
  232. repository := new(Repository)
  233. resp, err := s.client.Do(ctx, req, repository)
  234. if err != nil {
  235. return nil, resp, err
  236. }
  237. return repository, resp, nil
  238. }
  239. // TeamAddTeamRepoOptions specifies the optional parameters to the
  240. // TeamsService.AddTeamRepo method.
  241. type TeamAddTeamRepoOptions struct {
  242. // Permission specifies the permission to grant the team on this repository.
  243. // Possible values are:
  244. // pull - team members can pull, but not push to or administer this repository
  245. // push - team members can pull and push, but not administer this repository
  246. // admin - team members can pull, push and administer this repository
  247. //
  248. // If not specified, the team's permission attribute will be used.
  249. Permission string `json:"permission,omitempty"`
  250. }
  251. // AddTeamRepo adds a repository to be managed by the specified team. The
  252. // specified repository must be owned by the organization to which the team
  253. // belongs, or a direct fork of a repository owned by the organization.
  254. //
  255. // GitHub API docs: https://developer.github.com/v3/teams/#add-team-repo
  256. func (s *TeamsService) AddTeamRepo(ctx context.Context, team int64, owner string, repo string, opt *TeamAddTeamRepoOptions) (*Response, error) {
  257. u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo)
  258. req, err := s.client.NewRequest("PUT", u, opt)
  259. if err != nil {
  260. return nil, err
  261. }
  262. return s.client.Do(ctx, req, nil)
  263. }
  264. // RemoveTeamRepo removes a repository from being managed by the specified
  265. // team. Note that this does not delete the repository, it just removes it
  266. // from the team.
  267. //
  268. // GitHub API docs: https://developer.github.com/v3/teams/#remove-team-repo
  269. func (s *TeamsService) RemoveTeamRepo(ctx context.Context, team int64, owner string, repo string) (*Response, error) {
  270. u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo)
  271. req, err := s.client.NewRequest("DELETE", u, nil)
  272. if err != nil {
  273. return nil, err
  274. }
  275. return s.client.Do(ctx, req, nil)
  276. }
  277. // ListUserTeams lists a user's teams
  278. // GitHub API docs: https://developer.github.com/v3/teams/#list-user-teams
  279. func (s *TeamsService) ListUserTeams(ctx context.Context, opt *ListOptions) ([]*Team, *Response, error) {
  280. u := "user/teams"
  281. u, err := addOptions(u, opt)
  282. if err != nil {
  283. return nil, nil, err
  284. }
  285. req, err := s.client.NewRequest("GET", u, nil)
  286. if err != nil {
  287. return nil, nil, err
  288. }
  289. // TODO: remove custom Accept header when this API fully launches.
  290. req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
  291. var teams []*Team
  292. resp, err := s.client.Do(ctx, req, &teams)
  293. if err != nil {
  294. return nil, resp, err
  295. }
  296. return teams, resp, nil
  297. }
  298. // ListTeamProjects lists the organization projects for a team.
  299. //
  300. // GitHub API docs: https://developer.github.com/v3/teams/#list-team-projects
  301. func (s *TeamsService) ListTeamProjects(ctx context.Context, teamID int64) ([]*Project, *Response, error) {
  302. u := fmt.Sprintf("teams/%v/projects", teamID)
  303. req, err := s.client.NewRequest("GET", u, nil)
  304. if err != nil {
  305. return nil, nil, err
  306. }
  307. // TODO: remove custom Accept header when this API fully launches.
  308. acceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview}
  309. req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
  310. var projects []*Project
  311. resp, err := s.client.Do(ctx, req, &projects)
  312. if err != nil {
  313. return nil, resp, err
  314. }
  315. return projects, resp, nil
  316. }
  317. // ReviewTeamProjects checks whether a team has read, write, or admin
  318. // permissions for an organization project.
  319. //
  320. // GitHub API docs: https://developer.github.com/v3/teams/#review-a-team-project
  321. func (s *TeamsService) ReviewTeamProjects(ctx context.Context, teamID, projectID int64) (*Project, *Response, error) {
  322. u := fmt.Sprintf("teams/%v/projects/%v", teamID, projectID)
  323. req, err := s.client.NewRequest("GET", u, nil)
  324. if err != nil {
  325. return nil, nil, err
  326. }
  327. // TODO: remove custom Accept header when this API fully launches.
  328. acceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview}
  329. req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
  330. projects := &Project{}
  331. resp, err := s.client.Do(ctx, req, &projects)
  332. if err != nil {
  333. return nil, resp, err
  334. }
  335. return projects, resp, nil
  336. }
  337. // TeamProjectOptions specifies the optional parameters to the
  338. // TeamsService.AddTeamProject method.
  339. type TeamProjectOptions struct {
  340. // Permission specifies the permission to grant to the team for this project.
  341. // Possible values are:
  342. // "read" - team members can read, but not write to or administer this project.
  343. // "write" - team members can read and write, but not administer this project.
  344. // "admin" - team members can read, write and administer this project.
  345. //
  346. Permission *string `json:"permission,omitempty"`
  347. }
  348. // AddTeamProject adds an organization project to a team. To add a project to a team or
  349. // update the team's permission on a project, the authenticated user must have admin
  350. // permissions for the project.
  351. //
  352. // GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-project
  353. func (s *TeamsService) AddTeamProject(ctx context.Context, teamID, projectID int64, opt *TeamProjectOptions) (*Response, error) {
  354. u := fmt.Sprintf("teams/%v/projects/%v", teamID, projectID)
  355. req, err := s.client.NewRequest("PUT", u, opt)
  356. if err != nil {
  357. return nil, err
  358. }
  359. // TODO: remove custom Accept header when this API fully launches.
  360. acceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview}
  361. req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
  362. return s.client.Do(ctx, req, nil)
  363. }
  364. // RemoveTeamProject removes an organization project from a team. An organization owner or
  365. // a team maintainer can remove any project from the team. To remove a project from a team
  366. // as an organization member, the authenticated user must have "read" access to both the team
  367. // and project, or "admin" access to the team or project.
  368. // Note: This endpoint removes the project from the team, but does not delete it.
  369. //
  370. // GitHub API docs: https://developer.github.com/v3/teams/#remove-team-project
  371. func (s *TeamsService) RemoveTeamProject(ctx context.Context, teamID int64, projectID int64) (*Response, error) {
  372. u := fmt.Sprintf("teams/%v/projects/%v", teamID, projectID)
  373. req, err := s.client.NewRequest("DELETE", u, nil)
  374. if err != nil {
  375. return nil, err
  376. }
  377. // TODO: remove custom Accept header when this API fully launches.
  378. acceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview}
  379. req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
  380. return s.client.Do(ctx, req, nil)
  381. }
上海开阖软件有限公司 沪ICP备12045867号-1