Skip to content

Commit

Permalink
WIP #24
Browse files Browse the repository at this point in the history
  • Loading branch information
fireflycons committed Jan 14, 2020
1 parent 92746e9 commit d60befd
Show file tree
Hide file tree
Showing 6 changed files with 233 additions and 62 deletions.
48 changes: 48 additions & 0 deletions aws-toolbox/Private/IAM/Get-CliConfiguration.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
function Get-CliConfiguration
{
param
(
[ValidateSet('config', 'credentials')]
[string]$ConfigurationFileName
)

$environmentPath = $(

switch ($ConfigurationFileName)
{
'config'
{
$env:AWS_CONFIG_FILE
}

'credentials'
{
$env:AWS_SHARED_CREDENTIALS_FILE
}
}
)

$filePath = $(

if ($null -ne $environmentPath)
{
$environmentPath
}
else
{
if ((Get-OperatingSystem) -eq 'Windows')
{
Join-Path $env:USERPROFILE ".aws\$($ConfigurationFileName)"
}
else
{
"~/.aws/$($ConfigurationFileName)"
}
}
)

New-Object PSObject -Property @{
FilePath = $filePath
Directory = Split-Path -Parent $filePath
}
}
36 changes: 26 additions & 10 deletions aws-toolbox/Private/IAM/Get-CredentialProcess.ps1
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
function Get-CredentialProcess
{
param
(
[string]$CacheScriptPath
)

$edition = 'Desktop'
$windows = $PSVersionTable.PSVersion.Major -lt 6 -or $IsWindows

if (Get-Variable -Name PSEdition)
{
Expand All @@ -21,20 +27,30 @@ function Get-CredentialProcess
Module = (Get-PSCallStack)[0].InvocationInfo.MyCommand.Module.Name
}

$sb = New-Object System.Text.StringBuilder

if ($process.PowerShell -match '\s')
if ($CacheScriptPath -match '\s')
{
$sb.Append("`"$($process.PowerShell)`"") | Out-Null
}
else
{
$sb.Append($process.PowerShell) | Out-Null
$CacheScriptPath = "`"$CacheScripPath`""
}

$sb.Append(" -Command `"Import-Module $($process.Module); Set-AwsCredential {0}; Get-ATIAMSessionCredentials -AwsCli`"") | Out-Null
$process['CredentialProcess'] = $(

$process['CredentialProcess'] = $sb.ToString()
if ($windows)
{
if ($process.PowerShell -match '\s')
{
"`"$($process.PowerShell)`" -File $CacheScriptPath"
}
else
{
"$($process.PowerShell) -File $CacheScriptPath"
}
}
else
{
# shebang executable script
$CacheScriptPath
}
)

$process
}
23 changes: 1 addition & 22 deletions aws-toolbox/Private/Utils/Read-CliConfigurationFile.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -42,28 +42,7 @@ Function Read-CliConfigurationFile
$retval
}

$FilePath = $(

if ($Config -and $null -ne $env:AWS_CONFIG_FILE)
{
$env:AWS_CONFIG_FILE
}
elseif ($Credentials -and $null -ne $env:AWS_SHARED_CREDENTIALS_FILE)
{
$env:AWS_SHARED_CREDENTIALS_FILE
}
else
{
if ((Get-OperatingSystem) -eq 'Windows')
{
Join-Path $env:USERPROFILE ".aws\$($PSCmdlet.ParameterSetName)"
}
else
{
"~/.aws/$($PSCmdlet.ParameterSetName)"
}
}
)
$FilePath = (Get-CliConfiguration -ConfigurationFileName $PSCmdlet.ParameterSetName).FilePath

$configuration = @{ }

Expand Down
31 changes: 4 additions & 27 deletions aws-toolbox/Private/Utils/Write-CliConfigurationFile.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -46,28 +46,7 @@ Function Write-CliConfigurationFile
}
}

$FilePath = $(

if ($Config -and $null -ne $env:AWS_CONFIG_FILE)
{
$env:AWS_CONFIG_FILE
}
elseif ($Credentials -and $null -ne $env:AWS_SHARED_CREDENTIALS_FILE)
{
$env:AWS_SHARED_CREDENTIALS_FILE
}
else
{
if ((Get-OperatingSystem) -eq 'Windows')
{
Join-Path $env:USERPROFILE ".aws\$($PSCmdlet.ParameterSetName)"
}
else
{
"~/.aws/$($PSCmdlet.ParameterSetName)"
}
}
)
$FilePath = (Get-CliConfiguration -ConfigurationFileName $PSCmdlet.ParameterSetName).FilePath
}

Process
Expand All @@ -76,12 +55,12 @@ Function Write-CliConfigurationFile

if (-not ($outFile))
{
Throw "Could not create File"
Throw "Could not create file: $outFile"
}

foreach ($i in $InputObject.keys)
{
if (-not ($($InputObject[$i].GetType().Name) -eq "Hashtable"))
if (-not ($($InputObject[$i] -is [System.Collections.IDictionary])))
{
#No Sections
Add-Content -Path $outFile -Value "$i=$($InputObject[$i])" -Encoding ascii
Expand All @@ -97,7 +76,5 @@ Function Write-CliConfigurationFile
}

End
{
$x = 1
}
{ }
}
133 changes: 132 additions & 1 deletion aws-toolbox/Public/IAM/Set-ATIAMCliExternalCredentials.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,86 @@ function Set-ATIAMCliExternalCredentials

