Skip to content

Commit

Permalink
Merge pull request #5197 from PiyushDub/AADServicePrincipalDelegatedP…
Browse files Browse the repository at this point in the history
…ermissionClassification

AADServicePrincipalDelegatedPermissionClassification
  • Loading branch information
NikCharlebois authored Oct 16, 2024
2 parents 327aeb6 + 095db5a commit e249275
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 32 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
* Initial release.
* AADLifecycleWorkflowSettings
* Initial release.
* AADServicePrincipal
* Adding Delegated Permission Classification Property
* ADOPermissionGroupSettings
* Initial release.
* EXOATPBuiltInProtectionRule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ function Get-TargetResource
[System.Boolean]
$AppRoleAssignmentRequired,

[Parameter()]
[Microsoft.Management.Infrastructure.CimInstance[]]
$DelegatedPermissionClassifications,

[Parameter()]
[System.String]
$ErrorUrl,
Expand Down Expand Up @@ -212,32 +216,43 @@ function Get-TargetResource
}
}

[Array]$complexDelegatedPermissionClassifications = @()
$permissionClassifications = Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/v1.0/servicePrincipals(appId='$AppId')/delegatedPermissionClassifications" -Method Get
foreach ($permissionClassification in $permissionClassifications.Value){
$hashtable = @{
classification = $permissionClassification.Classification
permissionName = $permissionClassification.permissionName
}
$complexDelegatedPermissionClassifications += $hashtable
}

$result = @{
AppId = $AADServicePrincipal.AppId
AppRoleAssignedTo = $AppRoleAssignedToValues
ObjectID = $AADServicePrincipal.Id
DisplayName = $AADServicePrincipal.DisplayName
AlternativeNames = $AADServicePrincipal.AlternativeNames
AccountEnabled = [boolean]$AADServicePrincipal.AccountEnabled
AppRoleAssignmentRequired = $AADServicePrincipal.AppRoleAssignmentRequired
ErrorUrl = $AADServicePrincipal.ErrorUrl
Homepage = $AADServicePrincipal.Homepage
LogoutUrl = $AADServicePrincipal.LogoutUrl
Owners = $ownersValues
PublisherName = $AADServicePrincipal.PublisherName
ReplyURLs = $AADServicePrincipal.ReplyURLs
SamlMetadataURL = $AADServicePrincipal.SamlMetadataURL
ServicePrincipalNames = $AADServicePrincipal.ServicePrincipalNames
ServicePrincipalType = $AADServicePrincipal.ServicePrincipalType
Tags = $AADServicePrincipal.Tags
Ensure = 'Present'
Credential = $Credential
ApplicationId = $ApplicationId
ApplicationSecret = $ApplicationSecret
TenantId = $TenantId
CertificateThumbprint = $CertificateThumbprint
Managedidentity = $ManagedIdentity.IsPresent
AccessTokens = $AccessTokens
AppId = $AADServicePrincipal.AppId
AppRoleAssignedTo = $AppRoleAssignedToValues
ObjectID = $AADServicePrincipal.Id
DisplayName = $AADServicePrincipal.DisplayName
AlternativeNames = $AADServicePrincipal.AlternativeNames
AccountEnabled = [boolean]$AADServicePrincipal.AccountEnabled
AppRoleAssignmentRequired = $AADServicePrincipal.AppRoleAssignmentRequired
DelegatedPermissionClassifications = [Array]$complexDelegatedPermissionClassifications
ErrorUrl = $AADServicePrincipal.ErrorUrl
Homepage = $AADServicePrincipal.Homepage
LogoutUrl = $AADServicePrincipal.LogoutUrl
Owners = $ownersValues
PublisherName = $AADServicePrincipal.PublisherName
ReplyURLs = $AADServicePrincipal.ReplyURLs
SamlMetadataURL = $AADServicePrincipal.SamlMetadataURL
ServicePrincipalNames = $AADServicePrincipal.ServicePrincipalNames
ServicePrincipalType = $AADServicePrincipal.ServicePrincipalType
Tags = $AADServicePrincipal.Tags
Ensure = 'Present'
Credential = $Credential
ApplicationId = $ApplicationId
ApplicationSecret = $ApplicationSecret
TenantId = $TenantId
CertificateThumbprint = $CertificateThumbprint
Managedidentity = $ManagedIdentity.IsPresent
AccessTokens = $AccessTokens
}
Write-Verbose -Message "Get-TargetResource Result: `n $(Convert-M365DscHashtableToString -Hashtable $result)"
return $result
Expand Down Expand Up @@ -289,6 +304,10 @@ function Set-TargetResource
[System.Boolean]
$AppRoleAssignmentRequired,

