diff --git a/src/functions/public/Organization/Members/Get-GitHubOrganizationMember.ps1 b/src/functions/public/Organization/Members/Get-GitHubOrganizationMember.ps1 new file mode 100644 index 000000000..b6eae6ba2 --- /dev/null +++ b/src/functions/public/Organization/Members/Get-GitHubOrganizationMember.ps1 @@ -0,0 +1,59 @@ +function Get-GitHubOrganizationMember { + <# + .SYNOPSIS + List organization members + + .DESCRIPTION + List all users who are members of an organization. + If the authenticated user is also a member of this organization then both concealed and public members will be returned. + + .NOTES + [List organization members](https://docs.github.com/en/rest/orgs/members?apiVersion=2022-11-28#list-organization-members) + #> + [OutputType([pscustomobject])] + [CmdletBinding()] + param ( + # The organization name. The name is not case sensitive. + [Parameter(Mandatory)] + [Alias('Org')] + [string] $Organization, + + # Filter members returned in the list. + # `2fa_disabled` means that only members without two-factor authentication enabled will be returned. + # This options is only available for organization owners. + [Parameter()] + [ValidateSet('2fa_disabled', 'all')] + [string] $Filter = 'all', + + # Filter members returned by their role. + [Parameter()] + [ValidateSet('all', 'admin', 'member')] + [string] $Role = 'all', + + # The number of results per page (max 100). + [Parameter()] + [ValidateRange(1, 100)] + [int] $PerPage = 30, + + # The context to run the command in + [Parameter()] + [string] $Context = (Get-GitHubConfig -Name 'DefaultContext') + ) + + $body = @{ + filter = $Filter + role = $Role + per_page = $PerPage + } + + $inputObject = @{ + Context = $Context + Body = $body + Method = 'Get' + APIEndpoint = "/orgs/$Organization/members" + } + + Invoke-GitHubAPI @inputObject | ForEach-Object { + Write-Output $_.Response + } +} diff --git a/src/functions/public/Organization/Members/Get-GitHubOrganizationPendingInvitation.ps1 b/src/functions/public/Organization/Members/Get-GitHubOrganizationPendingInvitation.ps1 new file mode 100644 index 000000000..3f0665903 --- /dev/null +++ b/src/functions/public/Organization/Members/Get-GitHubOrganizationPendingInvitation.ps1 @@ -0,0 +1,58 @@ +function Get-GitHubOrganizationPendingInvitation { + <# + .SYNOPSIS + List pending organization invitations + + .DESCRIPTION + The return hash contains a `role` field which refers to the Organization + Invitation role and will be one of the following values: `direct_member`, `admin`, + `billing_manager`, or `hiring_manager`. If the invitee is not a GitHub + member, the `login` field in the return hash will be `null`. + + .NOTES + [List pending organization invitations](https://docs.github.com/rest/orgs/members#list-pending-organization-invitations) + #> + [CmdletBinding()] + param ( + # The organization name. The name is not case sensitive. + [Parameter(Mandatory)] + [Alias('Org')] + [string] $Organization, + + # Filter invitations by their member role. + [Parameter()] + [ValidateSet('all', 'admin', 'direct_member', 'billing_manager', 'hiring_manager')] + [string] $Role = 'all', + + # Filter invitations by their invitation source. + [Parameter()] + [ValidateSet('all', 'member', 'scim')] + [string] $InvitationSource = 'all', + + # The number of results per page (max 100). + [Parameter()] + [ValidateRange(1, 100)] + [int] $PerPage = 30, + + # The context to run the command in + [Parameter()] + [string] $Context = (Get-GitHubConfig -Name 'DefaultContext') + ) + + $body = @{ + role = $Role + invitation_source = $InvitationSource + per_page = $PerPage + } + + $inputObject = @{ + Context = $Context + Body = $body + Method = 'Get' + APIEndpoint = "/orgs/$Organization/invitations" + } + + Invoke-GitHubAPI @inputObject | ForEach-Object { + Write-Output $_.Response + } +} diff --git a/src/functions/public/Organization/Members/New-GitHubOrganizationInvitation.ps1 b/src/functions/public/Organization/Members/New-GitHubOrganizationInvitation.ps1 new file mode 100644 index 000000000..fa21f5c14 --- /dev/null +++ b/src/functions/public/Organization/Members/New-GitHubOrganizationInvitation.ps1 @@ -0,0 +1,82 @@ +function New-GitHubOrganizationInvitation { + <# + .SYNOPSIS + Create an organization invitation + + .DESCRIPTION + Invite people to an organization by using their GitHub user ID or their email address. In order to create invitations in an organization, + the authenticated user must be an organization owner. + + This endpoint triggers [notifications](https://docs.github.com/github/managing-subscriptions-and-notifications-on-github/about-notifications). + Creating content too quickly using this endpoint may result in secondary rate limiting. For more information, see + "[Rate limits for the API](https://docs.github.com/rest/using-the-rest-api/rate-limits-for-the-rest-api#about-secondary-rate-limits)" + and "[Best practices for using the REST API](https://docs.github.com/rest/guides/best-practices-for-using-the-rest-api)." + + .NOTES + [Create an organization invitation](https://docs.github.com/rest/orgs/members#list-pending-organization-invitations) + #> + [CmdletBinding(SupportsShouldProcess)] + param ( + # The organization name. The name is not case sensitive. + [Parameter(Mandatory)] + [Alias('Org')] + [string] $Organization, + + # GitHub user ID for the person you are inviting. + [Parameter( + Mandatory, + ParameterSetName = 'UserID' + )] + [Alias('invitee_id', 'user_id')] + [int] $InviteeID, + + # Email address of the person you are inviting, which can be an existing GitHub user. + [Parameter( + Mandatory, + ParameterSetName = 'Email' + )] + [string] $Email, + + # The role for the new member. + # + # - `admin` - Organization owners with full administrative rights to the organization and complete access to all repositories and teams. + # - `direct_member` - Non-owner organization members with ability to see other members and join teams by invitation. + # - `billing_manager` - Non-owner organization members with ability to manage the billing settings of your organization. + # - `reinstate` - The previous role assigned to the invitee before they were removed from your organization. + # Can be one of the roles listed above. + # Only works if the invitee was previously part of your organization. + [Parameter()] + [ValidateSet('admin', 'direct_member', 'billing_manager', 'reinstate')] + [string] $Role = 'direct_member', + + # Specify IDs for the teams you want to invite new members to. + [Parameter()] + [int[]] $TeamIDs, + + # The context to run the command in + [Parameter()] + [string] $Context = (Get-GitHubConfig -Name 'DefaultContext') + ) + + $body = @{ + invitee_id = $InviteeID + email = $Email + role = $Role + team_ids = $TeamIDs + } + + $body | Remove-HashtableEntry -NullOrEmptyValues + + $inputObject = @{ + Context = $Context + Body = $body + Method = 'post' + APIEndpoint = "/orgs/$Organization/invitations" + } + + if ($PSCmdlet.ShouldProcess("$InviteeID$Email to organization $Organization", 'Invite')) { + Invoke-GitHubAPI @inputObject | ForEach-Object { + Write-Output $_.Response + } + } +} diff --git a/tests/GitHub.Tests.ps1 b/tests/GitHub.Tests.ps1 index 067d52ee3..f6c199198 100644 --- a/tests/GitHub.Tests.ps1 +++ b/tests/GitHub.Tests.ps1 @@ -1,4 +1,11 @@ -Describe 'GitHub' { +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSUseDeclaredVarsMoreThanAssignments', '', + Justification = 'Pester grouping syntax: known issue.' +)] +[CmdletBinding()] +param() + +Describe 'GitHub' { Context 'Auth' { It 'Can connect and disconnect without parameters in GitHubActions' { { Connect-GitHubAccount } | Should -Not -Throw @@ -41,6 +48,14 @@ (Get-GitHubContext -ListAvailable).Count | Should -Be 3 } + It 'Can disconnect a specific context' { + { Disconnect-GitHubAccount -Context 'github.com/github-actions[bot]' -Silent } | Should -Not -Throw + (Get-GitHubContext -ListAvailable).Count | Should -Be 2 + Connect-GitHubAccount + Connect-GitHubAccount -ClientID $env:TEST_APP_CLIENT_ID -PrivateKey $env:TEST_APP_PRIVATE_KEY + (Get-GitHubContext -ListAvailable).Count | Should -Be 3 + } + It 'Can swap context to another' { { Set-GitHubDefaultContext -Context 'github.com/github-actions[bot]' } | Should -Not -Throw Get-GitHubConfig -Name 'DefaultContext' | Should -Be 'github.com/github-actions[bot]'