Modules/AzureDevOpsDsc.Common/Api/Functions/Private/Helper/Get-IdentityDescriptorIndexItem.ps1
|
<#
.SYNOPSIS Resolves an ACL descriptor to an identity via the flat descriptor->identity index. .DESCRIPTION Permission resolution (ConvertTo-FormattedACL -> Find-Identity) looks up an identity by its ACL descriptor once per ACE. The List-based LiveGroups/LiveUsers/LiveServicePrinciples caches store the descriptor nested under .value.ACLIdentity.descriptor, which is both an O(N) scan and frequently lost across the clixml round-trip / init double-wrap, forcing an expensive pair of API calls (Get-DevOpsDescriptorIdentity + List-DevOpsGroups) per miss. This index keeps a flat hashtable keyed by ACL descriptor whose values are plain all-string records, making lookups O(1) and clixml-safe so they survive DSC runspace isolation. On a hit a CacheItem is synthesised in the exact shape callers expect (.value.principalName / .value.originId / .value.ACLIdentity.descriptor / .id). Returns $null on a miss. #> function Get-IdentityDescriptorIndexItem { [CmdletBinding()] [OutputType([object])] param( # Not Mandatory: an empty descriptor simply misses (returns $null) rather than throwing, so # callers can pass a computed descriptor without pre-checking it. [Parameter()][string]$AclDescriptor ) if ([string]::IsNullOrEmpty($AclDescriptor)) { return $null } $index = Get-IdentityDescriptorIndex if (-not $index.ContainsKey($AclDescriptor)) { return $null } $record = $index[$AclDescriptor] $value = [PSCustomObject]@{ principalName = $record.principalName originId = $record.originId descriptor = $record.graphDescriptor ACLIdentity = [PSCustomObject]@{ id = $record.aclId descriptor = $record.aclDescriptor subjectDescriptor = $record.subjectDescriptor } } return [CacheItem]::New($record.principalName, $value) } |