Skip to content
Open
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
94 changes: 94 additions & 0 deletions Tests/ConvertFrom-Base64UrlString.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
Describe $($PSCommandPath -Replace '.Tests.ps1') {

BeforeAll {
#Get Current Directory
$Here = Split-Path -Parent $PSCommandPath

#Assume ModuleName from Repository Root folder
$ModuleName = Split-Path (Split-Path $Here -Parent) -Leaf

#Resolve Path to Module Directory
$ModulePath = Resolve-Path "$Here\..\$ModuleName"

#Define Path to Module Manifest
$ManifestPath = Join-Path "$ModulePath" "$ModuleName.psd1"

if ( -not (Get-Module -Name $ModuleName -All)) {

Import-Module -Name "$ManifestPath" -ArgumentList $true -Force -ErrorAction Stop

}

$Script:RequestBody = $null
$psPASSession = [ordered]@{
BaseURI = 'https://SomeURL/SomeApp'
User = $null
ExternalVersion = [System.Version]'0.0'
WebSession = New-Object Microsoft.PowerShell.Commands.WebRequestSession
StartTime = $null
ElapsedTime = $null
LastCommand = $null
LastCommandTime = $null
LastCommandResults = $null
}

New-Variable -Name psPASSession -Value $psPASSession -Scope Script -Force

}


AfterAll {

$Script:RequestBody = $null

}

InModuleScope $(Split-Path (Split-Path (Split-Path -Parent $PSCommandPath) -Parent) -Leaf ) {

Context 'Mandatory Parameters' {

$Parameters = @{Parameter = 'InputString' }

It 'specifies parameter <Parameter> as mandatory' -TestCases $Parameters {

param($Parameter)

(Get-Command ConvertFrom-Base64UrlString).Parameters["$Parameter"].Attributes.Mandatory | Should -Be $true

}

}

Context 'Base64Url Decoding' {

It 'decodes Base64Url string without padding' {
$base64Url = 'SGVsbG8gV29ybGQ'
$result = ConvertFrom-Base64UrlString -InputString $base64Url
$resultString = [System.Text.Encoding]::UTF8.GetString($result)
$resultString | Should -Be 'Hello World'
}

It 'decodes Base64Url with URL-safe characters (dash and underscore)' {
$base64Url = 'PDw_Pz8-Pg'
$result = ConvertFrom-Base64UrlString -InputString $base64Url
$result | Should -Not -BeNullOrEmpty
}

It 'handles padding correctly' {
$base64Url = 'YWJj'
$result = ConvertFrom-Base64UrlString -InputString $base64Url
$resultString = [System.Text.Encoding]::UTF8.GetString($result)
$resultString | Should -Be 'abc'
}

It 'converts Base64Url to byte array' {
$base64Url = 'VGVzdA'
$result = ConvertFrom-Base64UrlString -InputString $base64Url
$result.GetType().BaseType.Name | Should -Be 'Array'
}

}

}

}
128 changes: 128 additions & 0 deletions Tests/Invoke-FIDO2Authentication.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
Describe $($PSCommandPath -Replace '.Tests.ps1') {

BeforeAll {
#Get Current Directory
$Here = Split-Path -Parent $PSCommandPath

#Assume ModuleName from Repository Root folder
$ModuleName = Split-Path (Split-Path $Here -Parent) -Leaf

#Resolve Path to Module Directory
$ModulePath = Resolve-Path "$Here\..\$ModuleName"

#Define Path to Module Manifest
$ManifestPath = Join-Path "$ModulePath" "$ModuleName.psd1"

if ( -not (Get-Module -Name $ModuleName -All)) {

Import-Module -Name "$ManifestPath" -ArgumentList $true -Force -ErrorAction Stop

}

$Script:RequestBody = $null
$psPASSession = [ordered]@{
BaseURI = 'https://SomeURL/SomeApp'
User = $null
ExternalVersion = [System.Version]'0.0'
WebSession = New-Object Microsoft.PowerShell.Commands.WebRequestSession
StartTime = $null
ElapsedTime = $null
LastCommand = $null
LastCommandTime = $null
LastCommandResults = $null
}

New-Variable -Name psPASSession -Value $psPASSession -Scope Script -Force

}


AfterAll {

$Script:RequestBody = $null

}

InModuleScope $(Split-Path (Split-Path (Split-Path -Parent $PSCommandPath) -Parent) -Leaf ) {

Context 'Mandatory Parameters' {

$Parameters = @(
@{Parameter = 'BaseURI' },
@{Parameter = 'UserName' }
)

It 'specifies parameter as mandatory' -TestCases $Parameters {

param($Parameter)

(Get-Command Invoke-FIDO2Authentication).Parameters["$Parameter"].Attributes.Mandatory | Should -Be $true

}

It 'specifies parameter LogonRequest as optional' {

(Get-Command Invoke-FIDO2Authentication).Parameters["LogonRequest"].Attributes.Mandatory | Should -Be $false

}

}

Context 'Platform Requirements' {

BeforeEach {
$IsWindowsPlatform = (-not (Test-IsCoreCLR)) -or $IsWindows
}

It 'requires Windows platform' {
if (-not $IsWindowsPlatform) {
{ Invoke-FIDO2Authentication -BaseURI 'https://pvwa.example.com' -UserName 'testuser' -LogonRequest @{} } | Should -Throw '*Windows*'
}
}

}

Context 'Input Validation' {

It 'accepts BaseURI parameter' {
$params = (Get-Command Invoke-FIDO2Authentication).Parameters['BaseURI']
$params | Should -Not -BeNullOrEmpty
$params.ParameterType.Name | Should -Be 'String'
}

It 'accepts UserName parameter' {
$params = (Get-Command Invoke-FIDO2Authentication).Parameters['UserName']
$params | Should -Not -BeNullOrEmpty
$params.ParameterType.Name | Should -Be 'String'
}

It 'accepts LogonRequest parameter' {
$params = (Get-Command Invoke-FIDO2Authentication).Parameters['LogonRequest']
$params | Should -Not -BeNullOrEmpty
$params.ParameterType.Name | Should -Be 'Hashtable'
}

}

Context 'Help Content' {

It 'has a synopsis' {
$help = Get-Help Invoke-FIDO2Authentication
$help.Synopsis | Should -Not -BeNullOrEmpty
}

It 'has a description' {
$help = Get-Help Invoke-FIDO2Authentication
$help.Description | Should -Not -BeNullOrEmpty
}

It 'has examples' {
$help = Get-Help Invoke-FIDO2Authentication
$help.Examples | Should -Not -BeNullOrEmpty
}

}

}

}
63 changes: 63 additions & 0 deletions Tests/New-PASSession.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -1237,6 +1237,69 @@ Describe $($PSCommandPath -Replace '.Tests.ps1') {

}

