VMWare.Authentication.psm1

using module .\Classes\VMWare.VCenterManager.psm1
using module .\Classes\VMWare.AuthType.psm1
using module .\Classes\VMWare.VCenter.psm1
using module .\Classes\VMWare.Settings.psm1

function New-VSphereLogin {
    [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='Low')]
    [Alias('Login-VSphere')]
    param(
        [Parameter(Mandatory=$true)]
        [VMWareAuthType]$Type,
        [PSCredential]$Credential,
        [String]$ClientId,
        [SecureString]$ClientSecret,
        [String]$Scope,
        [String]$VSphere = '',
        [Switch]$NoSave,
        [Switch]$IgnoreCertificateErrors
    )
    if ($pscmdlet.ShouldProcess('VSphere Login', 'create'))
    {
        # Choose VSphere Instance
        if ($VSphere -eq ''){
            $VSphere = Read-ValidInput -Prompt 'Enter the VSphere URL (FQDN):' -Regex '^.+\..+$'
        }

        if((Test-VSphereURL $VSphere) -eq $false){
            throw 'Failed to connect to VSphere, confirm the URL and network connectivity...'
        }

        $VCenter = [VMWareVCenter]::new()
        $VCenter.VSphere = $VSphere
        $VCenter.AuthType = $Type
        $VCenter.IgnoreCertificateErrors = [Bool]$IgnoreCertificateErrors

        switch ($Type) {
            ([VMWareAuthType]::Credential) {
                if ($null -eq $Credential){
                    $Credential = Get-Credential
                }
                $VCenter.Credential = $Credential
            }
            ([VMWareAuthType]::SSO) {
                if (-not $ClientId){
                    $ClientId = Read-ValidInput -Prompt 'Enter the OAuth Client ID:' -Regex '^.+$'
                }
                if ($null -eq $ClientSecret){
                    # Prompt allows a plain string for convenience and converts it to a SecureString
                    $secretInput = Read-Host -Prompt 'Enter the Client Secret (optional, press Enter to skip)' -AsSecureString
                    if ($secretInput.Length -gt 0){
                        $ClientSecret = $secretInput
                    }
                }
                $VCenter.ClientId = $ClientId
                $VCenter.ClientSecret = $ClientSecret
                # Authorization and token endpoints are derived from the vCenter's ACS endpoint
                $VCenter.AuthorizationEndpointUrl = "https://$VSphere/acs/t/CUSTOMER/authorize"
                $VCenter.TokenEndpointUrl = "https://$VSphere/acs/t/CUSTOMER/token"
                $VCenter.RedirectUrl = 'http://localhost:8844/authcode'
                $VCenter.Scope = $Scope
            }
        }

        $Auth = [VCenterManager]::GetOrCreate()
        $Auth.AddOrUpdate($VCenter)
        Write-Output "Connecting to $($VCenter.VSphere)"
        $Auth.SetActive($VSphere)

        if(-not $NoSave){
            $Auth.Save()
        }
    }
}

function Save-VSphereLogin {
    [CmdletBinding()]
    param(
    )

    $Auth = [VCenterManager]::GetInstance()
    $Auth.save()
}

function Get-VSphereLogin {
    [CmdletBinding()]
    param(
    )

    $Auth = [VCenterManager]::GetOrCreate()

    return $Auth.Profiles | ForEach-Object {
        [PSCustomObject]@{
            VSphere  = $_.VSphere
            AuthType = $_.AuthType
            Active   = ($_.VSphere -eq $Auth.ActiveVSphere)
        }
    }
}

function Switch-VSphereLogin {
    [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='Low')]
    param(
        [String]$VSphere = ''
    )

    $Auth = [VCenterManager]::GetOrCreate()

    if ($VSphere -eq ''){
        switch ($Auth.Profiles.Count) {
            0 {
                throw 'No saved vCenter profiles are available.'
            }
            1 {
                Write-Output "There is only one vCenter connection: $($Auth.Profiles[0].VSphere). Use New-VSphereLogin to add another."
                return
            }
            default {
                $VSphere = (Select-FromList -List ([String[]]$Auth.Profiles.VSphere)).Value
            }
        }
    }

    if ($pscmdlet.ShouldProcess($VSphere, 'switch active vCenter'))
    {
        $Auth.SetActive($VSphere)
        $Auth.SaveIfPersisted()
    }
}

<#
    .SYNOPSIS
        Tests VSphere URL for connectivity

    .DESCRIPTION
        Tests VSphere URL for connectivity on port 443 TCP

    .PARAMETER VSphere
        VSphere URL
#>

function Test-VSphereURL {
    [CmdletBinding()]
    [OutputType('System.Boolean')]
    param(
        [String]$VSphere
    )
    $result = Test-NetConnection -ComputerName $VSphere -Port 443

    if($result.TcpTestSucceeded){
        return $true
    }else{
        Write-Warning "Failed to connect to VSphere URL: $VSphere at remote address: $($result.RemoteAddress)"
        return $false
    }
}

function Test-VSphereLogin {
    [CmdletBinding()]
    param()

    $Auth = [VCenterManager]::GetOrCreate()
    $Auth.GetActiveProfile().Connect()
}

function Remove-VSphereLogin {
    [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='Low')]
    param(
        [String]$VSphere = ''
    )

    $Auth = [VCenterManager]::GetOrCreate()

    if ($VSphere -eq ''){
        if ($Auth.Profiles.Count -eq 0){
            throw 'No saved vCenter profiles are available.'
        }
        $VSphere = (Select-FromList -List ([String[]]$Auth.Profiles.VSphere)).Value
    }

    if ($pscmdlet.ShouldProcess($VSphere, 'remove'))
    {
        $Auth.Disconnect($VSphere)
        $Auth.Remove($VSphere)

        if ($Auth.Profiles.Count -eq 0){
            [VCenterManager]::ClearInstance()
            [VCenterManager]::Delete()
        }else{
            $Auth.SaveIfPersisted()
        }
    }
}