Modules/IdLE.Core/Private/Get-IdleProviderCapabilities.ps1
|
Set-StrictMode -Version Latest function Get-IdleProviderCapabilities { <# .SYNOPSIS Returns the advertised capabilities of a provider instance. .DESCRIPTION Capabilities are stable string identifiers that describe what a provider can do. Steps will declare required capabilities, and the core will validate that the required capabilities are available before executing a plan. Providers can advertise capabilities explicitly by implementing a ScriptMethod named 'GetCapabilities' that returns a list of capability strings. For backward compatibility (during the migration), this function can infer a minimal set of capabilities from well-known provider methods when no explicit advertisement exists. .PARAMETER Provider The provider instance to read capabilities from. .PARAMETER AllowInference When set, capabilities may be inferred from provider methods if the provider does not explicitly advertise capabilities via GetCapabilities(). .OUTPUTS System.String[] #> [CmdletBinding()] param( [Parameter(Mandatory)] [ValidateNotNull()] [object] $Provider, [Parameter()] [switch] $AllowInference ) $capabilities = @() $capabilitySource = 'none' # Prefer explicit advertisement (provider-controlled, deterministic). $hasGetCapabilitiesMethod = $Provider.PSObject.Methods.Name -contains 'GetCapabilities' if ($hasGetCapabilitiesMethod) { $capabilities = @($Provider.GetCapabilities()) $capabilitySource = 'explicit' } elseif ($AllowInference) { # Migration helper: infer a minimal set from known method names. # We keep this conservative to avoid accidentally overstating capabilities. $methodNames = @($Provider.PSObject.Methods.Name) if ($methodNames -contains 'GrantEntitlement') { $capabilities += 'IdLE.Entitlement.Grant' } if ($methodNames -contains 'ListEntitlements') { $capabilities += 'IdLE.Entitlement.List' } if ($methodNames -contains 'RevokeEntitlement') { $capabilities += 'IdLE.Entitlement.Revoke' } if ($methodNames -contains 'EnsureAttribute') { $capabilities += 'Identity.Attribute.Ensure' } if ($methodNames -contains 'DisableIdentity') { $capabilities += 'Identity.Disable' } if ($methodNames -contains 'GetIdentity') { $capabilities += 'Identity.Read' } $capabilitySource = 'inferred' } # Normalize, validate, and return a stable list. $normalized = New-Object System.Collections.Generic.List[string] $seen = New-Object System.Collections.Generic.HashSet[string] foreach ($c in @($capabilities)) { if ($null -eq $c) { continue } $s = ($c -as [string]).Trim() if ([string]::IsNullOrWhiteSpace($s)) { continue } # Capability naming convention: # - dot-separated segments # - no whitespace # - starts with a letter # Example: 'Entitlement.Write', 'Identity.Attribute.Ensure' if ($s -notmatch '^[A-Za-z][A-Za-z0-9]*(\.[A-Za-z0-9]+)+$') { throw "Provider capability '$s' is invalid. Expected dot-separated segments like 'Identity.Read' or 'Entitlement.Write'." } if ($seen.Add($s)) { $null = $normalized.Add($s) } } if ($capabilitySource -eq 'explicit') { return @($normalized | Sort-Object -Unique) } # Preserve inference ordering to keep well-known capabilities in priority order # (e.g., entitlement operations before identity operations). return @($normalized) } |