Context 'Gen2 with FIDO2' {

BeforeEach {

Mock Assert-VersionRequirement -MockWith {}

Mock Invoke-FIDO2Authentication -MockWith {
[PSCustomObject]@{
'CyberArkLogonResult' = 'AAAAAAA\\\REEEAAAAALLLLYYYYY\\\\LOOOOONNNNGGGGG\\\ACCCCCEEEEEEEESSSSSSS\\\\\\TTTTTOOOOOKKKKKEEEEEN'
}
}

Mock Get-PASServer -MockWith {
[PSCustomObject]@{
ExternalVersion = '14.6'
}
}

Mock Get-PASLoggedOnUser -MockWith {
@{'UserName' = 'TestUser' }
}

$psPASSession.ExternalVersion = '14.6'
$psPASSession.WebSession = New-Object Microsoft.PowerShell.Commands.WebRequestSession

}

It 'sends request with UserName parameter' {
New-PASSession -BaseURI 'https://pvwa.cyberark.com' -type FIDO2 -UserName 'TestUser'
Assert-MockCalled Invoke-FIDO2Authentication -Times 1 -Exactly -Scope It

}

It 'sends request with expected parameters' {
New-PASSession -BaseURI 'https://pvwa.cyberark.com' -type FIDO2 -UserName 'TestUser'
Assert-MockCalled Invoke-FIDO2Authentication -ParameterFilter {

$BaseURI -eq 'https://pvwa.cyberark.com/PasswordVault' -and $UserName -eq 'TestUser'

} -Times 1 -Exactly -Scope It

}

It 'throws error when UserName is not provided' {
{ New-PASSession -BaseURI 'https://pvwa.cyberark.com' -type FIDO2 } | Should -Throw 'Username is required for FIDO2 authentication. Use -UserName parameter.'
}

It 'sets expected BaseURI' {

New-PASSession -BaseURI 'https://pvwa.cyberark.com' -type FIDO2 -UserName 'TestUser'
$Script:psPASSession.BaseURI | Should -Be 'https://pvwa.cyberark.com/PasswordVault'

}

It 'sets expected authorization header' {

New-PASSession -BaseURI 'https://pvwa.cyberark.com' -type FIDO2 -UserName 'TestUser'
$psPASSession.WebSession.Headers['Authorization'] | Should -Be 'AAAAAAA\\\REEEAAAAALLLLYYYYY\\\\LOOOOONNNNGGGGG\\\ACCCCCEEEEEEEESSSSSSS\\\\\\TTTTTOOOOOKKKKKEEEEEN'

}

}

}

}
Loading