Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: use aref when fieldmapping is empty #2

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions .github/workflows/createRelease.yaml
Original file line number Diff line number Diff line change
@@ -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 }}
30 changes: 30 additions & 0 deletions .github/workflows/verifyChangelog.yaml
Original file line number Diff line number Diff line change
@@ -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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ The following lifecycle actions are available:
| Action | Description |
| ------------------ | ------------------------------------ |
| create.ps1 | PowerShell _create_ lifecycle action |
| update.ps1 | PowerShell _update_ lifecycle action |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be good to describe the actions you're executing in each script. Especially since the create and update scripts only do correlation. I know we have a bit disclaimer describing this, but it wouldn't hurt to repeat that message?

| delete.ps1 | PowerShell _delete_ lifecycle action |
| configuration.json | Default _configuration.json_ |
| fieldMapping.json | Default _fieldMapping.json_ |
Expand All @@ -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

Expand Down
16 changes: 11 additions & 5 deletions delete.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,22 @@ try {
throw 'The account reference could not be found'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the readme, you say: 'The $actionContext.References.Account is used when $actionContext.Data.EmailAddress is empty in the delete lifecycle action.' and in the mapping the aRef is will empty when there's no emailaddress. If there's a situation where the emailaddress is empty in aRef, the script will fail here, instead of getting the emailaddress from the mapping. The chance that this occurs is very slim, but i do think we should fix this.

I think we can fix this by throwing an error only when aRef and Data.EmailAddress are empty.

}

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 = @{
Expand All @@ -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
})
}
Expand Down
6 changes: 3 additions & 3 deletions fieldMapping.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
"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
}
]
}
],
"UniqueFieldNames": []
}
}
36 changes: 36 additions & 0 deletions update.ps1
Original file line number Diff line number Diff line change
@@ -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]@{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to do something with previousData so the audit message is only shown when previousdata != data?

Action = 'CorrelateAccount'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also say we correlate while Data.Emailaddress is empty?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think these comments apply to the create script too

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
})
}
Loading