[Parameter()]
[Microsoft.Management.Infrastructure.CimInstance[]]
$DelegatedPermissionClassifications,

[Parameter()]
[System.String]
$ErrorUrl,
Expand Down Expand Up @@ -398,6 +417,8 @@ function Set-TargetResource
{
$currentParameters.AppRoleAssignedTo = $AppRoleAssignedToValue
}
# removing Delegated permission classifications from this new call, as adding below separately
$currentParameters.Remove('DelegatedPermissionClassifications') | Out-Null
$ObjectGuid = [System.Guid]::empty
if (-not [System.Guid]::TryParse($AppId, [System.Management.Automation.PSReference]$ObjectGuid))
{
Expand All @@ -419,6 +440,17 @@ function Set-TargetResource
Write-Verbose -Message "Adding new owner {$owner}"
$newOwner = New-MgServicePrincipalOwnerByRef -ServicePrincipalId $newSP.Id -BodyParameter $body
}

#adding delegated permissions classifications
if($null -ne $DelegatedPermissionClassifications){
foreach ($permissionClassification in $DelegatedPermissionClassifications){
$params = @{
classification = $permissionClassification.Classification
permissionName = $permissionClassification.permissionName
}
Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/v1.0/servicePrincipals(appId='$($currentParameters.AppId)')/delegatedPermissionClassifications" -Method Post -Body $params
}
}
}
# ServicePrincipal should exist and will be configured to desired state
elseif ($Ensure -eq 'Present' -and $currentAADServicePrincipal.Ensure -eq 'Present')
Expand All @@ -434,6 +466,7 @@ function Set-TargetResource
Write-Verbose -Message "ServicePrincipalID: $($currentAADServicePrincipal.ObjectID)"
$currentParameters.Remove('AppRoleAssignedTo') | Out-Null
$currentParameters.Remove('Owners') | Out-Null
$currentParameters.Remove('DelegatedPermissionClassifications') | Out-Null
Update-MgServicePrincipal -ServicePrincipalId $currentAADServicePrincipal.ObjectID @currentParameters

if ($AppRoleAssignedTo)
Expand Down Expand Up @@ -546,6 +579,26 @@ function Set-TargetResource
-DirectoryObjectId $userInfo.Id | Out-Null
}
}

Write-Verbose -Message "Checking if DelegatedPermissionClassifications need to be updated..."

if ($null -ne $DelegatedPermissionClassifications)
{
# removing old perm classifications
$permissionClassificationList = Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/v1.0/servicePrincipals(appId='$($currentParameters.AppId)')/delegatedPermissionClassifications" -Method Get
foreach($permissionClassification in $permissionClassificationList.Value){
Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/v1.0/servicePrincipals(appId='$($currentParameters.AppId)')/delegatedPermissionClassifications/$($permissionClassification.Id)" -Method Delete
}

# adding new perm classifications
foreach ($permissionClassification in $DelegatedPermissionClassifications){
$params = @{
classification = $permissionClassification.Classification
permissionName = $permissionClassification.permissionName
}
Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/v1.0/servicePrincipals(appId='$($currentParameters.AppId)')/delegatedPermissionClassifications" -Method Post -Body $params
}
}
}
# ServicePrincipal exists but should not
elseif ($Ensure -eq 'Absent' -and $currentAADServicePrincipal.Ensure -eq 'Present')
Expand Down Expand Up @@ -589,6 +642,10 @@ function Test-TargetResource
[System.Boolean]
$AppRoleAssignmentRequired,

[Parameter()]
[Microsoft.Management.Infrastructure.CimInstance[]]
$DelegatedPermissionClassifications,

[Parameter()]
[System.String]
$ErrorUrl,
Expand Down Expand Up @@ -677,21 +734,48 @@ function Test-TargetResource

Write-Verbose -Message 'Testing configuration of Azure AD ServicePrincipal'

$testTargetResource = $true
$CurrentValues = Get-TargetResource @PSBoundParameters
$ValuesToCheck = ([Hashtable]$PSBoundParameters).Clone()

#Compare Cim instances
foreach ($key in $PSBoundParameters.Keys)
{
$source = $PSBoundParameters.$key
$target = $CurrentValues.$key
if ($null -ne $source -and $source.GetType().Name -like '*CimInstance*')
{
$testResult = Compare-M365DSCComplexObject `
-Source ($source) `
-Target ($target)

if (-not $testResult)
{
$testTargetResource = $false
}
else {
$ValuesToCheck.Remove($key) | Out-Null
}
}
}

Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)"
Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $PSBoundParameters)"

