- HelloID-Conn-Prov-Target-V2Template
Hi 👋
If you're looking to create a new target connector for HelloID provisioning and don't know where to start, you're in the right place.
This GitHub repository is the perfect starting point for building out your new connector, with all the essential resources you'll need to get started.
Note
The templates in this repository are designed for the V2 target system. For more information on how to configure a HelloID PowerShell V2 target system, please refer to our documentation pages.
We can't wait to see the amazing PowerShell connectors you'll build with these templates.🔨
FileName | Description |
---|---|
./permissions/groups/grantPermission.ps1 | PowerShell grant lifecycle action |
./permissions/groups/revokePermission.ps1 | PowerShell revoke lifecycle action |
./permissions/groups/permissions.ps1 | PowerShell permissions lifecycle action |
./resources/groups/resources.ps1 | PowerShell resources lifecycle action |
./test/config.json | Prefilled config.json file for easy debugging |
./test/actionContext.json | Prefilled actionContext.json file for easy debugging |
./test/demoPerson.json | Prefilled demoPerson.json for easy debugging |
./test/debugStart.ps1 | Default debugStart.ps1 for easy debugging |
.gitignore | gitignore excluding the test folder when pushing commits to GitHub |
create.ps1 | PowerShell create lifecycle action |
delete.ps1 | PowerShell delete lifecycle action |
disable.ps1 | PowerShell disable lifecycle action |
enable.ps1 | PowerShell enable lifecycle action |
update.ps1 | PowerShell update lifecycle action |
configuration.json | Default configuration.json |
fieldMapping.json | Default fieldMapping.json |
README.md | A prefilled readme.md |
CHANGELOG.md | CHANGELOG.md to track changes made to the connector |
- Download or clone the content of this repo.
- Use the ConnectorGenerator VSCode extension.
Note
Downloading or cloning the contents of this repo does require some manuel changes to be made after you've downloaded the contents to your computer.
-
Make sure the
{connectorName}
property in all life cycle actions and README.md alligns with the name of the target system. -
Make sure the
{templateVersion}
setting in the CHANGELOG.md alligns with the latest version in the CHANGELOG.md in the root folder of this repository. -
Make sure the
{currentDate}
matches with the date of today. Or, the date on which your connector will be published to the Tools4ever GitHub repository.
- Download the extension from: https://github.com/JeroenBL/ConnectorGenerator/releases/latest
- Make sure to download the ConnectorGenerator-[version].VSIX file.
- Go to VSCode.
- Click on the extensions icon or press
ctrl+shift+x
(cmd+shift+x
on mac). - Click on the three dots ... and select
Install from VSIX
. - Browse to the folder where the ConnectorGenerator-[version].VSIX file is downloaded.
- Open the command palette by clicking on
View -> Command palette
or pressctrl+shift+p
(cmd+shift+p
on mac). - Search for
Create new HelloID connector project scaffolding
. - Select the connector type
target
. - Enter a name for the connector.
- Browse to the location where you want the files to be created and press
enter
.
- Right click to open the context menu.
- Click on
ConnectorGenerator -> Create new HelloID connector project scaffolding
. - Select the connector type
target
. - Enter a name for the connector.
- Browse to the location where you want the files to be created and press
enter
Important
Source connector templates are currently not available.
Best practices not only ensure the quality of your code, but also helps to improve the efficiency and effectiveness of your development processes. By adhering to these best practices, you will develop a PowerShell connector that is reliable, efficient, and easy to maintain.
Write code that is easy to read and maintain. This means:
- Use clear and concise variable names.
- Use consistent formatting throughout your scripts.
- Avoid unnecessary loops and other code constructs that can slow down your script.
We believe in a Fit for Purpose (FFP) approach to development, which means that we only build what is needed and nothing more.
There are several compelling reasons why we encourage you to adopt a Fit for Purpose approach to development:
-
Greater efficiency and effectiveness
By focusing only on the features and functions that are necessary for a given implementation, you can create connectors that are highly efficient and effective, without having to deal with unnecessary complexity or overhead. -
Increased customer satisfaction
By tailoring connectors to the specific needs of each customer, you can create solutions that better meet their expectations and requirements. This can lead to increased customer satisfaction and a better overall customer experience. -
Lower costs
By building only what is needed, you can avoid unnecessary development costs and reduce the time and effort required to create a connector. -
Improved scalability
By taking a modular approach to development, you can create connectors that are easily modified or expanded as needed. This can make it easier to scale the connector as the customer's needs change over time. -
Reduced risk
By focusing only on the features and functions that are necessary, you can reduce the risk of introducing bugs or other issues into the connector. This can lead to greater stability and reliability.
The $actionContext.DryRun
variable is used to distinguish between a provisioning job running in test (commonly referred to as Preview mode), or production mode.
We consider it a good practice, to only use the test mode, to validate an account, generate names and perform contract calculations.
In other words, when running in test mode, you will see what would happen with a person account during an actual enforcement.
With provisioning connectors, we typically differentiate between verbose logging, which contains the full error returned by the API, and audit logging, which contains a more user-friendly response.
Cmdlet / HelloID variable | Description |
---|---|
Write-Warning |
- Use in case of an error. - Include the script line number and code where the error has occurred. - Must contain the complete error record |
Write-Information |
- Debug logging only. |
$outputContext.AuditLogs |
- Must contain a more user-friendly error message |
Tip
Don’t use the audit logging for verbose or debugging logging. Only write an audit log if the lifecycle action itself has failed.
Some APIs do not provide the option to retrieve a single object, but instead only offer an HTTP.GET endpoint that retrieves all objects.
When the target application contains a large number of records, operations like these can take a considerable amount of time and are not well-suited for any of the lifecycle actions. In such cases, it is preferable to use a resource script instead.
In all life cycle actions, the initial step is to validate whether the account exists. Depending on the outcome of this validation, the appropriate action will be executed.
Please refer to the code following action logic code example for an example on how this is implemented in the create
lifecycle action.
# Verify if a user must be either [created and correlated] or just [correlated]
$correlatedAccount = 'The user object from the target system'
if ($null -eq $correlatedAccount){
$action = 'CreateAccount'
$outputContext.AccountReference = 'Currently not available'
} else {
$action = 'CorrelateAccount'
$outputContext.AccountReference = $correlatedAccount.id
}
# Process
switch ($action) {
'CreateAccount' {
Write-Information 'Creating and correlating {connectorName} account'
# Make sure to test with special characters and if needed; add utf8 encoding.
if (-not($actionContext.DryRun -eq $true)) {
# Write Create logic here
# $createdAccount = Invoke-RestMethod @splatParams
$outputContext.Data = $createdAccount
$outputContext.AccountReference = ''
}
$outputContext.AccountReference = ''
$outputContext.AccountCorrelated = $true
$auditLogMessage = "Create account was successful. AccountReference is: [$($outputContext.AccountReference)"
break
}
'CorrelateAccount' {
Write-Information 'Correlating {connectorName} account'
$outputContext.AccountReference = ''
$outputContext.AccountCorrelated = $true
$auditLogMessage = "Correlated account: [$($correlatedAccount.ExternalId)] on field: [$($correlationField)] with value: [$($correlationValue)]"
break
}
}
$outputContext.success = $true
$outputContext.AuditLogs.Add([PSCustomObject]@{
Action = $action
Message = $auditLogMessage
IsError = $false
})
On certain occasions, the managed account may inadvertently be removed from the target system, resulting in a failure of the lifecycle action. To ensure that the lifecycle action always continues, it is necessary to validate if the target account is present. Nevertheless, in some scenarios, even if the account cannot be found, the result of the action will be flagged as success
.
The table below provides an overview of the results when the target account may inadvertently be removed from the target system.
Lifecycle action | Result | Description |
---|---|---|
Delete | Success | The target account may inadvertently be removed, however, this is considered a successful outcome by HelloID. |
Disable | Success | The target account may have been inadvertently removed; consequently, it is no longer active. HelloID considers this to be an acceptable outcome. |
Enable | Fail | The target account has been deleted; however, this was not the anticipated outcome for HelloID. |
Update | Fail | The target account has been deleted; however, this was not the anticipated outcome for HelloID. |
Grant | Fail | The target account has been deleted; however, this was not the anticipated outcome for HelloID. |
Revoke | Success | Due to the account not existing anymore, the right is no longer granted. This is in accordance with the request by HelloID, and therefore it is recorded as a success |
When it comes to updating accounts in the target system, we take a careful and methodical approach. One of our key best practices is to always compare the target system account with the HelloID account object before making any updates. This allows us to ensure that we're only updating the necessary fields.
It's worth noting that the underlying data types for the account object in the target system may differ from the account object in HelloID. This can make it challenging to perform an accurate comparison between the two. If the data types are not aligned, it may be necessary to perform additional steps to ensure that the comparison is meaningful and that the appropriate actions are taken.
Note
It's important to note that the current compare logic only works for flat objects, and not for complex objects that, for example, contain nested arrays. This means that you will need to make adjustments to this logic depending on the specific requirements of the target system.
In addition to Updating accounts the same applies to the comparison between the $outputContext.Data
and $outputContext.PreviousData
.
This comparison between $outputContext.Data
vs $outputContext.PreviousData
is built-in within HelloID.
When a difference is found, The update lifecycle action will be triggered and an audit log will be shown. If both objects are equal, no lifecycle action will be triggered and no audit log will be shown.
Note
Currently you will need to ensure that the $outputContext.PreviousData
object contains the exact same properties as the $outputContext.Data
and ultimately the $actionContext.Data
.
If these objects are not the same, a difference will be detected. For example; if the target account contains an id
or createdDate
.
Debugging is arguably one of the most complex topics in any programming / scripting language.
The templates also comes with a debugStart.ps1, actionContext.json and demoPerson.json in the test folder. They allow you to easily debug your scripts. You can mock variables such as the $personContext
, $actionContext
and all built-in variables in HelloID you need. By mocking these variables, you can easily test your scripts under a variety of conditions, without having to worry about external dependencies or data sources.
To mock a variable in debugStart.ps1
, simply specify the value you want to use for that variable in the mock object at the top of the script.
Note
Note that, most variables are already specified with a default value.
To start debugging your code from VSCode:
- Select the code in the:
debugStart.ps1
and press:F8
- Run selection to add the variables to your PowerShell session. - Open up a lifecycle action and set a breakpoint somewhere in your code.
- Press:
F5
or click:Run -> Start Debugging
to start a new debugging session.
Caution
Never hardcode sensitive information like usernames, passwords, or API keys directly in your code. Instead, use secure methods for storing and retrieving these credentials.
Profiler is a PowerShell module that originated from Measure-Script
. Profiler can be installed directly from the PSGallery by running: Install-Module profiler
directly in your PowerShell console.
SpeedScope is a web viewer for performance profiles and can be downloaded from: https://github.com/jlfwong/speedscope/releases
Profiler can generate flame graphs that can be viewed using SpeedScope.
-
Avoid Hardcoding Credentials
Never hardcode sensitive information like usernames, passwords, or API keys directly in your code. Instead, use secure methods for storing and retrieving these credentials. -
Minimize Exposure
Implement robust error handling to minimize the exposure of sensitive information in error messages or logs. -
Peer Reviews
Conduct thorough code reviews, especially focusing on areas where sensitive information is handled. Multiple sets of eyes can help identify potential security risks. -
Have a Plan
Develop an incident response plan in case of a security breach. Be prepared to notify users and take necessary actions promptly.
There are several useful VSCode extensions that can be helpful when building PowerShell connectors. Here are a few examples:
-
PowerShell
https://marketplace.visualstudio.com/items?itemName=ms-vscode.PowerShell
The PowerShell extension provides a rich set of features for PowerShell development, including syntax highlighting, code snippets, IntelliSense, and more. This extension can be incredibly helpful when building PowerShell connectors, as it provides an efficient and intuitive environment for writing, testing, and debugging PowerShell code. -
Code Spell Checker
https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker
This extension checks the spelling of words in your code and comments, ensuring that everything is spelled correctly and improving the readability and professionalism of your code. -
GitHub Markdown Preview
https://marketplace.visualstudio.com/items?itemName=bierner.github-markdown-preview
With GitHub Markdown Preview, you can see exactly how your documentation will look when published to GitHub, ensuring that it is clear, concise, and easy to read. This can be particularly useful when documenting your PowerShell connector code, as it allows you to create professional-looking documentation that is easy to understand and follow.
Please consult our contributing guidelines for more information.