feat: add OneLogin as the seventh provider - #56
Merged
Merged
Conversation
Seeds a OneLogin account through its API as an API credential, reports on it, verifies it against the seed data, repairs it and tears it down, proving ownership of every object before deleting it. Seeded: four custom user fields, 321 people in every lifecycle state OneLogin keeps (one of them locked) with managers and directory identifiers, four roles, five office groups, two user security policies, five OIDC and SAML apps with two app rules, two API authorization servers with scopes, claims and seeded clients, two gated user mappings, a disabled Smart Hook, a disabled self-registration profile, and MFA factors where the account already offers them. Built to be safe in an account real people sign in to. A role, group, policy, mapping, app rule and hook are proved by what they hold or name, since most carry nothing but a name. Nothing seeded can reach a real object and nothing real is pulled into the seed, and none of those properties has a parameter. New-OneLoginApp -SaveAppSecret optionally keeps the two confidential apps' client secrets through the shared credential record writer (DPAPI or the SecretStore); Get-OneLoginAppCredential reads them back, and teardown deletes each with its app and any whose app is gone. Adds 13 exported commands with PlatyPS help, and the provider README.
Cuts the Unreleased section as 1.5.0: OneLogin joins as the seventh provider, with ownership proved by what each object holds, safety properties that have no parameter, and opt-in saved app secrets that teardown removes with their apps. Minor rather than patch: a new provider and thirteen new exported commands, with no change to any existing command's parameters or output. Also restores the UTF-8 byte order mark on TestEnvironment.psd1 and TestEnvironment.psm1, which an editing pass on this branch had dropped. Both files are ASCII today, so nothing read them differently, but main has always carried the mark and Windows PowerShell 5.1 needs it the moment either file holds a non-ASCII character.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds OneLogin as the module's seventh provider. It seeds a OneLogin account through the OneLogin API (v2, with v1 where v2 has no equivalent), authenticating as an API credential. It reports on the seeded objects, verifies them against the seed data, repairs drift, and tears everything down, proving ownership of each object before deleting it. It plugs into the shared dispatchers, so
Connect-TestEnvironment -Provider OneLogin,New-TestEnvironment,Get-TestEnvironmentReport,Test-TestEnvironment,Repair-TestEnvironment,Compare-TestEnvironmentandRemove-TestEnvironmentall work unchanged.The provider is designed to run against an account real people sign in to, not only a lab. Nothing it seeds can act on a real object, and no real object is drawn into the seed. None of the properties that guarantee this can be switched off by a parameter.
What is seeded
zztest_seed_tagcarries the ownership tag on every seeded personEvery person also gets the directory identifiers a directory-synchronised account would have: sAMAccountName, user principal name, distinguished name,
member_of, external id and phone. The people shared with other providers carry exactly the names inCore/Data/SeedPeople.csv, including the non-Latin writing systems and the decomposed name.Ownership and teardown
Most OneLogin objects carry nothing but a name, so
Get-OneLoginSeededObjectproves each type by its contents:zztest_seed_tagand the prefix on the username.// Seeded by TestEnvironment. Safe to delete. [ZZ-TEST-seed]first in its code, since a hook has no name or description.zztest_.A mapping, app rule or hook may name a seeded role, or a role that no longer exists (so a run interrupted after roles were deleted can still be proved). It may never name a role that exists and is not seeded.
Teardown proves every object before deleting any, because the proofs depend on each other, then deletes in dependency order. An object that fails its proof is listed with the reason and left alone.
-Keepalso keeps whatever the kept type is proved by (the transitive closure of$script:OneLoginProofDependency) and reports what it added. As on every provider,-WhatIfwins over-Force.Safety properties with no parameter
example.comby default) and has no default role or group; a re-run restores that state.member_of.New-OneLoginStep.Tests.ps1asserts each of these, and also that no step exposes a parameter that could loosen them.Saved app secrets (opt-in)
OneLogin returns an app's client secret only in the response to its creation; later reads of the app return the client id alone. By default the secret is discarded. With
New-TestEnvironment -SaveAppSecret:Export-TestCredentialRecord, one record per app id: DPAPI-protected under~/.testenvironment/<subdomain>.onelogin-app.<id>.json, or in a SecretStore vault with-UseSecretStore.Get-OneLoginAppCredentialreturns them asPSCredentialobjects (client id as user name). The secret never reaches the pipeline as plain text.-WhatIf. Under-Keep Appsit doesn't read the records at all.The seeded apps' redirect URLs are under the lab email domain, so a test relying party must be reachable there or have its redirect URL added in the portal. The client credentials grant isn't enabled on the seeded apps; token requests using it return HTTP 500.
OneLogin behaviour the provider accounts for
Each item below was observed against a live trial account. None of it produces an error.
SeedData.Tests.ps1enforces itlock_usercallfields=names them$script:OneLoginUserFieldsenabled=falseis requestedInvoke-OneLoginRequestreturns non-JSON success bodies as stringsConvertTo-Jsonserialises as a bare numberA trial account allows 5 roles (including Default), 5 apps and 12 user licences (including the owner). The seed data is sized to fit.
Not seeded: devices (OneLogin has no API to create one; a device appears when an agent enrols it), risk rules (they apply account-wide and cannot be scoped to seeded people), and branding, privileges, trusted identity providers and directories (unavailable on a trial, and each is account-wide).
Commands
Exported, with PlatyPS help under
docs/TestEnvironment/and rebuilt MAML:New-OneLoginCustomAttribute,New-OneLoginRole,New-OneLoginGroup,New-OneLoginPolicy,New-OneLoginApp,New-OneLoginAppRule,New-OneLoginApiAuthorization,New-OneLoginMapping,New-OneLoginSmartHook,New-OneLoginSelfRegistration,New-OneLoginUser,New-OneLoginMfaFactor,Get-OneLoginAppCredential.The connect, seed, report, verify and teardown commands are reached through the shared dispatchers and keep full comment-based help. Each is a
<Verb>-OneLoginEnvironmentcommand:Connect,Disconnect,New,Get-...Report,TestandRemove.Connect-TestEnvironment -Provider OneLogin -Subdomain <name>accepts a bare name, host or portal URL.-SaveSecretstores the API credential once the connection is proved, and-UseStoredCredentialreads it back.Disconnect-TestEnvironmentrevokes the token, which otherwise lives ten hours.Also in this change
Test-OneLoginEnvironment: the verifier originally counted one-row seed files with.Countdirectly. On Windows PowerShell 5.1 a singlePSCustomObjecthas no.Count, so the Smart Hook check would have failed there. Every seed read in it is now wrapped in@(), and the matching reads in the unit fixtures are too.docs/TestEnvironment/TestEnvironment.md) lists the PingOne commands, which were missing.CLAUDE.md,README.md,docs/Architecture.md,Tests/README.md,Verify/README.md,CHANGELOG.md(Unreleased) andabout_TestEnvironmentare updated for the new provider.Release
This PR also prepares 1.5.0 (commit
release: 1.5.0):ModuleVersionis1.5.0, and the manifest'sReleaseNotesopen with a 1.5.0 entry.CHANGELOG.mdmoves the Unreleased section under## [1.5.0] - 2026-09-29and leaves Unreleased as "Nothing yet."TestEnvironment.psd1andTestEnvironment.psm1. It had been dropped on this branch; both files are ASCII, so nothing read them differently../Build/Publish-Module.ps1 -WhatIfstages and verifies the tree asTestEnvironment 1.5.0 -> PSGallery, and Windows PowerShell 5.1 reads the manifest as 1.5.0.After merge, the release is tag-driven:
.github/workflows/release.ymlre-runs the quality gates, checks the tag againstModuleVersion, stages, imports the staged tree in a fresh process, and publishes.Verification
./Build/Build-Help.ps1: all help gates pass (100 commands); a rebuild matches the committed MAML byte for byte../Build/Publish-Module.ps1 -WhatIf: the staged module imports, exports the declared commands, discovers all seven providers and serves MAML help for every command.Verify/Invoke-LiveCycle.ps1 -Provider OneLogin:-SaveAppSecretcheck on both editions:Get-OneLoginAppCredential.-WhatIfteardown removed nothing.After every live run the account was confirmed back at its baseline: the owner, the Default role and the Default policy only.