Skip to content

Commit f353f7b

Browse files
authored
Merge pull request #323 from KelvinTegelaar/dev
[pull] dev from KelvinTegelaar:dev
2 parents bc66656 + 92fb8a3 commit f353f7b

File tree

13 files changed

+264
-162
lines changed

13 files changed

+264
-162
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
function Get-CIPPAlertVulnerabilities {
2+
<#
3+
.FUNCTIONALITY
4+
Entrypoint
5+
#>
6+
[CmdletBinding()]
7+
Param (
8+
[Parameter(Mandatory = $false)]
9+
[Alias('input')]
10+
$InputValue,
11+
$TenantFilter
12+
)
13+
14+
try {
15+
$VulnerabilityRequest = New-GraphGetRequest -tenantid $TenantFilter -uri "https://api.securitycenter.microsoft.com/api/machines/SoftwareVulnerabilitiesByMachine?`$top=999&`$filter=cveId ne null" -scope 'https://api.securitycenter.microsoft.com/.default'
16+
17+
if ($VulnerabilityRequest) {
18+
$AlertData = [System.Collections.Generic.List[PSCustomObject]]::new()
19+
20+
# Group by CVE ID and create objects for each vulnerability
21+
$VulnerabilityGroups = $VulnerabilityRequest | Where-Object { $_.cveId } | Group-Object cveId
22+
23+
foreach ($Group in $VulnerabilityGroups) {
24+
$FirstVuln = $Group.Group | Sort-Object firstSeenTimestamp | Select-Object -First 1
25+
$HoursOld = [math]::Round(((Get-Date) - [datetime]$FirstVuln.firstSeenTimestamp).TotalHours)
26+
27+
# Skip if vulnerability is not old enough
28+
if ($HoursOld -lt [int]$InputValue) {
29+
continue
30+
}
31+
32+
$DaysOld = [math]::Round(((Get-Date) - [datetime]$FirstVuln.firstSeenTimestamp).TotalDays)
33+
$AffectedDevices = ($Group.Group | Select-Object -ExpandProperty deviceName -Unique) -join ', '
34+
35+
$VulnerabilityAlert = [PSCustomObject]@{
36+
CVE = $Group.Name
37+
Severity = $FirstVuln.vulnerabilitySeverityLevel
38+
FirstSeenTimestamp = $FirstVuln.firstSeenTimestamp
39+
LastSeenTimestamp = $FirstVuln.lastSeenTimestamp
40+
DaysOld = $DaysOld
41+
HoursOld = $HoursOld
42+
AffectedDeviceCount = $Group.Count
43+
AffectedDevices = $AffectedDevices
44+
SoftwareName = $FirstVuln.softwareName
45+
SoftwareVendor = $FirstVuln.softwareVendor
46+
SoftwareVersion = $FirstVuln.softwareVersion
47+
CVSSScore = $FirstVuln.cvssScore
48+
ExploitabilityLevel = $FirstVuln.exploitabilityLevel
49+
RecommendedUpdate = $FirstVuln.recommendedSecurityUpdate
50+
RecommendedUpdateId = $FirstVuln.recommendedSecurityUpdateId
51+
RecommendedUpdateUrl = $FirstVuln.recommendedSecurityUpdateUrl
52+
Tenant = $TenantFilter
53+
}
54+
$AlertData.Add($VulnerabilityAlert)
55+
}
56+
57+
# Only send alert if we have vulnerabilities that meet the criteria
58+
if ($AlertData.Count -gt 0) {
59+
Write-AlertTrace -cmdletName $MyInvocation.MyCommand -tenantFilter $TenantFilter -data $AlertData
60+
}
61+
}
62+
} catch {
63+
Write-LogMessage -message "Failed to check vulnerabilities: $($_.exception.message)" -API 'Vulnerability Alerts' -tenant $TenantFilter -sev Error
64+
}
65+
}

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

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Function Invoke-ExecBrandingSettings {
1515
Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug'
1616

1717
$StatusCode = [HttpStatusCode]::OK
18-
$Results = @{}
18+
@{}
1919

2020
try {
2121
$Table = Get-CIPPTable -TableName Config
@@ -33,9 +33,9 @@ Function Invoke-ExecBrandingSettings {
3333

3434
$Action = if ($Request.Body.Action) { $Request.Body.Action } else { $Request.Query.Action }
3535

36-
switch ($Action) {
36+
$Results = switch ($Action) {
3737
'Get' {
38-
$Results = @{
38+
@{
3939
colour = $BrandingConfig.colour
4040
logo = $BrandingConfig.logo
4141
}
@@ -50,7 +50,7 @@ Function Invoke-ExecBrandingSettings {
5050
$Updated = $true
5151
} else {
5252
$StatusCode = [HttpStatusCode]::BadRequest
53-
$Results = 'Error: Invalid color format. Please use hex format (e.g., #F77F00)'
53+
'Error: Invalid color format. Please use hex format (e.g., #F77F00)'
5454
}
5555
}
5656

@@ -62,18 +62,18 @@ Function Invoke-ExecBrandingSettings {
6262
$ImageBytes = [Convert]::FromBase64String($Base64Data)
6363
if ($ImageBytes.Length -le 2097152) {
6464
Write-Host 'updating logo'
65-
$BrandingConfig.logo = $Logo
65+
$BrandingConfig | Add-Member -MemberType NoteProperty -Name 'logo' -Value $Logo -Force
6666
$Updated = $true
6767
} else {
6868
$StatusCode = [HttpStatusCode]::BadRequest
69-
$Results = 'Error: Image size must be less than 2MB'
69+
'Error: Image size must be less than 2MB'
7070
}
7171
} catch {
7272
$StatusCode = [HttpStatusCode]::BadRequest
73-
$Results = 'Error: Invalid base64 image data'
73+
'Error: Invalid base64 image data: ' + $_.Exception.Message
7474
}
7575
} elseif ($Logo -eq $null -or $Logo -eq '') {
76-
$BrandingConfig.logo = $null
76+
$BrandingConfig | Add-Member -MemberType NoteProperty -Name 'logo' -Value $null -Force
7777
$Updated = $true
7878
}
7979
}
@@ -84,10 +84,10 @@ Function Invoke-ExecBrandingSettings {
8484

8585
Add-CIPPAzDataTableEntity @Table -Entity $BrandingConfig -Force | Out-Null
8686
Write-LogMessage -API $APIName -tenant 'Global' -headers $Request.Headers -message 'Updated branding settings' -Sev 'Info'
87-
$Results = 'Successfully updated branding settings'
87+
'Successfully updated branding settings'
8888
} else {
8989
$StatusCode = [HttpStatusCode]::BadRequest
90-
$Results = 'Error: No valid branding data provided'
90+
'Error: No valid branding data provided'
9191
}
9292
}
9393
'Reset' {
@@ -100,17 +100,17 @@ Function Invoke-ExecBrandingSettings {
100100

101101
Add-CIPPAzDataTableEntity @Table -Entity $DefaultConfig -Force | Out-Null
102102
Write-LogMessage -API $APIName -tenant 'Global' -headers $Request.Headers -message 'Reset branding settings to defaults' -Sev 'Info'
103-
$Results = 'Successfully reset branding settings to defaults'
103+
'Successfully reset branding settings to defaults'
104104
}
105105
default {
106106
$StatusCode = [HttpStatusCode]::BadRequest
107-
$Results = 'Error: Invalid action specified'
107+
'Error: Invalid action specified'
108108
}
109109
}
110110
} catch {
111111
Write-LogMessage -API $APIName -tenant 'Global' -headers $Request.Headers -message "Branding Settings API failed: $($_.Exception.Message)" -Sev 'Error'
112112
$StatusCode = [HttpStatusCode]::InternalServerError
113-
$Results = "Failed to process branding settings: $($_.Exception.Message)"
113+
"Failed to process branding settings: $($_.Exception.Message)"
114114
}
115115

116116
$body = [pscustomobject]@{'Results' = $Results }

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ Function Invoke-ExecUpdateRefreshToken {
2020
if ($env:AzureWebJobsStorage -eq 'UseDevelopmentStorage=true') {
2121
$DevSecretsTable = Get-CIPPTable -tablename 'DevSecrets'
2222
$Secret = Get-CIPPAzDataTableEntity @DevSecretsTable -Filter "PartitionKey eq 'Secret' and RowKey eq 'Secret'"
23+
2324
if ($env:TenantID -eq $Request.body.tenantId) {
24-
$Secret.RefreshToken = $Request.body.RefreshToken
25+
$Secret | Add-Member -MemberType NoteProperty -Name 'RefreshToken' -Value $Request.body.refreshtoken -Force
2526
} else {
2627
Write-Host "$($env:TenantID) does not match $($Request.body.tenantId)"
2728
$name = $Request.body.tenantId -replace '-', '_'

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ExecModifyCalPerms.ps1

Lines changed: 48 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -11,30 +11,30 @@ Function Invoke-ExecModifyCalPerms {
1111
param($Request, $TriggerMetadata)
1212

1313
$APIName = $Request.Params.CIPPEndpoint
14-
Write-LogMessage -headers $Request.Headers -API $APINAME-message 'Accessed this API' -Sev 'Debug'
15-
16-
$Username = $request.body.userID
17-
$Tenantfilter = $request.body.tenantfilter
18-
$Permissions = $request.body.permissions
14+
$Headers = $Request.Headers
15+
Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug'
1916

20-
Write-LogMessage -headers $Request.Headers -API $APINAME-message "Processing request for user: $Username, tenant: $Tenantfilter" -Sev 'Debug'
17+
$Username = $Request.Body.userID
18+
$TenantFilter = $Request.Body.tenantFilter
19+
$Permissions = $Request.Body.permissions
2120

22-
if ($username -eq $null) {
23-
Write-LogMessage -headers $Request.Headers -API $APINAME-message 'Username is null' -Sev 'Error'
21+
Write-LogMessage -headers $Headers -API $APIName -message "Processing request for user: $Username, tenant: $TenantFilter" -Sev 'Debug'
22+
23+
if ($null -eq $Username) {
24+
Write-LogMessage -headers $Headers -API $APIName -message 'Username is null' -Sev 'Error'
2425
$body = [pscustomobject]@{'Results' = @('Username is required') }
2526
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
2627
StatusCode = [HttpStatusCode]::BadRequest
2728
Body = $Body
2829
})
2930
return
3031
}
31-
32+
3233
try {
33-
$userid = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/$($username)" -tenantid $Tenantfilter).id
34-
Write-LogMessage -headers $Request.Headers -API $APINAME-message "Retrieved user ID: $userid" -Sev 'Debug'
35-
}
36-
catch {
37-
Write-LogMessage -headers $Request.Headers -API $APINAME-message "Failed to get user ID: $($_.Exception.Message)" -Sev 'Error'
34+
$UserId = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/$($Username)" -tenantid $TenantFilter).id
35+
Write-LogMessage -headers $Headers -API $APIName -message "Retrieved user ID: $UserId" -Sev 'Debug'
36+
} catch {
37+
Write-LogMessage -headers $Headers -API $APIName -message "Failed to get user ID: $($_.Exception.Message)" -Sev 'Error'
3838
$body = [pscustomobject]@{'Results' = @("Failed to get user ID: $($_.Exception.Message)") }
3939
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
4040
StatusCode = [HttpStatusCode]::NotFound
@@ -43,98 +43,73 @@ Function Invoke-ExecModifyCalPerms {
4343
return
4444
}
4545

46-
$Results = [System.Collections.ArrayList]::new()
46+
$Results = [System.Collections.Generic.List[string]]::new()
4747
$HasErrors = $false
4848

4949
# Convert permissions to array format if it's an object with numeric keys
5050
if ($Permissions -is [PSCustomObject]) {
5151
if ($Permissions.PSObject.Properties.Name -match '^\d+$') {
5252
$Permissions = $Permissions.PSObject.Properties.Value
53-
}
54-
else {
53+
} else {
5554
$Permissions = @($Permissions)
5655
}
5756
}
5857

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

6160
foreach ($Permission in $Permissions) {
62-
Write-LogMessage -headers $Request.Headers -API $APINAME-message "Processing permission: $($Permission | ConvertTo-Json)" -Sev 'Debug'
63-
61+
Write-LogMessage -headers $Headers -API $APIName -message "Processing permission: $($Permission | ConvertTo-Json)" -Sev 'Debug'
62+
6463
$PermissionLevel = $Permission.PermissionLevel.value ?? $Permission.PermissionLevel
6564
$Modification = $Permission.Modification
6665
$CanViewPrivateItems = $Permission.CanViewPrivateItems ?? $false
67-
68-
Write-LogMessage -headers $Request.Headers -API $APINAME-message "Permission Level: $PermissionLevel, Modification: $Modification, CanViewPrivateItems: $CanViewPrivateItems" -Sev 'Debug'
69-
66+
$FolderName = $Permission.FolderName ?? 'Calendar'
67+
68+
Write-LogMessage -headers $Headers -API $APIName -message "Permission Level: $PermissionLevel, Modification: $Modification, CanViewPrivateItems: $CanViewPrivateItems, FolderName: $FolderName" -Sev 'Debug'
69+
7070
# Handle UserID as array or single value
7171
$TargetUsers = @($Permission.UserID | ForEach-Object { $_.value ?? $_ })
7272

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

7575
foreach ($TargetUser in $TargetUsers) {
7676
try {
77-
Write-LogMessage -headers $Request.Headers -API $APINAME-message "Processing target user: $TargetUser" -Sev 'Debug'
78-
79-
if ($Modification -eq 'Remove') {
80-
try {
81-
$CalPerms = New-ExoRequest -Anchor $username -tenantid $Tenantfilter -cmdlet 'Remove-MailboxFolderPermission' -cmdParams @{
82-
Identity = "$($userid):\Calendar"
83-
User = $TargetUser
84-
Confirm = $false
85-
}
86-
$null = $results.Add("Removed $($TargetUser) from $($username) Calendar permissions")
87-
}
88-
catch {
89-
$null = $results.Add("No existing permissions to remove for $($TargetUser)")
90-
}
91-
}
92-
else {
93-
Write-LogMessage -headers $Request.Headers -API $APINAME-message "Setting permissions with AccessRights: $PermissionLevel" -Sev 'Debug'
94-
95-
$cmdParams = @{
96-
Identity = "$($userid):\Calendar"
97-
User = $TargetUser
98-
AccessRights = $PermissionLevel
99-
Confirm = $false
100-
}
101-
102-
if ($CanViewPrivateItems) {
103-
$cmdParams['SharingPermissionFlags'] = 'Delegate,CanViewPrivateItems'
104-
}
105-
106-
try {
107-
# Try Add first
108-
$CalPerms = New-ExoRequest -Anchor $username -tenantid $Tenantfilter -cmdlet 'Add-MailboxFolderPermission' -cmdParams $cmdParams
109-
$null = $results.Add("Granted $($TargetUser) $($PermissionLevel) access to $($username) Calendar$($CanViewPrivateItems ? ' with access to private items' : '')")
110-
}
111-
catch {
112-
# If Add fails, try Set
113-
$CalPerms = New-ExoRequest -Anchor $username -tenantid $Tenantfilter -cmdlet 'Set-MailboxFolderPermission' -cmdParams $cmdParams
114-
$null = $results.Add("Updated $($TargetUser) $($PermissionLevel) access to $($username) Calendar$($CanViewPrivateItems ? ' with access to private items' : '')")
115-
}
77+
Write-LogMessage -headers $Headers -API $APIName -message "Processing target user: $TargetUser" -Sev 'Debug'
78+
$Params = @{
79+
APIName = $APIName
80+
Headers = $Headers
81+
RemoveAccess = if ($Modification -eq 'Remove') { $TargetUser } else { $null }
82+
TenantFilter = $TenantFilter
83+
UserID = $UserId
84+
folderName = $FolderName
85+
UserToGetPermissions = $TargetUser
86+
LoggingName = $TargetUser
87+
Permissions = $PermissionLevel
88+
CanViewPrivateItems = $CanViewPrivateItems
11689
}
117-
Write-LogMessage -headers $Request.Headers -API $APINAME-message "Successfully executed $($PermissionLevel) permission modification for $($TargetUser) on $($username)" -Sev 'Info' -tenant $TenantFilter
118-
}
119-
catch {
90+
91+
# Write-Host "Request params: $($Params | ConvertTo-Json)"
92+
$Result = Set-CIPPCalendarPermission @Params
93+
94+
$null = $Results.Add($Result)
95+
} catch {
12096
$HasErrors = $true
121-
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
122-
$null = $results.Add("Could not execute $($PermissionLevel) permission modification for $($TargetUser) on $($username). Error: $($_.Exception.Message)")
97+
$null = $Results.Add("$($_.Exception.Message)")
12398
}
12499
}
125100
}
126101

127-
if ($results.Count -eq 0) {
128-
Write-LogMessage -headers $Request.Headers -API $APINAME-message 'No results were generated from the operation' -Sev 'Warning'
129-
$null = $results.Add('No results were generated from the operation. Please check the logs for more details.')
102+
if ($Results.Count -eq 0) {
103+
Write-LogMessage -headers $Headers -API $APIName -message 'No results were generated from the operation' -Sev 'Warning'
104+
$null = $Results.Add('No results were generated from the operation. Please check the logs for more details.')
130105
$HasErrors = $true
131106
}
132107

133-
$body = [pscustomobject]@{'Results' = @($results) }
108+
$Body = [pscustomobject]@{'Results' = @($Results) }
134109

135110
# Associate values to output bindings by calling 'Push-OutputBinding'.
136111
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
137112
StatusCode = if ($HasErrors) { [HttpStatusCode]::InternalServerError } else { [HttpStatusCode]::OK }
138113
Body = $Body
139114
})
140-
}
115+
}

0 commit comments

Comments
 (0)