From b78023fa2ce26541e69ac04b7b0a0de8b9cb8ec0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 30 Jan 2026 18:10:25 +0000 Subject: [PATCH 1/3] Initial plan From eb9694c93301c430c49eb80883481b8de792be0d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 30 Jan 2026 18:14:31 +0000 Subject: [PATCH 2/3] Fix New-IdleAuthSession: Add New-IdleAuthSessionBroker to IdLE.Core exports and add comprehensive tests Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com> --- src/IdLE.Core/IdLE.Core.psd1 | 3 +- tests/Core/ModuleExports.Tests.ps1 | 113 +++++++++++++++++++++++ tests/Core/New-IdleAuthSession.Tests.ps1 | 106 +++++++++++++++++++++ 3 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 tests/Core/ModuleExports.Tests.ps1 create mode 100644 tests/Core/New-IdleAuthSession.Tests.ps1 diff --git a/src/IdLE.Core/IdLE.Core.psd1 b/src/IdLE.Core/IdLE.Core.psd1 index a7174ff7..04c5f7e8 100644 --- a/src/IdLE.Core/IdLE.Core.psd1 +++ b/src/IdLE.Core/IdLE.Core.psd1 @@ -12,7 +12,8 @@ 'Test-IdleWorkflowDefinitionObject', 'New-IdlePlanObject', 'Invoke-IdlePlanObject', - 'Export-IdlePlanObject' + 'Export-IdlePlanObject', + 'New-IdleAuthSessionBroker' ) CmdletsToExport = @() AliasesToExport = @() diff --git a/tests/Core/ModuleExports.Tests.ps1 b/tests/Core/ModuleExports.Tests.ps1 new file mode 100644 index 00000000..bb57d093 --- /dev/null +++ b/tests/Core/ModuleExports.Tests.ps1 @@ -0,0 +1,113 @@ +Set-StrictMode -Version Latest + +BeforeAll { + . (Join-Path (Split-Path -Path $PSScriptRoot -Parent) '_testHelpers.ps1') + $repoRoot = Get-RepoRootPath +} + +Describe 'Module Export Consistency' { + Context 'IdLE.Core module exports' { + BeforeAll { + $env:IDLE_ALLOW_INTERNAL_IMPORT = '1' + $coreModulePath = Join-Path -Path $repoRoot -ChildPath 'src/IdLE.Core/IdLE.Core.psd1' + Import-Module -Name $coreModulePath -Force -ErrorAction Stop + + $coreModule = Get-Module -Name 'IdLE.Core' + } + + It 'exports New-IdleAuthSessionBroker function' { + $exportedCommands = $coreModule.ExportedCommands.Keys + $exportedCommands | Should -Contain 'New-IdleAuthSessionBroker' + } + + It 'New-IdleAuthSessionBroker is accessible via module-qualified name' { + # Test that the function can be accessed with module-qualified name + $command = Get-Command -Name 'IdLE.Core\New-IdleAuthSessionBroker' -ErrorAction SilentlyContinue + $command | Should -Not -BeNullOrEmpty + } + + It 'exported functions match between psm1 Export-ModuleMember and psd1 FunctionsToExport' { + # Read the psm1 file to find Export-ModuleMember calls + $psm1Path = Join-Path -Path $repoRoot -ChildPath 'src/IdLE.Core/IdLE.Core.psm1' + $psm1Content = Get-Content -Path $psm1Path -Raw + + # Extract Export-ModuleMember function list + if ($psm1Content -match "Export-ModuleMember\s+-Function\s+@\(([\s\S]*?)\)") { + $exportedInPsm1Raw = $Matches[1] + $exportedInPsm1 = $exportedInPsm1Raw -split "[,\r\n]+" | ForEach-Object { + $_.Trim().Trim("'").Trim('"') + } | Where-Object { $_ -ne '' } + + # Read the psd1 manifest + $manifest = Import-PowerShellDataFile -Path $coreModulePath + $exportedInPsd1 = $manifest.FunctionsToExport + + # Compare the two lists + $exportedInPsm1 = $exportedInPsm1 | Sort-Object + $exportedInPsd1 = $exportedInPsd1 | Sort-Object + + # Check that all functions in psm1 are in psd1 + foreach ($func in $exportedInPsm1) { + $exportedInPsd1 | Should -Contain $func -Because "Function '$func' is exported in psm1 but not listed in psd1 FunctionsToExport" + } + + # Check that all functions in psd1 are in psm1 + foreach ($func in $exportedInPsd1) { + $exportedInPsm1 | Should -Contain $func -Because "Function '$func' is listed in psd1 FunctionsToExport but not exported in psm1" + } + } + } + } + + Context 'IdLE meta-module exports' { + BeforeAll { + $idleModulePath = Join-Path -Path $repoRoot -ChildPath 'src/IdLE/IdLE.psd1' + Import-Module -Name $idleModulePath -Force -ErrorAction Stop + + $idleModule = Get-Module -Name 'IdLE' + } + + It 'exports New-IdleAuthSession function' { + $exportedCommands = $idleModule.ExportedCommands.Keys + $exportedCommands | Should -Contain 'New-IdleAuthSession' + } + + It 'New-IdleAuthSession can be called without module qualification' { + $command = Get-Command -Name 'New-IdleAuthSession' -ErrorAction SilentlyContinue + $command | Should -Not -BeNullOrEmpty + $command.Module.Name | Should -Be 'IdLE' + } + + It 'exported functions match between psm1 Export-ModuleMember and psd1 FunctionsToExport' { + # Read the psm1 file to find Export-ModuleMember calls + $psm1Path = Join-Path -Path $repoRoot -ChildPath 'src/IdLE/IdLE.psm1' + $psm1Content = Get-Content -Path $psm1Path -Raw + + # Extract Export-ModuleMember function list + if ($psm1Content -match "Export-ModuleMember\s+-Function\s+@\(([\s\S]*?)\)") { + $exportedInPsm1Raw = $Matches[1] + $exportedInPsm1 = $exportedInPsm1Raw -split "[,\r\n]+" | ForEach-Object { + $_.Trim().Trim("'").Trim('"') + } | Where-Object { $_ -ne '' } + + # Read the psd1 manifest + $manifest = Import-PowerShellDataFile -Path $idleModulePath + $exportedInPsd1 = $manifest.FunctionsToExport + + # Compare the two lists + $exportedInPsm1 = $exportedInPsm1 | Sort-Object + $exportedInPsd1 = $exportedInPsd1 | Sort-Object + + # Check that all functions in psm1 are in psd1 + foreach ($func in $exportedInPsm1) { + $exportedInPsd1 | Should -Contain $func -Because "Function '$func' is exported in psm1 but not listed in psd1 FunctionsToExport" + } + + # Check that all functions in psd1 are in psm1 + foreach ($func in $exportedInPsd1) { + $exportedInPsm1 | Should -Contain $func -Because "Function '$func' is listed in psd1 FunctionsToExport but not exported in psm1" + } + } + } + } +} diff --git a/tests/Core/New-IdleAuthSession.Tests.ps1 b/tests/Core/New-IdleAuthSession.Tests.ps1 new file mode 100644 index 00000000..e636e1ab --- /dev/null +++ b/tests/Core/New-IdleAuthSession.Tests.ps1 @@ -0,0 +1,106 @@ +BeforeAll { + . (Join-Path (Split-Path -Path $PSScriptRoot -Parent) '_testHelpers.ps1') + Import-IdleTestModule +} + +Describe 'New-IdleAuthSession' { + BeforeEach { + # Create a test credential for use in tests + $password = ConvertTo-SecureString 'TestPassword123!' -AsPlainText -Force + $testCred = New-Object System.Management.Automation.PSCredential('TestUser', $password) + } + + It 'creates an auth session broker with the expected type' { + $broker = New-IdleAuthSession -SessionMap @{ + @{ Role = 'AD' } = $testCred + } + + $broker | Should -Not -BeNullOrEmpty + $broker.PSTypeNames | Should -Contain 'IdLE.AuthSessionBroker' + } + + It 'creates broker with AcquireAuthSession method' { + $broker = New-IdleAuthSession -SessionMap @{ + @{ Role = 'AD' } = $testCred + } + + $broker.PSObject.Methods['AcquireAuthSession'] | Should -Not -BeNullOrEmpty + } + + It 'accepts SessionMap parameter' { + $sessionMap = @{ + @{ Role = 'Tier0' } = $testCred + @{ Role = 'Admin' } = $testCred + } + + $broker = New-IdleAuthSession -SessionMap $sessionMap + + $broker.SessionMap | Should -Not -BeNullOrEmpty + $broker.SessionMap.Count | Should -Be 2 + } + + It 'accepts optional DefaultCredential parameter' { + $broker = New-IdleAuthSession -SessionMap @{ + @{ Role = 'AD' } = $testCred + } -DefaultCredential $testCred + + $broker.DefaultCredential | Should -Not -BeNullOrEmpty + $broker.DefaultCredential.UserName | Should -Be 'TestUser' + } + + It 'broker can acquire auth session with matching options' { + $broker = New-IdleAuthSession -SessionMap @{ + @{ Role = 'Tier0' } = $testCred + } + + $acquiredSession = $broker.AcquireAuthSession('TestName', @{ Role = 'Tier0' }) + + $acquiredSession | Should -Not -BeNullOrEmpty + $acquiredSession | Should -BeOfType [PSCredential] + $acquiredSession.UserName | Should -Be 'TestUser' + } + + It 'broker returns default credential when no options provided' { + $defaultPassword = ConvertTo-SecureString 'DefaultPassword!' -AsPlainText -Force + $defaultCred = New-Object System.Management.Automation.PSCredential('DefaultUser', $defaultPassword) + + $broker = New-IdleAuthSession -SessionMap @{ + @{ Role = 'Tier0' } = $testCred + } -DefaultCredential $defaultCred + + $acquiredSession = $broker.AcquireAuthSession('TestName', $null) + + $acquiredSession | Should -Not -BeNullOrEmpty + $acquiredSession.UserName | Should -Be 'DefaultUser' + } + + It 'throws when no matching credential found and no default provided' { + $broker = New-IdleAuthSession -SessionMap @{ + @{ Role = 'Tier0' } = $testCred + } + + { $broker.AcquireAuthSession('TestName', @{ Role = 'NonExistent' }) } | + Should -Throw '*No matching credential found*' + } + + It 'is available as exported command from IdLE module' { + # This test ensures the command is properly exported and accessible + $command = Get-Command -Name New-IdleAuthSession -ErrorAction SilentlyContinue + + $command | Should -Not -BeNullOrEmpty + $command.Name | Should -Be 'New-IdleAuthSession' + $command.Module.Name | Should -Be 'IdLE' + } + + It 'delegates to IdLE.Core\New-IdleAuthSessionBroker correctly' { + # This test ensures the underlying Core function is available and working + # by verifying that New-IdleAuthSession can complete without errors + { + $broker = New-IdleAuthSession -SessionMap @{ + @{ Role = 'AD' } = $testCred + } -ErrorAction Stop + + $broker | Should -Not -BeNullOrEmpty + } | Should -Not -Throw + } +} From da634bd5f9e92982bbe7c34f87f51fd8d0636d3b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 30 Jan 2026 20:48:32 +0000 Subject: [PATCH 3/3] Fix environment variable leak in ModuleExports.Tests.ps1 - save and restore IDLE_ALLOW_INTERNAL_IMPORT Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com> --- tests/Core/ModuleExports.Tests.ps1 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/Core/ModuleExports.Tests.ps1 b/tests/Core/ModuleExports.Tests.ps1 index bb57d093..09a3bc45 100644 --- a/tests/Core/ModuleExports.Tests.ps1 +++ b/tests/Core/ModuleExports.Tests.ps1 @@ -8,6 +8,7 @@ BeforeAll { Describe 'Module Export Consistency' { Context 'IdLE.Core module exports' { BeforeAll { + $script:originalIdleAllowInternalImport = $env:IDLE_ALLOW_INTERNAL_IMPORT $env:IDLE_ALLOW_INTERNAL_IMPORT = '1' $coreModulePath = Join-Path -Path $repoRoot -ChildPath 'src/IdLE.Core/IdLE.Core.psd1' Import-Module -Name $coreModulePath -Force -ErrorAction Stop @@ -15,6 +16,10 @@ Describe 'Module Export Consistency' { $coreModule = Get-Module -Name 'IdLE.Core' } + AfterAll { + $env:IDLE_ALLOW_INTERNAL_IMPORT = $script:originalIdleAllowInternalImport + } + It 'exports New-IdleAuthSessionBroker function' { $exportedCommands = $coreModule.ExportedCommands.Keys $exportedCommands | Should -Contain 'New-IdleAuthSessionBroker'