Skip to content
34 changes: 34 additions & 0 deletions github/orgs_organization_roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
//
Expand Down Expand Up @@ -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
}
35 changes: 35 additions & 0 deletions github/orgs_organization_roles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
})
}
Loading