github.com/google/go-github/v33@v33.0.0/github/teams.go (about) 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 6 package github 7 8 import ( 9 "context" 10 "fmt" 11 "net/http" 12 "strings" 13 "time" 14 ) 15 16 // TeamsService provides access to the team-related functions 17 // in the GitHub API. 18 // 19 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/ 20 type TeamsService service 21 22 // Team represents a team within a GitHub organization. Teams are used to 23 // manage access to an organization's repositories. 24 type Team struct { 25 ID *int64 `json:"id,omitempty"` 26 NodeID *string `json:"node_id,omitempty"` 27 Name *string `json:"name,omitempty"` 28 Description *string `json:"description,omitempty"` 29 URL *string `json:"url,omitempty"` 30 Slug *string `json:"slug,omitempty"` 31 32 // Permission specifies the default permission for repositories owned by the team. 33 Permission *string `json:"permission,omitempty"` 34 35 // Privacy identifies the level of privacy this team should have. 36 // Possible values are: 37 // secret - only visible to organization owners and members of this team 38 // closed - visible to all members of this organization 39 // Default is "secret". 40 Privacy *string `json:"privacy,omitempty"` 41 42 MembersCount *int `json:"members_count,omitempty"` 43 ReposCount *int `json:"repos_count,omitempty"` 44 Organization *Organization `json:"organization,omitempty"` 45 MembersURL *string `json:"members_url,omitempty"` 46 RepositoriesURL *string `json:"repositories_url,omitempty"` 47 Parent *Team `json:"parent,omitempty"` 48 49 // LDAPDN is only available in GitHub Enterprise and when the team 50 // membership is synchronized with LDAP. 51 LDAPDN *string `json:"ldap_dn,omitempty"` 52 } 53 54 func (t Team) String() string { 55 return Stringify(t) 56 } 57 58 // Invitation represents a team member's invitation status. 59 type Invitation struct { 60 ID *int64 `json:"id,omitempty"` 61 NodeID *string `json:"node_id,omitempty"` 62 Login *string `json:"login,omitempty"` 63 Email *string `json:"email,omitempty"` 64 // Role can be one of the values - 'direct_member', 'admin', 'billing_manager', 'hiring_manager', or 'reinstate'. 65 Role *string `json:"role,omitempty"` 66 CreatedAt *time.Time `json:"created_at,omitempty"` 67 Inviter *User `json:"inviter,omitempty"` 68 TeamCount *int `json:"team_count,omitempty"` 69 InvitationTeamURL *string `json:"invitation_team_url,omitempty"` 70 } 71 72 func (i Invitation) String() string { 73 return Stringify(i) 74 } 75 76 // ListTeams lists all of the teams for an organization. 77 // 78 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#list-teams 79 func (s *TeamsService) ListTeams(ctx context.Context, org string, opts *ListOptions) ([]*Team, *Response, error) { 80 u := fmt.Sprintf("orgs/%v/teams", org) 81 u, err := addOptions(u, opts) 82 if err != nil { 83 return nil, nil, err 84 } 85 86 req, err := s.client.NewRequest("GET", u, nil) 87 if err != nil { 88 return nil, nil, err 89 } 90 91 var teams []*Team 92 resp, err := s.client.Do(ctx, req, &teams) 93 if err != nil { 94 return nil, resp, err 95 } 96 97 return teams, resp, nil 98 } 99 100 // GetTeamByID fetches a team, given a specified organization ID, by ID. 101 // 102 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#get-a-team-by-name 103 func (s *TeamsService) GetTeamByID(ctx context.Context, orgID, teamID int64) (*Team, *Response, error) { 104 u := fmt.Sprintf("organizations/%v/team/%v", orgID, teamID) 105 req, err := s.client.NewRequest("GET", u, nil) 106 if err != nil { 107 return nil, nil, err 108 } 109 110 t := new(Team) 111 resp, err := s.client.Do(ctx, req, t) 112 if err != nil { 113 return nil, resp, err 114 } 115 116 return t, resp, nil 117 } 118 119 // GetTeamBySlug fetches a team, given a specified organization name, by slug. 120 // 121 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#get-a-team-by-name 122 func (s *TeamsService) GetTeamBySlug(ctx context.Context, org, slug string) (*Team, *Response, error) { 123 u := fmt.Sprintf("orgs/%v/teams/%v", org, slug) 124 req, err := s.client.NewRequest("GET", u, nil) 125 if err != nil { 126 return nil, nil, err 127 } 128 129 t := new(Team) 130 resp, err := s.client.Do(ctx, req, t) 131 if err != nil { 132 return nil, resp, err 133 } 134 135 return t, resp, nil 136 } 137 138 // NewTeam represents a team to be created or modified. 139 type NewTeam struct { 140 Name string `json:"name"` // Name of the team. (Required.) 141 Description *string `json:"description,omitempty"` 142 Maintainers []string `json:"maintainers,omitempty"` 143 RepoNames []string `json:"repo_names,omitempty"` 144 ParentTeamID *int64 `json:"parent_team_id,omitempty"` 145 146 // Deprecated: Permission is deprecated when creating or editing a team in an org 147 // using the new GitHub permission model. It no longer identifies the 148 // permission a team has on its repos, but only specifies the default 149 // permission a repo is initially added with. Avoid confusion by 150 // specifying a permission value when calling AddTeamRepo. 151 Permission *string `json:"permission,omitempty"` 152 153 // Privacy identifies the level of privacy this team should have. 154 // Possible values are: 155 // secret - only visible to organization owners and members of this team 156 // closed - visible to all members of this organization 157 // Default is "secret". 158 Privacy *string `json:"privacy,omitempty"` 159 160 // LDAPDN may be used in GitHub Enterprise when the team membership 161 // is synchronized with LDAP. 162 LDAPDN *string `json:"ldap_dn,omitempty"` 163 } 164 165 func (s NewTeam) String() string { 166 return Stringify(s) 167 } 168 169 // CreateTeam creates a new team within an organization. 170 // 171 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#create-a-team 172 func (s *TeamsService) CreateTeam(ctx context.Context, org string, team NewTeam) (*Team, *Response, error) { 173 u := fmt.Sprintf("orgs/%v/teams", org) 174 req, err := s.client.NewRequest("POST", u, team) 175 if err != nil { 176 return nil, nil, err 177 } 178 179 t := new(Team) 180 resp, err := s.client.Do(ctx, req, t) 181 if err != nil { 182 return nil, resp, err 183 } 184 185 return t, resp, nil 186 } 187 188 // newTeamNoParent is the same as NewTeam but ensures that the 189 // "parent_team_id" field will be null. It is for internal use 190 // only and should not be exported. 191 type newTeamNoParent struct { 192 Name string `json:"name"` 193 Description *string `json:"description,omitempty"` 194 Maintainers []string `json:"maintainers,omitempty"` 195 RepoNames []string `json:"repo_names,omitempty"` 196 ParentTeamID *int64 `json:"parent_team_id"` // This will be "null" 197 Privacy *string `json:"privacy,omitempty"` 198 LDAPDN *string `json:"ldap_dn,omitempty"` 199 } 200 201 // copyNewTeamWithoutParent is used to set the "parent_team_id" 202 // field to "null" after copying the other fields from a NewTeam. 203 // It is for internal use only and should not be exported. 204 func copyNewTeamWithoutParent(team *NewTeam) *newTeamNoParent { 205 return &newTeamNoParent{ 206 Name: team.Name, 207 Description: team.Description, 208 Maintainers: team.Maintainers, 209 RepoNames: team.RepoNames, 210 Privacy: team.Privacy, 211 LDAPDN: team.LDAPDN, 212 } 213 } 214 215 // EditTeamByID edits a team, given an organization ID, selected by ID. 216 // 217 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#update-a-team 218 func (s *TeamsService) EditTeamByID(ctx context.Context, orgID, teamID int64, team NewTeam, removeParent bool) (*Team, *Response, error) { 219 u := fmt.Sprintf("organizations/%v/team/%v", orgID, teamID) 220 221 var req *http.Request 222 var err error 223 if removeParent { 224 teamRemoveParent := copyNewTeamWithoutParent(&team) 225 req, err = s.client.NewRequest("PATCH", u, teamRemoveParent) 226 } else { 227 req, err = s.client.NewRequest("PATCH", u, team) 228 } 229 if err != nil { 230 return nil, nil, err 231 } 232 233 t := new(Team) 234 resp, err := s.client.Do(ctx, req, t) 235 if err != nil { 236 return nil, resp, err 237 } 238 239 return t, resp, nil 240 } 241 242 // EditTeamBySlug edits a team, given an organization name, by slug. 243 // 244 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#update-a-team 245 func (s *TeamsService) EditTeamBySlug(ctx context.Context, org, slug string, team NewTeam, removeParent bool) (*Team, *Response, error) { 246 u := fmt.Sprintf("orgs/%v/teams/%v", org, slug) 247 248 var req *http.Request 249 var err error 250 if removeParent { 251 teamRemoveParent := copyNewTeamWithoutParent(&team) 252 req, err = s.client.NewRequest("PATCH", u, teamRemoveParent) 253 } else { 254 req, err = s.client.NewRequest("PATCH", u, team) 255 } 256 if err != nil { 257 return nil, nil, err 258 } 259 260 t := new(Team) 261 resp, err := s.client.Do(ctx, req, t) 262 if err != nil { 263 return nil, resp, err 264 } 265 266 return t, resp, nil 267 } 268 269 // DeleteTeamByID deletes a team referenced by ID. 270 // 271 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#delete-a-team 272 func (s *TeamsService) DeleteTeamByID(ctx context.Context, orgID, teamID int64) (*Response, error) { 273 u := fmt.Sprintf("organizations/%v/team/%v", orgID, teamID) 274 req, err := s.client.NewRequest("DELETE", u, nil) 275 if err != nil { 276 return nil, err 277 } 278 279 return s.client.Do(ctx, req, nil) 280 } 281 282 // DeleteTeamBySlug deletes a team reference by slug. 283 // 284 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#delete-a-team 285 func (s *TeamsService) DeleteTeamBySlug(ctx context.Context, org, slug string) (*Response, error) { 286 u := fmt.Sprintf("orgs/%v/teams/%v", org, slug) 287 req, err := s.client.NewRequest("DELETE", u, nil) 288 if err != nil { 289 return nil, err 290 } 291 292 return s.client.Do(ctx, req, nil) 293 } 294 295 // ListChildTeamsByParentID lists child teams for a parent team given parent ID. 296 // 297 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#list-child-teams 298 func (s *TeamsService) ListChildTeamsByParentID(ctx context.Context, orgID, teamID int64, opts *ListOptions) ([]*Team, *Response, error) { 299 u := fmt.Sprintf("organizations/%v/team/%v/teams", orgID, teamID) 300 u, err := addOptions(u, opts) 301 if err != nil { 302 return nil, nil, err 303 } 304 305 req, err := s.client.NewRequest("GET", u, nil) 306 if err != nil { 307 return nil, nil, err 308 } 309 310 var teams []*Team 311 resp, err := s.client.Do(ctx, req, &teams) 312 if err != nil { 313 return nil, resp, err 314 } 315 316 return teams, resp, nil 317 } 318 319 // ListChildTeamsByParentSlug lists child teams for a parent team given parent slug. 320 // 321 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#list-child-teams 322 func (s *TeamsService) ListChildTeamsByParentSlug(ctx context.Context, org, slug string, opts *ListOptions) ([]*Team, *Response, error) { 323 u := fmt.Sprintf("orgs/%v/teams/%v/teams", org, slug) 324 u, err := addOptions(u, opts) 325 if err != nil { 326 return nil, nil, err 327 } 328 329 req, err := s.client.NewRequest("GET", u, nil) 330 if err != nil { 331 return nil, nil, err 332 } 333 334 var teams []*Team 335 resp, err := s.client.Do(ctx, req, &teams) 336 if err != nil { 337 return nil, resp, err 338 } 339 340 return teams, resp, nil 341 } 342 343 // ListTeamReposByID lists the repositories given a team ID that the specified team has access to. 344 // 345 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#list-team-repositories 346 func (s *TeamsService) ListTeamReposByID(ctx context.Context, orgID, teamID int64, opts *ListOptions) ([]*Repository, *Response, error) { 347 u := fmt.Sprintf("organizations/%v/team/%v/repos", orgID, teamID) 348 u, err := addOptions(u, opts) 349 if err != nil { 350 return nil, nil, err 351 } 352 353 req, err := s.client.NewRequest("GET", u, nil) 354 if err != nil { 355 return nil, nil, err 356 } 357 358 // TODO: remove custom Accept header when topics API fully launches. 359 headers := []string{mediaTypeTopicsPreview} 360 req.Header.Set("Accept", strings.Join(headers, ", ")) 361 362 var repos []*Repository 363 resp, err := s.client.Do(ctx, req, &repos) 364 if err != nil { 365 return nil, resp, err 366 } 367 368 return repos, resp, nil 369 } 370 371 // ListTeamReposBySlug lists the repositories given a team slug that the specified team has access to. 372 // 373 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#list-team-repositories 374 func (s *TeamsService) ListTeamReposBySlug(ctx context.Context, org, slug string, opts *ListOptions) ([]*Repository, *Response, error) { 375 u := fmt.Sprintf("orgs/%v/teams/%v/repos", org, slug) 376 u, err := addOptions(u, opts) 377 if err != nil { 378 return nil, nil, err 379 } 380 381 req, err := s.client.NewRequest("GET", u, nil) 382 if err != nil { 383 return nil, nil, err 384 } 385 386 // TODO: remove custom Accept header when topics API fully launches. 387 headers := []string{mediaTypeTopicsPreview} 388 req.Header.Set("Accept", strings.Join(headers, ", ")) 389 390 var repos []*Repository 391 resp, err := s.client.Do(ctx, req, &repos) 392 if err != nil { 393 return nil, resp, err 394 } 395 396 return repos, resp, nil 397 } 398 399 // IsTeamRepoByID checks if a team, given its ID, manages the specified repository. If the 400 // repository is managed by team, a Repository is returned which includes the 401 // permissions team has for that repo. 402 // 403 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#check-team-permissions-for-a-repository 404 func (s *TeamsService) IsTeamRepoByID(ctx context.Context, orgID, teamID int64, owner, repo string) (*Repository, *Response, error) { 405 u := fmt.Sprintf("organizations/%v/team/%v/repos/%v/%v", orgID, teamID, owner, repo) 406 req, err := s.client.NewRequest("GET", u, nil) 407 if err != nil { 408 return nil, nil, err 409 } 410 411 headers := []string{mediaTypeOrgPermissionRepo} 412 req.Header.Set("Accept", strings.Join(headers, ", ")) 413 414 repository := new(Repository) 415 resp, err := s.client.Do(ctx, req, repository) 416 if err != nil { 417 return nil, resp, err 418 } 419 420 return repository, resp, nil 421 } 422 423 // IsTeamRepoBySlug checks if a team, given its slug, manages the specified repository. If the 424 // repository is managed by team, a Repository is returned which includes the 425 // permissions team has for that repo. 426 // 427 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#check-team-permissions-for-a-repository 428 func (s *TeamsService) IsTeamRepoBySlug(ctx context.Context, org, slug, owner, repo string) (*Repository, *Response, error) { 429 u := fmt.Sprintf("orgs/%v/teams/%v/repos/%v/%v", org, slug, owner, repo) 430 req, err := s.client.NewRequest("GET", u, nil) 431 if err != nil { 432 return nil, nil, err 433 } 434 435 headers := []string{mediaTypeOrgPermissionRepo} 436 req.Header.Set("Accept", strings.Join(headers, ", ")) 437 438 repository := new(Repository) 439 resp, err := s.client.Do(ctx, req, repository) 440 if err != nil { 441 return nil, resp, err 442 } 443 444 return repository, resp, nil 445 } 446 447 // TeamAddTeamRepoOptions specifies the optional parameters to the 448 // TeamsService.AddTeamRepo method. 449 type TeamAddTeamRepoOptions struct { 450 // Permission specifies the permission to grant the team on this repository. 451 // Possible values are: 452 // pull - team members can pull, but not push to or administer this repository 453 // push - team members can pull and push, but not administer this repository 454 // admin - team members can pull, push and administer this repository 455 // maintain - team members can manage the repository without access to sensitive or destructive actions. 456 // triage - team members can proactively manage issues and pull requests without write access. 457 // 458 // If not specified, the team's permission attribute will be used. 459 Permission string `json:"permission,omitempty"` 460 } 461 462 // AddTeamRepoByID adds a repository to be managed by the specified team given the team ID. 463 // The specified repository must be owned by the organization to which the team 464 // belongs, or a direct fork of a repository owned by the organization. 465 // 466 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#add-or-update-team-repository-permissions 467 func (s *TeamsService) AddTeamRepoByID(ctx context.Context, orgID, teamID int64, owner, repo string, opts *TeamAddTeamRepoOptions) (*Response, error) { 468 u := fmt.Sprintf("organizations/%v/team/%v/repos/%v/%v", orgID, teamID, owner, repo) 469 req, err := s.client.NewRequest("PUT", u, opts) 470 if err != nil { 471 return nil, err 472 } 473 474 return s.client.Do(ctx, req, nil) 475 } 476 477 // AddTeamRepoBySlug adds a repository to be managed by the specified team given the team slug. 478 // The specified repository must be owned by the organization to which the team 479 // belongs, or a direct fork of a repository owned by the organization. 480 // 481 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#add-or-update-team-repository-permissions 482 func (s *TeamsService) AddTeamRepoBySlug(ctx context.Context, org, slug, owner, repo string, opts *TeamAddTeamRepoOptions) (*Response, error) { 483 u := fmt.Sprintf("orgs/%v/teams/%v/repos/%v/%v", org, slug, owner, repo) 484 req, err := s.client.NewRequest("PUT", u, opts) 485 if err != nil { 486 return nil, err 487 } 488 489 return s.client.Do(ctx, req, nil) 490 } 491 492 // RemoveTeamRepoByID removes a repository from being managed by the specified 493 // team given the team ID. Note that this does not delete the repository, it 494 // just removes it from the team. 495 // 496 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#remove-a-repository-from-a-team 497 func (s *TeamsService) RemoveTeamRepoByID(ctx context.Context, orgID, teamID int64, owner, repo string) (*Response, error) { 498 u := fmt.Sprintf("organizations/%v/team/%v/repos/%v/%v", orgID, teamID, owner, repo) 499 req, err := s.client.NewRequest("DELETE", u, nil) 500 if err != nil { 501 return nil, err 502 } 503 504 return s.client.Do(ctx, req, nil) 505 } 506 507 // RemoveTeamRepoBySlug removes a repository from being managed by the specified 508 // team given the team slug. Note that this does not delete the repository, it 509 // just removes it from the team. 510 // 511 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#remove-a-repository-from-a-team 512 func (s *TeamsService) RemoveTeamRepoBySlug(ctx context.Context, org, slug, owner, repo string) (*Response, error) { 513 u := fmt.Sprintf("orgs/%v/teams/%v/repos/%v/%v", org, slug, owner, repo) 514 req, err := s.client.NewRequest("DELETE", u, nil) 515 if err != nil { 516 return nil, err 517 } 518 519 return s.client.Do(ctx, req, nil) 520 } 521 522 // ListUserTeams lists a user's teams 523 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#list-teams-for-the-authenticated-user 524 func (s *TeamsService) ListUserTeams(ctx context.Context, opts *ListOptions) ([]*Team, *Response, error) { 525 u := "user/teams" 526 u, err := addOptions(u, opts) 527 if err != nil { 528 return nil, nil, err 529 } 530 531 req, err := s.client.NewRequest("GET", u, nil) 532 if err != nil { 533 return nil, nil, err 534 } 535 536 var teams []*Team 537 resp, err := s.client.Do(ctx, req, &teams) 538 if err != nil { 539 return nil, resp, err 540 } 541 542 return teams, resp, nil 543 } 544 545 // ListTeamProjectsByID lists the organization projects for a team given the team ID. 546 // 547 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#list-team-projects 548 func (s *TeamsService) ListTeamProjectsByID(ctx context.Context, orgID, teamID int64) ([]*Project, *Response, error) { 549 u := fmt.Sprintf("organizations/%v/team/%v/projects", orgID, teamID) 550 551 req, err := s.client.NewRequest("GET", u, nil) 552 if err != nil { 553 return nil, nil, err 554 } 555 556 // TODO: remove custom Accept header when this API fully launches. 557 acceptHeaders := []string{mediaTypeProjectsPreview} 558 req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) 559 560 var projects []*Project 561 resp, err := s.client.Do(ctx, req, &projects) 562 if err != nil { 563 return nil, resp, err 564 } 565 566 return projects, resp, nil 567 } 568 569 // ListTeamProjectsBySlug lists the organization projects for a team given the team slug. 570 // 571 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#list-team-projects 572 func (s *TeamsService) ListTeamProjectsBySlug(ctx context.Context, org, slug string) ([]*Project, *Response, error) { 573 u := fmt.Sprintf("orgs/%v/teams/%v/projects", org, slug) 574 575 req, err := s.client.NewRequest("GET", u, nil) 576 if err != nil { 577 return nil, nil, err 578 } 579 580 // TODO: remove custom Accept header when this API fully launches. 581 acceptHeaders := []string{mediaTypeProjectsPreview} 582 req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) 583 584 var projects []*Project 585 resp, err := s.client.Do(ctx, req, &projects) 586 if err != nil { 587 return nil, resp, err 588 } 589 590 return projects, resp, nil 591 } 592 593 // ReviewTeamProjectsByID checks whether a team, given its ID, has read, write, or admin 594 // permissions for an organization project. 595 // 596 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#check-team-permissions-for-a-project 597 func (s *TeamsService) ReviewTeamProjectsByID(ctx context.Context, orgID, teamID, projectID int64) (*Project, *Response, error) { 598 u := fmt.Sprintf("organizations/%v/team/%v/projects/%v", orgID, teamID, projectID) 599 req, err := s.client.NewRequest("GET", u, nil) 600 if err != nil { 601 return nil, nil, err 602 } 603 604 // TODO: remove custom Accept header when this API fully launches. 605 acceptHeaders := []string{mediaTypeProjectsPreview} 606 req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) 607 608 projects := &Project{} 609 resp, err := s.client.Do(ctx, req, &projects) 610 if err != nil { 611 return nil, resp, err 612 } 613 614 return projects, resp, nil 615 } 616 617 // ReviewTeamProjectsBySlug checks whether a team, given its slug, has read, write, or admin 618 // permissions for an organization project. 619 // 620 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#check-team-permissions-for-a-project 621 func (s *TeamsService) ReviewTeamProjectsBySlug(ctx context.Context, org, slug string, projectID int64) (*Project, *Response, error) { 622 u := fmt.Sprintf("orgs/%v/teams/%v/projects/%v", org, slug, projectID) 623 req, err := s.client.NewRequest("GET", u, nil) 624 if err != nil { 625 return nil, nil, err 626 } 627 628 // TODO: remove custom Accept header when this API fully launches. 629 acceptHeaders := []string{mediaTypeProjectsPreview} 630 req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) 631 632 projects := &Project{} 633 resp, err := s.client.Do(ctx, req, &projects) 634 if err != nil { 635 return nil, resp, err 636 } 637 638 return projects, resp, nil 639 } 640 641 // TeamProjectOptions specifies the optional parameters to the 642 // TeamsService.AddTeamProject method. 643 type TeamProjectOptions struct { 644 // Permission specifies the permission to grant to the team for this project. 645 // Possible values are: 646 // "read" - team members can read, but not write to or administer this project. 647 // "write" - team members can read and write, but not administer this project. 648 // "admin" - team members can read, write and administer this project. 649 // 650 Permission *string `json:"permission,omitempty"` 651 } 652 653 // AddTeamProjectByID adds an organization project to a team given the team ID. 654 // To add a project to a team or update the team's permission on a project, the 655 // authenticated user must have admin permissions for the project. 656 // 657 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#add-or-update-team-project-permissions 658 func (s *TeamsService) AddTeamProjectByID(ctx context.Context, orgID, teamID, projectID int64, opts *TeamProjectOptions) (*Response, error) { 659 u := fmt.Sprintf("organizations/%v/team/%v/projects/%v", orgID, teamID, projectID) 660 req, err := s.client.NewRequest("PUT", u, opts) 661 if err != nil { 662 return nil, err 663 } 664 665 // TODO: remove custom Accept header when this API fully launches. 666 acceptHeaders := []string{mediaTypeProjectsPreview} 667 req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) 668 669 return s.client.Do(ctx, req, nil) 670 } 671 672 // AddTeamProjectBySlug adds an organization project to a team given the team slug. 673 // To add a project to a team or update the team's permission on a project, the 674 // authenticated user must have admin permissions for the project. 675 // 676 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#add-or-update-team-project-permissions 677 func (s *TeamsService) AddTeamProjectBySlug(ctx context.Context, org, slug string, projectID int64, opts *TeamProjectOptions) (*Response, error) { 678 u := fmt.Sprintf("orgs/%v/teams/%v/projects/%v", org, slug, projectID) 679 req, err := s.client.NewRequest("PUT", u, opts) 680 if err != nil { 681 return nil, err 682 } 683 684 // TODO: remove custom Accept header when this API fully launches. 685 acceptHeaders := []string{mediaTypeProjectsPreview} 686 req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) 687 688 return s.client.Do(ctx, req, nil) 689 } 690 691 // RemoveTeamProjectByID removes an organization project from a team given team ID. 692 // An organization owner or a team maintainer can remove any project from the team. 693 // To remove a project from a team as an organization member, the authenticated user 694 // must have "read" access to both the team and project, or "admin" access to the team 695 // or project. 696 // Note: This endpoint removes the project from the team, but does not delete it. 697 // 698 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#remove-a-project-from-a-team 699 func (s *TeamsService) RemoveTeamProjectByID(ctx context.Context, orgID, teamID, projectID int64) (*Response, error) { 700 u := fmt.Sprintf("organizations/%v/team/%v/projects/%v", orgID, teamID, projectID) 701 req, err := s.client.NewRequest("DELETE", u, nil) 702 if err != nil { 703 return nil, err 704 } 705 706 // TODO: remove custom Accept header when this API fully launches. 707 acceptHeaders := []string{mediaTypeProjectsPreview} 708 req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) 709 710 return s.client.Do(ctx, req, nil) 711 } 712 713 // RemoveTeamProjectBySlug removes an organization project from a team given team slug. 714 // An organization owner or a team maintainer can remove any project from the team. 715 // To remove a project from a team as an organization member, the authenticated user 716 // must have "read" access to both the team and project, or "admin" access to the team 717 // or project. 718 // Note: This endpoint removes the project from the team, but does not delete it. 719 // 720 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#remove-a-project-from-a-team 721 func (s *TeamsService) RemoveTeamProjectBySlug(ctx context.Context, org, slug string, projectID int64) (*Response, error) { 722 u := fmt.Sprintf("orgs/%v/teams/%v/projects/%v", org, slug, projectID) 723 req, err := s.client.NewRequest("DELETE", u, nil) 724 if err != nil { 725 return nil, err 726 } 727 728 // TODO: remove custom Accept header when this API fully launches. 729 acceptHeaders := []string{mediaTypeProjectsPreview} 730 req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) 731 732 return s.client.Do(ctx, req, nil) 733 } 734 735 // IDPGroupList represents a list of external identity provider (IDP) groups. 736 type IDPGroupList struct { 737 Groups []*IDPGroup `json:"groups"` 738 } 739 740 // IDPGroup represents an external identity provider (IDP) group. 741 type IDPGroup struct { 742 GroupID *string `json:"group_id,omitempty"` 743 GroupName *string `json:"group_name,omitempty"` 744 GroupDescription *string `json:"group_description,omitempty"` 745 } 746 747 // ListIDPGroupsInOrganization lists IDP groups available in an organization. 748 // 749 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#list-idp-groups-for-an-organization 750 func (s *TeamsService) ListIDPGroupsInOrganization(ctx context.Context, org string, opts *ListCursorOptions) (*IDPGroupList, *Response, error) { 751 u := fmt.Sprintf("orgs/%v/team-sync/groups", org) 752 u, err := addOptions(u, opts) 753 if err != nil { 754 return nil, nil, err 755 } 756 757 req, err := s.client.NewRequest("GET", u, nil) 758 if err != nil { 759 return nil, nil, err 760 } 761 762 groups := new(IDPGroupList) 763 resp, err := s.client.Do(ctx, req, groups) 764 if err != nil { 765 return nil, resp, err 766 } 767 return groups, resp, nil 768 } 769 770 // ListIDPGroupsForTeamByID lists IDP groups connected to a team on GitHub 771 // given organization and team IDs. 772 // 773 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#list-idp-groups-for-a-team 774 func (s *TeamsService) ListIDPGroupsForTeamByID(ctx context.Context, orgID, teamID int64) (*IDPGroupList, *Response, error) { 775 u := fmt.Sprintf("organizations/%v/team/%v/team-sync/group-mappings", orgID, teamID) 776 777 req, err := s.client.NewRequest("GET", u, nil) 778 if err != nil { 779 return nil, nil, err 780 } 781 782 groups := new(IDPGroupList) 783 resp, err := s.client.Do(ctx, req, groups) 784 if err != nil { 785 return nil, resp, err 786 } 787 return groups, resp, err 788 } 789 790 // ListIDPGroupsForTeamBySlug lists IDP groups connected to a team on GitHub 791 // given organization name and team slug. 792 // 793 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#list-idp-groups-for-a-team 794 func (s *TeamsService) ListIDPGroupsForTeamBySlug(ctx context.Context, org, slug string) (*IDPGroupList, *Response, error) { 795 u := fmt.Sprintf("orgs/%v/teams/%v/team-sync/group-mappings", org, slug) 796 797 req, err := s.client.NewRequest("GET", u, nil) 798 if err != nil { 799 return nil, nil, err 800 } 801 802 groups := new(IDPGroupList) 803 resp, err := s.client.Do(ctx, req, groups) 804 if err != nil { 805 return nil, resp, err 806 } 807 return groups, resp, err 808 } 809 810 // CreateOrUpdateIDPGroupConnectionsByID creates, updates, or removes a connection 811 // between a team and an IDP group given organization and team IDs. 812 // 813 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#create-or-update-idp-group-connections 814 func (s *TeamsService) CreateOrUpdateIDPGroupConnectionsByID(ctx context.Context, orgID, teamID int64, opts IDPGroupList) (*IDPGroupList, *Response, error) { 815 u := fmt.Sprintf("organizations/%v/team/%v/team-sync/group-mappings", orgID, teamID) 816 817 req, err := s.client.NewRequest("PATCH", u, opts) 818 if err != nil { 819 return nil, nil, err 820 } 821 822 groups := new(IDPGroupList) 823 resp, err := s.client.Do(ctx, req, groups) 824 if err != nil { 825 return nil, resp, err 826 } 827 828 return groups, resp, nil 829 } 830 831 // CreateOrUpdateIDPGroupConnectionsBySlug creates, updates, or removes a connection 832 // between a team and an IDP group given organization name and team slug. 833 // 834 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/teams/#create-or-update-idp-group-connections 835 func (s *TeamsService) CreateOrUpdateIDPGroupConnectionsBySlug(ctx context.Context, org, slug string, opts IDPGroupList) (*IDPGroupList, *Response, error) { 836 u := fmt.Sprintf("orgs/%v/teams/%v/team-sync/group-mappings", org, slug) 837 838 req, err := s.client.NewRequest("PATCH", u, opts) 839 if err != nil { 840 return nil, nil, err 841 } 842 843 groups := new(IDPGroupList) 844 resp, err := s.client.Do(ctx, req, groups) 845 if err != nil { 846 return nil, resp, err 847 } 848 849 return groups, resp, nil 850 }