lib/Import-TMCActionRequest.ps1

Function Import-TMCActionRequest {
    param(
        [Parameter(Mandatory = $false)][String]$FromB64,
        [Parameter(Mandatory = $false)][String]$SerializedActionRequestObject,
        [Parameter(Mandatory = $false)][PSObject]$PSObjectActionRequest,
        [Parameter(Mandatory = $false)][String]$FromFile,
        [Parameter(Mandatory = $false)][Switch]$PassThru,
        [Parameter(Mandatory = $false)][Switch]$SkipProviderLoad
    )
    if ($FromFile) {
        $ActionRequest = (Get-Content -Path $FromFile | ConvertFrom-Json)
    }
 elseif ($SerializedActionRequestObject) {
        $ActionRequest = [System.Management.Automation.PSSerializer]::Deserialize($SerializedActionRequestObject)
    }
 elseif ($PSObjectActionRequest) {
        $ActionRequest = $PSObjectActionRequest
    }
 elseif ($FromB64) { 
        $ActionRequest = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($FromB64)) | ConvertFrom-Json
    }
 else { 
        throw 'Unable to create Action Request Object.'
    }
            
    ## Make sure we created a new ActionRequest,
    ## use it as a container to populate the runspace with some variables
    if ($ActionRequest) {
            
        ## Create the TM Session Callback options for the Task Update functions
        $TMDCallbackOptions = @{
            SiteURL     = $ActionRequest.options.callback.siteUrl;
            BearerToken = $ActionRequest.options.callback.token;
            ProjectID   = $ActionRequest.options.projectId;
            TaskID      = $ActionRequest.task.id;
        }

        ## Handle Credential Creation for items passed from Credentials
        if ($null -ne $ActionRequest.options.credentials) {

            ## Extract the Username and and Encrypt the password
            $Username = $ActionRequest.options.credentials.username
            $EncryptedPassword = ConvertTo-SecureString $ActionRequest.options.credentials.password -AsPlainText -Force
                
            ## Remove the credentials object from the $ActionRequest
            $ActionRequest.options.credentials = $null
                
            ## Create a new Credential and assign it to the $Credential variable in the current scope (session)
            $PSCredential = New-Object System.Management.Automation.PSCredential ($Username, $EncryptedPassword)
            $ActionRequest | Add-Member -NotePropertyName 'PSCredential' -NotePropertyValue $PSCredential | Out-Null
            New-Variable -Name 'Credential' -Value $PSCredential -Force -Scope Global
        }

        

        ## Handle Credential Creation within any Parameters that defined a credential
        $suppliedCredentials = $ActionRequest.params.PSObject.Properties | Where-Object { $_.Name -like 'supplied_credential_*' } 
        
        ## Convert any 'supplied_credential_' objects into their appropriate PSObject format.
        if ($suppliedCredentials.count -gt 0) {

            $suppliedCredentials | ForEach-Object {
                $suppliedCredential = $_
                
                ## Remove the credentials object from the parameter
                $ActionRequest.params.PSObject.Properties.Remove($suppliedCredential.Name)
                
                ## Extract the Username and and Encrypt the password
                $Username = $suppliedCredential.value.username
                $EncryptedPassword = ConvertTo-SecureString $suppliedCredential.value.password -AsPlainText -Force
                $ConvertedCredential = New-Object System.Management.Automation.PSCredential ($Username, $EncryptedPassword)
                
                ## Add the converted credential to the Params
                $ActionRequest.params | Add-Member -NotePropertyName ($suppliedCredential.Name -replace 'supplied_credential_', '' ) -NotePropertyValue $ConvertedCredential -Force
            }
        }
        
        ## Handle Credential Creation within any Parameters that defined a credential
        $storedCredentials = $ActionRequest.params.PSObject.Properties | Where-Object { $_.Name -like 'use_storedcredential_*' } 
        
        ## Retrieve any 'use_stored_credential_' objects from local storage into their appropriate PSObject format.
        if ($storedCredentials.count -gt 0) {
            
            $storedCredentials | ForEach-Object {
                $storedCredential = $_
                
                ## Remove the credentials object from the parameter
                $ActionRequest.params.PSObject.Properties.Remove($storedCredential.Name)
                
                $RetrievedCredential = Get-StoredCredential -CredentialName $storedCredential.Value
                
                ## Add the converted credential to the Params
                $ActionRequest.params | Add-Member -NotePropertyName ($storedCredential.Name -replace 'use_storedcredential_', '' ) -NotePropertyValue $RetrievedCredential -Force
            }
        }
        
        ## Remove any leftover 'get_' parameter names
        $ActionRequest.params.PSObject.Properties.Name | Where-Object {
            $_ -like 'get_*'
        } | ForEach-Object {
            $ActionRequest.params.PSObject.Properties.Remove($_)
        }

        ## Import the Provider Configuratoin by name
        . Import-TMCProvider -Provider $ActionRequest.options.apiAction.provider.name
            
        ## Import the remaining Variables
        New-Variable -Name 'ActionRequest' -Value $ActionRequest -Force -Scope Global
        New-Variable -Name 'Params' -Value $ActionRequest.params -Force -Scope Global
        New-Variable -Name 'TMDCallbackOptions' -Value $TMDCallbackOptions -Force -Scope Global
        
        ## Create a Convenient TM Object with useful details
        $TM = [pscustomobject]@{
            TMServer      = ([uri]$ActionRequest.options.callback.siteUrl).Host
            TMProjectName = $ActionRequest.task.project.name
            Task          = [pscustomobject]@{
                Id         = $ActionRequest.task.id
                Title      = $ActionRequest.task.title
                TaskNumber = $ActionRequest.task.taskNumber
                Invoker    = $ActionRequest.task.assignedTo.name
            }
            # Event = [pscustomobject]@{
                
            # ## Versions: 5.0+ 4.7
            # Id = $ActionRequest.task.event.id ??= $ActionRequest.task.moveEvent
                
            # ## 50 has a value, 47 does not
            # Name = $ActionRequest.task.event.name ??= ''
            # }
            Provider      = $ActionRequest.options.apiAction.provider.name
        }
        New-Variable -Name 'TM' -Value $TM -Scope Global -Force

        ## Add a 'Default' TMSession
        Write-Verbose 'Creating TMSession created for the TMConsole User Context'
        $NewSesion = [TMSession]::new($ActionRequest)
        $Global:TMSessions.Default = $NewSesion
    }
    else {
        ## The result of the script didn't produce an ActionRequest object
        throw 'Unable to create an $ActionRequest object'
    }
    if ($PassThru) { $ActionRequest }
}