<#
 
.DESCRIPTION
 Imports a Relying Party Trust into an ADFS farm.
  
 Example Import: Import.ps1 -targetRPID http://localhost/mvp/ -targetName "mvp localhost" -path C:\mvp\
 
#> 

Param([Parameter(Mandatory = $true)]
    [String]
    $targetRPID,
    [Parameter(Mandatory = $true)]
    [String]
    $targetName,
    [Parameter(Mandatory = $true)]
    [String]
    $path
)

function import-RP {
    #Using Hashtable to collect all of the parameters and then splat them into add-adfsrelyingpartytrust
    $hashTable = @{};
    $rawRP = Get-Content -Path "$path\relyingparty.json" | ConvertFrom-Json;
    #$issueruleset = New-AdfsClaimRuleSet -ClaimRuleFile "$path\Claims-$filename";
    $hashTable.add("Name", $targetName);
    $hashTable.add("Identifier", $targetRPID);
    #$hashTable.add("IssuanceTransformRulesFile", $issueruleset);

    #boolean values
    $hashTable.add("EncryptClaims", [System.Convert]::ToBoolean($rawRP.EncryptClaims));
    $hashTable.add("Enabled", [System.Convert]::ToBoolean($rawRP.Enabled));
    $hashTable.add("AutoUpdateEnabled", [System.Convert]::ToBoolean($rawRP.AutoUpdateEnabled));
    $hashTable.add("EncryptedNameIdRequired", [System.Convert]::ToBoolean($rawRP.EncryptedNameIdRequired));
    $hashTable.add("SignedSamlRequestsRequired", [System.Convert]::ToBoolean($rawRP.SignedSamlRequestsRequired));
    $hashTable.add("AlwaysRequireAuthentication", [System.Convert]::ToBoolean($rawRP.AlwaysRequireAuthentication));
    $hashTable.add("RequestMFAFromClaimsProviders", [System.Convert]::ToBoolean($rawRP.RequestMFAFromClaimsProviders));
    $hashTable.add("EnableJWT", [System.Convert]::ToBoolean($rawRP.EnableJWT));
    $hashTable.add("RefreshTokenProtectionEnabled", [System.Convert]::ToBoolean($rawRP.RefreshTokenProtectionEnabled));
    $hashTable.add("MonitoringEnabled", [System.Convert]::ToBoolean($rawRP.MonitoringEnabled));

    #certificate values

    #Encryption Certificate - There can only be one
    if ($rawRP.EncryptionCertificate -ne "" -and $rawRP.EncryptionCertificate -ne $null){
        $enc = [System.Security.Cryptography.X509Certificates.X509Certificate2]([System.Convert]::FromBase64String([System.Convert]::ToBase64String($rawRP.EncryptionCertificate.RawData)))
        $hashTable.add("EncryptionCertificate", $enc);
    }

    #Signing Certificates - There may be more that one configured
    if ($rawRP.RequestSigningCertificate -ne "" -and $rawRP.RequestSigningCertificate -ne $null){
        $i = 0;
        
        foreach ($signingCert in $rawRP.RequestSigningCertificate) {
            $tmpString = $signingCert.RawData;
            [byte[]]$tmpBytes = @($tmpString.Split(" "));
            if ($i -eq 0) {
                $tmpCert = [System.Security.Cryptography.X509Certificates.X509Certificate2]([System.Convert]::FromBase64String([System.Convert]::ToBase64String($tmpBytes)))
                $certs = @($tmpCert);
                $i += 1;
            }else {
                $tmpCert = [System.Security.Cryptography.X509Certificates.X509Certificate2]([System.Convert]::FromBase64String([System.Convert]::ToBase64String($tmpBytes)))
                $certs += $tmpCert;
                $i += 1;
            }
         }

        $hashTable.add("RequestSigningCertificate", $certs);
    }

    #uris
    if ($rawRP.WSFedEndPoint -ne "" -and $rawRP.WSFedEndPoint -ne $null){
        $hashTable.add("WSFedEndPoint", [System.Uri]$rawRP.WSFedEndPoint);
    }

    #text/misc values
    if ($rawRP.Notes -ne "" -and $rawRP.Notes -ne $null){
        $hashTable.add("Notes", $rawRP.Notes);
    }
    else {
        $dt = Get-Date;
        $hashTable.add("Notes", $dt);
    }
    if ($rawRP.ClaimAccepted -ne "" -and $rawRP.ClaimAccepted -ne $null){
        $hashTable.add("ClaimAccepted", $rawRP.ClaimAccepted);
    }
    if ($rawRP.TokenLifetime -ne "" -and $rawRP.TokenLifetime -ne $null){
        $hashTable.add("TokenLifetime", $rawRP.TokenLifetime);
    }   
    if ($rawRP.NotBeforeSkew -ne "" -and $rawRP.NotBeforeSkew -ne $null){
        $hashTable.add("NotBeforeSkew", $rawRP.NotBeforeSkew);
    }      
    if ($rawRP.ProtocolProfile -ne "" -and $rawRP.ProtocolProfile -ne $null){
        $hashTable.add("ProtocolProfile", $rawRP.ProtocolProfile);
    } 
    if ($rawRP.SignatureAlgorithm -ne "" -and $rawRP.SignatureAlgorithm -ne $null){
        $hashTable.add("SignatureAlgorithm", $rawRP.SignatureAlgorithm);
    }  
    if ($rawRP.SamlResponseSignature -ne "" -and $rawRP.SamlResponseSignature -ne $null){
        $hashTable.add("SamlResponseSignature", $rawRP.SamlResponseSignature);
    } 
    if ($rawRP.AllowedClientTypes -ne "" -and $rawRP.AllowedClientTypes -ne $null){
        $hashTable.add("AllowedClientTypes", $rawRP.AllowedClientTypes);
    } 
    if ($rawRP.IssueOAuthRefreshTokensTo -ne "" -and $rawRP.IssueOAuthRefreshTokensTo -ne $null){
        $hashTable.add("IssueOAuthRefreshTokensTo", $rawRP.IssueOAuthRefreshTokensTo);
    } 
    if ($rawRP.AdditionalWSFedEndpoint -ne "" -and $rawRP.AdditionalWSFedEndpoint -ne $null){
        $hashTable.add("AdditionalWSFedEndpoint", $rawRP.AdditionalWSFedEndpoint);
    }
    if ($rawRP.AllowedAuthenticationClassReferences -ne "" -and $rawRP.AllowedAuthenticationClassReferences -ne $null){
        $hashTable.add("AllowedAuthenticationClassReferences", $rawRP.AllowedAuthenticationClassReferences);
    }

    switch ($rawRP.SigningCertificateRevocationCheck){
        0 {
            $hashTable.add("SigningCertificateRevocationCheck", 'None');
        }
        1 {
            $hashTable.add("SigningCertificateRevocationCheck", 'CheckEndCert');
        }
        2 {
            $hashTable.add("SigningCertificateRevocationCheck", 'CheckEndCertCacheOnly');
        }
        3 {
            $hashTable.add("SigningCertificateRevocationCheck", 'CheckChain');
        }
        4 {
            $hashTable.add("SigningCertificateRevocationCheck", 'CheckChainCacheOnly');
        }
        5 {
            $hashTable.add("SigningCertificateRevocationCheck", 'CheckChainExcludeRoot');
        }
        6 {
            $hashTable.add("SigningCertificateRevocationCheck", 'CheckChainExcludeRootCacheOnly');
        }
    }

    switch ($rawRP.EncryptionCertificateRevocationCheck){
        0 {
            $hashTable.add("EncryptionCertificateRevocationCheck", 'None');
        }
        1 {
            $hashTable.add("EncryptionCertificateRevocationCheck", 'CheckEndCert');
        }
        2 {
            $hashTable.add("EncryptionCertificateRevocationCheck", 'CheckEndCertCacheOnly');
        }
        3 {
            $hashTable.add("EncryptionCertificateRevocationCheck", 'CheckChain');
        }
        4 {
            $hashTable.add("EncryptionCertificateRevocationCheck", 'CheckChainCacheOnly');
        }
        5 {
            $hashTable.add("EncryptionCertificateRevocationCheck", 'CheckChainExcludeRoot');
        }
        6 {
            $hashTable.add("EncryptionCertificateRevocationCheck", 'CheckChainExcludeRootCacheOnly');
        }
    }

    Write-Output @hashTable;

    Add-AdfsRelyingPartyTrust @hashTable;

    #Add SAML Endpoints if neccesary
    if ($rawRP.SamlEndpoints -ne "" -and $rawRP.SamlEndpoints -ne $null){
        $EPs = New-Object -TypeName "System.Collections.ArrayList";
        foreach ($saml in $rawRP.SamlEndpoints){
            $Binding = $saml.Binding;
            $Index = $saml.Index;
            $IsDefault = $saml.IsDefault;
            $Protocol = $saml.Protocol;
            $Uri = $saml.Location;
            
            if ($saml.ResponseLocation -ne "null") {
                $ResponseUri = $saml.ResponseLocation;
                $EP = New-AdfsSamlEndpoint -Binding $Binding -Index $Index -IsDefault $IsDefault -Protocol $Protocol -Uri $Uri -ResponseUri $ResponseUri;

            }
            else {
                $EP = New-AdfsSamlEndpoint -Binding $Binding -Index $Index -IsDefault $IsDefault -Protocol $Protocol -Uri $Uri;
                
            }
            #write-host $Uri;
            $EPs.Add($EP); 
 
        }
        Set-AdfsRelyingPartyTrust -TargetIdentifier $targetRPID -SamlEndpoint $EPs;
    }
    #Get the claim rules/authorization/additional authentication created
    Import-Claims;
}
function Import-Claims {
    $issuanceRules = "$path\IssuanceRules.txt";
    if (Test-Path $issuanceRules -PathType Leaf) {
        #$ruleset = New-AdfsClaimRuleSet -ClaimRuleFile $issuanceRules;
        Set-AdfsRelyingPartyTrust -TargetIdentifier $targetRPID -IssuanceTransformRulesFile $issuanceRules;
    }

    $authorizationRules = "$path\AuthorizationRules.txt";
    if (Test-Path $authorizationRules -PathType Leaf) {
        #$ruleset = New-AdfsClaimRuleSet -ClaimRuleFile $authorizationRules;
        Set-AdfsRelyingPartyTrust -TargetIdentifier $targetRPID -IssuanceAuthorizationRulesFile $authorizationRules;
    }

    $additionalRules = "$path\AdditionalAuthenticationRules.txt";
    if (Test-Path $additionalRules -PathType Leaf) {
        #$ruleset = New-AdfsClaimRuleSet -ClaimRuleFile $additionalRules;
        Set-AdfsRelyingPartyTrust -TargetIdentifier $targetRPID -IssuanceAuthorizationRulesFile $additionalRules;
    }
}

function Validate-RP {
    $rp = Get-AdfsRelyingPartyTrust -Identifier $targetRPID;
    if ($null -ne $rp) {
        throw "Relying Party Trust already exists.";
    } 
    else {
        $Result = import-RP;
        $Result;
        Write-Output "Relying party $targetName created.";
    }       
}

Validate-RP;