Skip to content

Commit 086f442

Browse files
Merge pull request KelvinTegelaar#1517 from kris6673/OoO
Improve error handling and parameter validation for out-of-office functions
2 parents 2a92d6b + f3b0051 commit 086f442

File tree

5 files changed

+99
-45
lines changed

5 files changed

+99
-45
lines changed

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

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,39 +11,64 @@ Function Invoke-ExecSetOoO {
1111
param($Request, $TriggerMetadata)
1212
try {
1313
$APIName = $Request.Params.CIPPEndpoint
14-
Write-LogMessage -headers $Request.Headers -API $APIName -message 'Accessed this API' -Sev 'Debug'
14+
$Headers = $Request.Headers
15+
Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug'
16+
17+
1518
$Username = $Request.Body.userId
1619
$TenantFilter = $Request.Body.tenantFilter
20+
$State = $Request.Body.AutoReplyState.value
21+
22+
$SplatParams = @{
23+
userid = $Username
24+
tenantFilter = $TenantFilter
25+
APIName = $APIName
26+
Headers = $Headers
27+
State = $State
28+
}
29+
30+
# User action uses input, edit exchange uses InternalMessage and ExternalMessage
31+
# User action disable OoO doesn't send any input
1732
if ($Request.Body.input) {
1833
$InternalMessage = $Request.Body.input
1934
$ExternalMessage = $Request.Body.input
2035
} else {
2136
$InternalMessage = $Request.Body.InternalMessage
2237
$ExternalMessage = $Request.Body.ExternalMessage
23-
}
24-
#if starttime and endtime are a number, they are unix timestamps and need to be converted to datetime, otherwise just use them.
25-
$StartTime = if ($Request.Body.StartTime -match '^\d+$') { [DateTimeOffset]::FromUnixTimeSeconds([int]$Request.Body.StartTime).DateTime } else { $Request.Body.StartTime }
26-
$EndTime = if ($Request.Body.EndTime -match '^\d+$') { [DateTimeOffset]::FromUnixTimeSeconds([int]$Request.Body.EndTime).DateTime } else { $Request.Body.EndTime }
27-
28-
$Results = try {
29-
if ($Request.Body.AutoReplyState.value -ne 'Scheduled') {
30-
Set-CIPPOutOfOffice -userid $Username -tenantFilter $TenantFilter -APIName $APIName -Headers $Request.Headers -InternalMessage $InternalMessage -ExternalMessage $ExternalMessage -State $Request.Body.AutoReplyState.value
31-
} else {
32-
Set-CIPPOutOfOffice -userid $Username -tenantFilter $TenantFilter -APIName $APIName -Headers $Request.Headers -InternalMessage $InternalMessage -ExternalMessage $ExternalMessage -StartTime $StartTime -EndTime $EndTime -State $Request.Body.AutoReplyState.value
38+
39+
# Only add the internal and external message if they are not empty/null. Done to be able to set the OOO to disabled, while keeping the existing messages intact.
40+
# This works because the frontend always sends some HTML even if the fields are empty.
41+
if (-not [string]::IsNullOrWhiteSpace($InternalMessage)) {
42+
$SplatParams.InternalMessage = $InternalMessage
43+
}
44+
if (-not [string]::IsNullOrWhiteSpace($ExternalMessage)) {
45+
$SplatParams.ExternalMessage = $ExternalMessage
3346
}
34-
} catch {
35-
"Could not add out of office message for $($Username). Error: $($_.Exception.Message)"
3647
}
3748

38-
$Body = [PSCustomObject]@{'Results' = $($Results) }
49+
50+
# If the state is scheduled, add the start and end times to the splat params
51+
if ($State -eq 'Scheduled') {
52+
# If starttime and endtime are a number, they are unix timestamps and need to be converted to datetime, otherwise just use them.
53+
$StartTime = $Request.Body.StartTime -match '^\d+$' ? [DateTimeOffset]::FromUnixTimeSeconds([int]$Request.Body.StartTime).DateTime : $Request.Body.StartTime
54+
$EndTime = $Request.Body.EndTime -match '^\d+$' ? [DateTimeOffset]::FromUnixTimeSeconds([int]$Request.Body.EndTime).DateTime : $Request.Body.EndTime
55+
$SplatParams.StartTime = $StartTime
56+
$SplatParams.EndTime = $EndTime
57+
}
58+
59+
$Results = Set-CIPPOutOfOffice @SplatParams
60+
$StatusCode = [HttpStatusCode]::OK
3961
} catch {
40-
$Body = [PSCustomObject]@{'Results' = "Could not set Out of Office user: $($_.Exception.Message)" }
62+
$ErrorMessage = Get-CippException -Exception $_
63+
$Results = "Could not set Out of Office for user: $($Username). Error: $($ErrorMessage.NormalizedError)"
64+
Write-LogMessage -headers $Headers -API $APIName -message $Results -Sev 'Error' -LogData $ErrorMessage
65+
$StatusCode = [HttpStatusCode]::InternalServerError
4166
}
4267

4368
# Associate values to output bindings by calling 'Push-OutputBinding'.
4469
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
45-
StatusCode = [HttpStatusCode]::OK
46-
Body = $Body
70+
StatusCode = $StatusCode
71+
Body = @{'Results' = $($Results) }
4772
})
4873

