RiverMeadow.Development.Login/RiverMeadow.Development.Login.psm1

Import-Module -Name $PSScriptRoot\..\Common\Error\Error
Import-Module -Name $PSScriptRoot\..\Common\Wrappers\Wrappers
function Invoke-RMLogin {
    param (
        [Alias("ea")]
        [string] $EmailAddress,
        [Alias("pw")]
        [string] $Password,
        [Alias("mfavc")]
        [string] $MFAVerificationCode
    )

    if (0 -eq $PSBoundParameters.Count) {
        $EmailAddress = Read-RMString -UserMessage "Enter email address" -IsRequired $true -ParameterName "Email address"
        $Password = Read-RMSecureString -UserMessage "Enter password" -IsRequired $true -ParameterName "Password"
    } else {
        if ([string]::IsNullOrEmpty($EmailAddress)) {
           throw "Email address is required"
        }

        if ([string]::IsNullOrEmpty($Password)) {
           throw "Password is required"
        }
    }

    $Uri = Get-RMUri
    $Body = @{
        email = $EmailAddress
        password = $Password
    }

    if ($MFAVerificationCode) {
        $Body['mfa_token'] = $MFAVerificationCode
    }

    $JsonBody = $Body | ConvertTo-Json
    $Headers = @{
        Accept = "application/rm+json"
    }

    $Params = @{
        Method = "Post"
        Uri = $Uri + "/login"
        Body = $JsonBody
        ContentType = "application/json"
        Headers = $Headers
    }

    if (Get-Variable -Name "RMContext-UserLogin" -ErrorAction SilentlyContinue) {
        # Delete the previous Login result before attempting a new one
        Remove-RMVariable
    }

    $UserLogin = $null
    try {
        $UserLogin = Invoke-RestMethod @Params
    } catch [System.Exception] {
        $ErrorString = $PSItem.ToString()
        if ($ErrorString.Contains("error_code")) {
            $ErrorString = $ErrorString | ConvertFrom-Json
            if ($ErrorString.error_code -eq "mfa_token_required") {
                Get-RMMFACode -InputParameter $PSBoundParameters
            } else {
                Show-RMError -ErrorObj $PSItem
            }
        } elseif ($PSVersionTable.PSVersion.Major -eq 5 -and $ErrorString.Contains("403")) {
            Get-RMMFACode -InputParameter $PSBoundParameters
        } else {
            Show-RMError -ErrorObj $PSItem
        }
        return
    }

    Set-Variable -Name "RMContext-UserLogin" -Value $UserLogin -Scope Global
    Set-Variable -Name "RMContext-ReactorURI" -Value $Uri -Scope Global
    Get-RMUser -UserId $UserLogin.user_id -Uri $Uri

    $CurrentOrg = (Get-Variable -Name "RMContext-CurrentOrganizationName").Value
    $CurrentProjectName = (Get-Variable -Name "RMContext-CurrentProjectName").Value

    Write-Output "Current Organization Name: $CurrentOrg" | Out-Host
    Write-Output "Current Project Name: $CurrentProjectName" | Out-Host
}

function Invoke-RMLogout {
    param ()
    
    Remove-RMVariable
    Write-Output "Logout was successful."
    return
}

function Get-RMUri {
    param()
    $Uri = "https://migrate.rivermeadow.com/api/v3"
    $RMHost = [Environment]::GetEnvironmentVariable('RMHost')
    if ([string]::IsNullOrEmpty($RMHost)) {
        # Env. variable RMHost is not set, use production URI
        return $Uri
    }

    if ($RMHost.Contains("http://") -or $RMHost.Contains("https://")) {
        $Uri = $RMHost + "/api/v3"
    } else {
        $Uri = "http://" + $RMHost + "/api/v3"
    }
    return $Uri
}

function Get-RMUser {
    param(
        [Parameter(Mandatory)]
        [string]$UserId,
        [Parameter(Mandatory)]
        [string]$Uri
    )

    $LoginResult = Get-Variable -Name "RMContext-UserLogin"

    $Headers = @{
        "Accept" = "application/rm+json"
        "X-Auth-Token" = $LoginResult.Value.token
    }

    $Params = @{
        Method = "Get"
        Uri = $Uri + "/users/" + $UserId
        Headers = $Headers
    }

    try {
        $UserInfo = Invoke-RestMethod @Params
    } catch [System.Net.WebException] {
        Show-RMError -ErrorObj $PSItem
        throw $PSItem
    }

    Set-Variable -Name "RMContext-UserOrganizations" -Value $UserInfo.organizations -Scope Global
    $CurrentOrgName  = Get-RMParentOrganizationNameById -OrganizationId $UserInfo.organization
    $CurrentProjectName = Get-RMOrganizationNameById -OrganizationId $UserInfo.organization
    Set-Variable -Name "RMContext-CurrentOrganizationName" -Value $CurrentOrgName -Scope Global
    Set-Variable -Name "RMContext-CurrentProjectName" -Value $CurrentProjectName -Scope Global
    Set-Variable -Name "RMContext-CurrentProjectId" -Value $UserInfo.organization -Scope Global
}

function Get-RMOrganizationNameById {
    param(
        [string] $OrganizationId
    )

    $UserOrgs = Get-Variable -Name "RMContext-UserOrganizations"

    foreach($Org in $UserOrgs.Value) {
        if ($Org.id -eq $OrganizationId) {
            return $Org.name
        }
    }

    throw "No organization or project exists by the given $OrganizationId"
}

function Get-RMParentOrganizationIdById {
    param(
        [string] $OrganizationId
    )

    $UserOrgs = Get-Variable -Name "RMContext-UserOrganizations"

    foreach($Org in $UserOrgs.Value) {
        if ($Org.id -eq $OrganizationId) {
            return $Org.parent_organization_id
        }
    }

    throw "No organization or project exists by the given $OrganizationId"

}

function Get-RMParentOrganizationNameById {
    param(
        [string] $OrganizationId
    )

    $ParentOrgId = Get-RMParentOrganizationIdById -OrganizationId $OrganizationId

    $UserOrgs = Get-Variable -Name "RMContext-UserOrganizations"

    foreach($Org in $UserOrgs.Value) {
        if ($Org.id -eq $ParentOrgId) {
            return $Org.name
        }
    }

    throw "No organization or project exists by the given $OrganizationId"

}

function Remove-RMVariable {
    param()
    Remove-Variable -Name "RMContext-UserLogin" -Scope Global -ErrorAction SilentlyContinue
    Remove-Variable -Name "RMContext-UserOrganizations" -Scope Global -ErrorAction SilentlyContinue
    Remove-Variable -Name "RMContext-CurrentOrganizationName" -Scope Global -ErrorAction SilentlyContinue
    Remove-Variable -Name "RMContext-CurrentProjectName" -Scope Global -ErrorAction SilentlyContinue
    Remove-Variable -Name "RMContext-CurrentProjectId" -Scope Global -ErrorAction SilentlyContinue
}

function Get-RMMFACode {
    param(
        [hashtable] $InputParameter
    )
    if (0 -eq $InputParameter.Count) {
        $VerificationCode = Read-Host "We sent you the Verification Code. Please enter it here"
        Invoke-RMLogin -EmailAddress $EmailAddress -Password $Password -MFAVerificationCode $VerificationCode
        return
    }
    Write-Output "We sent you the Verification Code, please re-run this cmdlet as 'Invoke-RMLogin -EmailAddress <email address> -Password <password> -MFAVerificationCode <received verification code>" |Out-Host
}
Export-ModuleMember -Function Invoke-RMLogin, Invoke-RMLogout -Alias irmlogin