diff --git a/github/orgs_organization_roles.go b/github/orgs_organization_roles.go index 0954b92d41b..a957c0e88cc 100644 --- a/github/orgs_organization_roles.go +++ b/github/orgs_organization_roles.go @@ -37,6 +37,12 @@ type CreateOrUpdateOrgRoleOptions struct { BaseRole *string `json:"base_role,omitempty"` } +// OrganizationFineGrainedPermission represents a fine-grained permission that protects organization resources. +type OrganizationFineGrainedPermission struct { + Name string `json:"name"` + Description string `json:"description"` +} + // ListRoles lists the custom roles available in this organization. // In order to see custom roles in an organization, the authenticated user must be an organization owner. // @@ -293,3 +299,31 @@ func (s *OrganizationsService) ListUsersAssignedToOrgRole(ctx context.Context, o return users, resp, nil } + +// ListFineGrainedPermissions lists the fine-grained permissions that can be used in custom organization roles for an organization. +// +// To use this endpoint, the authenticated user must be one of: +// - An administrator for the organization. +// - A user, or a user on a team, with the fine-grained permissions of `read_organization_custom_org_role` in the organization. +// +// OAuth app tokens and personal access tokens (classic) need the `admin:org` scope to use this endpoint. +// +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/orgs/organization-roles#list-organization-fine-grained-permissions-for-an-organization +// +//meta:operation GET /orgs/{org}/organization-fine-grained-permissions +func (s *OrganizationsService) ListFineGrainedPermissions(ctx context.Context, org string) ([]*OrganizationFineGrainedPermission, *Response, error) { + u := fmt.Sprintf("orgs/%v/organization-fine-grained-permissions", org) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var permissions []*OrganizationFineGrainedPermission + resp, err := s.client.Do(ctx, req, &permissions) + if err != nil { + return nil, resp, err + } + + return permissions, resp, nil +} diff --git a/github/orgs_organization_roles_test.go b/github/orgs_organization_roles_test.go index 1ae9b9ff111..cedde893827 100644 --- a/github/orgs_organization_roles_test.go +++ b/github/orgs_organization_roles_test.go @@ -495,3 +495,38 @@ func TestOrganizationsService_ListUsersAssignedToOrgRole(t *testing.T) { return resp, err }) } + +func TestOrganizationsService_ListFineGrainedPermissions(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/orgs/o/organization-fine-grained-permissions", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `[{"name":"p1", "description":"d1"}]`) + }) + + ctx := t.Context() + permissions, _, err := client.Organizations.ListFineGrainedPermissions(ctx, "o") + if err != nil { + t.Errorf("Organizations.ListFineGrainedPermissions returned error: %v", err) + } + + want := []*OrganizationFineGrainedPermission{{Name: "p1", Description: "d1"}} + if !cmp.Equal(permissions, want) { + t.Errorf("Organizations.ListFineGrainedPermissions returned %+v, want %+v", permissions, want) + } + + const methodName = "ListFineGrainedPermissions" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Organizations.ListFineGrainedPermissions(ctx, "\no") + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Organizations.ListFineGrainedPermissions(ctx, "o") + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +}