diff --git a/src/functions/private/Auth/DeviceFlow/Invoke-GitHubDeviceFlowLogin.ps1 b/src/functions/private/Auth/DeviceFlow/Invoke-GitHubDeviceFlowLogin.ps1 index 1fc237268..19b3c1bc7 100644 --- a/src/functions/private/Auth/DeviceFlow/Invoke-GitHubDeviceFlowLogin.ps1 +++ b/src/functions/private/Auth/DeviceFlow/Invoke-GitHubDeviceFlowLogin.ps1 @@ -32,6 +32,10 @@ [Parameter()] [string] $Scope, + # The host to connect to. + [Parameter(Mandatory)] + [string] $HostName, + # The refresh token to use for re-authentication. [Parameter()] [securestring] $RefreshToken @@ -39,9 +43,9 @@ do { if ($RefreshToken) { - $tokenResponse = Wait-GitHubAccessToken -ClientID $ClientID -RefreshToken $RefreshToken + $tokenResponse = Wait-GitHubAccessToken -ClientID $ClientID -RefreshToken $RefreshToken -HostName $HostName } else { - $deviceCodeResponse = Request-GitHubDeviceCode -ClientID $ClientID -Scope $Scope + $deviceCodeResponse = Request-GitHubDeviceCode -ClientID $ClientID -Scope $Scope -HostName $HostName $deviceCode = $deviceCodeResponse.device_code $interval = $deviceCodeResponse.interval @@ -54,7 +58,7 @@ Read-Host 'Press Enter to open github.com in your browser...' Start-Process $verificationUri - $tokenResponse = Wait-GitHubAccessToken -DeviceCode $deviceCode -ClientID $ClientID -Interval $interval + $tokenResponse = Wait-GitHubAccessToken -DeviceCode $deviceCode -ClientID $ClientID -Interval $interval -HostName $HostName } } while ($tokenResponse.error) $tokenResponse diff --git a/src/functions/private/Auth/DeviceFlow/Request-GitHubAccessToken.ps1 b/src/functions/private/Auth/DeviceFlow/Request-GitHubAccessToken.ps1 index d920e8f6e..f0d1f2476 100644 --- a/src/functions/private/Auth/DeviceFlow/Request-GitHubAccessToken.ps1 +++ b/src/functions/private/Auth/DeviceFlow/Request-GitHubAccessToken.ps1 @@ -8,7 +8,7 @@ This will poll the GitHub API until the user has entered the code. .EXAMPLE - Request-GitHubAccessToken -DeviceCode $deviceCode -ClientID $ClientID + Request-GitHubAccessToken -DeviceCode $deviceCode -ClientID $ClientID -HostName 'github.com' This will poll the GitHub API until the user has entered the code. @@ -35,7 +35,11 @@ Mandatory, ParameterSetName = 'RefreshToken' )] - [securestring] $RefreshToken + [securestring] $RefreshToken, + + # The host to connect to. + [Parameter(Mandatory)] + [string] $HostName ) $body = @{ @@ -57,7 +61,7 @@ } $RESTParams = @{ - Uri = 'https://github.com/login/oauth/access_token' + Uri = "https://$HostName/login/oauth/access_token" Method = 'POST' Body = $body Headers = @{ 'Accept' = 'application/json' } diff --git a/src/functions/private/Auth/DeviceFlow/Request-GitHubDeviceCode.ps1 b/src/functions/private/Auth/DeviceFlow/Request-GitHubDeviceCode.ps1 index 1171229ea..c21fdb9fe 100644 --- a/src/functions/private/Auth/DeviceFlow/Request-GitHubDeviceCode.ps1 +++ b/src/functions/private/Auth/DeviceFlow/Request-GitHubDeviceCode.ps1 @@ -7,7 +7,7 @@ Request a GitHub Device Code. .EXAMPLE - Request-GitHubDeviceCode -ClientID $ClientID -Mode $Mode + Request-GitHubDeviceCode -ClientID $ClientID -Mode $Mode -HostName 'github.com' This will request a GitHub Device Code. @@ -27,7 +27,11 @@ # For more information on scopes visit: # https://docs.github.com/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps [Parameter()] - [string] $Scope = 'gist, read:org, repo, workflow' + [string] $Scope = 'gist, read:org, repo, workflow', + + # The host to connect to. + [Parameter(Mandatory)] + [string] $HostName ) $headers = @{ @@ -40,7 +44,7 @@ } $RESTParams = @{ - Uri = 'https://github.com/login/device/code' + Uri = "https://$HostName/login/device/code" Method = 'POST' Body = $body Headers = $headers diff --git a/src/functions/private/Auth/DeviceFlow/Wait-GitHubAccessToken.ps1 b/src/functions/private/Auth/DeviceFlow/Wait-GitHubAccessToken.ps1 index 2a45ed719..eb1a98d7b 100644 --- a/src/functions/private/Auth/DeviceFlow/Wait-GitHubAccessToken.ps1 +++ b/src/functions/private/Auth/DeviceFlow/Wait-GitHubAccessToken.ps1 @@ -40,17 +40,20 @@ )] [securestring] $RefreshToken, + # The host to connect to. + [Parameter(Mandatory)] + [string] $HostName, + # The interval to wait between polling for the token. [Parameter()] [int] $Interval = 5 - ) do { if ($RefreshToken) { - $response = Request-GitHubAccessToken -ClientID $ClientID -RefreshToken $RefreshToken + $response = Request-GitHubAccessToken -ClientID $ClientID -RefreshToken $RefreshToken -HostName $HostName } else { - $response = Request-GitHubAccessToken -ClientID $ClientID -DeviceCode $DeviceCode + $response = Request-GitHubAccessToken -ClientID $ClientID -DeviceCode $DeviceCode -HostName $HostName } if ($response.error) { switch ($response.error) { diff --git a/src/functions/private/Commands/Initialize-RunnerEnvironment.ps1 b/src/functions/private/Commands/Initialize-RunnerEnvironment.ps1 index c7925d8ed..303d20ca9 100644 --- a/src/functions/private/Commands/Initialize-RunnerEnvironment.ps1 +++ b/src/functions/private/Commands/Initialize-RunnerEnvironment.ps1 @@ -23,6 +23,7 @@ $tokenVar = Get-ChildItem -Path 'Env:' | Where-Object Name -In 'GH_TOKEN', 'GITHUB_TOKEN' | Select-Object -First 1 -ExpandProperty Value $tokenVarPresent = $tokenVar.count -gt 0 -and -not [string]::IsNullOrEmpty($tokenVar) if ($tokenVarPresent) { - Connect-GitHubAccount -Repo $env:GITHUB_REPOSITORY_NAME -Owner $env:GITHUB_REPOSITORY_OWNER -ApiBaseUri $env:GITHUB_API_URL + $HostName = $env:GITHUB_SERVER_URL -replace '^https?://' + Connect-GitHubAccount -Repo $env:GITHUB_REPOSITORY_NAME -Owner $env:GITHUB_REPOSITORY_OWNER -Host $HostName } } diff --git a/src/functions/public/Auth/Connect-GitHubAccount.ps1 b/src/functions/public/Auth/Connect-GitHubAccount.ps1 index f1b4559a3..38f183d33 100644 --- a/src/functions/public/Auth/Connect-GitHubAccount.ps1 +++ b/src/functions/public/Auth/Connect-GitHubAccount.ps1 @@ -105,15 +105,15 @@ [Alias('Repository')] [string] $Repo, - # API host used for API requests. - [Parameter()] - [Alias('BaseURL')] - [string] $ApiBaseUri = 'https://api.github.com', - # API version used for API requests. [Parameter()] [string] $ApiVersion = '2022-11-28', + # The host to connect to. + [Parameter()] + [Alias('Host')] + [uri] $HostName = 'github.com', + # Suppresses the output of the function. [Parameter()] [Alias('Quiet')] @@ -122,6 +122,8 @@ [switch] $Silent ) + $ApiBaseUri = "https://api.$HostName" + $envVars = Get-ChildItem -Path 'Env:' Write-Debug 'Environment variables:' Write-Debug ($envVars | Format-Table -AutoSize | Out-String) @@ -137,7 +139,7 @@ $clientID = $script:Auth.$Mode.ClientID if ($Mode -ne (Get-GitHubConfig -Name 'DeviceFlowType' -ErrorAction SilentlyContinue)) { Write-Verbose "Using $Mode authentication..." - $tokenResponse = Invoke-GitHubDeviceFlowLogin -ClientID $clientID -Scope $Scope + $tokenResponse = Invoke-GitHubDeviceFlowLogin -ClientID $clientID -Scope $Scope -HostName $HostName } else { $accessTokenValidity = [datetime](Get-GitHubConfig -Name 'AccessTokenExpirationDate') - (Get-Date) $accessTokenIsValid = $accessTokenValidity.Seconds -gt 0 @@ -157,7 +159,7 @@ Write-Host '⚠ ' -ForegroundColor Yellow -NoNewline Write-Host "Access token remaining validity $accessTokenValidityText. Refreshing access token..." } - $tokenResponse = Invoke-GitHubDeviceFlowLogin -ClientID $clientID -RefreshToken (Get-GitHubConfig -Name 'RefreshToken') + $tokenResponse = Invoke-GitHubDeviceFlowLogin -ClientID $clientID -RefreshToken (Get-GitHubConfig -Name 'RefreshToken') -HostName $HostName } } else { $refreshTokenValidity = [datetime](Get-GitHubConfig -Name 'RefreshTokenExpirationDate') - (Get-Date) @@ -167,10 +169,10 @@ Write-Host '⚠ ' -ForegroundColor Yellow -NoNewline Write-Host 'Access token expired. Refreshing access token...' } - $tokenResponse = Invoke-GitHubDeviceFlowLogin -ClientID $clientID -RefreshToken (Get-GitHubConfig -Name 'RefreshToken') + $tokenResponse = Invoke-GitHubDeviceFlowLogin -ClientID $clientID -RefreshToken (Get-GitHubConfig -Name 'RefreshToken') -HostName $HostName } else { Write-Verbose "Using $Mode authentication..." - $tokenResponse = Invoke-GitHubDeviceFlowLogin -ClientID $clientID -Scope $Scope + $tokenResponse = Invoke-GitHubDeviceFlowLogin -ClientID $clientID -Scope $Scope -HostName $HostName } } } diff --git a/tools/dev/UserJourney.ps1 b/tools/dev/UserJourney.ps1 new file mode 100644 index 000000000..ac66ee0fa --- /dev/null +++ b/tools/dev/UserJourney.ps1 @@ -0,0 +1,69 @@ +### +### CONNECTING +### + +# When you connect, a context is saved. +# Variables, stored under "Contexts" on the existing config.json. +# Secrets, names are stored in the variables. +# Context = [ +# { +# name: "github.com/MariusStorhaug" +# id: 1 +# host: "github.com" +# default: true +# type: UAT +# }, +# { +# name: "dnb.ghe.com/Marius-Storhaug" +# id: 2 +# host: "dnb.ghe.com" +# default: false +# type: UAT +# } +# ] + +# Connect to GitHub interactively using GitHub App and Device Flow (User Access Token, UAT) +Connect-GitHub (-Host github.com) (-ClientID '') + +# Log on to a specific instance of GitHub (enterprise) +Connect-GitHub -Host 'dnb.ghe.com' + +# Connect to GitHub interactively using OAuth App and Device Flow (should not use this, should we even support it?) +Connect-GitHub -Mode 'OAuthApp' -Scope 'gist read:org repo workflow' + +# Connect to GitHub interactively using less desired PAT flow +Connect-GitHub -AccessToken + +# Connect to GitHub programatically (GitHub Actions) +Connect-GitHub # Looks for the GITHUB_TOKEN variable + +# Connect to GitHub programatically (GitHub App, for GitHub Actions or external applications, JWT login) +Connect-GitHub -ClientID '' -PrivateKey '' + +# Connect to GitHub programatically (GitHub App Installation Access Token) +Connect-GitHub -Token *********** + +### +### ADVANCED CONNECTING +### + +# Bring you own GitHub App +Set-GitHubAuthApp -ClientID '' +Check-GitHubAuthApp +Connect-GitHub + + + + + +# What about profiles? +Get-GitHubContext # List all contexts +Get-GitHubContext -Context 'name' # Returns a specific context + +Set-GitHubContext -Context 'name' # Take a name? Autocomplete the name + +Disconnect-GitHub -Context 'name' + + +# Calling specific functions with context or an ad-hoc token? +Get-GitHubRepository -Context 'dnb.ghe.com/MariusStorhaug'