diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Extensions/Invoke-ExecExtensionTest.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Extensions/Invoke-ExecExtensionTest.ps1 index c8078ed93509..3a61241b5753 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Extensions/Invoke-ExecExtensionTest.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Extensions/Invoke-ExecExtensionTest.ps1 @@ -59,9 +59,13 @@ Function Invoke-ExecExtensionTest { $token = Get-SherwebAuthentication $Results = [pscustomobject]@{'Results' = 'Successfully Connected to Sherweb' } } + 'HIBP' { + $ConnectionTest = Get-HIBPConnectionTest + $Results = [pscustomobject]@{'Results' = 'Successfully Connected to HIBP' } + } } } catch { - $Results = [pscustomobject]@{'Results' = "Failed to connect: $($_.Exception.Message) $($_.InvocationInfo.ScriptLineNumber)" } + $Results = [pscustomobject]@{'Results' = "Failed to connect: $($_.Exception.Message). Line $($_.InvocationInfo.ScriptLineNumber)" } } # Associate values to output bindings by calling 'Push-OutputBinding'. diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListBreachesAccount.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListBreachesAccount.ps1 new file mode 100644 index 000000000000..03473f343622 --- /dev/null +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListBreachesAccount.ps1 @@ -0,0 +1,23 @@ +using namespace System.Net + +Function Invoke-ListBreachesAccount { + <# + .FUNCTIONALITY + Entrypoint + .ROLE + CIPP.Core.Read + #> + [CmdletBinding()] + param($Request, $TriggerMetadata) + + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + + $Results = Get-HIBPRequest "breachedaccount/$($Request.query.account)?truncateResponse=false" + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = @($results) + }) + +} diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListBreachesTenant.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListBreachesTenant.ps1 new file mode 100644 index 000000000000..61dd7a122404 --- /dev/null +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListBreachesTenant.ps1 @@ -0,0 +1,34 @@ +using namespace System.Net + +Function Invoke-ListBreachesTenant { + <# + .FUNCTIONALITY + Entrypoint + .ROLE + CIPP.Core.Read + #> + [CmdletBinding()] + param($Request, $TriggerMetadata) + + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $users = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users?`$select=UserPrincipalName,mail" -tenantid $Request.query.TenantFilter + $usersResults = foreach ($user in $users) { + $Results = Get-HIBPRequest "breachedaccount/$($user.UserPrincipalName)?truncateResponse=true" + if ($null -eq $Results) { + $Results = 'No breaches found.' + } + [PSCustomObject]@{ + user = $user.UserPrincipalName + breaches = $Results + } + } + + + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = @($usersResults) + }) + +} diff --git a/Modules/CippExtensions/Public/HIBP/Get-HIBPAuth.ps1 b/Modules/CippExtensions/Public/HIBP/Get-HIBPAuth.ps1 new file mode 100644 index 000000000000..1d3459ed4506 --- /dev/null +++ b/Modules/CippExtensions/Public/HIBP/Get-HIBPAuth.ps1 @@ -0,0 +1,17 @@ +function Get-HIBPAuth { + if ($env:AzureWebJobsStorage -eq 'UseDevelopmentStorage=true') { + $DevSecretsTable = Get-CIPPTable -tablename 'DevSecrets' + $Secret = (Get-CIPPAzDataTableEntity @DevSecretsTable -Filter "PartitionKey eq 'HIBP' and RowKey eq 'HIBP'").APIKey + } else { + $null = Connect-AzAccount -Identity + $VaultName = ($ENV:WEBSITE_DEPLOYMENT_ID -split '-')[0] + $Secret = Get-AzKeyVaultSecret -VaultName $VaultName -Name 'HIBP' -AsPlainText + } + + return @{ + 'User-Agent' = "CIPP-$($ENV:TenantId)" + 'Accept' = 'application/json' + 'api-version' = '3' + 'hibp-api-key' = $Secret + } +} diff --git a/Modules/CippExtensions/Public/HIBP/Get-HIBPConnectionTest.ps1 b/Modules/CippExtensions/Public/HIBP/Get-HIBPConnectionTest.ps1 new file mode 100644 index 000000000000..2cbf90eb7e8e --- /dev/null +++ b/Modules/CippExtensions/Public/HIBP/Get-HIBPConnectionTest.ps1 @@ -0,0 +1,8 @@ +function Get-HIBPConnectionTest { + $uri = 'https://haveibeenpwned.com/api/v3/subscription/status' + try { + Invoke-RestMethod -Uri $uri -Headers (Get-HIBPAuth) + } catch { + throw "Failed to connect to HIBP: $($_.Exception.Message)" + } +} diff --git a/Modules/CippExtensions/Public/HIBP/Get-HIBPRequest.ps1 b/Modules/CippExtensions/Public/HIBP/Get-HIBPRequest.ps1 new file mode 100644 index 000000000000..2f6de9d51e1d --- /dev/null +++ b/Modules/CippExtensions/Public/HIBP/Get-HIBPRequest.ps1 @@ -0,0 +1,17 @@ +function Get-HIBPRequest { + [CmdletBinding()] + param ( + [Parameter()]$endpoint + + ) + $uri = "https://haveibeenpwned.com/api/v3/$endpoint" + try { + Invoke-RestMethod -Uri $uri -Headers (Get-HIBPAuth) + } catch { + #If the error is a 404, it means no breach has been found. Return an empty object. + if ($_.Exception.Response.StatusCode -eq 404) { + return @() + } + throw "Failed to connect to HIBP: $($_.Exception.Message)" + } +}