Providers/FreeIPA/Public/New-FreeIPAOtpToken.ps1
|
function New-FreeIPAOtpToken { <# .EXTERNALHELP TestEnvironment-Help.xml .SYNOPSIS Creates the seeded OTP tokens from Data\FreeIPAOtpTokens.csv on their users #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] [OutputType([PSCustomObject])] param( [Parameter()] [string[]]$TokenId, [Parameter()] [switch]$PassThru ) $connection = Get-FreeIPAConnection $marker = Get-FreeIPASeedMarker -Connection $connection $csvPath = Join-Path -Path (Get-FreeIPADataPath) -ChildPath 'FreeIPAOtpTokens.csv' $rows = @(Import-Csv -Path $csvPath -Encoding UTF8) if ($TokenId) { $rows = @($rows | Where-Object { $TokenId -contains $_.Id }) $unknown = @($TokenId | Where-Object { $rows.Id -notcontains $_ }) if ($unknown) { throw "No definition in $csvPath for: $($unknown -join ', ')" } } $result = [PSCustomObject]@{ TotalTokens = $rows.Count CreatedTokens = 0 UpdatedTokens = 0 Tokens = @() Errors = @() } $existing = @{} foreach ($entry in (Get-FreeIPASeededObject -Type OtpTokens -Connection $connection)) { $existing[[string](@($entry.ipatokenuniqueid)[0])] = $entry } $tokens = [System.Collections.Generic.List[object]]::new() foreach ($row in $rows) { $id = Resolve-FreeIPASeedName -Key $row.Id -Marker $marker -Connection $connection if (-not $PSCmdlet.ShouldProcess("$id for $($row.Owner)", 'Create FreeIPA OTP token')) { continue } try { $mutable = @{ description = ('{0} {1}' -f $row.Description, $marker.Marker).Trim() ipatokendisabled = ($row.Enabled -eq 'FALSE') } if ($row.ExpiresInDays -match '^-?\d+$') { $mutable['ipatokennotafter'] = ConvertTo-FreeIPADateTime -Value ([DateTimeOffset]::UtcNow.AddDays([int]$row.ExpiresInDays)) } if ($row.Vendor) { $mutable['ipatokenvendor'] = $row.Vendor } if ($row.Model) { $mutable['ipatokenmodel'] = $row.Model } if ($existing.ContainsKey($id)) { $null = Invoke-FreeIPARequest -Method 'otptoken_mod' -Arguments $id -Options $mutable -Connection $connection -IgnoreError 'EmptyModlist' $result.UpdatedTokens++ } else { $options = @{ type = $row.Type ipatokenowner = $row.Owner ipatokenotpalgorithm = $row.Algorithm ipatokenotpdigits = [int]$row.Digits no_qrcode = $true } foreach ($key in $mutable.Keys) { $options[$key] = $mutable[$key] } # The answer carries the secret and its URI. Discarded on the spot. $null = Invoke-FreeIPARequest -Method 'otptoken_add' -Arguments $id -Options $options -Connection $connection $result.CreatedTokens++ Write-Verbose "Created OTP token $id" } $tokens.Add([PSCustomObject]@{ Key = $row.Id Id = $id Owner = $row.Owner Type = $row.Type Enabled = ($row.Enabled -ne 'FALSE') Expired = ($row.ExpiresInDays -match '^-\d+$') }) } catch { $message = "Failed to create OTP token '$id': $($_.Exception.Message)" $result.Errors += $message Write-Error $message } } $result.Tokens = $tokens.ToArray() Write-Verbose "OTP tokens: $($result.CreatedTokens) created, $($result.UpdatedTokens) updated, $($result.Errors.Count) problems" if ($PassThru) { return $result } } |