Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
42 changes: 42 additions & 0 deletions core/powershell/ediscovery.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import json
import logging
from core.powershell.client import PowerShellClient

logger = logging.getLogger("EDiscoveryService")

class EDiscoveryService:
def __init__(self, client: PowerShellClient):
self.client = client

def fetch_ediscovery_cases(self) -> list:
"""Locates certificate, triggers powershell execution, and parses eDiscovery cases."""
try:
cert_path = self.client.locate_certificate()
except Exception as e:
raise RuntimeError(f"Failed to locate certificate for authentication: {str(e)}")

args = [
"-AppId", self.client.client_id,
"-Organization", self.client.tenant_id,
"-CertificatePath", cert_path
]
if self.client.cert_password:
args += ["-CertificatePassword", self.client.cert_password]

raw_output = self.client.execute_script("scripts/get_compliance_cases.ps1", args)

if not raw_output or not raw_output.strip():
return []

try:
return json.loads(raw_output)
except json.JSONDecodeError:
# Parse JSON block in case of warning/header lines outputted by powershell environment
lines = raw_output.strip().split('\n')
json_str = ""
for line in lines:
if line.startswith("[") or line.startswith("{") or json_str:
json_str += line
if json_str:
return json.loads(json_str)
raise RuntimeError(f"PowerShell returned non-JSON format: {raw_output}")
85 changes: 85 additions & 0 deletions core/powershell/scripts/get_compliance_cases.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
param(
[Parameter(Mandatory=$true)]
[string]$AppId,
[Parameter(Mandatory=$true)]
[string]$Organization,
[Parameter(Mandatory=$true)]
[string]$CertificatePath,
[Parameter(Mandatory=$false)]
[string]$CertificatePassword
)

$ErrorActionPreference = "Stop"

# Check if ExchangeOnlineManagement module is installed beforehand
if (-not (Get-Module -ListAvailable -Name ExchangeOnlineManagement)) {
throw "ExchangeOnlineManagement PowerShell module is not installed. Please install it beforehand by running: Install-Module -Name ExchangeOnlineManagement -Scope CurrentUser"
}

Import-Module ExchangeOnlineManagement

# Connect to Security & Compliance PowerShell using App-Only Cert Auth
if ($CertificatePassword) {
$secPassword = ConvertTo-SecureString -String $CertificatePassword -AsPlainText -Force
Connect-IPPSSession -CertificateFilePath $CertificatePath -CertificatePassword $secPassword -AppId $AppId -Organization $Organization -ShowBanner:$false -WarningAction SilentlyContinue
} else {
Connect-IPPSSession -CertificateFilePath $CertificatePath -AppId $AppId -Organization $Organization -ShowBanner:$false -WarningAction SilentlyContinue
}

try {
$output = @()
$standardError = $null
$premiumError = $null

# Get Standard eDiscovery cases
try {
$standardCases = Get-ComplianceCase -CaseType eDiscovery -WarningAction SilentlyContinue
if ($standardCases) {
foreach ($case in @($standardCases)) {
$caseObj = [PSCustomObject]@{
Name = $case.Name
Status = $case.Status
CaseType = "eDiscovery (Standard)"
CreatedBy = $case.CreatedBy
WhenCreated = $case.WhenCreated
}
$output += $caseObj
}
}
} catch {
$standardError = $_.Exception.Message
}

# Get Premium (Advanced) eDiscovery cases
try {
$premiumCases = Get-ComplianceCase -CaseType AdvancedEdiscovery -WarningAction SilentlyContinue
if ($premiumCases) {
foreach ($case in @($premiumCases)) {
$caseObj = [PSCustomObject]@{
Name = $case.Name
Status = $case.Status
CaseType = "eDiscovery (Premium)"
CreatedBy = $case.CreatedBy
WhenCreated = $case.WhenCreated
}
$output += $caseObj
}
}
} catch {
$premiumError = $_.Exception.Message
}

# If both failed, throw a combined exception
if ($standardError -and $premiumError) {
throw "Failed to fetch eDiscovery cases. eDiscovery (Standard) error: $standardError; eDiscovery (Premium) error: $premiumError"
}

if ($output) {
$output | ConvertTo-Json -Depth 5
} else {
"[]"
}
}
finally {
Disconnect-ExchangeOnline -Confirm:$false
}
Loading