Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Modules/CIPPCore/Public/Add-CIPPDelegatedPermission.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ function Add-CIPPDelegatedPermission {
$OldScope = ($CurrentDelegatedScopes | Where-Object -Property Resourceid -EQ $svcPrincipalId.id)

if (!$OldScope) {
if ([string]::IsNullOrEmpty($NewScope) -or $NewScope -eq ' ') {
$Results.add("No delegated permissions to add for $($svcPrincipalId.displayName)")
continue
}
try {
$Createbody = @{
clientId = $ourSVCPrincipal.id
Expand Down Expand Up @@ -147,6 +151,13 @@ function Add-CIPPDelegatedPermission {
$Results.add("All delegated permissions exist for $($svcPrincipalId.displayName)")
continue
}

if ([string]::IsNullOrEmpty($NewScope) -or $NewScope -eq ' ') {
# No permissions to update
$Results.add("No delegated permissions to update for $($svcPrincipalId.displayName)")
continue
}

$Patchbody = @{
scope = "$NewScope"
} | ConvertTo-Json -Compress
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
using namespace System.Net

Function Invoke-ExecModifyCalPerms {
<#
.FUNCTIONALITY
Entrypoint
.ROLE
Exchange.Calendar.ReadWrite
#>
[CmdletBinding()]
param($Request, $TriggerMetadata)

$APIName = $Request.Params.CIPPEndpoint
Write-LogMessage -headers $Request.Headers -API $APINAME-message 'Accessed this API' -Sev 'Debug'

$Username = $request.body.userID
$Tenantfilter = $request.body.tenantfilter
$Permissions = $request.body.permissions

Write-LogMessage -headers $Request.Headers -API $APINAME-message "Processing request for user: $Username, tenant: $Tenantfilter" -Sev 'Debug'

if ($username -eq $null) {
Write-LogMessage -headers $Request.Headers -API $APINAME-message 'Username is null' -Sev 'Error'
$body = [pscustomobject]@{'Results' = @('Username is required') }
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = [HttpStatusCode]::BadRequest
Body = $Body
})
return
}

try {
$userid = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/$($username)" -tenantid $Tenantfilter).id
Write-LogMessage -headers $Request.Headers -API $APINAME-message "Retrieved user ID: $userid" -Sev 'Debug'
}
catch {
Write-LogMessage -headers $Request.Headers -API $APINAME-message "Failed to get user ID: $($_.Exception.Message)" -Sev 'Error'
$body = [pscustomobject]@{'Results' = @("Failed to get user ID: $($_.Exception.Message)") }
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = [HttpStatusCode]::NotFound
Body = $Body
})
return
}

$Results = [System.Collections.ArrayList]::new()
$HasErrors = $false

# Convert permissions to array format if it's an object with numeric keys
if ($Permissions -is [PSCustomObject]) {
if ($Permissions.PSObject.Properties.Name -match '^\d+$') {
$Permissions = $Permissions.PSObject.Properties.Value
}
else {
$Permissions = @($Permissions)
}
}

Write-LogMessage -headers $Request.Headers -API $APINAME-message "Processing $($Permissions.Count) permission entries" -Sev 'Debug'

foreach ($Permission in $Permissions) {
Write-LogMessage -headers $Request.Headers -API $APINAME-message "Processing permission: $($Permission | ConvertTo-Json)" -Sev 'Debug'

$PermissionLevel = $Permission.PermissionLevel.value ?? $Permission.PermissionLevel
$Modification = $Permission.Modification
$CanViewPrivateItems = $Permission.CanViewPrivateItems ?? $false

Write-LogMessage -headers $Request.Headers -API $APINAME-message "Permission Level: $PermissionLevel, Modification: $Modification, CanViewPrivateItems: $CanViewPrivateItems" -Sev 'Debug'

# Handle UserID as array or single value
$TargetUsers = @($Permission.UserID | ForEach-Object { $_.value ?? $_ })

Write-LogMessage -headers $Request.Headers -API $APINAME-message "Target Users: $($TargetUsers -join ', ')" -Sev 'Debug'

foreach ($TargetUser in $TargetUsers) {
try {
Write-LogMessage -headers $Request.Headers -API $APINAME-message "Processing target user: $TargetUser" -Sev 'Debug'

if ($Modification -eq 'Remove') {
try {
$CalPerms = New-ExoRequest -Anchor $username -tenantid $Tenantfilter -cmdlet 'Remove-MailboxFolderPermission' -cmdParams @{
Identity = "$($userid):\Calendar"
User = $TargetUser
Confirm = $false
}
$null = $results.Add("Removed $($TargetUser) from $($username) Calendar permissions")
}
catch {
$null = $results.Add("No existing permissions to remove for $($TargetUser)")
}
}
else {
Write-LogMessage -headers $Request.Headers -API $APINAME-message "Setting permissions with AccessRights: $PermissionLevel" -Sev 'Debug'

$cmdParams = @{
Identity = "$($userid):\Calendar"
User = $TargetUser
AccessRights = $PermissionLevel
Confirm = $false
}

if ($CanViewPrivateItems) {
$cmdParams['SharingPermissionFlags'] = 'Delegate,CanViewPrivateItems'
}

try {
# Try Add first
$CalPerms = New-ExoRequest -Anchor $username -tenantid $Tenantfilter -cmdlet 'Add-MailboxFolderPermission' -cmdParams $cmdParams
$null = $results.Add("Granted $($TargetUser) $($PermissionLevel) access to $($username) Calendar$($CanViewPrivateItems ? ' with access to private items' : '')")
}
catch {
# If Add fails, try Set
$CalPerms = New-ExoRequest -Anchor $username -tenantid $Tenantfilter -cmdlet 'Set-MailboxFolderPermission' -cmdParams $cmdParams
$null = $results.Add("Updated $($TargetUser) $($PermissionLevel) access to $($username) Calendar$($CanViewPrivateItems ? ' with access to private items' : '')")
}
}
Write-LogMessage -headers $Request.Headers -API $APINAME-message "Successfully executed $($PermissionLevel) permission modification for $($TargetUser) on $($username)" -Sev 'Info' -tenant $TenantFilter
}
catch {
$HasErrors = $true
Write-LogMessage -headers $Request.Headers -API $APINAME-message "Could not execute $($PermissionLevel) permission modification for $($TargetUser) on $($username). Error: $($_.Exception.Message)" -Sev 'Error' -tenant $TenantFilter
$null = $results.Add("Could not execute $($PermissionLevel) permission modification for $($TargetUser) on $($username). Error: $($_.Exception.Message)")
}
}
}

if ($results.Count -eq 0) {
Write-LogMessage -headers $Request.Headers -API $APINAME-message 'No results were generated from the operation' -Sev 'Warning'
$null = $results.Add('No results were generated from the operation. Please check the logs for more details.')
$HasErrors = $true
}

$body = [pscustomobject]@{'Results' = @($results) }

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = if ($HasErrors) { [HttpStatusCode]::InternalServerError } else { [HttpStatusCode]::OK }
Body = $Body
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
using namespace System.Net

Function Invoke-ExecModifyMBPerms {
<#
.FUNCTIONALITY
Entrypoint
.ROLE
Exchange.Mailbox.ReadWrite
#>
[CmdletBinding()]
param($Request, $TriggerMetadata)

$APIName = $Request.Params.CIPPEndpoint
Write-LogMessage -headers $Request.Headers -API $APINAME-message 'Accessed this API' -Sev 'Debug'

$Username = $request.body.userID
$Tenantfilter = $request.body.tenantfilter
$Permissions = $request.body.permissions

if ($username -eq $null) { exit }

$userid = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/$($username)" -tenantid $Tenantfilter).id
$Results = [System.Collections.ArrayList]::new()

# Convert permissions to array format if it's an object with numeric keys
if ($Permissions -is [PSCustomObject]) {
if ($Permissions.PSObject.Properties.Name -match '^\d+$') {
$Permissions = $Permissions.PSObject.Properties.Value
}
else {
$Permissions = @($Permissions)
}
}

foreach ($Permission in $Permissions) {
$PermissionLevel = $Permission.PermissionLevel
$Modification = $Permission.Modification
$AutoMap = if ($Permission.PSObject.Properties.Name -contains 'AutoMap') { $Permission.AutoMap } else { $true }

# Handle UserID as array of objects or single value
$TargetUsers = if ($Permission.UserID -is [array]) {
$Permission.UserID | ForEach-Object { $_.value }
}
else {
@($Permission.UserID)
}

foreach ($TargetUser in $TargetUsers) {
try {
switch ($PermissionLevel) {
'FullAccess' {
if ($Modification -eq 'Remove') {
$MailboxPerms = New-ExoRequest -Anchor $username -tenantid $Tenantfilter -cmdlet 'Remove-mailboxpermission' -cmdParams @{
Identity = $userid
user = $TargetUser
accessRights = @('FullAccess')
Confirm = $false
}
$null = $results.Add("Removed $($TargetUser) from $($username) Shared Mailbox permissions")
}
else {
$MailboxPerms = New-ExoRequest -Anchor $username -tenantid $Tenantfilter -cmdlet 'Add-MailboxPermission' -cmdParams @{
Identity = $userid
user = $TargetUser
accessRights = @('FullAccess')
automapping = $AutoMap
Confirm = $false
}
$null = $results.Add("Granted $($TargetUser) access to $($username) Mailbox with automapping set to $($AutoMap)")
}
}
'SendAs' {
if ($Modification -eq 'Remove') {
$MailboxPerms = New-ExoRequest -Anchor $username -tenantid $Tenantfilter -cmdlet 'Remove-RecipientPermission' -cmdParams @{
Identity = $userid
Trustee = $TargetUser
accessRights = @('SendAs')
Confirm = $false
}
$null = $results.Add("Removed $($TargetUser) from $($username) with Send As permissions")
}
else {
$MailboxPerms = New-ExoRequest -Anchor $username -tenantid $Tenantfilter -cmdlet 'Add-RecipientPermission' -cmdParams @{
Identity = $userid
Trustee = $TargetUser
accessRights = @('SendAs')
Confirm = $false
}
$null = $results.Add("Granted $($TargetUser) access to $($username) with Send As permissions")
}
}
'SendOnBehalf' {
if ($Modification -eq 'Remove') {
$MailboxPerms = New-ExoRequest -Anchor $username -tenantid $Tenantfilter -cmdlet 'Set-Mailbox' -cmdParams @{
Identity = $userid
GrantSendonBehalfTo = @{
'@odata.type' = '#Exchange.GenericHashTable'
remove = $TargetUser
}
Confirm = $false
}
$null = $results.Add("Removed $($TargetUser) from $($username) Send on Behalf Permissions")
}
else {
$MailboxPerms = New-ExoRequest -Anchor $username -tenantid $Tenantfilter -cmdlet 'Set-Mailbox' -cmdParams @{
Identity = $userid
GrantSendonBehalfTo = @{
'@odata.type' = '#Exchange.GenericHashTable'
add = $TargetUser
}
Confirm = $false
}
$null = $results.Add("Granted $($TargetUser) access to $($username) with Send On Behalf Permissions")
}
}
}
Write-LogMessage -headers $Request.Headers -API $APINAME-message "Executed $($PermissionLevel) permission modification for $($TargetUser) on $($username)" -Sev 'Info' -tenant $TenantFilter
}
catch {
Write-LogMessage -headers $Request.Headers -API $APINAME-message "Could not execute $($PermissionLevel) permission modification for $($TargetUser) on $($username)" -Sev 'Error' -tenant $TenantFilter
$null = $results.Add("Could not execute $($PermissionLevel) permission modification for $($TargetUser) on $($username). Error: $($_.Exception.Message)")
}
}
}

$body = [pscustomobject]@{'Results' = @($results) }

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = [HttpStatusCode]::OK
Body = $Body
})
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using namespace System.Net

