Skip to content
Closed
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
17 changes: 13 additions & 4 deletions setup/support/Epp.Setup.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ function Resolve-EppApplicationProvider {
}
$application = Get-EppApplication -Inputs $Inputs -ClientId $Inputs.ApplicationId
$restriction = Get-EppSignInAudienceRestrictions -Inputs $Inputs -ApplicationObjectId $application.Id
$state = Get-EppProviderRestrictionState -Restriction $restriction
$state = Get-EppProviderRestrictionState -Restriction $restriction -SignInAudience $application.SignInAudience
$configured = @()
if ($application.SignInAudience -eq 'AzureADMultipleOrgs' -and $state -and $state.isHomeTenantAllowed) {
foreach ($entry in $entries) {
Expand Down Expand Up @@ -968,9 +968,16 @@ function Get-EppSignInAudienceRestrictions {
}

function Get-EppProviderRestrictionState {
param($Restriction)
param($Restriction, [string] $SignInAudience)

if ($null -eq $Restriction) { return $null }
# Graph can return unrestrictedAudience instead of null for a new single-tenant app. The
# app's sign-in audience still prevents external tenants, so this is equivalent to having no
# provider allowlist yet. Never normalize the same shape for a multitenant application.
if ($Restriction -is [Collections.IDictionary] -and $Restriction['kind'] -ceq 'unrestricted' -and
$SignInAudience -ceq 'AzureADMyOrg') {
return $null
}
if ($Restriction -isnot [Collections.IDictionary] -or $Restriction['kind'] -cne 'allowedTenants' -or
$Restriction['isHomeTenantAllowed'] -isnot [bool] -or $Restriction['allowedTenantIds'] -isnot [Array]) {
throw 'The application has an unsupported provider-tenant restriction. Review it before running setup.'
Expand Down Expand Up @@ -1288,7 +1295,8 @@ function Connect-EppContext {
$tenantRestriction = if (-not $pendingApplication) {
Get-EppSignInAudienceRestrictions -Inputs $Inputs -ApplicationObjectId $application.Id
} else { $null }
$providerRestrictionState = Get-EppProviderRestrictionState -Restriction $tenantRestriction
$providerRestrictionState = Get-EppProviderRestrictionState -Restriction $tenantRestriction `
-SignInAudience $application.SignInAudience
$allowedTenants = @(if ($providerRestrictionState) { $providerRestrictionState.allowedTenantIds })
$Inputs.ProviderAllowedTenantIds = @(($allowedTenants + @($Inputs.ProviderTenantId)) | Sort-Object -Unique)
$version = if ($application.Api -and $application.Api.RequestedAccessTokenVersion) { [int]$application.Api.RequestedAccessTokenVersion } else { 1 }
Expand Down Expand Up @@ -1618,7 +1626,8 @@ function Initialize-EppGraphAccess {
}
Assert-EppCertificatePlanUnchanged -Application $application -Plan $Context.CertificatePlan
$restriction = Get-EppSignInAudienceRestrictions -Inputs $Inputs -ApplicationObjectId $application.Id
$currentProviderState = Get-EppProviderRestrictionState -Restriction $restriction
$currentProviderState = Get-EppProviderRestrictionState -Restriction $restriction `
-SignInAudience $application.SignInAudience
if (-not (Test-EppJsonEqual $currentProviderState $Context.ProviderRestrictionState)) {
throw 'The application provider configuration changed after the plan was reviewed. Rerun setup; no provider tenants will be removed.'
}
Expand Down
13 changes: 12 additions & 1 deletion setup/tests/ProviderConfiguration.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ try {
Assert (Test-EppProviderTenantRestriction -Restriction $both -ProviderTenantId $telesign.TenantId) 'A configured provider can coexist with other allowed providers.'
Assert (Test-EppProviderTenantRestriction -Restriction $both -ProviderTenantId $telesign.TenantId -ExpectedAllowedTenantIds @($telesign.TenantId, $soprano.TenantId)) 'Compare allowed tenants independently of ordering.'
Assert (-not (Test-EppProviderTenantRestriction -Restriction $both -ProviderTenantId $telesign.TenantId -ExpectedAllowedTenantIds @($telesign.TenantId))) 'Readback must match the complete approved allowlist.'
$unrestricted = @{ '@odata.type' = '#microsoft.graph.unrestrictedAudience'; kind = 'unrestricted'; allowedTenantIds = @($script:Tenant) }
Assert ($null -eq (Get-EppProviderRestrictionState -Restriction $unrestricted -SignInAudience 'AzureADMyOrg')) 'Treat Graph unrestrictedAudience as an empty provider configuration only while the app is single tenant.'
Assert-Throws { Get-EppProviderRestrictionState -Restriction $unrestricted -SignInAudience 'AzureADMultipleOrgs' } 'unsupported provider-tenant restriction'
Assert-Throws { Get-EppProviderRestrictionState (New-TestRestriction @($telesign.TenantId, $telesign.TenantId)) } 'duplicate allowed'
Assert-Throws { Get-EppProviderRestrictionState @{ kind = 'unexpected'; isHomeTenantAllowed = $true; allowedTenantIds = @() } } 'unsupported provider-tenant restriction'
Assert-Throws { Get-EppProviderRestrictionState (New-TestRestriction @('invalid')) } 'nonempty GUID'
Expand Down Expand Up @@ -174,6 +177,11 @@ try {
$expected = @((@($existing) + @($telesign.TenantId)) | Sort-Object -Unique)
Assert (($inputs.ProviderAllowedTenantIds -join ',') -ceq ($expected -join ',')) 'Preflight must preserve existing known and unknown allowed tenants while adding the selected provider.'
}
Reset-TestState
$script:Restriction = $unrestricted
$inputs = New-TestInputs
Assert-Throws { Connect-EppContext -Inputs $inputs -Names @{ resourceGroup = 'unit' } -NonInteractive } '^provider-preflight-boundary$'
Assert (($inputs.ProviderAllowedTenantIds -join ',') -ceq $telesign.TenantId) 'Single-tenant unrestrictedAudience must enter preflight as an empty provider configuration.'
foreach ($alreadyConfigured in @($false, $true)) {
Reset-TestState
$script:Application.SignInAudience = 'AzureADMultipleOrgs'
Expand Down Expand Up @@ -210,7 +218,10 @@ try {
Reset-TestState
$inputs = New-TestInputs
$inputs.ProviderAllowedTenantIds = @($telesign.TenantId)
if ($case.New) { $inputs.NewApplicationDisplayName = 'New EPP application' }
if ($case.New) {
$inputs.NewApplicationDisplayName = 'New EPP application'
$script:Restriction = $unrestricted
}
for ($index = 0; $index -lt $case.Failures; $index++) { $script:ApplicationReadErrors.Enqueue($case.Error) }
$context = @{
Application = @{ Id = $script:ObjectId; SignInAudience = $script:Application.SignInAudience }
Expand Down
Loading