4974
}

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

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,23 @@ Function Invoke-ListOoO {
1111
param($Request, $TriggerMetadata)
1212

1313
$APIName = $Request.Params.CIPPEndpoint
14-
$Tenantfilter = $request.query.tenantFilter
14+
$Headers = $Request.Headers
15+
Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug'
16+
17+
$TenantFilter = $Request.Query.tenantFilter
18+
$UserID = $Request.Query.userid
1519
try {
16-
$Body = Get-CIPPOutOfOffice -UserID $Request.query.userid -tenantFilter $TenantFilter -APIName $APINAME -Headers $Request.Headers
20+
$Results = Get-CIPPOutOfOffice -UserID $UserID -tenantFilter $TenantFilter -APIName $APIName -Headers $Headers
21+
$StatusCode = [HttpStatusCode]::OK
1722
} catch {
18-
$ErrorMessage = Get-NormalizedError -Message $_.Exception.Message
19-
$Body = [pscustomobject]@{'Results' = "Failed. $ErrorMessage" }
20-
23+
$Results = $_.Exception.Message
24+
$StatusCode = [HttpStatusCode]::InternalServerError
2125
}
2226

2327
# Associate values to output bindings by calling 'Push-OutputBinding'.
2428
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
25-
StatusCode = [HttpStatusCode]::OK
26-
Body = $Body
29+
StatusCode = $StatusCode
30+
Body = $Results
2731
})
2832