Function Invoke-AddTransportRule {
function Invoke-AddTransportRule {
<#
.FUNCTIONALITY
Entrypoint
Entrypoint,AnyTenant
.ROLE
Exchange.TransportRule.ReadWrite
#>
Expand All @@ -17,6 +17,15 @@ Function Invoke-AddTransportRule {
$RequestParams = $Request.Body.PowerShellCommand | ConvertFrom-Json | Select-Object -Property * -ExcludeProperty GUID, HasSenderOverride, ExceptIfHasSenderOverride, ExceptIfMessageContainsDataClassifications, MessageContainsDataClassifications

$Tenants = ($Request.body.selectedTenants).value

$AllowedTenants = Test-CippAccess -Request $Request -TenantList

if ($AllowedTenants -ne 'AllTenants') {
$AllTenants = Get-Tenants -IncludeErrors
$AllowedTenantList = $AllTenants | Where-Object { $_.customerId -in $AllowedTenants }
$Tenants = $Tenants | Where-Object { $_ -in $AllowedTenantList.defaultDomainName }
}

$Result = foreach ($tenantFilter in $tenants) {
$Existing = New-ExoRequest -ErrorAction SilentlyContinue -tenantid $tenantFilter -cmdlet 'Get-TransportRule' -useSystemMailbox $true | Where-Object -Property Identity -EQ $RequestParams.name
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,8 @@ function Invoke-AddStandardsTemplate {
RowKey = "$GUID"
PartitionKey = 'StandardsTemplateV2'
GUID = "$GUID"

}
Write-LogMessage -headers $Request.Headers -API $APINAME -message "Created CA Template $($Request.body.name) with GUID $GUID" -Sev 'Debug'
Write-LogMessage -headers $Request.Headers -API $APINAME -message "Standards Template $($Request.body.templateName) with GUID $GUID added/edited." -Sev 'Info'
$body = [pscustomobject]@{'Results' = 'Successfully added template'; Metadata = @{id = $GUID } }

# Associate values to output bindings by calling 'Push-OutputBinding'.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using namespace System.Net

Function Invoke-ListStandardsCompare {
function Invoke-ListStandardsCompare {
<#
.FUNCTIONALITY
Entrypoint
Expand All @@ -10,7 +10,13 @@ Function Invoke-ListStandardsCompare {
[CmdletBinding()]
param($Request, $TriggerMetadata)


$Table = Get-CIPPTable -TableName 'CippStandardsReports'
$TenantFilter = $Request.Query.tenantFilter
if ($TenantFilter) {
$Table.Filter = "RowKey eq '{0}'" -f $TenantFilter
}

$Results = Get-CIPPAzDataTableEntity @Table

#in the results we have objects starting with "standards." All these have to be converted from JSON. Do not do this is its a boolean
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using namespace System.Net

Function Invoke-listStandardTemplates {
function Invoke-listStandardTemplates {
<#
.FUNCTIONALITY
Entrypoint,AnyTenant
Expand Down Expand Up @@ -29,7 +29,16 @@ Function Invoke-listStandardTemplates {
return
}
$Data | Add-Member -NotePropertyName 'GUID' -NotePropertyValue $_.GUID -Force
if ($Data.excludedTenants) { $Data.excludedTenants = @($Data.excludedTenants) }

if (!$Data.excludedTenants) {
$Data | Add-Member -NotePropertyName 'excludedTenants' -NotePropertyValue @() -Force
}

if ($Data.excludedTenants -and $Data.excludedTenants -ne 'excludedTenants') {
$Data.excludedTenants = @($Data.excludedTenants)
} else {
$Data.excludedTenants = @()
}
$Data
} | Sort-Object -Property templateName

Expand Down
Loading