Skip to content

Commit 3997863

Browse files
authored
Merge pull request #564 from KelvinTegelaar/dev
[pull] dev from KelvinTegelaar:dev
2 parents ff48a6b + d6e7c52 commit 3997863

File tree

3 files changed

+113
-24
lines changed

3 files changed

+113
-24
lines changed

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ function Invoke-ExecApiClient {
148148
if (!$Client) {
149149
$Results = @{
150150
resultText = 'API client not found'
151-
severity = 'error'
151+
state = 'error'
152152
}
153153
} else {
154154
$ApiConfig = New-CIPPAPIConfig -ResetSecret -AppId $Request.Body.ClientId -Headers $Request.Headers

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Setup/Invoke-ExecUpdateRefreshToken.ps1

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Function Invoke-ExecUpdateRefreshToken {
1+
function Invoke-ExecUpdateRefreshToken {
22
<#
33
.FUNCTIONALITY
44
Entrypoint,AnyTenant
@@ -49,16 +49,21 @@ Function Invoke-ExecUpdateRefreshToken {
4949
$TenantName = $request.body.tenantId
5050
}
5151
$Results = @{
52-
'message' = "Successfully updated the credentials for $($TenantName). You may continue to the next step, or add additional tenants if required."
53-
'severity' = 'success'
52+
'resultText' = "Successfully updated the credentials for $($TenantName). You may continue to the next step, or add additional tenants if required."
53+
'state' = 'success'
5454
}
5555
} catch {
56-
$Results = [pscustomobject]@{'Results' = "Failed. $($_.InvocationInfo.ScriptLineNumber): $($_.Exception.message)"; severity = 'failed' }
57-
}
56+
$Results = [pscustomobject]@{
57+
'Results' = @{
58+
resultText = "Failed. $($_.InvocationInfo.ScriptLineNumber): $($_.Exception.message)"
59+
state = 'failed'
60+
}
61+
}
5862

59-
return ([HttpResponseContext]@{
60-
StatusCode = [HttpStatusCode]::OK
61-
Body = $Results
62-
})
63+
return ([HttpResponseContext]@{
64+
StatusCode = [HttpStatusCode]::OK
65+
Body = $Results
66+
})
6367

68+
}
6469
}

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

Lines changed: 98 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ function Invoke-ExecCreateAppTemplate {
1111
param($Request, $TriggerMetadata)
1212

1313
$APIName = $TriggerMetadata.FunctionName
14-
Write-LogMessage -user $Request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug'
14+
Write-LogMessage -headers $Request.headers -API $APINAME -message 'Accessed this API' -Sev 'Debug'
1515

1616
try {
1717
$TenantFilter = $Request.Body.TenantFilter
@@ -47,7 +47,7 @@ function Invoke-ExecCreateAppTemplate {
4747
$RequiredResourceAccess = @()
4848
}
4949
} catch {
50-
Write-LogMessage -user $Request.headers.'x-ms-client-principal' -API $APINAME -message "Could not retrieve app registration for $AppId - will extract from service principal" -Sev 'Warning'
50+
Write-LogMessage -headers $Request.headers -API $APINAME -message "Could not retrieve app registration for $AppId - will extract from service principal" -Sev 'Warning'
5151
$RequiredResourceAccess = @()
5252
}
5353

@@ -56,16 +56,91 @@ function Invoke-ExecCreateAppTemplate {
5656
$Permissions = $RequiredResourceAccess
5757
} else {
5858
# No permissions found - warn the user
59-
Write-LogMessage -user $Request.headers.'x-ms-client-principal' -API $APINAME -message "No permissions found for $AppId. The app registration may not have configured API permissions." -Sev 'Warning'
59+
Write-LogMessage -headers $Request.headers -API $APINAME -message "No permissions found for $AppId. The app registration may not have configured API permissions." -Sev 'Warning'
6060
$Permissions = @()
6161
}
6262
} else {
6363
# For app registrations (applications)
64-
$AppDetails = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/applications?`$filter=appId eq '$AppId'&`$select=id,appId,displayName,requiredResourceAccess" -tenantid $TenantFilter
65-
if (-not $AppDetails -or $AppDetails.Count -eq 0) {
66-
throw "Application not found for AppId: $AppId"
64+
$App = New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/applications(appId='$AppId')" -tenantid $TenantFilter
65+
if (-not $App -or $App.Count -eq 0) {
66+
throw "App registration not found for AppId: $AppId"
6767
}
68-
$App = $AppDetails[0]
68+
69+
$Tenant = Get-Tenants -TenantFilter $TenantFilter
70+
if ($Tenant.customerId -ne $env:TenantID) {
71+
$ExistingApp = New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/applications?`$filter=displayName eq '$DisplayName'" -tenantid $env:TenantID -NoAuthCheck $true -AsApp $true
72+
73+
if ($ExistingApp) {
74+
Write-Information "App Registration $AppId already exists in partner tenant"
75+
$AppId = $ExistingApp.appId
76+
$App = $ExistingApp
77+
Write-LogMessage -headers $Request.headers -API $APINAME -message "App Registration $($AppDetails.displayName) already exists in partner tenant" -Sev 'Info'
78+
} else {
79+
Write-Information "Copying App Registration $AppId from customer tenant $TenantFilter to partner tenant"
80+
$PropertiesToRemove = @(
81+
'appId'
82+
'id'
83+
'createdDateTime'
84+
'deletedDateTime'
85+
'publisherDomain'
86+
'servicePrincipalLockConfiguration'
87+
'identifierUris'
88+
'applicationIdUris'
89+
'keyCredentials'
90+
'passwordCredentials'
91+
'isDisabled'
92+
)
93+
$AppCopyBody = $App | Select-Object -Property * -ExcludeProperty $PropertiesToRemove
94+
# Remove any null properties
95+
$NullProperties = [System.Collections.Generic.List[string]]::new()
96+
foreach ($Property in $AppCopyBody.PSObject.Properties.Name) {
97+
if ($null -eq $AppCopyBody.$Property -or $AppCopyBody.$Property -eq '' -or !$AppCopyBody.$Property) {
98+
Write-Information "Removing null property $Property from app copy body"
99+
$NullProperties.Add($Property)
100+
}
101+
}
102+
$AppCopyBody = $AppCopyBody | Select-Object -Property * -ExcludeProperty $NullProperties
103+
if ($AppCopyBody.signInAudience -eq 'AzureADMyOrg') {
104+
# Enterprise apps cannot be copied to another tenant
105+
$AppCopyBody.signInAudience = 'AzureADMultipleOrgs'
106+
}
107+
if ($AppCopyBody.web -and $AppCopyBody.web.redirectUris) {
108+
# Remove redirect URI settings if property exists
109+
$AppCopyBody.web.PSObject.Properties.Remove('redirectUriSettings')
110+
}
111+
if ($AppCopyBody.api.oauth2PermissionScopes) {
112+
$AppCopyBody.api.oauth2PermissionScopes = @(foreach ($Scope in $AppCopyBody.api.oauth2PermissionScopes) {
113+
$Scope | Select-Object * -ExcludeProperty 'isPrivate'
114+
})
115+
}
116+
if ($AppCopyBody.appRoles) {
117+
$AppCopyBody.appRoles = @(foreach ($Role in $AppCopyBody.api.appRoles) {
118+
$Role | Select-Object * -ExcludeProperty 'isPreAuthorizationRequired', 'isPrivate'
119+
})
120+
}
121+
if ($AppCopyBody.api -and $AppCopyBody.api.tokenEncryptionSetting) {
122+
# Remove token encryption settings if property exists
123+
$AppCopyBody.api.PSObject.Properties.Remove('tokenEncryptionSetting')
124+
}
125+
126+
$NewApp = New-GraphPOSTRequest -uri 'https://graph.microsoft.com/v1.0/applications' -tenantid $env:TenantID -NoAuthCheck $true -AsApp $true -type POST -body ($AppCopyBody | ConvertTo-Json -Depth 10)
127+
128+
if (-not $NewApp) {
129+
throw 'Failed to copy app registration to partner tenant'
130+
}
131+
132+
Write-Information "App Registration copied. New AppId: $($NewApp.appId)"
133+
$App = $NewApp
134+
$AppId = $NewApp.appId
135+
Write-Information "Creating service principal for AppId: $AppId in partner tenant"
136+
$Body = @{
137+
appId = $AppId
138+
}
139+
$NewSP = New-GraphPOSTRequest -uri 'https://graph.microsoft.com/v1.0/servicePrincipals' -tenantid $env:TenantID -NoAuthCheck $true -AsApp $true -type POST -body ($Body | ConvertTo-Json -Depth 10)
140+
Write-LogMessage -headers $Request.headers -API $APINAME -message "App Registration $($AppDetails.displayName) copied to partner tenant" -Sev 'Info'
141+
}
142+
}
143+
69144
$Permissions = if ($App.requiredResourceAccess) { $App.requiredResourceAccess } else { @() }
70145
}
71146

@@ -114,7 +189,7 @@ function Invoke-ExecCreateAppTemplate {
114189
}
115190

116191
Add-CIPPAzDataTableEntity @PermissionsTable -Entity $PermissionEntity -Force
117-
Write-LogMessage -user $Request.headers.'x-ms-client-principal' -API $APINAME -message "Permission set created with ID: $PermissionSetId for $($Permissions.Count) resource(s)" -Sev 'Info'
192+
Write-LogMessage -headers $Request.headers -API $APINAME -message "Permission set created with ID: $PermissionSetId for $($Permissions.Count) resource(s)" -Sev 'Info'
118193
}
119194

120195
# Create the template
@@ -156,24 +231,33 @@ function Invoke-ExecCreateAppTemplate {
156231
}
157232

158233
$Message = "Template created: $DisplayName with $PermissionCount permission(s)"
159-
Write-LogMessage -user $Request.headers.'x-ms-client-principal' -API $APINAME -message $Message -Sev 'Info'
234+
Write-LogMessage -headers $Request.headers -API $APINAME -message $Message -Sev 'Info'
160235

161236
$Body = @{
162-
Results = $Message
163-
TemplateId = $TemplateId
237+
Results = @{'resultText' = $Message; 'state' = 'success' }
238+
Metadata = @{
239+
TemplateId = $TemplateId
240+
SourceTenant = $TenantFilter
241+
}
164242
}
165243
$StatusCode = [HttpStatusCode]::OK
166244
} catch {
167245
$ErrorMessage = Get-NormalizedError -Message $_.Exception.Message
168-
Write-LogMessage -user $Request.headers.'x-ms-client-principal' -API $APINAME -message "Failed to create template: $ErrorMessage" -Sev 'Error'
246+
Write-LogMessage -headers $Request.headers -API $APINAME -message "Failed to create template: $ErrorMessage" -Sev 'Error' -LogData (Get-CippException -Exception $_)
247+
Write-Warning "Failed to create template: $ErrorMessage"
248+
Write-Information $_.InvocationInfo.PositionMessage
169249

170250
$Body = @{
171-
Results = "Failed to create template: $ErrorMessage"
251+
Results = @(@{
252+
resultText = "Failed to create template: $ErrorMessage"
253+
state = 'error'
254+
details = Get-CippException -Exception $_
255+
})
172256
}
173257
$StatusCode = [HttpStatusCode]::BadRequest
174258
}
175259

176-
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
260+
return ([HttpResponseContext]@{
177261
StatusCode = $StatusCode
178262
Body = ($Body | ConvertTo-Json -Depth 10)
179263
})

0 commit comments

Comments
 (0)