2933
}

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-CIPPOffboardingJob.ps1

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,11 @@ function Invoke-CIPPOffboardingJob {
4242
$Options.AccessAutomap | ForEach-Object { Set-CIPPMailboxAccess -tenantFilter $TenantFilter -userid $username -AccessUser $_.value -Automap $true -AccessRights @('FullAccess') -Headers $Headers -APIName $APIName }
4343
}
4444
{ $_.OOO } {
45-
Set-CIPPOutOfOffice -tenantFilter $TenantFilter -userid $username -InternalMessage $Options.OOO -ExternalMessage $Options.OOO -Headers $Headers -APIName $APIName -state 'Enabled'
45+
try {
46+
Set-CIPPOutOfOffice -tenantFilter $TenantFilter -UserID $username -InternalMessage $Options.OOO -ExternalMessage $Options.OOO -Headers $Headers -APIName $APIName -state 'Enabled'
47+
} catch {
48+
$_.Exception.Message
49+
}
4650
}
4751
{ $_.forward } {
4852
if (!$Options.KeepCopy) {
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
function Get-CIPPOutOfOffice {
22
[CmdletBinding()]
33
param (
4-
$userid,
4+
$UserID,
55
$TenantFilter,
66
$APIName = 'Get Out of Office',
77
$Headers
88
)
99

1010
try {
11-
$OutOfOffice = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Get-MailboxAutoReplyConfiguration' -cmdParams @{Identity = $userid } -Anchor $userid
11+
$OutOfOffice = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Get-MailboxAutoReplyConfiguration' -cmdParams @{Identity = $UserID } -Anchor $UserID
1212
$Results = @{
1313
AutoReplyState = $OutOfOffice.AutoReplyState
1414
StartTime = $OutOfOffice.StartTime.ToString('yyyy-MM-dd HH:mm')
@@ -18,7 +18,9 @@ function Get-CIPPOutOfOffice {
1818
} | ConvertTo-Json
1919
return $Results
2020
} catch {
21-
$ErrorMessage = Get-NormalizedError -Message $_.Exception.Message
22-
return "Could not retrieve out of office message for $($userid). Error: $ErrorMessage"
21+
$ErrorMessage = Get-CippException -Exception $_
22+
$Results = "Could not retrieve out of office message for $($UserID). Error: $($ErrorMessage.NormalizedError)"
23+
Write-LogMessage -headers $Headers -API $APIName -message $Results -Sev 'Error' -LogData $ErrorMessage
24+
throw $Results
2325
}
2426
}
Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,55 @@
11
function Set-CIPPOutOfOffice {
22
[CmdletBinding()]
33
param (
4-
$userid,
4+
[Parameter(Mandatory = $true)]
5+
$UserID,
56
$InternalMessage,
67
$ExternalMessage,
78
$TenantFilter,
8-
$State,
9+
[ValidateSet('Enabled', 'Disabled', 'Scheduled')]
10+
[Parameter(Mandatory = $true)]
11+
[string]$State,
912
$APIName = 'Set Out of Office',
1013
$Headers,
1114
$StartTime,
1215
$EndTime
1316
)
1417

1518
try {
16-
if (-not $StartTime) {
17-
$StartTime = (Get-Date).ToString()
19+
20+
$CmdParams = @{
21+
Identity = $UserID
22+
AutoReplyState = $State
23+
}
24+
25+
if ($PSBoundParameters.ContainsKey('InternalMessage')) {
26+
$CmdParams.InternalMessage = $InternalMessage
1827
}
19-
if (-not $EndTime) {
20-
$EndTime = (Get-Date $StartTime).AddDays(7)
28+
29+
if ($PSBoundParameters.ContainsKey('ExternalMessage')) {
30+
$CmdParams.ExternalMessage = $ExternalMessage
2131
}
22-
if ($State -ne 'Scheduled') {
23-
$null = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Set-MailboxAutoReplyConfiguration' -cmdParams @{Identity = $userid; AutoReplyState = $State; InternalMessage = $InternalMessage; ExternalMessage = $ExternalMessage } -Anchor $userid
24-
Write-LogMessage -headers $Headers -API $APIName -message "Set Out-of-office for $($userid) to $State" -Sev 'Info' -tenant $TenantFilter
25-
return "Set Out-of-office for $($userid) to $State."
26-
} else {
27-
$null = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Set-MailboxAutoReplyConfiguration' -cmdParams @{Identity = $userid; AutoReplyState = $State; InternalMessage = $InternalMessage; ExternalMessage = $ExternalMessage; StartTime = $StartTime; EndTime = $EndTime } -Anchor $userid
28-
Write-LogMessage -headers $Headers -API $APIName -message "Scheduled Out-of-office for $($userid) between $StartTime and $EndTime" -Sev 'Info' -tenant $TenantFilter
29-
return "Scheduled Out-of-office for $($userid) between $($StartTime.toString()) and $($EndTime.toString())"
32+
33+
if ($State -eq 'Scheduled') {
34+
# If starttime or endtime are not provided, default to enabling OOO for 7 days
35+
$StartTime = $StartTime ? $StartTime : (Get-Date).ToString()
36+
$EndTime = $EndTime ? $EndTime : (Get-Date $StartTime).AddDays(7)
37+
$CmdParams.StartTime = $StartTime
38+
$CmdParams.EndTime = $EndTime
3039
}
40+
41+
$null = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Set-MailboxAutoReplyConfiguration' -cmdParams $CmdParams -Anchor $UserID
42+
43+
$Results = $State -eq 'Scheduled' ?
44+
"Scheduled Out-of-office for $($UserID) between $($StartTime.toString()) and $($EndTime.toString())" :
45+
"Set Out-of-office for $($UserID) to $State."
46+
47+
Write-LogMessage -headers $Headers -API $APIName -message $Results -Sev 'Info' -tenant $TenantFilter
48+
return $Results
3149
} catch {
3250
$ErrorMessage = Get-CippException -Exception $_
33-
Write-LogMessage -headers $Headers -API $APIName -message "Could not add OOO for $($userid). Error: $($ErrorMessage.NormalizedError)" -Sev 'Error' -tenant $TenantFilter -LogData $ErrorMessage
34-
return "Could not add out of office message for $($userid). Error: $($ErrorMessage.NormalizedError)"
51+
$Results = "Could not add OOO for $($UserID). Error: $($ErrorMessage.NormalizedError)"
52+
Write-LogMessage -headers $Headers -API $APIName -message $Results -Sev 'Error' -tenant $TenantFilter -LogData $ErrorMessage
53+
throw $Results
3554
}
3655
}

0 commit comments

Comments
 (0)