begin
{
[scriptblock]$cacheScriptBlock = {
#!/usr/bin/env pwsh

# Silence warnings, or aws will consume them and fail
$warnPef = $WarningPreference

try
{
$WarningPreference = 'SilentlyContinue'
$credentialCache = '{0}'
$profileName = '{1}'

if (Test-Path -Path $credentialCache)
{
$profiles = Get-Content -Raw -Path $credentialCache | ConvertFrom-Json
}
else
{
$profiles = @()
}

$profile = $profiles | Where-Object {
$_.Name -eq $profileName
}

$cred = @{
Expiration = [DateTime]'1900-01-01'
}

if ($profile)
{
# Decode secure string back to JSON
$ss = ConvertTo-SecureString $pofile.Credential
$json = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto(([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR(([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($ss)))))

# Check credential time
$cred = $json | ConvertFrom-Json
}

if ($cred.Expiration -le [datetime]::UtcNow.AddMinutes(-5))
{
# Regenerate
if ($PSVersionTable.PSVersion.Major -lt 6)
{
Import-Module aws-toolbox
}
else
{
Import-Module aws-toolbox.netcore
}
}

Set-AwsCredential -ProfileName $profileName
$json = Get-ATIAMSessionCredentials -AwsCli

$encryptedCredential = $json | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString

if ($profile)
{
$profile.Credential = $encryptedCredential
}
else {
$profiles += New-Object PSObject -Property @{
Name = $profileName
Credential = $encryptedCredential
}
}

# Write out credential cache
$profiles | Set-Content -Path $credentialCache -Force
}
finally
{
$WarningPreference = $warnPef
}

# Emit credential
$json
}

foreach ($p in $PSBoundParameters.Keys)
{
if (-not (Get-Variable -Name $p -Scope Local -ErrorAction SilentlyContinue))
Expand All @@ -57,6 +137,9 @@ function Set-ATIAMCliExternalCredentials

end
{
$windows = $PSVersionTable.PSVersion.Major -lt 6 -or $IsWindows
$credentialStore = Get-CliConfiguration -ConfigurationFileName credentials

if ([string]::IsNullOrEmpty($CliProfileName))
{
$CliProfileName = $ProfileName
Expand All @@ -69,8 +152,56 @@ function Set-ATIAMCliExternalCredentials
$creds.Remove($CliProfileName)
}

# Write cache script for this profile
$cacheScriptDir = Join-Path $credentialStore.Directory 'aws-toolbox-cache'
if (-not (Test-Path -Path $cacheScriptDir -PathType Container))
{
New-Item -Path $cacheScriptDir -ItemType Directory | Out-Null
}

$cacheScriptPath = Join-Path $cacheScriptDir "$($ProfileName).ps1"
$credentialCachePath = Join-Path $cacheScriptDir "credential-cache"

$cacheScript = ($cacheScriptBlock.ToString().Replace('{0}', $credentialCachePath).Replace('{1}', $ProfileName)) -split ([System.Environment]::NewLine)

$line = 0

# Remove leading blank lines
while([string]::IsNullOrEmpty($cacheScript[$line]))
{
$line++
}

$cacheScript[$line] -match '^(\s*)' | Out-Null
$totalLines = $cacheScript.Length
$blanks = ($Matches.1).Length

# Remove leading space
$cacheScript = $(
for($i = $line; $i -lt $totalLines; ++$i)
{
if ($cacheScript[$i].Length -ge $blanks)
{
$cacheScript[$i].Substring($blanks)
}
else
{
$cacheScript[$i]
}
}
) -join ([System.Environment]::NewLine)

# Write Cache script
$cacheScript | Set-Content -Path $cacheScriptPath -Force -Encoding ascii

if (-not $windows)
{
# Make cache script executable
& chmod +x $cacheScript
}

$creds[$CliProfileName] = @{
credential_process = (Get-CredentialProcess).CredentialProcess -f $ProfileName
credential_process = (Get-CredentialProcess -CacheScriptPath $cacheScriptPath).CredentialProcess -f $ProfileName
}

$creds | Write-CliConfigurationFile -Credentials
Expand Down
24 changes: 22 additions & 2 deletions tests/aws-toolbox.Private.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -554,9 +554,11 @@ InModuleScope $ModuleName {

Describe 'AWS CLI External Credential Source' {

Context 'Credential Souce Generation' {
$savedCredentials = $env:AWS_SHARED_CREDENTIALS_FILE

Context 'Credential Process Generation' {

$credProcess = Get-CredentialProcess
$credProcess = Get-CredentialProcess -CacheScriptPath (Join-Path ([IO.Path]::GetTempPath()) "test-cache.ps1")
$ps = $(
if ($PSEdition -eq 'Desktop')
{
Expand All @@ -578,5 +580,23 @@ InModuleScope $ModuleName {
$credProcess.Module | Should -Be $thisModule.Name
}
}

Context 'Credential Source Configuration' {

BeforeEach {

$env:AWS_SHARED_CREDENTIALS_FILE = Join-Path $TestDrive 'credentials'
}

AfterEach {

$env:AWS_SHARED_CREDENTIALS_FILE = $savedCredentials
}

It 'Does something' {

Set-ATIAMCliExternalCredentials -ProfileName eddie
}
}
}
}

0 comments on commit d60befd

Please sign in to comment.