diff --git a/README.md b/README.md index 3510620..d487b81 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,15 @@ - [Getting help](#getting-help) - [HelloID docs](#helloid-docs) +Supported features: +| Feature | Supported | Actions | Remarks | +| ----------------------------------- | --------- | --------------------------------------------------------------------------- | ------- | +| **Account Lifecycle** | ✅ | Create, Update, Enable, Disable, Delete | | +| **Permissions** | ❌ | - | | +| **Resources** | ❌ | - | | +| **Entitlement Import: Accounts** | ✅ | - | | +| **Entitlement Import: Permissions** | ❌ | - | | + ### Requirements - [ ] HelloID Provisioning agent (cloud or on-prem). diff --git a/import.ps1 b/import.ps1 new file mode 100644 index 0000000..11471ec --- /dev/null +++ b/import.ps1 @@ -0,0 +1,177 @@ +################################################# +# HelloID-Conn-Prov-Target-AFAS-Profit-Users-Import +# PowerShell V2 +################################################# + +# Enable TLS1.2 +[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor [System.Net.SecurityProtocolType]::Tls12 + +function Resolve-HTTPError { + [CmdletBinding()] + param ( + [Parameter(Mandatory, + ValueFromPipeline + )] + [object]$ErrorObject + ) + process { + $httpErrorObj = [PSCustomObject]@{ + FullyQualifiedErrorId = $ErrorObject.FullyQualifiedErrorId + MyCommand = $ErrorObject.InvocationInfo.MyCommand + RequestUri = $ErrorObject.TargetObject.RequestUri + ScriptStackTrace = $ErrorObject.ScriptStackTrace + ErrorMessage = '' + } + if ($ErrorObject.Exception.GetType().FullName -eq 'Microsoft.PowerShell.Commands.HttpResponseException') { + $httpErrorObj.ErrorMessage = $ErrorObject.ErrorDetails.Message + } + elseif ($ErrorObject.Exception.GetType().FullName -eq 'System.Net.WebException') { + $httpErrorObj.ErrorMessage = [System.IO.StreamReader]::new($ErrorObject.Exception.Response.GetResponseStream()).ReadToEnd() + } + Write-Output $httpErrorObj + } +} + +function Resolve-AFASErrorMessage { + [CmdletBinding()] + param ( + [Parameter(Mandatory, + ValueFromPipeline + )] + [object]$ErrorObject + ) + process { + try { + $errorObjectConverted = $ErrorObject | ConvertFrom-Json -ErrorAction Stop + + if ($null -ne $errorObjectConverted.externalMessage) { + $errorMessage = $errorObjectConverted.externalMessage + } + else { + $errorMessage = $errorObjectConverted + } + } + catch { + $errorMessage = "$($ErrorObject.Exception.Message)" + } + + Write-Output $errorMessage + } +} + +function Get-ErrorMessage { + [CmdletBinding()] + param ( + [Parameter(Mandatory, + ValueFromPipeline + )] + [object]$ErrorObject + ) + process { + $errorMessage = [PSCustomObject]@{ + VerboseErrorMessage = $null + AuditErrorMessage = $null + } + + if ( $($ErrorObject.Exception.GetType().FullName -eq 'Microsoft.PowerShell.Commands.HttpResponseException') -or $($ErrorObject.Exception.GetType().FullName -eq 'System.Net.WebException')) { + $httpErrorObject = Resolve-HTTPError -ErrorObject $ErrorObject + + if (-not[String]::IsNullOrEmpty($httpErrorObject.ErrorMessage)) { + $errorMessage.VerboseErrorMessage = $httpErrorObject.ErrorMessage + $errorMessage.AuditErrorMessage = Resolve-AFASErrorMessage -ErrorObject $httpErrorObject.ErrorMessage + } + else { + $errorMessage.VerboseErrorMessage = $ErrorObject.Exception.Message + $errorMessage.AuditErrorMessage = $ErrorObject.Exception.Message + } + } + + # If error message empty, fall back on $ex.Exception.Message + if ([String]::IsNullOrEmpty($errorMessage.VerboseErrorMessage)) { + $errorMessage.VerboseErrorMessage = $ErrorObject.Exception.Message + } + if ([String]::IsNullOrEmpty($errorMessage.AuditErrorMessage)) { + $errorMessage.AuditErrorMessage = $ErrorObject.Exception.Message + } + + Write-Output $errorMessage + } +} +#endregion functions + +try { + Write-Information 'Starting AFAS Users account entitlement import' + + #Filter - Determine what defines an account entitlement, copy from AFAS Connect cURL + $Filter = "filterfieldids=Gebruiker&filtervalues=%5Bis%20niet%20leeg%5D&operatortypes=9" + + Write-Verbose "Starting downloading objects through get-connector [$($actionContext.Configuration.GetConnector)]" + $encodedToken = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($($actionContext.Configuration.Token))) + $authValue = "AfasToken $encodedToken" + $Headers = @{ Authorization = $authValue } + $Headers.Add("IntegrationId", "45963_140664") # Fixed value - Tools4ever Partner Integration ID + + $take = 1000 + $skip = 0 + + do { + $uri = $($actionContext.Configuration.BaseUri) + "/connectors/" + $($actionContext.Configuration.GetConnector) + "?$Filter&skip=$skip&take=$take&orderbyfieldids=Medewerker" + $dataset = Invoke-RestMethod -Method Get -Uri $uri -Headers $Headers -UseBasicParsing + + foreach ($importedAccount in $dataset.rows) { + $data = @{} + + if ($null -ne $($importedAccount.Email_werk_gebruiker)) { + $importedAccount | Add-Member -MemberType NoteProperty -Name "EmAd" -Value $($importedAccount.Email_werk_gebruiker) -Force + } + + if ($null -ne $($importedAccount.Gebruiker)) { + $importedAccount | Add-Member -MemberType NoteProperty -Name "UsId" -Value $($importedAccount.Gebruiker) -Force + } + + if ($null -ne $($importedAccount.InSite)) { + $importedAccount | Add-Member -MemberType NoteProperty -Name "Insi" -Value $($importedAccount.InSite) -Force + } + + if ($null -ne $($importedAccount.OutSite)) { + $importedAccount | Add-Member -MemberType NoteProperty -Name "Site" -Value $($importedAccount.OutSite) -Force + } + + foreach ($field in $($actionContext.ImportFields)) { + $data[$field] = $importedAccount."$field" + } + + # Also append Medewerker for correlating user + $data["Medewerker"] = $importedAccount.Medewerker + + # Determine Enabled status + $Enabled = $false + + if (($importedAccount.Geblokkeerd -eq $false) -and ($importedAccount.InSite -eq $true)) { + $Enabled = $true + } + + # Return the result + Write-Output @{ + AccountReference = [PSCustomObject]@{ Gebruiker = $importedAccount.Gebruiker } + DisplayName = $importedAccount.DisplayName + UserName = $importedAccount.Gebruiker + Enabled = $Enabled + Data = $data + } + } + + $skip += $take + } while (@($dataset.rows).count -eq $take) + + Write-Verbose "Downloaded records through get-connector [$($actionContext.Configuration.GetConnector)]" + + Write-Information 'AFAS Users account entitlement import completed' +} +catch { + $ex = $PSItem + $errorMessage = Get-ErrorMessage -ErrorObject $ex + + Write-Warning "Error at Line [$($ex.InvocationInfo.ScriptLineNumber)]: $($ex.InvocationInfo.Line). Error: $($errorMessage.VerboseErrorMessage)" + Write-Error "Could not import AFAS Users account entitlements. Error: $($errorMessage.VerboseErrorMessage)" +} \ No newline at end of file