diff --git a/README.md b/README.md index 988e606df..6b7b037dd 100644 --- a/README.md +++ b/README.md @@ -20,38 +20,105 @@ The **GitHub PowerShell** module serves as a convenient API wrapper around [GitH ## Getting Started with GitHub PowerShell -To dive into the world of GitHub automation with PowerShell, follow these steps: +To dive into the world of GitHub automation with PowerShell, follow the sections below. -1. **Installation**: Download and install the GitHub PowerShell module from the provided link or the PowerShell Gallery. +### Installing the module - ```powershell - Install-Module -Name GitHub -Force -AllowClobber - ``` +Download and install the GitHub PowerShell module from the PowerShell Gallery with the following command: -1. **Authentication**: Authenticate using your GitHub credentials or access tokens to begin executing commands. +```powershell +Install-Module -Name GitHub -Force -AllowClobber +``` + +### Logging on + +Authenticate using your GitHub credentials or access tokens to begin executing commands. Tokens and other +configuration details are stored encrypted on the system using the PowerShell modules [SecretManagement and SecretStore Overview](https://learn.microsoft.com/en-us/powershell/utility-modules/secretmanagement/overview?view=ps-modules), +for more info on the implementation, see the section on [storing configuration](#storing-configuration). + +#### Device flow + +This is the recommended method for authentication due to access tokens being short lived. +It opens a browser window and prompts you to log in to GitHub. Once you log in, you will be provided with +a code that you need to paste into the PowerShell console. The command already puts the code in your clipboard. +It uses a GitHub App to authenticate, which is more secure than using a personal access token. The GitHub App +is only granted access to the repositories you add it to. Visit the [GitHub Apps documentation](https://docs.github.com/en/developers/apps/about-apps) +to read more about GitHub Apps. -Logging in using device flow: ```powershell Connect-GitHubAccount +! We added the code to your clipboard: [AB55-FA2E] +Press Enter to open github.com in your browser...: #-> Press enter and paste the code in the browser window +✓ Logged in as octocat! +``` + +After this you will need to install the GitHub App on the repos you want to manage. You can do this by visiting the +[PowerShell for GitHub](https://github.com/apps/powershell-for-github) app page. -Please visit: https://github.com/login/device -and enter code: ABCD-1234 -Successfully authenticated! +> Info: We will be looking to include this as a check in the module in the future. So it becomes a part of the regular sign in process. + + + +Consecutive runs of the `Connect-GitHubAccount` will not require you to paste the code again unless you revoke the token +or you change the type of authentication you want to use. Instead, it checks the remaining duration of the access token and +uses the refresh token to get a new access token if its less than 4 hours remaining. + +```powershell +Connect-GitHubAccount +✓ Access token is still valid for 05:30:41 ... +✓ Logged in as octocat! ``` -Logging in using PAT token: +This is also happening automatically when you run a command that requires authentication. The validity of the token is checked before the command is executed. +If it is no longer valid, the token is refreshed and the command is executed. + +#### Device Flow with OAuth app + +This uses the same flow as above, but instead of using the GitHub App, it uses an OAuth app with long lived tokens. +During the signing you can also authorize the app to access your private repositories. +Visit the [OAuth apps documentation](https://docs.github.com/en/developers/apps/about-apps) to read more about OAuth apps on GitHub. + +```powershell +Connect-GitHubAccount -Mode OAuth + +! We added the code to your clipboard: [AB55-FA2E] +Press Enter to open github.com in your browser...: +✓ Logged in as octocat! +``` + +#### Personal access token +This is the least secure method of authentication, but it is also the simplest. Running the `Connect-GitHubAccount` command +with the `-AccessToken` parameter will send you to the GitHub website where you can create a new personal access token. +Give it the access you need and paste it into the terminal. + +```powershell +Connect-GitHubAccount -AccessToken +! Enter your personal access token: **************************************** +✓ Logged in as octocat! +``` + +#### System Access Token +The module also detects the presence of a system access token and uses that if it is present. +This is useful if you are running the module in a CI/CD pipeline or in a scheduled task. +The function looks for the `GH_TOKEN` and `GITHUB_TOKEN` environment variables (in order). + ```powershell ->_ Connect-GitHubAccount -AccessToken 'ghp_abcdefghklmnopqrstuvwxyz123456789123' ->_ +Connect-GitHubAccount +✓ Logged in as system! ``` -2. **Command Exploration**: Familiarize yourself with the available cmdlets using the module's comprehensive documentation or inline help. +### Command Exploration +Familiarize yourself with the available cmdlets using the module's comprehensive documentation or inline help. + +```powershell +Get-Command -Module GitHub +``` - ```powershell - Get-Command -Module GitHub - ``` +### Sample Scripts -3. **Sample Scripts**: Check out sample scripts and usage patterns to jumpstart your automation tasks on GitHub. +To be added: Sample scripts demonstrating the module's capabilities. ## More Information & Resources @@ -85,7 +152,6 @@ For a detailed understanding of the framework, [read more about PSModule here](h - [Generic HTTP Status Codes (MDN)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) ### Tools Planned for Development: -- [Microsoft.PowerShell.SecretManagement](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.secretmanagement/?view=ps-modules) - [Azure AutoRest (OpenAPI Specification Code Generator)](https://github.com/Azure/autorest) ### Inspiration Behind the Project: @@ -95,7 +161,6 @@ For a detailed understanding of the framework, [read more about PSModule here](h - [libsodium NuGet Package](https://www.nuget.org/packages/Sodium.Core/) ### Authentication and Login: -- [SecretManagement and SecretStore Overview](https://learn.microsoft.com/en-us/powershell/utility-modules/secretmanagement/overview?view=ps-modules) - [PowerShell for GitHub on GitHub Marketplace](https://github.com/apps/powershell-for-github) - [Building a CLI with a GitHub App](https://docs.github.com/en/apps/creating-github-apps/writing-code-for-a-github-app/building-a-cli-with-a-github-app) diff --git a/src/GitHub/private/Auth/DeviceFlow/Test-GitHubAccessTokenRefreshRequired.ps1 b/src/GitHub/private/Auth/DeviceFlow/Test-GitHubAccessTokenRefreshRequired.ps1 index 5d16cf56e..1606c6630 100644 --- a/src/GitHub/private/Auth/DeviceFlow/Test-GitHubAccessTokenRefreshRequired.ps1 +++ b/src/GitHub/private/Auth/DeviceFlow/Test-GitHubAccessTokenRefreshRequired.ps1 @@ -14,15 +14,16 @@ [CmdletBinding()] param() - $tokenExpirationDate = Get-GitHubConfig -Name 'AccessTokenExpirationDate' -ErrorAction SilentlyContinue - if (-not $tokenExpirationDate) { + $tokenType = Get-GitHubConfig -Name 'AccessTokenType' -ErrorAction SilentlyContinue + if ($tokenType -ne 'ghu_*') { + Write-Verbose "The access token is not a user token. No need to refresh." return $false } - $currentDateTime = Get-Date - # Calulate the remaining time in hours - $remainindDuration = [datetime]$tokenExpirationDate - $currentDateTime + $tokenExpirationDate = Get-GitHubConfig -Name 'AccessTokenExpirationDate' -ErrorAction SilentlyContinue + $currentDateTime = Get-Date + $remainingDuration = [datetime]$tokenExpirationDate - $currentDateTime # If the remaining time is less that $script:Auth.AccessTokenGracePeriodInHours then the token should be refreshed - $remainindDuration.TotalHours -lt $script:Auth.AccessTokenGracePeriodInHours + $remainingDuration.TotalHours -lt $script:Auth.AccessTokenGracePeriodInHours } diff --git a/src/GitHub/public/Auth/Connect-GitHubAccount.ps1 b/src/GitHub/public/Auth/Connect-GitHubAccount.ps1 index 441952710..64b771674 100644 --- a/src/GitHub/public/Auth/Connect-GitHubAccount.ps1 +++ b/src/GitHub/public/Auth/Connect-GitHubAccount.ps1 @@ -62,18 +62,26 @@ Mandatory, ParameterSetName = 'PAT' )] + [Alias('Token')] + [Alias('PAT')] [switch] $AccessToken, # Set the default owner to use in commands. [Parameter()] + [Alias('Organization')] + [Alias('Org')] [string] $Owner, # Set the default repository to use in commands. [Parameter()] + [Alias('Repository')] [string] $Repo, # Suppresses the output of the function. [Parameter()] + [Alias('Quiet')] + [Alias('q')] + [Alias('s')] [switch] $Silent ) diff --git a/src/GitHub/public/Organization/Blocking/Assert-GitHubOrganizationBlockedUser.ps1 b/src/GitHub/public/Organization/Blocking/Assert-GitHubOrganizationBlockedUser.ps1 index 67219e3e8..9e2a73803 100644 --- a/src/GitHub/public/Organization/Blocking/Assert-GitHubOrganizationBlockedUser.ps1 +++ b/src/GitHub/public/Organization/Blocking/Assert-GitHubOrganizationBlockedUser.ps1 @@ -43,13 +43,13 @@ Method = 'GET' } - $statusCode = (Invoke-GitHubAPI @inputObject -ErrorAction SilentlyContinue).StatusCode - - if ($statusCode -eq 204) { - return $true - } elseif ($statusCode -eq 404) { - return $false - } else { - throw "Unexpected status code: $statusCode" + try { + (Invoke-GitHubAPI @inputObject).StatusCode -eq 204 + } catch { + if ($_.Exception.Response.StatusCode.Value__ -eq 404) { + return $false + } else { + throw $_ + } } } diff --git a/src/GitHub/public/Users/Blocking/Get-GitHubBlockedUser copy.ps1 b/src/GitHub/public/Users/Blocking/Assert-GitHubBlockedUser.ps1 similarity index 80% rename from src/GitHub/public/Users/Blocking/Get-GitHubBlockedUser copy.ps1 rename to src/GitHub/public/Users/Blocking/Assert-GitHubBlockedUser.ps1 index 2b55d0370..9bf24e819 100644 --- a/src/GitHub/public/Users/Blocking/Get-GitHubBlockedUser copy.ps1 +++ b/src/GitHub/public/Users/Blocking/Assert-GitHubBlockedUser.ps1 @@ -27,6 +27,14 @@ Body = $body } - (Invoke-GitHubAPI @inputObject).Response + try { + (Invoke-GitHubAPI @inputObject).StatusCode -eq 204 + } catch { + if ($_.Exception.Response.StatusCode.Value__ -eq 404) { + return $false + } else { + throw $_ + } + } } diff --git a/tools/utilities/Local-Testing.ps1 b/tools/utilities/Local-Testing.ps1 index dd395151d..cc9a1aa28 100644 --- a/tools/utilities/Local-Testing.ps1 +++ b/tools/utilities/Local-Testing.ps1 @@ -1,6 +1,9 @@ ##### +Get-Module -Name GitHub -ListAvailable Get-Module -Name GitHub* -ListAvailable | Remove-Module -Force Get-Module -Name GitHub* -ListAvailable | Uninstall-Module -Force -AllVersions +Get-Module -Name GitHub -ListAvailable + Get-SecretVault | Unregister-SecretVault Get-SecretVault