Skip to content

Commit 1871edc

Browse files
committed
new application actions
1 parent fff1b07 commit 1871edc

File tree

3 files changed

+141
-4
lines changed

3 files changed

+141
-4
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ function Invoke-ExecServicePrincipals {
33
.FUNCTIONALITY
44
Entrypoint,AnyTenant
55
.ROLE
6-
CIPP.Core.ReadWrite
6+
Tenant.Application.ReadWrite
77
#>
88
[CmdletBinding()]
99
param($Request, $TriggerMetadata)
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
function Invoke-ExecApplication {
2+
<#
3+
.FUNCTIONALITY
4+
Entrypoint
5+
.ROLE
6+
Tenant.Application.ReadWrite
7+
#>
8+
[CmdletBinding()]
9+
param($Request, $TriggerMetadata)
10+
11+
$APIName = $Request.Params.CIPPEndpoint
12+
$Headers = $Request.Headers
13+
Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug'
14+
15+
$ValidTypes = @('applications', 'servicePrincipals')
16+
$ValidActions = @('Update', 'Upsert', 'Delete', 'RemoveKey', 'RemovePassword')
17+
18+
$Id = $Request.Query.Id ?? $Request.Body.Id
19+
$Type = $Request.Query.Type ?? $Request.Body.Type
20+
if (-not $Id) {
21+
$AppId = $Request.Query.AppId ?? $Request.Body.AppId
22+
if (-not $AppId) {
23+
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
24+
StatusCode = [HttpStatusCode]::BadRequest
25+
Body = "Required parameter 'Id' or 'AppId' is missing"
26+
})
27+
return
28+
}
29+
$IdPath = "(appId='$AppId')"
30+
} else {
31+
$IdPath = "/$Id"
32+
}
33+
if ($Type -and $ValidTypes -notcontains $Type) {
34+
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
35+
StatusCode = [HttpStatusCode]::BadRequest
36+
Body = "Invalid Type specified. Valid types are: $($ValidTypes -join ', ')"
37+
})
38+
return
39+
}
40+
41+
$Uri = "https://graph.microsoft.com/beta/$($Type)$($IdPath)"
42+
$Action = $Request.Query.Action ?? $Request.Body.Action
43+
44+
if ($ValidActions -notcontains $Action) {
45+
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
46+
StatusCode = [HttpStatusCode]::BadRequest
47+
Body = "Invalid Action specified. Valid actions are: $($ValidActions -join ', ')"
48+
})
49+
return
50+
}
51+
52+
$PostParams = @{
53+
Uri = $Uri
54+
}
55+
56+
if ($Action -eq 'Delete') {
57+
$PostParams.Type = 'DELETE'
58+
}
59+
if ($Action -eq 'Update' -or $Action -eq 'Upsert') {
60+
$PostParams.Type = 'PATCH'
61+
}
62+
63+
if ($Action -eq 'Upsert') {
64+
$PostParams.AddedHeaders = @{
65+
'Prefer' = 'create-if-missing'
66+
}
67+
}
68+
69+
if ($Request.Body) {
70+
$PostParams.Body = $Request.Body.Payload | ConvertTo-Json -Compress
71+
}
72+
73+
$TenantFilter = $Request.Query.tenantFilter ?? $Request.Body.tenantFilter
74+
75+
try {
76+
if ($Action -eq 'RemoveKey' -or $Action -eq 'RemovePassword') {
77+
# Handle credential removal by patching the object
78+
$KeyIds = $Request.Body.KeyIds.value ?? $Request.Body.KeyIds
79+
if (-not $KeyIds -or $KeyIds.Count -eq 0) {
80+
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
81+
StatusCode = [HttpStatusCode]::BadRequest
82+
Body = "KeyIds parameter is required for $Action action"
83+
})
84+
return
85+
}
86+
87+
# Get the current application/service principal
88+
$CurrentObject = New-GraphGetRequest -Uri $Uri -tenantid $TenantFilter -AsApp $true
89+
90+
if ($Action -eq 'RemoveKey') {
91+
# Filter out the key credentials to remove
92+
$UpdatedKeyCredentials = $CurrentObject.keyCredentials | Where-Object { $_.keyId -notin $KeyIds }
93+
$PatchBody = @{
94+
keyCredentials = @($UpdatedKeyCredentials)
95+
}
96+
} else {
97+
# Filter out the password credentials to remove
98+
$UpdatedPasswordCredentials = $CurrentObject.passwordCredentials | Where-Object { $_.keyId -notin $KeyIds }
99+
$PatchBody = @{
100+
passwordCredentials = @($UpdatedPasswordCredentials)
101+
}
102+
}
103+
104+
# Update the object with the filtered credentials
105+
$null = New-GraphPOSTRequest -Uri $Uri -Type 'PATCH' -Body ($PatchBody | ConvertTo-Json -Depth 10) -tenantid $TenantFilter -AsApp $true
106+
107+
$Results = @{
108+
resultText = "Successfully removed $($KeyIds.Count) credential(s) from $Type"
109+
state = 'success'
110+
}
111+
} else {
112+
# Handle regular actions
113+
$null = New-GraphPOSTRequest @PostParams -tenantid $TenantFilter -AsApp $true
114+
$Results = @{
115+
resultText = "Successfully executed $Action on $Type with Id: $Id"
116+
state = 'success'
117+
}
118+
}
119+
120+
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
121+
StatusCode = [HttpStatusCode]::OK
122+
Body = @{ Results = $Results }
123+
})
124+
} catch {
125+
$Results = @{
126+
resultText = "Failed to execute $Action on $Type with Id: $Id. Error: $($_.Exception.Message)"
127+
state = 'error'
128+
}
129+
130+
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
131+
StatusCode = [HttpStatusCode]::InternalServerError
132+
Body = @{ Results = @($Results) }
133+
})
134+
}
135+
}

Modules/CIPPCore/Public/GraphHelper/New-GraphBulkRequest.ps1

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,21 @@ function New-GraphBulkRequest {
33
.FUNCTIONALITY
44
Internal
55
#>
6-
Param(
6+
param(
77
$tenantid,
88
$NoAuthCheck,
99
$scope,
1010
$asapp,
1111
$Requests,
12-
$NoPaginateIds = @()
12+
$NoPaginateIds = @(),
13+
[ValidateSet('v1.0', 'beta')]
14+
$Version = 'beta'
1315
)
1416

1517
if ($NoAuthCheck -or (Get-AuthorisedRequest -Uri $uri -TenantID $tenantid)) {
1618
$headers = Get-GraphToken -tenantid $tenantid -scope $scope -AsApp $asapp
1719

18-
$URL = 'https://graph.microsoft.com/beta/$batch'
20+
$URL = "https://graph.microsoft.com/$Version/`$batch"
1921

2022
# Track consecutive Graph API failures
2123
$TenantsTable = Get-CippTable -tablename Tenants

0 commit comments

Comments
 (0)