Skip to content

Commit 9d0c671

Browse files
committed
feat: custom data management
- Schema extensions
1 parent bd2afc2 commit 9d0c671

File tree

3 files changed

+357
-56
lines changed

3 files changed

+357
-56
lines changed

Config/schemaDefinitions.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[
2+
{
3+
"id": "cippUser",
4+
"description": "CIPP User Schema",
5+
"targetTypes": ["User"],
6+
"properties": [
7+
{ "name": "jitAdminEnabled", "type": "Boolean" },
8+
{ "name": "jitAdminExpiration", "type": "DateTime" },
9+
{ "name": "mailboxType", "type": "String" },
10+
{ "name": "archiveEnabled", "type": "Boolean" },
11+
{ "name": "autoExpandingArchiveEnabled", "type": "Boolean" },
12+
{ "name": "perUserMfaState", "type": "String" }
13+
],
14+
"status": "Available"
15+
}
16+
]
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
function Invoke-ExecCustomData {
2+
<#
3+
.FUNCTIONALITY
4+
Entrypoint,AnyTenant
5+
.ROLE
6+
CIPP.AppSettings.ReadWrite
7+
#>
8+
[CmdletBinding()]
9+
param($Request, $TriggerMetadata)
10+
11+
$Action = $Request.Query.Action ?? $Request.Body.Action
12+
$CustomDataTable = Get-CippTable -TableName 'CustomData'
13+
14+
Write-Information "Executing action '$Action'"
15+
16+
switch ($Action) {
17+
'ListSchemaExtensions' {
18+
try {
19+
$SchemaExtensions = Get-CIPPAzDataTableEntity @CustomDataTable -Filter "PartitionKey eq 'SchemaExtension'" | Select-Object -ExpandProperty JSON | ConvertFrom-Json
20+
if (!$SchemaExtensions) {
21+
$SchemaExtensions = Get-CIPPSchemaExtensions | Sort-Object id
22+
}
23+
$Body = @{
24+
Results = @($SchemaExtensions)
25+
}
26+
} catch {
27+
$Body = @{
28+
Results = @(
29+
@{
30+
state = 'error'
31+
resultText = "Failed to retrieve schema extensions: $($_.Exception.Message)"
32+
}
33+
)
34+
}
35+
}
36+
}
37+
'AddSchemaExtension' {
38+
try {
39+
$SchemaExtension = $Request.Body.schemaExtension
40+
if (!$SchemaExtension) {
41+
throw 'SchemaExtension data is missing in the request body.'
42+
}
43+
44+
$Entity = @{
45+
PartitionKey = 'SchemaExtension'
46+
RowKey = $SchemaExtension.id
47+
JSON = [string]($SchemaExtension | ConvertTo-Json -Depth 5 -Compress)
48+
}
49+
50+
Add-CIPPAzDataTableEntity @CustomDataTable -Entity $Entity -Force
51+
$SchemaExtensions = Get-CIPPSchemaExtensions | Where-Object { $_.id -eq $SchemaExtension.id }
52+
53+
$Body = @{
54+
Results = @{
55+
state = 'success'
56+
resultText = "Schema extension '$($SchemaExtension.id)' added successfully."
57+
}
58+
}
59+
} catch {
60+
$Body = @{
61+
Results = @(
62+
@{
63+
state = 'error'
64+
resultText = "Failed to add schema extension: $($_.Exception.Message)"
65+
}
66+
)
67+
}
68+
}
69+
}
70+
'DeleteSchema' {
71+
try {
72+
$SchemaId = $Request.Body.id
73+
if (!$SchemaId) {
74+
throw 'Schema ID is missing in the request body.'
75+
}
76+
77+
# Retrieve the schema extension entity
78+
$SchemaEntity = Get-CIPPAzDataTableEntity @CustomDataTable -Filter "PartitionKey eq 'SchemaExtension'" | Where-Object { $SchemaId -match $_.RowKey }
79+
if (!$SchemaEntity) {
80+
throw "Schema extension with ID '$SchemaId' not found."
81+
}
82+
83+
# Ensure the schema is in 'InDevelopment' state before deletion
84+
$SchemaDefinition = $SchemaEntity.JSON | ConvertFrom-Json
85+
if ($SchemaDefinition.status -ne 'InDevelopment') {
86+
throw "Schema extension '$SchemaId' cannot be deleted because it is not in 'InDevelopment' state."
87+
}
88+
89+
try {
90+
$null = New-GraphPOSTRequest -Type DELETE -Uri "https://graph.microsoft.com/v1.0/schemaExtensions/$SchemaId" -AsApp $true -NoAuthCheck $true -tenantid $env:TenantID -Verbose
91+
} catch {
92+
Write-Warning "Schema extension '$SchemaId' not found in Microsoft Graph."
93+
}
94+
95+
96+
# Delete the schema extension entity
97+
Remove-AzDataTableEntity @CustomDataTable -Entity $SchemaEntity
98+
99+
$Body = @{
100+
Results = @{
101+
state = 'success'
102+
resultText = "Schema extension '$SchemaId' deleted successfully."
103+
}
104+
}
105+
} catch {
106+
$Body = @{
107+
Results = @(
108+
@{
109+
state = 'error'
110+
resultText = "Failed to delete schema extension: $($_.Exception.Message)"
111+
}
112+
)
113+
}
114+
}
115+
}
116+
'AddSchemaProperty' {
117+
try {
118+
$SchemaId = $Request.Body.id
119+
$Name = $Request.Body.name
120+
$Type = $Request.Body.type
121+
$NewProperty = @{
122+
name = $Name
123+
type = $Type
124+
}
125+
if (!$SchemaId) {
126+
throw 'Schema ID is missing in the request body.'
127+
}
128+
if (!$Name -or !$Type) {
129+
throw 'Property data is missing or incomplete in the request body.'
130+
}
131+
132+
# Retrieve the schema extension entity
133+
$SchemaEntity = Get-CIPPAzDataTableEntity @CustomDataTable -Filter "PartitionKey eq 'SchemaExtension'" | Where-Object { $SchemaId -match $_.RowKey }
134+
if (!$SchemaEntity) {
135+
throw "Schema extension with ID '$SchemaId' not found."
136+
}
137+
138+
# Parse the schema definition
139+
$SchemaDefinition = $SchemaEntity.JSON | ConvertFrom-Json
140+
141+
if ($SchemaDefinition.status -eq 'Deprecated') {
142+
throw "Properties cannot be added to schema extension '$SchemaId' because it is in the 'Deprecated' state."
143+
}
144+
145+
# Check if the property already exists
146+
if ($SchemaDefinition.properties | Where-Object { $_.name -eq $NewProperty.name }) {
147+
throw "Property with name '$($NewProperty.name)' already exists in schema extension '$SchemaId'."
148+
}
149+
150+
# Add the new property
151+
$Properties = [System.Collections.Generic.List[object]]::new()
152+
foreach ($Property in $SchemaDefinition.properties) {
153+
$Properties.Add($Property)
154+
}
155+
$Properties.Add($NewProperty)
156+
$SchemaDefinition.properties = $Properties
157+
158+
# Update the schema extension entity
159+
$SchemaEntity.JSON = [string]($SchemaDefinition | ConvertTo-Json -Depth 5 -Compress)
160+
Add-CIPPAzDataTableEntity @CustomDataTable -Entity $SchemaEntity -Force
161+
try { $null = Get-CIPPSchemaExtensions } catch {}
162+
163+
$Body = @{
164+
Results = @{
165+
state = 'success'
166+
resultText = "Property '$($NewProperty.name)' added to schema extension '$SchemaId' successfully."
167+
}
168+
}
169+
} catch {
170+
$Body = @{
171+
Results = @(
172+
@{
173+
state = 'error'
174+
resultText = "Failed to add property to schema extension: $($_.Exception.Message)"
175+
}
176+
)
177+
}
178+
}
179+
}
180+
'ChangeSchemaState' {
181+
try {
182+
$SchemaId = $Request.Body.id
183+
$NewStatus = $Request.Body.status
184+
if (!$SchemaId) {
185+
throw 'Schema ID is missing in the request body.'
186+
}
187+
if (!$NewStatus) {
188+
throw 'New status is missing in the request body.'
189+
}
190+
191+
# Retrieve the schema extension entity
192+
$SchemaEntity = Get-CIPPAzDataTableEntity @CustomDataTable -Filter "PartitionKey eq 'SchemaExtension'" | Where-Object { $SchemaId -match $_.RowKey }
193+
if (!$SchemaEntity) {
194+
throw "Schema extension with ID '$SchemaId' not found."
195+
}
196+
197+
# Parse the schema definition
198+
$SchemaDefinition = $SchemaEntity.JSON | ConvertFrom-Json
199+
200+
# Check if the status is already the same
201+
if ($SchemaDefinition.status -eq $NewStatus) {
202+
throw "Schema extension '$SchemaId' is already in the '$NewStatus' state."
203+
}
204+
205+
# Update the status
206+
$SchemaDefinition.status = $NewStatus
207+
208+
# Update the schema extension entity
209+
$SchemaEntity.JSON = [string]($SchemaDefinition | ConvertTo-Json -Depth 5 -Compress)
210+
Add-CIPPAzDataTableEntity @CustomDataTable -Entity $SchemaEntity -Force
211+
$null = Get-CIPPSchemaExtensions
212+
213+
$Body = @{
214+
Results = @{
215+
state = 'success'
216+
resultText = "Schema extension '$SchemaId' status changed to '$NewStatus' successfully."
217+
}
218+
}
219+
} catch {
220+
$Body = @{
221+
Results = @(
222+
@{
223+
state = 'error'
224+
resultText = "Failed to change schema extension status: $($_.Exception.Message)"
225+
}
226+
)
227+
}
228+
}
229+
}
230+
default {
231+
$Body = @{
232+
Results = @(
233+
@{
234+
state = 'error'
235+
resultText = 'Invalid action specified.'
236+
}
237+
)
238+
}
239+
}
240+
}
241+
242+
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
243+
StatusCode = [HttpStatusCode]::OK
244+
Body = $Body
245+
})
246+
}

0 commit comments

Comments
 (0)