Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
function Remove-PowerShellGalleryContext {
<#
.SYNOPSIS
Remove a PowerShell Gallery context.

.DESCRIPTION
Remove a PowerShell Gallery context from the vault.

.EXAMPLE
Remove-PowerShellGalleryContext -ID 'MyAccount'

Removes the PowerShell Gallery context with ID 'MyAccount'.
#>
[OutputType([void])]
[CmdletBinding(SupportsShouldProcess)]
param(
# The ID of the context to remove.
[Parameter(Mandatory)]
[string] $ID
)

begin {
Write-Debug '[Remove-PowerShellGalleryContext] - Start'
$null = Get-PowerShellGalleryConfig
}

process {
if ($PSCmdlet.ShouldProcess("Context [$ID]", 'Remove')) {
Write-Verbose "Removing context: [$ID]"
Remove-Context -ID $ID -Vault $script:PowerShellGallery.ContextVault

# If this was the default context, clear the default
if ($script:PowerShellGallery.Config.DefaultContext -eq $ID) {
Write-Verbose 'Clearing default context'
$script:PowerShellGallery.Config.DefaultContext = $null
$configID = $script:PowerShellGallery.DefaultConfig.ID
$vault = $script:PowerShellGallery.ContextVault
$null = Set-Context -ID $configID -Context $script:PowerShellGallery.Config -Vault $vault
}
}
}

end {
Write-Debug '[Remove-PowerShellGalleryContext] - End'
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
function Set-PowerShellGalleryContext {
<#
.SYNOPSIS
Sets the PowerShell Gallery context and stores it in the context vault.

.DESCRIPTION
This function sets the PowerShell Gallery context and stores it in the context vault.
The context is used to authenticate with the PowerShell Gallery API.

.EXAMPLE
$context = @{
ID = 'MyAccount'
Name = 'MyAccount'
ApiKey = $secureApiKey
GalleryUrl = 'https://www.powershellgallery.com'
ConnectedAt = Get-Date
}
Set-PowerShellGalleryContext -Context $context

Sets the PowerShell Gallery context with the specified settings as a hashtable.
#>
[OutputType([System.Object])]
[CmdletBinding(SupportsShouldProcess)]
param(
# The ID of the context.
[Parameter(Mandatory)]
[string] $ID,

# The PowerShell Gallery context to save in the vault.
[Parameter(Mandatory)]
[hashtable] $Context,

# Set as the default context.
[Parameter()]
[switch] $Default,

# Pass the context through the pipeline.
[Parameter()]
[switch] $PassThru
)

begin {
Write-Debug '[Set-PowerShellGalleryContext] - Start'
$null = Get-PowerShellGalleryConfig
}

process {
Write-Debug "Setting context: [$ID]"
# Create a copy of the context hashtable to avoid modifying the original
$contextObj = $Context.Clone()
$contextObj['ID'] = $ID

if ($PSCmdlet.ShouldProcess("Context [$ID]", 'Set')) {
$vault = $script:PowerShellGallery.ContextVault
$result = Set-Context -ID $ID -Context $contextObj -Vault $vault -PassThru

if ($Default) {
Write-Debug "Setting [$ID] as default context"
$script:PowerShellGallery.Config.DefaultContext = $ID
$configID = $script:PowerShellGallery.DefaultConfig.ID
$null = Set-Context -ID $configID -Context $script:PowerShellGallery.Config -Vault $vault
}

if ($PassThru) {
return $result
}
}
}

end {
Write-Debug '[Set-PowerShellGalleryContext] - End'
}
}
33 changes: 33 additions & 0 deletions src/functions/private/Config/Get-PowerShellGalleryConfig.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
function Get-PowerShellGalleryConfig {
<#
.SYNOPSIS
Get the PowerShell Gallery configuration.

.DESCRIPTION
Get the PowerShell Gallery configuration. Initializes if not already loaded.

.EXAMPLE
Get-PowerShellGalleryConfig

Gets the PowerShell Gallery configuration.
#>
[OutputType([System.Object])]
[CmdletBinding()]
param()

begin {
Write-Debug '[Get-PowerShellGalleryConfig] - Start'
}

process {
if ($null -eq $script:PowerShellGallery.Config) {
Write-Debug 'Config not initialized, initializing...'
Initialize-PowerShellGalleryConfig
}
return $script:PowerShellGallery.Config
}

end {
Write-Debug '[Get-PowerShellGalleryConfig] - End'
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
function Initialize-PowerShellGalleryConfig {
<#
.SYNOPSIS
Initialize the PowerShellGallery module configuration.

.DESCRIPTION
Initialize the PowerShellGallery module configuration.

.EXAMPLE
Initialize-PowerShellGalleryConfig

Initializes the PowerShellGallery module configuration.

.EXAMPLE
Initialize-PowerShellGalleryConfig -Force

Forces the initialization of the PowerShellGallery module configuration.
#>
[OutputType([void])]
[CmdletBinding()]
param (
# Force the initialization of the PowerShellGallery config.
[switch] $Force
)

begin {
Write-Debug '[Initialize-PowerShellGalleryConfig] - Start'
}

process {
Write-Debug "Force: [$Force]"
if ($Force) {
Write-Debug 'Forcing initialization of PowerShellGalleryConfig.'
$config = Set-Context -Context $script:PowerShellGallery.DefaultConfig -Vault $script:PowerShellGallery.ContextVault -PassThru
$script:PowerShellGallery.Config = $config
return
}

if ($null -ne $script:PowerShellGallery.Config) {
Write-Debug 'PowerShellGalleryConfig already initialized and available in memory.'
return
}

Write-Debug 'Attempt to load the stored PowerShellGalleryConfig from ContextVault'
$config = Get-Context -ID $script:PowerShellGallery.DefaultConfig.ID -Vault $script:PowerShellGallery.ContextVault
if ($config) {
Write-Debug 'PowerShellGalleryConfig loaded into memory.'
$script:PowerShellGallery.Config = $config
return
}

Write-Debug 'Initializing PowerShellGalleryConfig from defaults'
$config = Set-Context -Context $script:PowerShellGallery.DefaultConfig -Vault $script:PowerShellGallery.ContextVault -PassThru
$script:PowerShellGallery.Config = $config
}

end {
Write-Debug '[Initialize-PowerShellGalleryConfig] - End'
}
}
127 changes: 127 additions & 0 deletions src/functions/public/Auth/Connect-PowerShellGallery.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
function Connect-PowerShellGallery {
<#
.SYNOPSIS
Connects to the PowerShell Gallery by storing an API key context.

.DESCRIPTION
Connects to the PowerShell Gallery by storing an API key in a secure context vault.
When called without an API key, it opens the user's browser to the PowerShell Gallery
API key management page and prompts for the key.

.EXAMPLE
Connect-PowerShellGallery -Name 'MyAccount'

Opens browser to API key page and prompts for API key, then stores it with name 'MyAccount'.

.EXAMPLE
Connect-PowerShellGallery -Name 'CIAccount' -ApiKey $secureApiKey -Silent

Stores the provided API key without prompting or informational output.

.EXAMPLE
$context = Connect-PowerShellGallery -Name 'MyAccount' -PassThru

Stores the API key and returns the context object.
#>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSAvoidUsingConvertToSecureStringWithPlainText', '',
Justification = 'The API key is received as clear text from user input.'
)]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSAvoidUsingWriteHost', '',
Justification = 'Is the CLI part of the module. Consistent with GitHub module pattern.'
)]
[CmdletBinding(DefaultParameterSetName = 'Interactive')]
[OutputType([System.Object])]
param(
# A friendly name/identifier for this connection context
[Parameter(Mandatory)]
[string] $Name,

# The API key as a SecureString. If not provided, user will be prompted.
[Parameter(ParameterSetName = 'Interactive')]
[Parameter(Mandatory, ParameterSetName = 'NonInteractive')]
[SecureString] $ApiKey,

# Return the context object after creation
[Parameter()]
[switch] $PassThru,

# Suppress informational output
[Parameter()]
[switch] $Silent
)

begin {
Write-Debug '[Connect-PowerShellGallery] - Start'
$null = Get-PowerShellGalleryConfig
}

process {
# Open browser to API key page if interactive
if ($PSCmdlet.ParameterSetName -eq 'Interactive' -and -not $ApiKey) {
if (-not $Silent) {
Write-Host '🌐 Opening PowerShell Gallery API key management page...' -ForegroundColor Cyan
}

$apiKeyUrl = 'https://www.powershellgallery.com/account/apikeys'

# Try to open browser
try {
if ($IsWindows -or $PSVersionTable.PSVersion.Major -le 5) {
Start-Process $apiKeyUrl
} elseif ($IsMacOS) {
Start-Process 'open' -ArgumentList $apiKeyUrl
} elseif ($IsLinux) {
Start-Process 'xdg-open' -ArgumentList $apiKeyUrl
}
} catch {
Write-Warning "Unable to open browser automatically. Please visit: $apiKeyUrl"
}

if (-not $Silent) {
Write-Host ''
Write-Host 'Please create or copy your API key from the PowerShell Gallery.' -ForegroundColor Yellow
Write-Host ''
}
}

# Prompt for API key if not provided
if (-not $ApiKey) {
$ApiKey = Read-Host -Prompt 'Enter your PowerShell Gallery API key' -AsSecureString
}

# Validate API key is not empty
if ($null -eq $ApiKey) {
Write-Error 'API key is required to connect to PowerShell Gallery.'
return
}

# Create context object using centralized configuration
$config = Get-PowerShellGalleryConfig
$context = @{
ID = $Name
Name = $Name
ApiKey = $ApiKey
GalleryUrl = $config.GalleryUrl
ApiUrl = $config.ApiUrl
ConnectedAt = Get-Date
}

# Store context
Write-Verbose "Storing context with ID: [$Name]"
$result = Set-PowerShellGalleryContext -ID $Name -Context $context -Default -PassThru

if (-not $Silent) {
Write-Host "✓ Successfully connected to PowerShell Gallery as [$Name]" -ForegroundColor Green
}

if ($PassThru) {
return $result
}
}

end {
Write-Debug '[Connect-PowerShellGallery] - End'
}
}
Loading
Loading