From e7677b4b0d6b82e6c41b2fe655b39296d3dbed5e Mon Sep 17 00:00:00 2001 From: rhouthuijzen Date: Tue, 3 Dec 2024 11:39:13 +0100 Subject: [PATCH 1/3] Fix: use aref when fieldmapping is empty --- CHANGELOG.md | 4 ++++ README.md | 3 ++- delete.ps1 | 16 +++++++++++----- fieldMapping.json | 6 +++--- update.ps1 | 36 ++++++++++++++++++++++++++++++++++++ 5 files changed, 56 insertions(+), 9 deletions(-) create mode 100644 update.ps1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 51b4f49..5c7083e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com), and this project adheres to [Semantic Versioning](https://semver.org). +## [1.2.0] - 03-12-2024 + +Fallback to account reference because the account that GoogHabitz is dependent on could already be deleted/revoked. Also added check in complex mapping if the user is deleted in HelloID. + ## [1.1.0] - 25-07-2024 This is the first release after implementation. diff --git a/README.md b/README.md index 8f93a2d..3b2d359 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ The following lifecycle actions are available: | Action | Description | | ------------------ | ------------------------------------ | | create.ps1 | PowerShell _create_ lifecycle action | +| update.ps1 | PowerShell _update_ lifecycle action | | delete.ps1 | PowerShell _delete_ lifecycle action | | configuration.json | Default _configuration.json_ | | fieldMapping.json | Default _fieldMapping.json_ | @@ -52,7 +53,7 @@ The following settings are required to connect to the API. #### Correlation not being used -Within the _create_ lifecycle action, the `$outputContext.AccountReference` is set to: `$actionContext.Data.EmailAddress`. However, the account reference is not being used within the _delete_ lifecycle action since the account reference is not being updated. +Within the _create_ and _update_ lifecycle action, the `$outputContext.AccountReference` is set to: `$actionContext.Data.EmailAddress` when not empty. The `$actionContext.References.Account` is used when `$actionContext.Data.EmailAddress` is empty in the _delete_ lifecycle action. #### Delete only diff --git a/delete.ps1 b/delete.ps1 index b81f338..7cfff88 100644 --- a/delete.ps1 +++ b/delete.ps1 @@ -44,16 +44,22 @@ try { throw 'The account reference could not be found' } + if ([string]::IsNullOrEmpty($actionContext.Data.EmailAddress)) { + $emailAddress = $actionContext.References.Account + } else { + $emailAddress = $actionContext.Data.EmailAddress + } + if ($actionContext.DryRun -eq $true) { - Write-Information "[DryRun] Delete GoodHabitz account: [$($actionContext.References.Account)] for person: [$($personContext.Person.DisplayName)] will be executed during enforcement" + Write-Information "[DryRun] Delete GoodHabitz account: [$emailAddress] for person: [$($personContext.Person.DisplayName)] will be executed during enforcement" } # Process if (-not($actionContext.DryRun -eq $true)) { - Write-Information "Deleting GoodHabitz account with accountReference: [$($actionContext.Data.EmailAddress)]" + Write-Information "Deleting GoodHabitz account with accountReference: [$emailAddress]" $splatParams = @{ - Uri = "$($actionContext.Configuration.BaseUrl)/api/person/forget?email=$($actionContext.Data.EmailAddress)" + Uri = "$($actionContext.Configuration.BaseUrl)/api/person/forget?email=$emailAddress" Method = 'POST' ContentType = 'application/x-www-form-urlencoded' Headers = @{ @@ -65,14 +71,14 @@ try { $null = Invoke-RestMethod @splatParams $outputContext.AuditLogs.Add([PSCustomObject]@{ - Message = "Account [$($actionContext.Data.EmailAddress)] was successfully deleted" + Message = "Account [$emailAddress] was successfully deleted" IsError = $false }) } catch { if ($_.Exception.Response.StatusCode -eq 404) { $outputContext.AuditLogs.Add([PSCustomObject]@{ - Message = "Account [$($actionContext.Data.EmailAddress)] was not found, action skiped" + Message = "Account [$emailAddress] was not found, action skiped" IsError = $false }) } diff --git a/fieldMapping.json b/fieldMapping.json index 91bc651..68b55eb 100644 --- a/fieldMapping.json +++ b/fieldMapping.json @@ -11,8 +11,8 @@ "Create", "Delete" ], - "MappingMode": "Field", - "Value": "\"function getActiveDirectoryEmail(){\\n return Person.Accounts.MicrosoftActiveDirectory.mail\\n}\\ngetActiveDirectoryEmail();\"", + "MappingMode": "Complex", + "Value": "\"function getEmail() {\\r\\n let mail = '';\\r\\n if (typeof Person.ExternalId !== 'undefined' && Person.ExternalId) {\\r\\n if (typeof Person.Accounts.MicrosoftActiveDirectory.mail !== 'undefined' && Person.Accounts.MicrosoftActiveDirectory.mail) {\\r\\n mail = Person.Accounts.MicrosoftActiveDirectory.mail;\\r\\n }\\r\\n }\\r\\n return mail;\\r\\n}\\r\\n\\r\\ngetEmail()\"", "UsedInNotifications": false, "StoreInAccountData": true } @@ -20,4 +20,4 @@ } ], "UniqueFieldNames": [] -} +} \ No newline at end of file diff --git a/update.ps1 b/update.ps1 new file mode 100644 index 0000000..51987b6 --- /dev/null +++ b/update.ps1 @@ -0,0 +1,36 @@ +############################################ +# HelloID-Conn-Prov-Target-GoodHabitz-Update +# PowerShell V2 +############################################ + +try { + if ($actionContext.DryRun -eq $true) { + Write-Information "[DryRun] correlate GoodHabitz account for: [$($personContext.Person.DisplayName)], will be executed during enforcement" + if (-not([string]::IsNullOrEmpty($actionContext.Data.EmailAddress))) { + $outputContext.AccountReference = $actionContext.Data.EmailAddress + } + $outputContext.success = $true + } + + if (-not($actionContext.DryRun -eq $true)) { + Write-Information 'Correlating GoodHabitz account' + + if (-not([string]::IsNullOrEmpty($actionContext.Data.EmailAddress))) { + $outputContext.AccountReference = $actionContext.Data.EmailAddress + } + $outputContext.success = $true + $outputContext.AuditLogs.Add([PSCustomObject]@{ + Action = 'CorrelateAccount' + Message = "Account [$($actionContext.Data.EmailAddress)] successfully correlated on field [EmailAddress]" + IsError = $false + }) + } +} +catch { + $outputContext.success = $false + Write-Warning "Error at Line '$($_.InvocationInfo.ScriptLineNumber)': $($_.InvocationInfo.Line). Error: $($_.Exception.Message)" + $outputContext.AuditLogs.Add([PSCustomObject]@{ + Message = "Could not create or correlate GoodHabitz account. Error: $($_.Exception.Message)" + IsError = $true + }) +} \ No newline at end of file From 1348041d6094e92b10728a4bafd23db35ff36610 Mon Sep 17 00:00:00 2001 From: Jeroen Blaauw <72070984+JeroenBL@users.noreply.github.com> Date: Tue, 3 Dec 2024 15:05:07 +0100 Subject: [PATCH 2/3] Create createRelease.yaml --- .github/workflows/createRelease.yaml | 92 ++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 .github/workflows/createRelease.yaml diff --git a/.github/workflows/createRelease.yaml b/.github/workflows/createRelease.yaml new file mode 100644 index 0000000..45c917b --- /dev/null +++ b/.github/workflows/createRelease.yaml @@ -0,0 +1,92 @@ +name: Create Release + +on: + workflow_dispatch: + inputs: + version: + description: 'Version number (e.g., v1.0.0). Leave blank to use the latest version from CHANGELOG.md.' + required: false + pull_request: + types: + - closed + +permissions: + contents: write + +jobs: + create-release: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Determine Version + id: determine_version + run: | + if [ -n "${{ github.event.inputs.version }}" ]; then + VERSION="${{ github.event.inputs.version }}" + echo "Using provided version: $VERSION" + else + if [ -f CHANGELOG.md ]; then + # Extract the latest version heading from CHANGELOG.md + VERSION=$(grep -oP '^## \[\K[^]]+' CHANGELOG.md | head -n 1) + if [ -z "$VERSION" ]; then + echo "No versions found in CHANGELOG.md." + exit 1 + fi + echo "Using latest version from CHANGELOG.md: $VERSION" + else + echo "CHANGELOG.md not found. Cannot determine version." + exit 1 + fi + fi + + # Prepend 'v' if not already present + if [[ "$VERSION" != v* ]]; then + VERSION="v$VERSION" + fi + + echo "version=$VERSION" >> $GITHUB_ENV + echo "version_no_v=${VERSION#v}" >> $GITHUB_ENV + + - name: Extract Release Notes from CHANGELOG.md + id: extract_notes + if: ${{ github.event.inputs.version == '' }} # Skip if a version is provided as input + run: | + if [ -f CHANGELOG.md ]; then + NOTES=$(awk '/## \['"${{ env.version_no_v }}"'\]/{flag=1; next} /## \[/{flag=0} flag' CHANGELOG.md) + if [ -z "$NOTES" ]; then + echo "No release notes found for version ${{ env.version_no_v }} in CHANGELOG.md." + exit 1 + fi + echo "Release notes extracted." + else + echo "CHANGELOG.md not found in the repository." + exit 1 + fi + echo "::set-output name=notes::$NOTES" + + - name: Default Release Notes + id: default_notes + if: ${{ github.event.inputs.version != '' }} # Use default notes if a version is provided as input + run: | + echo "Release notes not provided; using default placeholder." + echo "::set-output name=notes::Release notes not provided for version ${{ env.version }}." + + - name: Debug Release Notes + run: | + echo "Extracted Release Notes:" + echo "${{ steps.extract_notes.outputs.notes || steps.default_notes.outputs.notes }}" + + - name: Create GitHub Release + id: create_release + uses: actions/create-release@v1 + with: + tag_name: ${{ env.version }} + release_name: ${{ env.version }} + body: ${{ steps.extract_notes.outputs.notes || steps.default_notes.outputs.notes }} + draft: false + prerelease: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 80ca4176ab99c32839f1946ec9fdd081afc8c9c2 Mon Sep 17 00:00:00 2001 From: Jeroen Blaauw <72070984+JeroenBL@users.noreply.github.com> Date: Tue, 3 Dec 2024 15:05:35 +0100 Subject: [PATCH 3/3] Create verifyChangelog.yaml --- .github/workflows/verifyChangelog.yaml | 30 ++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/verifyChangelog.yaml diff --git a/.github/workflows/verifyChangelog.yaml b/.github/workflows/verifyChangelog.yaml new file mode 100644 index 0000000..c3816fd --- /dev/null +++ b/.github/workflows/verifyChangelog.yaml @@ -0,0 +1,30 @@ +name: Verify CHANGELOG Updated + +on: + pull_request: + types: [opened, synchronize] + +jobs: + check-changelog: + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + with: + fetch-depth: 0 # Ensure full history is fetched + + - name: Ensure CHANGELOG.md is updated + run: | + # Fetch the base branch to compare against + git fetch origin ${{ github.base_ref }} --depth=1 + + # Compare changes between the current branch and the base branch + CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}) + + # Check if CHANGELOG.md is included in the list of changed files + if echo "$CHANGED_FILES" | grep -q 'CHANGELOG.md'; then + echo "CHANGELOG.md is updated." + else + echo "ERROR: Please update the CHANGELOG.md file with your changes." && exit 1 + fi