Skip to content

Commit 75e73ce

Browse files
committed
app approval template deployment
1 parent c8c04b3 commit 75e73ce

File tree

3 files changed

+112
-46
lines changed

3 files changed

+112
-46
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
function Push-ExecAppApprovalTemplate {
2+
<#
3+
.FUNCTIONALITY
4+
Entrypoint
5+
#>
6+
param($Item)
7+
8+
try {
9+
$Item = $Item | ConvertTo-Json -Depth 10 | ConvertFrom-Json
10+
$TemplateId = $Item.templateId
11+
12+
$TemplateTable = Get-CIPPTable -TableName 'templates'
13+
$Filter = "RowKey eq '$TemplateId' and PartitionKey eq 'AppApprovalTemplate'"
14+
$Template = (Get-CIPPAzDataTableEntity @TemplateTable -Filter $Filter).JSON | ConvertFrom-Json -ErrorAction SilentlyContinue
15+
16+
if (!$Template) {
17+
Write-LogMessage -message "Template $TemplateId not found" -tenant $Item.Tenant -API 'Add Multitenant App' -sev Error
18+
return
19+
}
20+
21+
$Permissions = $Template.Permissions
22+
23+
Write-Host "$($Item | ConvertTo-Json -Depth 10)"
24+
$ServicePrincipalList = New-GraphGETRequest -uri "https://graph.microsoft.com/beta/servicePrincipals?`$select=AppId,id,displayName&`$top=999" -tenantid $Item.Tenant
25+
if ($Item.AppId -notin $ServicePrincipalList.appId) {
26+
$PostResults = New-GraphPostRequest 'https://graph.microsoft.com/beta/servicePrincipals' -type POST -tenantid $Item.tenant -body "{ `"appId`": `"$($Item.appId)`" }"
27+
Write-LogMessage -message "Added $($Item.AppId) to tenant $($Item.Tenant)" -tenant $Item.Tenant -API 'Add Multitenant App' -sev Info
28+
} else {
29+
Write-LogMessage -message "This app already exists in tenant $($Item.Tenant). We're adding the required permissions." -tenant $Item.Tenant -API 'Add Multitenant App' -sev Info
30+
}
31+
Add-CIPPApplicationPermission -RequiredResourceAccess ($Item.applicationResourceAccess) -ApplicationId $Item.AppId -Tenantfilter $Item.Tenant
32+
Add-CIPPDelegatedPermission -RequiredResourceAccess ($Item.DelegateResourceAccess) -ApplicationId $Item.AppId -Tenantfilter $Item.Tenant
33+
} catch {
34+
Write-LogMessage -message "Error adding application to tenant $($Item.Tenant) - $($_.Exception.Message)" -tenant $Item.Tenant -API 'Add Multitenant App' -sev Error
35+
}
36+
}

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecServicePrincipals.ps1

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,32 @@ function Invoke-ExecServicePrincipals {
2020
try {
2121
switch ($Request.Query.Action) {
2222
'Create' {
23+
$BlockList = @(
24+
'e9a7fea1-1cc0-4cd9-a31b-9137ca5deedd', # eM Client
25+
'ff8d92dc-3d82-41d6-bcbd-b9174d163620', # PerfectData Software
26+
'a245e8c0-b53c-4b67-9b45-751d1dff8e6b', # Newsletter Software Supermailer
27+
'b15665d9-eda6-4092-8539-0eec376afd59', # rclone
28+
'a43e5392-f48b-46a4-a0f1-098b5eeb4757', # CloudSponge
29+
'caffae8c-0882-4c81-9a27-d1803af53a40' # SigParser
30+
)
2331
$Action = 'Create'
32+
2433
if ($Request.Query.AppId -match '^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$') {
25-
$Body = @{
26-
'appId' = $Request.Query.AppId
27-
} | ConvertTo-Json -Compress
28-
try {
29-
$ServicePrincipal = New-GraphPostRequest -Uri 'https://graph.microsoft.com/beta/servicePrincipals' -tenantid $TenantFilter -type POST -body $Body -NoAuthCheck $true
30-
$Results = "Created service principal for $($ServicePrincipal.displayName) ($($ServicePrincipal.appId))"
31-
} catch {
32-
$Results = "Unable to create service principal: $($_.Exception.Message)"
34+
35+
if ($BlockList -contains $Request.Query.AppId) {
36+
$Results = 'Service Principal creation is blocked for this AppId'
3337
$Success = $false
38+
} else {
39+
$Body = @{
40+
'appId' = $Request.Query.AppId
41+
} | ConvertTo-Json -Compress
42+
try {
43+
$ServicePrincipal = New-GraphPostRequest -Uri 'https://graph.microsoft.com/beta/servicePrincipals' -tenantid $TenantFilter -type POST -body $Body -NoAuthCheck $true
44+
$Results = "Created service principal for $($ServicePrincipal.displayName) ($($ServicePrincipal.appId))"
45+
} catch {
46+
$Results = "Unable to create service principal: $($_.Exception.Message)"
47+
$Success = $false
48+
}
3449
}
3550
} else {
3651
$Results = 'Invalid AppId'

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Application Approval/Invoke-ExecAddMultiTenantApp.ps1

Lines changed: 53 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -12,51 +12,66 @@ function Invoke-ExecAddMultiTenantApp {
1212
$APIName = $Request.Params.CIPPEndpoint
1313
$Headers = $Request.Headers
1414
Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug'
15-
$DelegateResources = $request.body.permissions | Where-Object -Property origin -EQ 'Delegated' | ForEach-Object { @{ id = $_.id; type = 'Scope' } }
16-
$DelegateResourceAccess = @{ ResourceAppId = '00000003-0000-0000-c000-000000000000'; resourceAccess = $DelegateResources }
17-
$ApplicationResources = $request.body.permissions | Where-Object -Property origin -EQ 'Application' | ForEach-Object { @{ id = $_.id; type = 'Role' } }
18-
$ApplicationResourceAccess = @{ ResourceAppId = '00000003-0000-0000-c000-000000000000'; resourceAccess = $ApplicationResources }
1915

20-
$Results = try {
21-
if ($Request.Body.CopyPermissions -eq $true) {
22-
$Command = 'ExecApplicationCopy'
23-
} else {
24-
$Command = 'ExecAddMultiTenantApp'
25-
}
26-
if ('allTenants' -in $Request.Body.tenantFilter.value) {
27-
$TenantFilter = (Get-Tenants).defaultDomainName
28-
} else {
29-
$TenantFilter = $Request.Body.tenantFilter.value
30-
}
16+
if ($Request.Body.configMode -eq 'manual') {
17+
$DelegateResources = $request.body.permissions | Where-Object -Property origin -EQ 'Delegated' | ForEach-Object { @{ id = $_.id; type = 'Scope' } }
18+
$DelegateResourceAccess = @{ ResourceAppId = '00000003-0000-0000-c000-000000000000'; resourceAccess = $DelegateResources }
19+
$ApplicationResources = $request.body.permissions | Where-Object -Property origin -EQ 'Application' | ForEach-Object { @{ id = $_.id; type = 'Role' } }
20+
$ApplicationResourceAccess = @{ ResourceAppId = '00000003-0000-0000-c000-000000000000'; resourceAccess = $ApplicationResources }
21+
22+
$Results = try {
23+
if ($Request.Body.CopyPermissions -eq $true) {
24+
$Command = 'ExecApplicationCopy'
25+
} else {
26+
$Command = 'ExecAddMultiTenantApp'
27+
}
28+
if ('allTenants' -in $Request.Body.tenantFilter.value) {
29+
$TenantFilter = (Get-Tenants).defaultDomainName
30+
} else {
31+
$TenantFilter = $Request.Body.tenantFilter.value
32+
}
3133

32-
$TenantCount = ($TenantFilter | Measure-Object).Count
33-
$Queue = New-CippQueueEntry -Name 'Application Approval' -TotalTasks $TenantCount
34-
foreach ($Tenant in $TenantFilter) {
35-
try {
36-
$InputObject = @{
37-
OrchestratorName = 'ExecMultiTenantAppOrchestrator'
38-
Batch = @([pscustomobject]@{
39-
FunctionName = $Command
40-
Tenant = $tenant
41-
AppId = $Request.Body.AppId
42-
applicationResourceAccess = $ApplicationResourceAccess
43-
delegateResourceAccess = $DelegateResourceAccess
44-
QueueId = $Queue.RowKey
45-
})
46-
SkipLog = $true
34+
$TenantCount = ($TenantFilter | Measure-Object).Count
35+
$Queue = New-CippQueueEntry -Name 'Application Approval' -TotalTasks $TenantCount
36+
foreach ($Tenant in $TenantFilter) {
37+
try {
38+
$InputObject = @{
39+
OrchestratorName = 'ExecMultiTenantAppOrchestrator'
40+
Batch = @([pscustomobject]@{
41+
FunctionName = $Command
42+
Tenant = $tenant
43+
AppId = $Request.Body.AppId
44+
applicationResourceAccess = $ApplicationResourceAccess
45+
delegateResourceAccess = $DelegateResourceAccess
46+
QueueId = $Queue.RowKey
47+
})
48+
SkipLog = $true
49+
}
50+
$null = Start-NewOrchestration -FunctionName 'CIPPOrchestrator' -InputObject ($InputObject | ConvertTo-Json -Depth 5 -Compress)
51+
"Queued application to tenant $Tenant. See the logbook for deployment details"
52+
} catch {
53+
"Error queuing application to tenant $Tenant - $($_.Exception.Message)"
4754
}
48-
$null = Start-NewOrchestration -FunctionName 'CIPPOrchestrator' -InputObject ($InputObject | ConvertTo-Json -Depth 5 -Compress)
49-
"Queued application to tenant $Tenant. See the logbook for deployment details"
50-
} catch {
51-
"Error queuing application to tenant $Tenant - $($_.Exception.Message)"
5255
}
56+
$StatusCode = [HttpStatusCode]::OK
57+
} catch {
58+
$ErrorMsg = Get-NormalizedError -message $($_.Exception.Message)
59+
$Results = "Function Error: $ErrorMsg"
60+
$StatusCode = [HttpStatusCode]::BadRequest
5361
}
62+
} elseif ($Request.Body.configMode -eq 'template') {
63+
Write-Information 'Application Approval - Template Mode'
64+
Write-Information ($Request.Body | ConvertTo-Json -Depth 5)
65+
66+
67+
68+
69+
70+
71+
$Results = 'Deploying {0} to {1}' -f $Request.Body.selectedTemplate.label, ($Request.Body.tenantFilter.label -join ', ')
5472
$StatusCode = [HttpStatusCode]::OK
55-
} catch {
56-
$ErrorMsg = Get-NormalizedError -message $($_.Exception.Message)
57-
$Results = "Function Error: $ErrorMsg"
58-
$StatusCode = [HttpStatusCode]::BadRequest
5973
}
74+
6075
# Associate values to output bindings by calling 'Push-OutputBinding'.
6176
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
6277
StatusCode = $StatusCode

0 commit comments

Comments
 (0)