$ValuesToCheck = $PSBoundParameters

$TestResult = Test-M365DSCParameterState -CurrentValues $CurrentValues `
-Source $($MyInvocation.MyCommand.Source) `
-DesiredValues $PSBoundParameters `
-ValuesToCheck $ValuesToCheck.Keys
-Source $($MyInvocation.MyCommand.Source) `
-DesiredValues $PSBoundParameters `
-ValuesToCheck $ValuesToCheck.Keys `
-IncludedDrifts $driftedParams

if(-not $TestResult)
{
$testTargetResource = $false
}

Write-Verbose -Message "Test-TargetResource returned $TestResult"
Write-Verbose -Message "Test-TargetResource returned $testTargetResource"

return $TestResult
return $testTargetResource
}

function Export-TargetResource
Expand Down Expand Up @@ -785,6 +869,10 @@ function Export-TargetResource
{
$Results.AppRoleAssignedTo = Get-M365DSCAzureADServicePrincipalAssignmentAsString -Assignments $Results.AppRoleAssignedTo
}
if ($Results.DelegatedPermissionClassifications.Count -gt 0)
{
$Results.DelegatedPermissionClassifications = Get-M365DSCAzureADServicePrincipalDelegatedPermissionClassifications -PermissionClassifications $Results.DelegatedPermissionClassifications
}
$currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName `
-ConnectionMode $ConnectionMode `
-ModulePath $PSScriptRoot `
Expand All @@ -795,6 +883,11 @@ function Export-TargetResource
$currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock `
-ParameterName 'AppRoleAssignedTo'
}
if ($null -ne $Results.DelegatedPermissionClassifications)
{
$currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock `
-ParameterName 'DelegatedPermissionClassifications'
}
$dscContent += $currentDSCBlock
Save-M365DSCPartialExport -Content $currentDSCBlock `
-FileName $Global:PartialExportFileName
Expand Down Expand Up @@ -841,4 +934,26 @@ function Get-M365DSCAzureADServicePrincipalAssignmentAsString
return $StringContent
}

function Get-M365DSCAzureADServicePrincipalDelegatedPermissionClassifications
{
[CmdletBinding()]
[OutputType([System.String])]
param(
[Parameter(Mandatory = $true)]
[System.Collections.ArrayList]
$PermissionClassifications
)

$StringContent = "@(`r`n"
foreach ($permissionClassification in $PermissionClassifications)
{
$StringContent += " MSFT_AADServicePrincipalDelegatedPermissionClassification {`r`n"
$StringContent += " Classification = '" + $PermissionClassification.Classification + "'`r`n"
$StringContent += " PermissionName = '" + $PermissionClassification.PermissionName + "'`r`n"
$StringContent += " }`r`n"
}
$StringContent += ' )'
return $StringContent
}

Export-ModuleMember -Function *-TargetResource
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ class MSFT_AADServicePrincipalRoleAssignment
[Write, Description("Unique identity representing the principal.")] String Identity;
};

[ClassVersion("1.0.0")]
class MSFT_AADServicePrincipalDelegatedPermissionClassification
{
[Write, Description("Classification of the delegated permission"), ValueMap{"low", "medium", "high"}, Values{"low", "medium", "high"}] String Classification;
[Write, Description("Name of the permission")] String PermissionName;
};

[ClassVersion("1.0.0.0"), FriendlyName("AADServicePrincipal")]
class MSFT_AADServicePrincipal : OMI_BaseResource
{
Expand All @@ -25,6 +32,8 @@ class MSFT_AADServicePrincipal : OMI_BaseResource
[Write, Description("Specifies an array of service principal names. Based on the identifierURIs collection, plus the application's appId property, these URIs are used to reference an application's service principal.")] String ServicePrincipalNames[];
[Write, Description("The type of the service principal.")] String ServicePrincipalType;
[Write, Description("Tags linked to this service principal.Note that if you intend for this service principal to show up in the All Applications list in the admin portal, you need to set this value to {WindowsAzureActiveDirectoryIntegratedApp}")] String Tags[];
[Write, Description("The permission classifications for delegated permissions exposed by the app that this service principal represents."), EmbeddedInstance("MSFT_AADServicePrincipalDelegatedPermissionClassification")] String DelegatedPermissionClassifications[];

[Write, Description("Specify if the Azure AD App should exist or not."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure;
[Write, Description("Id of the Azure Active Directory application to authenticate with.")] String ApplicationId;
[Write, Description("Id of the Azure Active Directory tenant used for authentication.")] String TenantId;
Expand Down

0 comments on commit e249275

Please sign in to comment.