FireEyeNX

FireEye Network Security is an effective cyber threat protection solution that helps organizations minimize the risk of costly breaches by accurately detecting and immediately stopping advanced, targeted, and other evasive attacks hiding in internet traffic.

Network Security · FireEye Network Security (NX)

Details

IDFireEyeNX
ProviderTrellix
CategoryNetwork Security
From Version5.0.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

FireEye Network Security is an effective cyber threat protection solution that helps organizations minimize the risk of costly breaches by accurately detecting and immediately stopping advanced, targeted, and other evasive attacks hiding in internet traffic.
This integration was integrated and tested with version 2.0.0 of FireEyeNX APIs.

Configure FireEyeNX in Cortex

Parameter Description Required
url URL True
credentials Username True
request_timeout HTTP(S) Request Timeout (in seconds) False
isFetch Fetch incidents False
incidentType Incident type False
first_fetch First fetch time interval False
max_fetch Fetch Limit False
fetch_type Fetch Types False
fetch_mvx_correlated_events Fetches MVX-correlated events only. False
malware_type Alert Malware Type False
replace_alert_url Use instance URL for all the fetched alerts URL. False
fetch_artifacts Fetch artifacts for each alert. False
insecure Trust any certificate (not secure) False
proxy Use system proxy settings False

Commands

You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.

fireeye-nx-get-alerts


Search and retrieve FireEye alerts based on several filters.

Base Command

fireeye-nx-get-alerts

Input

Argument Name Description Required
alert_id The ID number of the alert to retrieve. To retrieve the alert ID, execute the fireeye-nx-get-alerts command without specifying the alert_id. Optional
src_ip The source IPv4 address related to the malware alert to retrieve. Optional
dst_ip The destination IPv4 address related to the malware alert to retrieve. Optional
duration The time interval to search. This filter is used with either the start_time or end_time filter. If duration, start time, and end time are not specified, the system defaults to duration=12_hours, end_time=current_time. If only the duration is specified, the end_time defaults to the current_time. Possible values are: “1_hour”, “2_hours”, “6_hours”, “12_hours”, “24_hours”, and “48_hours”. Optional
start_time The start time of the search. This filter is used with the duration filter. If the start_time is specified but not the duration, the system defaults to duration=12_hours, starting at the specified start_time.
Formats:
YYYY-MM-dd
YYYY-MM-ddTHH:mm:ss
N days
N hours
Example:
2020-05-01
2020-05-01T00:00:00
2 days
5 hours
Optional
end_time The end time of the search. This filter is used with the duration filter. If the end_time is specified but not the duration, the system defaults to duration=12_hours, ending at the specified end_time.
Formats:
YYYY-MM-dd
YYYY-MM-ddTHH:mm:ss
N days
N hours
Example:
2020-05-01
2020-05-01T00:00:00
2 days
5 hours
Optional
file_name The name of the malware file to retrieve. Optional
file_type The malware file type to retrieve. Optional
info_level The level of information to retrieve. Possible values are: “concise”, “normal”, and “extended”. Optional
malware_name The name of the malware object to retrieve. Optional
malware_type The type of the malware object to retrieve. Possible values are: “domain_match”, “malware_callback”, “malware_object”, “web_infection”, and “infection_match”. Optional
md5 The MD5 hash of the alert to retrieve. This filter is not time dependent; it does not default to duration=12_hours. Optional
url A specific alert URL to retrieve. Optional

Context Output

Path Type Description
FireEyeNX.Alert.Explanation.MalwareDetected.Malware.Md5Sum String The md5sum of malware associated with the alert.
FireEyeNX.Alert.Explanation.MalwareDetected.Malware.Sha256 String The SHA256 hash of malware associated with the alert.
FireEyeNX.Alert.Explanation.MalwareDetected.Malware.Application String The application of the malware associated with the alert.
FireEyeNX.Alert.Explanation.MalwareDetected.Malware.HttpHeader String The HTTP header of the malware associated with the alert.
FireEyeNX.Alert.Explanation.MalwareDetected.Malware.Original String The filename of the malware associated with the alert.
FireEyeNX.Alert.Explanation.MalwareDetected.Malware.Name String The name of the malware associated with the alert.
FireEyeNX.Alert.Explanation.MalwareDetected.Malware.Sid String The SID of the malware associated with the alert.
FireEyeNX.Alert.Explanation.MalwareDetected.Malware.Type String The file type of the malware associated with the alert.
FireEyeNX.Alert.Explanation.MalwareDetected.Malware.Stype String The STYPE of the malware associated with the alert.
FireEyeNX.Alert.Explanation.MalwareDetected.Malware.Url String The URL of the malware associated with the alert.
FireEyeNX.Alert.Explanation.MalwareDetected.Malware.Content String The content of the malware associated with the alert.
FireEyeNX.Alert.Explanation.CncServices.CncService.Address String The CNC service IP address associated with the alert.
FireEyeNX.Alert.Explanation.CncServices.CncService.Channel String The CNC service channel associated with the alert.
FireEyeNX.Alert.Explanation.CncServices.CncService.Port Number The CNC service port address associated with the alert.
FireEyeNX.Alert.Explanation.CncServices.CncService.Protocol String The CNC service protocol associated with the alert.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.Totalmemory Number The total memory of heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.Lastbytesreceived Number The last byte received in heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.Processinfo.Imagepath String The image path of the process in heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.Processinfo.Md5sum String The md5sum of the process in heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.Processinfo.Pid Number The PID of the process in heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.IncrementCount Number The increment count in heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.Name String The name of the heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.Bytesreceived Number The bytes received in heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.Lasttotalmemory Number The last total memory in heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.Type String The type of heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.Timestamp Number The timestamp of the heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.RCount Number The RCount of the heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.TotalSize String The total size of the heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.RUnit String The RUnit of the heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.Mode String The mode of the heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.Pattern String The pattern of the heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.BytesList.Entry.Percentage Number The entry percentage of the bytes list in the heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.BytesList.Entry.Byte String The entry byte of the bytes list in the heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.BytesList.Entry.Count Number The entry count of the bytes list in the heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.BytesList.Entry.FirstOffset String The entry offset of the bytes list in the heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.BytesList.Entry.IsNOP String If entry NOP appears in the bytes list in the heap spraying then yes, otherwise no.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.BytesList.Distinct Number The distinct number of the byte list in the heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.BytesList.Count Number The number of the byte list in the heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.Javascript String If heap spraying has javascript then yes, otherwise no.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.DNA Number The DNA of the heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.TotalRCount Number The total row count of the heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.ProcessedRCount Number The processed row count of the heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Heapspraying.Processed String The processed memory of the heap spraying.
FireEyeNX.Alert.Explanation.OsChanges.Process.Fid.Ads String The FID ads of the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.Fid.Content Number The FID content of the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.ParentUserAccount.UserSid String The parent user account SID of the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.ParentUserAccount.SessionId Number The parent user account session ID of the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.ParentUserAccount.UserAccountName String The parent user account name of the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.ParentUserAccount.AuthenticationId String The parent user account authentication ID of the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.ParentUserAccount.SuperPrivilegesPresent Number If super privileges are present in this process then 1, otherwise 0.
FireEyeNX.Alert.Explanation.OsChanges.Process.Parentname String The path of the parent process.
FireEyeNX.Alert.Explanation.OsChanges.Process.Sha256sum String The sha256sum of the parent process.
FireEyeNX.Alert.Explanation.OsChanges.Process.Pid Number The PID of the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.Filesize Number File size of the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.Ppid Number The PPID of the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.Mode String The mode of the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.Cmdline String The path of the command associated with the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.Sha1sum String The sha1sum of the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.Md5sum String The md5sum of the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.SrcThread String The source thread name of the process.
FireEyeNX.Alert.Explanation.osChanges.Process.Value String The value of the path in the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.UserAccount.UserSid String The SID of the user account for the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.UserAccount.SessionId Number The session ID of the user account for the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.UserAccount.UserAccountName String The name of the user account for the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.UserAccount.AuthenticationId String The authentication ID of the user account for the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.UserAccount.SuperPrivilegesPresent Number If super privileges are present in this user account then 1, otherwise 0.
FireEyeNX.Alert.Explanation.OsChanges.Process.Timestamp Number The timestamp of the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.MemoryData String The memory data of the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.TelemetryData.LocalThreadCount Number The local thread count of the telemetry data in the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.TelemetryData.FileOpenCount Number The file open count of the telemetry data in the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.TelemetryData.FileModifyCount Number The file modify count of the telemetry data in the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.TelemetryData.FileCreateCount Number The file created count of the telemetry data in the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.TelemetryData.ChildProcessCount Number The file process count of the telemetry data in the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.TelemetryData.FileFailedCount Number The file failed count of the telemetry data in the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.TelemetryData.HttpReqCount Number The HTTP request count of the telemetry data in the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.TelemetryData.RemoteThreadCount Number The remote thread count of the telemetry data in the process.
FireEyeNX.Alert.Explanation.OsChanges.Process.TelemetryData.MutexCreateCount Number The mutex-created count of the telemetry data in the process.
FireEyeNX.Alert.Explanation.OsChanges.Regkey.Mode String The mode of the registry key.
FireEyeNX.Alert.Explanation.OsChanges.Regkey.Processinfo.Imagepath String The image path of the process in the registry key.
FireEyeNX.Alert.Explanation.OsChanges.Regkey.Processinfo.Md5sum String The md5sum of the process in the registry key.
FireEyeNX.Alert.Explanation.OsChanges.Regkey.Processinfo.Pid Number The PID of the process in the registry key.
FireEyeNX.Alert.Explanation.OsChanges.Regkey.Ntstatus String The NTSTATUS of the registry key.
FireEyeNX.Alert.Explanation.OsChanges.Regkey.Suppressed Boolean If the registry key was suppressed then true, otherwise false.
FireEyeNX.Alert.Explanation.OsChanges.Regkey.Value String The value of the registry key.
FireEyeNX.Alert.Explanation.OsChanges.Regkey.Timestamp Number The timestamp of the registry key.
FireEyeNX.Alert.Explanation.OsChanges.Regkey.SrcThread String The source thread name of the registry key.
FireEyeNX.Alert.Explanation.OsChanges.Regkey.Randomized Boolean If the registry key was randomized then true, otherwise false.
FireEyeNX.Alert.Explanation.OsChanges.Regkey.Buffered Boolean If the registry key was buffered then true, otherwise false.
FireEyeNX.Alert.Explanation.OsChanges.Regkey.NoExtend Boolean If the registry key has no_extend then true, otherwise false.
FireEyeNX.Alert.Explanation.OsChanges.Os.Name String The name of the operating system.
FireEyeNX.Alert.Explanation.OsChanges.Os.Arch String The architecture of the operating system.
FireEyeNX.Alert.Explanation.OsChanges.Os.Version String The version of the operating system.
FireEyeNX.Alert.Explanation.OsChanges.Os.Sp Number The service pack version of the operating system.
FireEyeNX.Alert.Explanation.OsChanges.OsMonitor.Date String The monitored date of the operating system.
FireEyeNX.Alert.Explanation.OsChanges.OsMonitor.Build Number The monitored build of the operating system.
FireEyeNX.Alert.Explanation.OsChanges.OsMonitor.Time String The monitored time of the operating system.
FireEyeNX.Alert.Explanation.OsChanges.OsMonitor.Version String The monitored version of the operating system.
FireEyeNX.Alert.Explanation.OsChanges.Analysis.Mode String The mode of the analysis.
FireEyeNX.Alert.Explanation.OsChanges.Analysis.Product String The product name of the analysis.
FireEyeNX.Alert.Explanation.OsChanges.Analysis.Ftype String The file type of the analysis.
FireEyeNX.Alert.Explanation.OsChanges.Analysis.Version String The version of the analysis.
FireEyeNX.Alert.Explanation.OsChanges.Network.Mode String The mode of the network.
FireEyeNX.Alert.Explanation.OsChanges.Network.ProtocolType String The protocol type of the network.
FireEyeNX.Alert.Explanation.OsChanges.Network.Ipaddress String The IP address of the network.
FireEyeNX.Alert.Explanation.OsChanges.Network.DestinationPort Number The destination port address of the network.
FireEyeNX.Alert.Explanation.OsChanges.Network.Processinfo.Imagepath String The image path of the process in the network.
FireEyeNX.Alert.Explanation.OsChanges.Network.Processinfo.Tainted Boolean If the process state is tainted then true, otherwise false for the network.
FireEyeNX.Alert.Explanation.OsChanges.Network.Processinfo.Md5sum String The md5sum of the process in the network.
FireEyeNX.Alert.Explanation.OsChanges.Network.Processinfo.Pid Number The PID of the process in the network.
FireEyeNX.Alert.Explanation.OsChanges.Network.HttpRequest String The HTTP request of the network.
FireEyeNX.Alert.Explanation.OsChanges.Network.Timestamp Number The timestamp of the network.
FireEyeNX.Alert.Explanation.OsChanges.Network.Hostname String The hostname of the network.
FireEyeNX.Alert.Explanation.OsChanges.Network.Qtype String The QTYPE of the network.
FireEyeNX.Alert.Explanation.OsChanges.Network.AnswerNumber Number The answer number of the network.
FireEyeNX.Alert.Explanation.OsChanges.Network.DnsResponseCode Number The DNS response code of the network.
FireEyeNX.Alert.Explanation.OsChanges.ActionFopen.Mode String The mode of opening the file.
FireEyeNX.Alert.Explanation.OsChanges.ActionFopen.Ext String The extension of opening the file.
FireEyeNX.Alert.Explanation.OsChanges.ActionFopen.Buffered Boolean If the opened file was buffered then true, otherwise false.
FireEyeNX.Alert.Explanation.OsChanges.ActionFopen.NoExtend Boolean If the opened file has no_extend then true, otherwise false.
FireEyeNX.Alert.Explanation.OsChanges.ActionFopen.Name String The name of the action for opening the file.
FireEyeNX.Alert.Explanation.OsChanges.ActionFopen.Timestamp Number The timestamp of opening the file.
FireEyeNX.Alert.Explanation.OsChanges.Exploitcode.Dllname String The DLL file name of the exploit code.
FireEyeNX.Alert.Explanation.OsChanges.Exploitcode.Apiname String The API name of the exploit code.
FireEyeNX.Alert.Explanation.OsChanges.Exploitcode.Address String The address of the exploit code.
FireEyeNX.Alert.Explanation.OsChanges.Exploitcode.Processinfo.Imagepath String The image path of the process in the exploit code.
FireEyeNX.Alert.Explanation.OsChanges.Exploitcode.Processinfo.Md5sum String The md5sum of the process in the exploit code.
FireEyeNX.Alert.Explanation.OsChanges.Exploitcode.Processinfo.Pid Number The PID of the process in the exploit code.
FireEyeNX.Alert.Explanation.OsChanges.Exploitcode.SrcThread String The source thread name of the exploit code.
FireEyeNX.Alert.Explanation.OsChanges.Exploitcode.Protection String The protection number of the exploit code.
FireEyeNX.Alert.Explanation.OsChanges.Exploitcode.Callstack.CallstackEntry.SymbolName String The symbol name of the call stack entry in the exploit code.
FireEyeNX.Alert.Explanation.OsChanges.Exploitcode.Callstack.CallstackEntry.FrameNumber Number The frame number of the call stack entries in the exploit code.
FireEyeNX.Alert.Explanation.OsChanges.Exploitcode.Callstack.CallstackEntry.ModuleName String The module name of the call stack entry in the exploit code.
FireEyeNX.Alert.Explanation.OsChanges.Exploitcode.Callstack.CallstackEntry.InstructionAddress String The instruction address of the call stack entry in the exploit code.
FireEyeNX.Alert.Explanation.OsChanges.Exploitcode.Callstack.CallstackEntry.SymbolDisplacement String The symbol displacement of the call stack entry in the exploit code.
FireEyeNX.Alert.Explanation.OsChanges.Exploitcode.Params.Param.Id Number The ID parameter of the exploit code.
FireEyeNX.Alert.Explanation.OsChanges.Exploitcode.Params.Param.Content String The path parameter of the exploit code.
FireEyeNX.Alert.Explanation.OsChanges.Exploitcode.Timestamp Number The timestamp of the exploit codes.
FireEyeNX.Alert.Explanation.OsChanges.Folder.Mode String The mode of the folder.
FireEyeNX.Alert.Explanation.OsChanges.Folder.Processinfo.Imagepath String The image path of the process in the folder.
FireEyeNX.Alert.Explanation.OsChanges.Folder.Processinfo.Md5sum String The md5sum of the process in the folder.
FireEyeNX.Alert.Explanation.OsChanges.Folder.Processinfo.Pid Number The PID of the process in the folder.
FireEyeNX.Alert.Explanation.OsChanges.Folder.SrcThread String The source thread name of the folder.
FireEyeNX.Alert.Explanation.OsChanges.Folder.Value String The path of the folder.
FireEyeNX.Alert.Explanation.OsChanges.Folder.Timestamp Number The timestamp of the folder.
FireEyeNX.Alert.Explanation.OsChanges.File.Mode String The mode of the file.
FireEyeNX.Alert.Explanation.OsChanges.File.Fid.Ads String The Alternate Data Stream (ADS) of the FID for the file.
FireEyeNX.Alert.Explanation.OsChanges.File.Fid.Content Number The content of the FID in the file.
FireEyeNX.Alert.Explanation.OsChanges.File.Processinfo.Imagepath String The image path of the process for the file.
FireEyeNX.Alert.Explanation.OsChanges.File.Processinfo.Md5sum String The md5sum of the process for the file.
FireEyeNX.Alert.Explanation.OsChanges.File.Processinfo.Pid Number The PID of the process for the file.
FireEyeNX.Alert.Explanation.OsChanges.File.Processinfo.Tainted Boolean If the process state is tainted then true, otherwise false for the file.
FireEyeNX.Alert.Explanation.OsChanges.File.SrcThread String The source thread name of the file.
FireEyeNX.Alert.Explanation.OsChanges.File.Ntstatus String The NTSTATUS of the file.
FireEyeNX.Alert.Explanation.OsChanges.File.Filesize Number The size of the file.
FireEyeNX.Alert.Explanation.OsChanges.File.Value String The value of the file.
FireEyeNX.Alert.Explanation.OsChanges.File.CreateOptions String The created option of the file.
FireEyeNX.Alert.Explanation.OsChanges.File.Timestamp Number The timestamp of the file.
FireEyeNX.Alert.Explanation.OsChanges.File.Type String The type of the file.
FireEyeNX.Alert.Explanation.OsChanges.File.Sha256sum String The sha256sum of the file.
FireEyeNX.Alert.Explanation.OsChanges.File.Sha1sum String The sha1sum of the file.
FireEyeNX.Alert.Explanation.OsChanges.File.PE.InspectionType String The inspection type of the portable executable file.
FireEyeNX.Alert.Explanation.OsChanges.File.PE.TimeDateStamp String The time date stamp of the portable executable file.
FireEyeNX.Alert.Explanation.OsChanges.File.PE.Characteristics.Names.Name Unknown The list of characteristic names in the portable executable file.
FireEyeNX.Alert.Explanation.OsChanges.File.PE.Characteristics.Value String The characteristic value in the portable executable file.
FireEyeNX.Alert.Explanation.OsChanges.File.PE.DllCharacteristics.Names String The characteristic name in the DLL portable executable file.
FireEyeNX.Alert.Explanation.OsChanges.File.PE.DllCharacteristics.Value String The characteristic value in the DLL portable executable file.
FireEyeNX.Alert.Explanation.OsChanges.File.PE.Dll String If the portable file is a DLL file then yes, otherwise no file.
FireEyeNX.Alert.Explanation.OsChanges.File.PE.Magic String The magic hex value of the portable executable file.
FireEyeNX.Alert.Explanation.OsChanges.File.PE.Subsystem String The subsystem of the portable executable file.
FireEyeNX.Alert.Explanation.OsChanges.File.PE.Machine String The hexadecimal address of the machine in the file.
FireEyeNX.Alert.Explanation.OsChanges.File.Md5sum String The md5sum of the file.
FireEyeNX.Alert.Explanation.OsChanges.Application.AppName String The app name of the application.
FireEyeNX.Alert.Explanation.OsChanges.QuerySystemTime.Processinfo.Imagepath String The image path of the queried system process.
FireEyeNX.Alert.Explanation.OsChanges.QuerySystemTime.Processinfo.Md5sum String The system time process info of the md5sum that is queried.
FireEyeNX.Alert.Explanation.OsChanges.QuerySystemTime.Processinfo.Pid Number The system time process info of the PID (process ID) that is queried
FireEyeNX.Alert.Explanation.OsChanges.QuerySystemTime.Ntstatus String The NTSTATUS of the system time that is queried.
FireEyeNX.Alert.Explanation.OsChanges.QuerySystemTime.Timestamp Number The timestamp of the system that is queried.
FireEyeNX.Alert.Explanation.OsChanges.QuerySystemTime.SystemTime.Value String The time value of the system that is queried.
FireEyeNX.Alert.Explanation.OsChanges.QuerySystemTime.SystemTime.Time String The time of the system that is queried.
FireEyeNX.Alert.Explanation.OsChanges.EndOfReport String The end of the report.
FireEyeNX.Alert.Explanation.OsChanges.MaliciousAlert.Classtype String The class type of the malicious alert.
FireEyeNX.Alert.Explanation.OsChanges.MaliciousAlert.DisplayMsg String The display message of the malicious alert.
FireEyeNX.Alert.Explanation.OsChanges.DialogDetected.Hwnd String The hexadecimal address of the dialog detected.
FireEyeNX.Alert.Explanation.OsChanges.DialogDetected.Processinfo.Imagepath String The image path of the process for the dialog detected.
FireEyeNX.Alert.Explanation.OsChanges.DialogDetected.Processinfo.Pid Number The PID of the process for the dialog detected.
FireEyeNX.Alert.Explanation.OsChanges.DialogDetected.Buffered Boolean A flag indicating whether the dialog detected is buffered.
FireEyeNX.Alert.Explanation.OsChanges.DialogDetected.NoExtend Boolean A flag indicating whether NoExtend is true in the dialog detected.
FireEyeNX.Alert.Explanation.OsChanges.DialogDetected.Timestamp Number The timestamp of the dialog detected.
FireEyeNX.Alert.Explanation.OsChanges.DialogDetected.DlgId String The dialog ID of the dialog detected.
FireEyeNX.Alert.Explanation.OsChanges.DialogDismissed.Note String A note in the dismissed dialog.
FireEyeNX.Alert.Explanation.OsChanges.DialogDismissed.Hwnd String The hexadecimal address of the dismissed dialog.
FireEyeNX.Alert.Explanation.OsChanges.DialogDismissed.Processinfo.Imagepath String The image path of the process for the dismissed dialog.
FireEyeNX.Alert.Explanation.OsChanges.DialogDismissed.Processinfo.Pid Number The PID of the process for the dismissed dialog.
FireEyeNX.Alert.Explanation.OsChanges.DialogDismissed.Buffered Boolean A flag indicating whether the dismissed dialog is buffered.
FireEyeNX.Alert.Explanation.OsChanges.DialogDismissed.NoExtend Boolean A flag indicating whether NoExtend is true in the dismissed dialog.
FireEyeNX.Alert.Explanation.OsChanges.DialogDismissed.Timestamp Number The timestamp of the dismissed dialog.
FireEyeNX.Alert.Explanation.OsChanges.DialogDismissed.DlgId String The dialog ID of the dismissed dialog.
FireEyeNX.Alert.Explanation.OsChanges.Wmiquery.Processinfo.Imagepath String The image path of the process for the Windows Management Instrumentation (WMI) query.
FireEyeNX.Alert.Explanation.OsChanges.Wmiquery.Processinfo.Md5sum String The md5sum of the process for the WMI query.
FireEyeNX.Alert.Explanation.OsChanges.Wmiquery.Processinfo.Pid Number The PID of the process for the WMI query.
FireEyeNX.Alert.Explanation.OsChanges.Wmiquery.Wmicontents.Wmiconent.Query String The query for the WMI content for WMI query.
FireEyeNX.Alert.Explanation.OsChanges.Wmiquery.Wmicontents.Wmicontent.Lang String Language of the WMI content for the WMI query.
FireEyeNX.Alert.Explanation.OsChanges.Wmiquery.Timestamp Number The timestamp of the WMI query.
FireEyeNX.Alert.Explanation.OsChanges.Wmiquery.Buffered Boolean A flag indicating whether the WMI query is buffered.
FireEyeNX.Alert.Explanation.OsChanges.Wmiquery.NoExtend Boolean A flag indicating whether NoExtend is true in the WMI query.
FireEyeNX.Alert.Explanation.OsChanges.Uac.Mode String The mode of the User Account Control (UAC).
FireEyeNX.Alert.Explanation.OsChanges.Uac.Value String The value of the User Account Control.
FireEyeNX.Alert.Explanation.OsChanges.Uac.Timestamp Number The timestamp of the User Account Control.
FireEyeNX.Alert.Explanation.OsChanges.Uac.Status String The status of the User Account Control.
FireEyeNX.Alert.Explanation.StaticAnalysis.Static.Value String The value of the static analysis.
FireEyeNX.Alert.Explanation.StolenData.Info.Field Unknown The information field of the stolen data.
FireEyeNX.Alert.Explanation.StolenData.Info.Type String The information type of the stolen data.
FireEyeNX.Alert.Explanation.StolenData.EventId Number The event ID of the stolen data.
FireEyeNX.Alert.Src.Ip String The source IP address of the alert.
FireEyeNX.Alert.Src.Mac String The source MAC address of the alert.
FireEyeNX.Alert.Src.Port Number The source port address of the alert.
FireEyeNX.Alert.Src.Host String The source host of the alert.
FireEyeNX.Alert.AlertUrl String The alert URL.
FireEyeNX.Alert.Action String The action of the alert.
FireEyeNX.Alert.Occurred String The time when the alert occurred.
FireEyeNX.Alert.AttackTime String The time when an attack occurred.
FireEyeNX.Alert.Dst.Mac String The destination MAC address of the alert.
FireEyeNX.Alert.Dst.Port Number The destination port address of the alert.
FireEyeNX.Alert.Dst.Ip String The destination IP address of the alert.
FireEyeNX.Alert.ApplianceId String The appliance ID of the alert.
FireEyeNX.Alert.Id Number The ID of the alert.
FireEyeNX.Alert.Name String The type of the alert.
FireEyeNX.Alert.Severity String The severity of the alert.
FireEyeNX.Alert.Uuid String The universally unique identifier (UUID) of the alert.
FireEyeNX.Alert.Ack String A flag indicating whether an acknowledgment is received.
FireEyeNX.Alert.Product String The product name of the alert.
FireEyeNX.Alert.Vlan Number The virtual LAN (VLAN) of the alert.
FireEyeNX.Alert.Malicious String A flag indicating whether the alert is malicious.
FireEyeNX.Alert.ScVersion String The SC version of the alert.

Command Example


#### Context Example

{
“FireEyeNX”: {
“Alert”: [
{
“Ack”: “no”,
“Action”: “notified”,
“AlertUrl”: “https://fireeye-941918/event_stream/events_for_bot?ev_id=11364”,
“ApplianceId”: “866ED7558A08”,
“AttackTime”: “2020-09-29 18:30:01 +0000”,
“Dst”: {
“Mac”: “xx:xx:xx:xx:xx:xx”,
“Ip”: “1.1.1.1”,
“Port”: 0
},
“Explanation”: {
“MalwareDetected”: {
“Malware”: [
{
“Name”: “dummy malware name 1”
}
]
}
},
“Id”: 1,
“Malicious”: “yes”,
“Name”: “dummy name 1”,
“Occurred”: “0000-00-00 02:12:53 +0000”,
“Product”: “WEB_MPS”,
“ScVersion”: “1.000”,
“Severity”: “MINR”,
“Src”: {
“Ip”: “1.1.1.1”,
“Port”: 0,
“Mac”: “xx:xx:xx:xx:xx:xx”
},
“Uuid”: “0b0b0b0b0-0b0b0b-0b0b-0b0b-0b0b0b0b0b”,
“Vlan”: 0
},
{
“Ack”: “no”,
“Action”: “notified”,
“AlertUrl”: “https://fireeye-941918/event_stream/events_for_bot?ev_id=11365”,
“ApplianceId”: “866ED7558A08”,
“AttackTime”: “2020-09-29 19:00:01 +0000”,
“Dst”: {
“Mac”: “xx:xx:xx:xx:xx:xx”,
“Ip”: “1.1.1.1”,
“Port”: 0
},
“Explanation”: {
“MalwareDetected”: {
“Malware”: [
{
“Name”: “dummy malware name 2”
}
]
}
},
“Id”: 2,
“Malicious”: “yes”,
“Name”: “dummy name 2”,
“Occurred”: “0000-00-00 02:12:53 +0000”,
“Product”: “WEB_MPS”,
“ScVersion”: “1.000”,
“Severity”: “MINR”,
“Src”: {
“Ip”: “1.1.1.1”,
“Port”: 0,
“Mac”: “xx:xx:xx:xx:xx:xx”
},
“Uuid”: “0a0a0a0a0-0a0a0a-0a0a-0a0a-0a0a0a0a0a”,
“Vlan”: 0
}
]
}
}


#### Human Readable Output

>### Alert(s) Information
>
>|ID|Distinguisher(UUID)|Malware Name|Alert Type|Victim IP|Time (UTC)|Severity|Malicious|SC Version|Victim Port|Victim MAC Address|Target IP|Target Port|Target MAC Address|
>|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
>| 1 | 0b0b0b0b0-0b0b0b-0b0b-0b0b-0b0b0b0b0b | dummy malware name 1 | dummy name 1 | 1.1.1.1 | 0000-00-00 02:12:53 +0000 | MINR | yes | 1.000 | 0 | xx:xx:xx:xx:xx:xx | 1.1.1.1 | 0 | xx:xx:xx:xx:xx:xx |
>| 2 | 0a0a0a0a0-0a0a0a-0a0a-0a0a-0a0a0a0a0a | dummy malware name 2 | dummy name 2 | 1.1.1.1 | 0000-00-00 02:12:53 +0000 | MINR | yes | 1.000 | 0 | xx:xx:xx:xx:xx:xx | 1.1.1.1 | 0 | xx:xx:xx:xx:xx:xx |

### fireeye-nx-get-artifacts-metadata-by-alert

***
Gets malware artifacts metadata for the specified UUID.

#### Base Command

`fireeye-nx-get-artifacts-metadata-by-alert`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| uuid | Universally unique ID (UUID) of the alert. To retrieve the UUID, execute the fireeye-nx-get-alerts command. | Required |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| FireEyeNX.Alert.Uuid | String | Universally unique ID \(UUID\) of the alert. |
| FireEyeNX.Alert.ArtifactsMetadata.ArtifactType | String | The artifact type. |
| FireEyeNX.Alert.ArtifactsMetadata.ArtifactName | String | The artifact name. |
| FireEyeNX.Alert.ArtifactsMetadata.ArtifactSize | String | The artifact size. |

#### Command Example

```!fireeye-nx-get-artifacts-metadata-by-alert uuid=0b0b0b0b-0b0b-0b0b-0b0b-0b0b0b0b0b0b```

#### Context Example

{
“FireEyeNX”: {
“Alert”: {
“ArtifactsMetadata”: [
{
“ArtifactType”: “artifact type test 1”,
“ArtifactName”: “artifact name test 1”,
“ArtifactSize”: “1010”
},
{
“ArtifactType”: “artifact type test 2”,
“ArtifactName”: “artifact name test 2”,
“ArtifactSize”: “1010”
}
],
“Uuid”: “0b0b0b0b-0b0b-0b0b-0b0b-0b0b0b0b0b0b”
}
}
}


#### Human Readable Output

>### Artifacts Metadata
>
>|Artifact Type|Artifact Name|Artifact Size (Bytes)|
>|---|---|---|
>| artifact type test 1 | artifact name test 1 | 1010 |
>| artifact type test 2 | artifact name test 2 | 1010 |

### fireeye-nx-get-artifacts-by-alert

***
Downloads malware artifacts data for the specified UUID as a zip file.

#### Base Command

`fireeye-nx-get-artifacts-by-alert`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| uuid | The universally unique ID (UUID) of the alert. To get the UUID, execute the fireeye-nx-get-alerts command. | Required |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| File.Size | Number | The size of the file. |
| File.SHA1 | String | The SHA1 hash of the file. |
| File.SHA256 | String | The SHA256 hash of the file. |
| File.Name | String | The name of the file. |
| File.SSDeep | String | The SSDeep hash of the file. |
| File.EntryID | String | The entry ID of the file. |
| File.Info | String | The file information. |
| File.Type | String | The file type. |
| File.MD5 | String | The MD5 hash of the file. |
| File.Extension | String | The file extension. |

#### Command Example

```!fireeye-nx-get-artifacts-by-alert uuid=0b0b0b0b-0b0b-0b0b-0b0b-0b0b0b0b0b0b```

#### Context Example

{
“File”: {
“Size”: 17277,
“SHA1”: “574352bb238d3379429063d71990c0000000000”,
“SHA256”: “1f8ac8eaba9abaf9d12b9b82180a110eab15b14aeec14715f48b4dedaaaaaaaaa”,
“Name”: “0b0b0b0b-0b0b-0b0b-0b0b-0b0b0b0b0b0b.zip”,
“SSDeep”: “000:aaaaaa/aAaAaAaA+AaAaAaAaA:aa0/aAaAaAaAaAaAaA”,
“EntryID”: “150@1”,
“Info”: “zip”,
“Type”: “Zip archive data, at least v1.0 to extract”,
“MD5”: “1aA1aA1aA1aA1aA1aA1aA1aA”,
“Extension”: “zip”
}
}


### fireeye-nx-get-reports

***
Returns reports on selected alerts by specifying a time_frame value or a start_time and end_time of the search range.

#### Base Command

`fireeye-nx-get-reports`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| report_type | The type of report to be queried. | Required |
| type | The output format of the report. Possible values are: "csv" and "pdf", or both depending upon the report type. | Optional |
| start_time | The start time of the search. The search occurs between the start and end times. When specifying a start_time value, you must specify both a start_time and an end_ time value.<br/> Formats:<br/>YYYY-MM-dd<br/>YYYY-MM-ddTHH:mm:ss<br/>N days <br/>N hours<br/>Example:<br/> 2020-05-01 <br/> 2020-05-01T00:00:00 <br/> 2 days <br/> 5 hours. | Optional |
| end_time | The end time of the search. The search occurs between the start and end times. When specifying an end_time value, you must specify both a start_time and an end_time value.<br/> Formats:<br/>YYYY-MM-dd<br/>YYYY-MM-ddTHH:mm:ss<br/>N days <br/>N hours<br/>Example:<br/> 2020-05-01 <br/> 2020-05-01T00:00:00 <br/> 2 days <br/> 5 hours. | Optional |
| time_frame | The time frame in which reports are searched. | Optional |
| limit | The maximum number (N) of items covered by each IPS Top N report. This argument is required only for IPS Top N reports. Possible values are: "25", "50", "75", and "100". | Optional |
| interface | The internet interface. Possible values are: "A", "B", "C", "D", "AB", and "All". This option is required only for IPS reports. | Optional |
| infection_id | The alert ID. To retrieve the alert ID, execute the fireeye-nx-get-alerts command. Use the combination of infection_id and infection_type arguments to specify a unique alert to describe in the Alert Details Report. If one option is used alone and does not specify a unique alert, an error message is produced. | Optional |
| infection_type | The type of the infection. Use the combination of infection_id and infection_type arguments to specify a unique alert to describe in the Alert Details Report. If one option is used alone and does not specify a unique alert, an error message is produced. Possible values are: "malware-object", "malware-callback", "infection-match", "domain-match", and "web-infection". | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| InfoFile.Name | String | The file name. |
| InfoFile.EntryID | String | The ID for locating the file in the War Room. |
| InfoFile.Size | Number | The size of the file \(in bytes\). |
| InfoFile.Type | String | The file type, as determined by libmagic \(same as displayed in the file entries\). |
| InfoFile.Extension | String | The file extension. |
| InfoFile.Info | String | Basic information about the file. |

#### Command Example

```!fireeye-nx-get-reports report_type="IPS Executive Summary Report" type=csv time_frame=between start_time=2020-01-29T23:59:59 end_time=2020-08-29T23:59:59```

#### Context Example

{
“InfoFile”: {
“EntryID”: “1052@8db8b36d-df26-4a3a-8f8a-40e45629ff54”,
“Extension”: “csv”,
“Info”: “csv”,
“Name”: “ips_executive_summary_report_fireeye_20200709_151727878642.csv”,
“Size”: 606,
“Type”: “ASCII text”
}
}


### fireeye-nx-get-events

***
Search and retrieve FireEye events based on several filters.

#### Base Command

`fireeye-nx-get-events`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| duration | The time interval to search. This filter is used with the end_time filter. If the duration is not specified, the system defaults to duration=12_hours, end_time=current_time. | Optional |
| start_time | The start time of the search. This filter is used with the duration filter. If the start_time is specified but not the duration, the system defaults to duration=12_hours, starting at the specified start_time.<br/>Formats:<br/>YYYY-MM-dd<br/>YYYY-MM-ddTHH:mm:ss<br/>N days <br/>N hours<br/>Example:<br/> 2020-05-01 <br/> 2020-05-01T00:00:00 <br/> 2 days <br/> 5 hours | Optional |
| end_time | The end time of the search. This filter is used with the duration filter. If the end_time is specified but not the duration, the system defaults to duration=12_hours, ending at the specified end_time. <br/>Formats:<br/>YYYY-MM-dd<br/>YYYY-MM-ddTHH:mm:ss<br/>N days <br/>N hours<br/>Example:<br/> 2020-05-01 <br/> 2020-05-01T00:00:00 <br/> 2 days <br/> 5 hours | Optional |
| mvx_correlated_only | Whether to include all IPS events or MVX-correlated events only. Default: false | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| FireEyeNX.Event.EventId | Number | The ID of the event. |
| FireEyeNX.Event.Occurred | String | The date and time when the event occurred. |
| FireEyeNX.Event.SrcIp | String | The IP address of the victim. |
| FireEyeNX.Event.SrcPort | Number | The port number of the victim. |
| FireEyeNX.Event.DstIp | String | The IP address of the attacker. |
| FireEyeNX.Event.DstPort | Number | The port number of the attacker. |
| FireEyeNX.Event.Severity | Number | The severity level of the event. |
| FireEyeNX.Event.SignatureRev | Number | The signature revision number of the event. |
| FireEyeNX.Event.SignatureIden | Number | The signature identity number of the event. |
| FireEyeNX.Event.SignatureMatchCnt | Number | The signature match count number of the event. |
| FireEyeNX.Event.Vlan | Number | The virtual LAN \(VLAN\) of the event. |
| FireEyeNX.Event.VmVerified | Boolean | Whether the event VM was verified. |
| FireEyeNX.Event.SrcMac | String | The MAC address of the source machine. |
| FireEyeNX.Event.DstMac | String | The MAC address of the destination machine. |
| FireEyeNX.Event.RuleName | String | The rule name for the event. |
| FireEyeNX.Event.SensorId | String | The sensor ID of the FireEye machine. |
| FireEyeNX.Event.CveId | String | The CVE ID found in the event. |
| FireEyeNX.Event.ActionTaken | Number | The IPS blocking action taken on the event. |
| FireEyeNX.Event.AttackMode | String | The attack mode mentioned in the event. |
| FireEyeNX.Event.InterfaceId | Number | The interface ID of the event. |
| FireEyeNX.Event.Protocol | Number | The protocol used in the event. |
| FireEyeNX.Event.IncidentId | Number | The incident ID of the event on FireEye. |

#### Command Example

```!fireeye-nx-get-events duration=48_hours end_time=2020-08-10T06:31:00```

#### Context Example

{
“FireEyeNX”: {
“Event”: [
{
“EventId”:1,
“Occurred”:”2020-08-10T06:31:00Z”,
“SrcIp”:”1.1.1.1”,
“SrcPort”:1,
“DstIp”:”1.1.1.1”,
“DstPort”:1,
“Vlan”:0,
“SignatureMatchCnt”:1,
“SignatureIden”:1,
“SignatureRev”:1,
“Severity”:1,
“VmVerified”:true,
“SrcMac”:”dummy”,
“DstMac”:”dummy”,
“RuleName”:”dummy”,
“SensorId”:”dummy”,
“CveId”:”CVE-123”,
“ActionTaken”:1,
“AttackMode”:”dummy”,
“InterfaceId”:1,
“Protocol”:1,
“IncidentId”:1
}
]
}
}
```

Human Readable Output

IPS Events

Event ID Time (UTC) Victim IP Attacker IP CVE ID Severity Rule Protocol
1 2020-08-10T06:31:00Z 1.1.1.1 1.1.1.1 CVE-123 1 dummy 1

Configuration parameters

  • url — URL (required)
  • credentials — Username (required)
  • request_timeout — HTTP(S) Request Timeout (in seconds)
  • isFetch — Fetch incidents
  • incidentType — Incident type
  • incidentFetchInterval — Incidents Fetch Interval
  • first_fetch — First fetch time interval
  • max_fetch — Fetch Limit
  • fetch_type — Fetch Types
  • fetch_mvx_correlated_events — Fetches MVX-correlated events only
  • malware_type — Alert Malware Type
  • replace_alert_url — Use instance URL for all the fetched alerts URL.
  • fetch_artifacts — Fetch artifacts for each alert
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (5)

  • fireeye-nx-get-alerts

    Search and retrieve FireEye alerts based on several filters.

  • fireeye-nx-get-artifacts-by-alert

    Downloads malware artifacts data for the specified UUID as a zip file.

  • fireeye-nx-get-artifacts-metadata-by-alert

    Gets malware artifacts metadata for the specified UUID.

  • fireeye-nx-get-events

    Search and retrieve FireEye events based on several filters.

  • fireeye-nx-get-reports

    Returns reports on selected alerts by specifying a time_frame value or a start_time and end_time of the search range.

from datetime import UTC
from unittest import mock
from unittest.mock import patch

import pytest
from CommonServerPython import *
from requests import Response
from requests.exceptions import (
    HTTPError,
    InvalidSchema,
    InvalidURL,
    MissingSchema,
    SSLError,
)

API_TOKEN = "API Token for FireEye"
CONTENT_TYPE_JSON = "application/json"
SAMPLE_URL = "https://sample.api.com"

AUTHENTICATION_RESP_HEADER = {
    "X-FeApi-Token": API_TOKEN,
    "Content-Type": CONTENT_TYPE_JSON,
}

MOCK_INTEGRATION_CONTEXT = {
    "api_token": API_TOKEN,
    "valid_until": time.time() + 900,
}

PARAMS = {
    "url": SAMPLE_URL,
    "fetch_limit": 10,
    "firstFetchTimestamp": "1 hour",
}

MOCK_TEST_URL_SUFFIX = "/test/url/suffix"

ALERT_ID_TYPE_ERROR = "The given value for alert_id is invalid. Expected integer value."
ALERT_DETAILS_REPORT = "Alert Details Report"
CONTENT_TYPE_ZIP = "application/zip"

""" HELPER FUNCTION"""


@pytest.fixture()
def client():
    from FireEyeNX import Client

    return Client(
        base_url=SAMPLE_URL,
        verify=False,
        proxy=False,
        auth=("username", "password"),
        request_timeout=60,
    )


def mock_http_response(
    status=200,
    headers=None,
    json_data=None,
    raise_for_status=None,
    text=None,
    content=None,
):
    mock_resp = mock.Mock()
    # mock raise_for_status call w/optional error
    mock_resp.raise_for_status = mock.Mock()
    if raise_for_status:
        mock_resp.raise_for_status.side_effect = raise_for_status
    # set status code
    mock_resp.status_code = status
    # add header if provided
    mock_resp.text = text
    mock_resp.content = content
    if headers:
        mock_resp.headers = headers
    mock_resp.ok = status < 400
    # add json data if provided
    if json_data:
        mock_resp.json = mock.Mock(return_value=json_data)
    return mock_resp


class MockResponse:
    def __init__(self, content, headers, status_code):
        self.content = content
        self.status_code = status_code
        self.headers = headers

    def text(self):
        return self.content

    def json(self):
        return json.loads(self.content)

    def raise_for_status(self):
        if self.status_code != 200:
            raise HTTPError("test")


""" Unit Test Cases """


@patch("FireEyeNX.Client.http_request")
@patch("demistomock.getIntegrationContext")
@patch("demistomock.setIntegrationContext")
def test_get_api_token_when_not_found_in_integration_context(mocker_set_context, mocker_get_context, mock_request, client):
    """
    When get_api_token method called and headers is set with X-FeApi-Token also call_count is one,
    it should match.
    """
    mocker_get_context.return_value = {}
    mocker_set_context.return_value = {}

    mock_request.return_value = mock_http_response(status=200, headers=AUTHENTICATION_RESP_HEADER, text="")

    api_token = client.get_api_token()

    assert api_token == AUTHENTICATION_RESP_HEADER["X-FeApi-Token"]
    assert mocker_set_context.call_count == 1


@patch("FireEyeNX.Client._http_request")
@patch("demistomock.getIntegrationContext")
@patch("demistomock.setIntegrationContext")
def test_get_api_token_when_found_in_integration_context(mocker_set_context, mocker_get_context, mock_request, client):
    """
    When get_api_token method called and headers is set with X-FeApi-Token also call_count is zero, it should match.
    """
    mocker_get_context.return_value = MOCK_INTEGRATION_CONTEXT
    mocker_set_context.return_value = {}

    mock_request.return_value = mock_http_response(status=200, headers=AUTHENTICATION_RESP_HEADER, text="")

    api_token = client.get_api_token()

    assert api_token == AUTHENTICATION_RESP_HEADER["X-FeApi-Token"]
    assert mocker_set_context.call_count == 0


@patch("FireEyeNX.BaseClient._http_request")
def test_http_request_invalid_schema_error(mock_base_http_request, client):
    """
    When http request return invalid schema exception then appropriate error message should match.
    """
    # Configure
    mock_base_http_request.side_effect = InvalidSchema

    # Execute
    with pytest.raises(ValueError) as e:
        client.http_request("GET", MOCK_TEST_URL_SUFFIX)

    # Assert
    assert str(e.value) == "Invalid API URL. Supplied schema is invalid, supports http(s)."


@patch("FireEyeNX.BaseClient._http_request")
def test_http_proxy_error(mock_base_http_request, client):
    """
    When http request return proxy error with exception then appropriate error message should match.
    """
    # Configure
    mock_base_http_request.side_effect = DemistoException("Proxy Error")

    # Execute
    with pytest.raises(ConnectionError) as e:
        client.http_request("GET", MOCK_TEST_URL_SUFFIX)

    # Assert
    assert (
        str(e.value) == "Proxy Error - cannot connect to proxy. Either try clearing the 'Use system proxy'"
        " check-box or check the host, authentication details and connection details for the proxy."
    )


@patch("FireEyeNX.Client._http_request")
def test_http_request_connection_error(mock_base_http_request, client):
    """
    When http request return connection error with Demisto exception then appropriate error message should match.
    """
    # Configure
    mock_base_http_request.side_effect = DemistoException("ConnectionError")

    # Execute
    with pytest.raises(ConnectionError) as e:
        client.http_request("GET", MOCK_TEST_URL_SUFFIX)

    # Assert
    assert str(e.value) == "Connectivity failed. Check your internet connection or the API URL."


@patch("FireEyeNX.BaseClient._http_request")
def test_http_request_read_timeout_error(mock_base_http_request, client):
    """
    When http request return connection error with Demisto exception then appropriate error message should match.
    """
    # Configure
    mock_base_http_request.side_effect = DemistoException("ReadTimeoutError")

    # Execute
    with pytest.raises(ConnectionError) as e:
        client.http_request("GET", MOCK_TEST_URL_SUFFIX)

    # Assert
    assert str(e.value) == "Request timed out. Check the configured HTTP(S) Request Timeout (in seconds) value."


@patch("FireEyeNX.BaseClient._http_request")
def test_http_ssl_error(mock_base_http_request, client):
    """
    When http request return ssl error with Demisto exception then appropriate error message should match.
    """
    # Configure
    mock_base_http_request.side_effect = DemistoException("SSLError")
    # Execute
    with pytest.raises(SSLError) as e:
        client.http_request("GET", MOCK_TEST_URL_SUFFIX)

    # Assert
    assert (
        str(e.value) == "SSL Certificate Verification Failed - try selecting 'Trust any certificate' checkbox "
        "in the integration configuration."
    )


@patch("FireEyeNX.BaseClient._http_request")
def test_http_request_missing_schema_error(mock_base_http_request, client):
    """
    When http request return MissingSchema exception then appropriate error message should display.
    """
    # Configure
    mock_base_http_request.side_effect = MissingSchema

    # Execute
    with pytest.raises(ValueError) as e:
        client.http_request("GET", MOCK_TEST_URL_SUFFIX)

    # Assert
    assert str(e.value) == "Invalid API URL. No schema supplied: http(s)."


@patch("FireEyeNX.BaseClient._http_request")
def test_http_request_invalid_url_error(mock_base_http_request, client):
    """
    When http request return invalid url exception then appropriate error message should match.
    """
    # Configure
    mock_base_http_request.side_effect = InvalidURL

    # Execute
    with pytest.raises(ValueError) as e:
        client.http_request("GET", MOCK_TEST_URL_SUFFIX)

    # Assert
    assert str(e.value) == "Invalid API URL."


@patch("FireEyeNX.BaseClient._http_request")
def test_http_request_other_demisto_exception(mock_base_http_request, client):
    """
    When http request return other custom Demisto exception then appropriate error message should match.
    """
    # Configure
    mock_base_http_request.side_effect = DemistoException("custom")

    # Execute
    with pytest.raises(Exception) as e:
        client.http_request("GET", MOCK_TEST_URL_SUFFIX)

    # Assert
    assert str(e.value) == "custom"


def test_main_success(mocker):
    """
    When main function called test function should call.
    """
    import FireEyeNX

    mocker.patch.object(demisto, "params", return_value=PARAMS)
    mocker.patch.object(demisto, "command", return_value="test-module")
    mocker.patch.object(FireEyeNX, "test_function", return_value="ok")
    FireEyeNX.main()
    assert FireEyeNX.test_function.called


def test_strip_blank():
    import FireEyeNX

    args = {
        "malware_name": " malware_name ",
        "malware_type": " domain_match ",
        "url": SAMPLE_URL,
    }
    actual_output = {
        "malware_name": "malware_name",
        "malware_type": "domain_match",
        "url": SAMPLE_URL,
    }
    assert FireEyeNX.strip_blank(args) == actual_output


def test_main_strip_blank_called(mocker):
    import FireEyeNX

    mocker.patch.object(demisto, "params", return_value=PARAMS)
    mocker.patch.object(demisto, "command", return_value="fireeye-nx-get-alerts")
    mocker.patch.object(FireEyeNX, "get_alerts_command", return_value="ok")
    args = {
        "malware_name": " malware_name ",
        "malware_type": " domain_match ",
        "url": SAMPLE_URL,
    }
    mocker.patch.object(demisto, "args", return_value=args)
    strip_blank = mocker.patch.object(FireEyeNX, "strip_blank")
    FireEyeNX.main()
    assert strip_blank.call_count > 0


def test_main_when_fetch_incident_called_it_should_called_fetch_incident_method(
    mocker,
):
    import FireEyeNX

    mocker.patch.object(demisto, "params", return_value=PARAMS)
    mocker.patch.object(demisto, "command", return_value="fetch-incidents")
    mocker.patch.object(FireEyeNX, "fetch_incidents", return_value="ok")
    mocker.patch.object(demisto, "setLastRun", return_value="")
    mocker.patch.object(demisto, "incidents", return_value="")
    FireEyeNX.main()


@patch("FireEyeNX.return_error")
def test_main_failure(mock_return_error, mocker):
    """
    When main function get some exception then valid message should be print.
    """
    import FireEyeNX

    mocker.patch.object(demisto, "error")
    mocker.patch.object(demisto, "params", return_value=PARAMS)
    mocker.patch.object(demisto, "command", return_value="test-module")
    mocker.patch.object(FireEyeNX, "test_function", side_effect=Exception)
    FireEyeNX.main()

    mock_return_error.assert_called_once_with("Error: ")


@patch("FireEyeNX.BaseClient._http_request")
def test_module_success_without_test_fetch_incident(mock_request, client):
    """
    When test_function called with status code 200 without is_fetch=false, it successful return ok.
    """
    from FireEyeNX import test_function

    mock_request.return_value = mock_http_response(status=200, headers=AUTHENTICATION_RESP_HEADER, text="")
    first_fetch_time = "12 hours"
    fetch_limit = "1"
    malware_type = ""
    is_fetch = False
    fetch_type = "Alert"
    mvx_correlated = False
    replace_alert_url = False
    instance_url = SAMPLE_URL
    fetch_artifacts = False

    resp = test_function(
        client=client,
        first_fetch_time=first_fetch_time,
        fetch_limit=fetch_limit,
        malware_type=malware_type,
        is_fetch=is_fetch,
        fetch_type=fetch_type,
        mvx_correlated=mvx_correlated,
        replace_alert_url=replace_alert_url,
        instance_url=instance_url,
        fetch_artifacts=fetch_artifacts,
    )

    assert resp == "ok"


@patch("FireEyeNX.get_incidents_for_alert")
@patch("FireEyeNX.BaseClient._http_request")
def test_module_success_with_fetch_incident(mock_get_alert, mock_request, client):
    """
    When test_function called with status code 200 without is_fetch=False, it successful return ok.
    """
    from FireEyeNX import test_function

    mock_get_alert.return_value = []
    mock_last_run = {"alerts": {"start_time": datetime.now().replace(tzinfo=UTC).timestamp(), "alert_ids": ["1"]}}

    mock_request.return_value = mock_http_response(status=200, headers=AUTHENTICATION_RESP_HEADER, text="")
    first_fetch_time = "12 hours"
    fetch_limit = "1"
    malware_type = None
    is_fetch = True
    fetch_type = "Alert"
    mvx_correlated = False
    replace_alert_url = False
    instance_url = SAMPLE_URL
    fetch_artifacts = False
    resp = test_function(
        client=client,
        first_fetch_time=first_fetch_time,
        fetch_limit=fetch_limit,
        malware_type=malware_type,
        is_fetch=is_fetch,
        fetch_type=fetch_type,
        mvx_correlated=mvx_correlated,
        replace_alert_url=replace_alert_url,
        instance_url=instance_url,
        fetch_artifacts=fetch_artifacts,
        last_run=mock_last_run,
    )

    assert resp == "ok"


def test_validate_date_range_failure():
    """
    When validate_date_range_failure() method call and date more then 48 hour then raise value error.
    """
    from FireEyeNX import validate_date_range

    fetch_time = "49 hours"

    with pytest.raises(ValueError) as e:
        validate_date_range(fetch_time)

    assert str(e.value) == "The First fetch time interval should be up to 48 hour as per API limitation."


def test_fetch_limit_when_valid_value_success(mocker):
    """
    When valid fetch_limit is given, test should pass.
    """
    from FireEyeNX import get_fetch_limit

    mocker.patch.object(demisto, "params", return_value=PARAMS)

    fetch_limit = get_fetch_limit(fetch_limit="")
    assert fetch_limit == 50


@pytest.mark.parametrize("inputs", ["0", "201", "dfdf"])
def test_fetch_limit_when_invalid_value_should_raise_exception(mocker, inputs):
    """
    When invalid fetch limit is passed, should raises value error.
    """
    from FireEyeNX import get_fetch_limit

    mocker.patch.object(demisto, "params", return_value={"fetch_limit": inputs})

    with pytest.raises(ValueError) as e:
        get_fetch_limit(inputs)

    assert str(e.value) == "Value of Fetch Limit should be an integer and between range 1 to 200."


def test_command_called_from_main_success(mocker, client):
    """
    When main function is called get_reports_command should be called if that command is triggered.
    """
    import FireEyeNX

    mocker.patch.object(demisto, "command", return_value="fireeye-nx-get-reports")
    mocker.patch.object(
        FireEyeNX,
        "get_reports_command",
        return_value="No report contents were found for the given argument(s).",
    )
    FireEyeNX.main()
    assert FireEyeNX.get_reports_command.called


@patch("FireEyeNX.Client.http_request")
def test_get_artifacts_metadata_by_alert_command_invalid_uuid(client):
    """
    When fireeye-nx-get-artifacts-metadata-by-alert command executes with uuid and it failure due to
    artifacts metadata is not present.
    """
    from FireEyeNX import get_artifacts_metadata_by_alert_command

    client.http_request.return_value = {"artifactsInfoList": []}

    args = {"uuid": "abc-dsh-didA"}
    return_value = get_artifacts_metadata_by_alert_command(client, args)

    assert return_value == "No artifacts metadata were found for the given argument(s)."


@patch("FireEyeNX.Client.http_request")
def test_get_artifacts_metadata_by_alert_command_success(client):
    """
    When fireeye-nx-get-artifacts-metadata-by-alert command executes successfully then context output and
    response should match.
    """
    from FireEyeNX import get_artifacts_metadata_by_alert_command

    args = {"uuid": "test"}

    with open("TestData/get_artifacts_metadata_by_alert_response.json") as f:
        expected_res = json.load(f)

    client.http_request.return_value = expected_res

    cmd_res = get_artifacts_metadata_by_alert_command(client, args)
    with open(
        "TestData/get_artifacts_metadata_by_alert_context.json",
        encoding="utf-8",
    ) as f:
        expected_ec = json.load(f)

    with open("TestData/get_artifacts_metadata.md") as f:
        expected_hr = f.read()

    assert cmd_res.raw_response == expected_res
    assert cmd_res.outputs == expected_ec
    assert cmd_res.readable_output == expected_hr


@patch("FireEyeNX.BaseClient._http_request")
@pytest.mark.parametrize(
    "args",
    [
        {
            "report_type": ALERT_DETAILS_REPORT,
            "type": "pdf",
            "time_frame": "between",
            "start_time": "2020-01-29",
            "end_time": "2020-02-29T23:59:59+13:00",
            "infection_id": "rt",
            "infection_type": "all",
        },
        {
            "report_type": ALERT_DETAILS_REPORT,
            "type": "pdf",
            "time_frame": "between",
            "start_time": "2020-01-29T23:59:59+13:01",
            "end_time": "2020-02-29",
            "infection_id": "rt",
            "infection_type": "all",
        },
    ],
)
def test_get_reports_success(mock_request, args, client):
    """
    When fireeye-nx-get-reports command execute and passed valid arguments, it should be successful.
    """
    from FireEyeNX import get_reports_command

    with open("TestData/get_reports_response.pdf", encoding="utf-8") as f:
        expected_res = f.read()

    headers = {
        "X-FeApi-Token": API_TOKEN,
        "Content-Type": "application/pdf",
        "Content-Length": 56,
    }

    mock_request.return_value = mock_http_response(status=200, headers=headers, content=expected_res)

    result = get_reports_command(client, args=args)
    assert result.get("File", "") != ""
    assert result.get("FileID", "") != ""


@patch("FireEyeNX.BaseClient._http_request")
def test_get_reports_no_records_found(mock_request, client):
    """
    When fireeye-nx-get-reports command returns empty response then corresponding message should be populated.
    """
    from FireEyeNX import get_reports_command

    with open("TestData/get_reports_response.pdf", encoding="utf-8") as f:
        expected_res = f.read()

    headers = {
        "X-FeApi-Token": API_TOKEN,
        "Content-Type": "application/pdf",
        "Content-Length": 0,
    }

    mock_request.return_value = mock_http_response(status=200, headers=headers, content=expected_res)

    args = {
        "report_type": "IPS Top N Attackers Report",
        "limit": 56,
        "interface": "C",
        "type": "csv",
    }

    result = get_reports_command(client, args=args)
    assert result == "No report contents were found for the given argument(s)."


def test_reports_command_invalid_report_type(client):
    """
    When fireeye-nx-get-reports command is provided invalid report type argument
    it should give an error message.
    """
    from FireEyeNX import get_reports_params

    args = {"report_type": "XYZ"}
    with pytest.raises(ValueError) as e:
        get_reports_params(args=args)

    assert str(e.value) == "The given value for report_type is invalid."


def test_reports_command_invalid_output_type(client):
    """
    When fireeye-nx-get-reports command is provided invalid output type argument
    it should give an error message.
    """
    from FireEyeNX import get_reports_params

    args = {"report_type": ALERT_DETAILS_REPORT, "type": "csv"}
    with pytest.raises(ValueError) as e:
        get_reports_params(args=args)

    assert str(e.value) == "The given value for the argument type (report's format) is invalid. Valid value(s): pdf."


def test_reports_command_invalid_limit(client):
    """
    When fireeye-nx-get-reports command is provided with invalid value of limit it should give an error message.
    """
    from FireEyeNX import get_reports_params

    args = {
        "report_type": "IPS Top N Attackers Report",
        "limit": "dummy",
        "end_time": "--",
    }
    with pytest.raises(ValueError) as e:
        get_reports_params(args=args)

    assert str(e.value) == "The given value for limit is invalid. Expected integer value."


def test_reports_command_missing_alert_argument():
    """
    When fireeye-nx-get-reports command is provided with same value of
    start_time and end_time it should give an error message.
    """
    from FireEyeNX import get_reports_params

    args = {"report_type": ALERT_DETAILS_REPORT, "type": "pdf"}
    with pytest.raises(ValueError) as e:
        get_reports_params(args=args)

    assert str(e.value) == 'For fetching Alert Details Report, "infection_id" and "infection_type" arguments are required.'


@pytest.mark.parametrize(
    "args",
    [
        {
            "duration": "1_hour",
            "end_time": "2020",
            "mvx_correlated_only": "dummy",
            "start_time": "2020",
        },
        {
            "duration": "1_hour",
            "end_time": "2020",
            "mvx_correlated_only": "dummy",
            "start_time": "2020",
        },
    ],
)
def test_events_command_invalid_bool_value(args):
    """
    When fireeye-nx-get-events command is provided with invalid bool value of an argument
    it should give an error message.
    """
    from FireEyeNX import get_events_params

    with pytest.raises(ValueError) as e:
        get_events_params(args=args)

    assert str(e.value) == "The given value for mvx_correlated_only argument is invalid. Valid values: true, false."


def test_request_timeout_success():
    """
    When provided valid request timeout then test should be passed.
    """
    from FireEyeNX import get_request_timeout

    request_timeout = "5"

    request_timeout_int = get_request_timeout(request_timeout)
    assert request_timeout_int == int(request_timeout)


@pytest.mark.parametrize("request_timeout", ["invalid_str_value", "-5", "0"])
def test_request_timeout_invalid_value(request_timeout):
    """
    When provided invalid request timeout then display error message.
    """
    from FireEyeNX import get_request_timeout

    # Execute
    with pytest.raises(ValueError) as e:
        get_request_timeout(request_timeout)

    # Assert
    assert str(e.value) == "HTTP(S) Request timeout parameter must be a positive integer."


def test_request_timeout_large_value_failure():
    """
    When too large value provided for request timeout then raised value error and
    appropriate error message should display.
    """
    from FireEyeNX import get_request_timeout

    request_timeout = "990000000000000000"

    # Execute
    with pytest.raises(ValueError) as e:
        get_request_timeout(request_timeout)

    assert str(e.value) == "Value is too large for HTTP(S) Request Timeout."


@patch("FireEyeNX.BaseClient._http_request")
def test_http_request_when_response_type_is_json_return_type_should_match(mock_request, client):
    """
    When http_request called and response type is json and content is '{}' passed
    then response should match with {}.
    """
    headers = {"X-FeApi-Token": API_TOKEN, "Content-Type": CONTENT_TYPE_JSON}
    mock_request.return_value = MockResponse(status_code=200, content="{}", headers=headers)
    mock_request.return_value.ok = True
    resp = client.http_request(method="GET", url_suffix="")

    assert resp == {}


def test_handle_error_response_when_status_code_not_in_list_then_raise_for_status():
    """
    When handle_error_response method called and status is not in list then it must raise DemistoException.
    """
    from FireEyeNX import Client

    resp = MockResponse(content="{}", headers={}, status_code=200)

    with pytest.raises(DemistoException):
        Client.handle_error_response(resp)


def test_handle_error_response_when_content_type_zip(client):
    """
    When handle_error_response method called and status is not in list and content type is application/zip
    then it must called raise_for_status.
    """
    from FireEyeNX import Client

    resp = {}
    resp = mock_http_response(
        text="Could not fetch any artifact due to wrong uuid",
        headers={"Content-Type": "application/zip"},
        status=403,
    )
    with pytest.raises(DemistoException) as e:
        Client.handle_error_response(resp)
    assert str(e.value) == "Could not fetch any artifact due to wrong uuid"


def test_handle_error_response_when_content_not_type_json_throw_value_error():
    """
    When handle_error_response method called and json string have error then through ValueError and it passed
    and again raise DemistoException.
    """
    from FireEyeNX import Client

    resp = MockResponse(content="{[]}", headers={}, status_code=400)
    with pytest.raises(DemistoException) as e:
        Client.handle_error_response(resp)

    assert str(e.value) == "An error occurred while fetching the data. "


def test_set_integration_context_api_token_empty_failure():
    """
    When set_integration_context method called api token not there then must throw ValueError.
    """
    from FireEyeNX import Client

    resp = MockResponse(content="{}", headers={}, status_code=200)
    with pytest.raises(ValueError) as e:
        Client.set_integration_context(resp)

    assert str(e.value) == "No api token found. Please try again"


@patch("FireEyeNX.replace_alert_url_key_domain_to_instance_url")
@patch("FireEyeNX.Client.http_request")
def test_get_alerts_command_success(mock_request, replace_url, client):
    """
    When fireeye-nx-get-alerts command is passed with valid arguments, it should be successful.
    """
    from FireEyeNX import get_alerts_command

    args = {
        "src_ip": "0.0.0.0",
        "dst_ip": "0.0.0.0",
        "duration": "1_hour",
        "start_time": "2017-06-21T16:30:00",
        "file_name": "file_name",
        "file_type": "file_type",
        "info_level": "extended",
        "malware_name": "malware_name",
        "malware_type": "domain_match",
        "url": SAMPLE_URL,
    }

    with open("TestData/get_alerts_response.json", encoding="utf-8") as f:
        expected_res = json.load(f)

    with open("TestData/get_alerts_context.json", encoding="utf-8") as f:
        expected_outputs = json.load(f)

    with open("TestData/get_alerts.md", encoding="utf-8") as f:
        expected_hr = f.read()

    mock_request.return_value = expected_res
    replace_url.return_value = None

    replace_alert_url = True
    instance_url = SAMPLE_URL

    cmd_result = get_alerts_command(client, args, replace_alert_url, instance_url)

    assert cmd_result.raw_response == expected_res
    assert cmd_result.outputs == expected_outputs
    assert cmd_result.readable_output == expected_hr


@patch("FireEyeNX.Client.http_request")
def test_get_alerts_command_no_record_failure(mock_request, client):
    """
    When fireeye-nx-get-alerts command called and passed with valid arguments but records are not present
    then it must return error message.
    """
    from FireEyeNX import get_alerts_command

    args = {
        "alert_id": "1",
        "src_ip": "0.0.0.0",
        "dst_ip": "0.0.0.0",
        "duration": "1_hour",
        "start_time": "2017-06-21T16:30:00",
        "file_name": "file_name",
        "file_type": "file_type",
        "info_level": "concise",
        "malware_name": "malware_name",
        "malware_type": "domain_match",
        "url": SAMPLE_URL,
    }

    mock_request.return_value = {}
    replace_alert_url = False
    instance_url = SAMPLE_URL
    cmd_result = get_alerts_command(client, args, replace_alert_url, instance_url)

    assert cmd_result == "No alert(s) were found for the given argument(s)."


@patch("FireEyeNX.Client.http_request")
def test_get_events_command_no_record_failure(mock_request, client):
    """
    When fireeye-nx-get-events command called passed with valid arguments but records are not present
    then it must return error message.
    """
    from FireEyeNX import get_events_command

    args = {
        "duration": "1_hour",
        "end_time": "2017-06-21T16:30:00",
        "mvx_correlated_only": "true",
    }

    mock_request.return_value = {}
    cmd_result = get_events_command(client, args=args)

    assert cmd_result == "No event(s) were found for the given argument(s)."


@patch("FireEyeNX.Client.http_request")
def test_get_artifacts_by_alert_command_zero_content_length_failure(mock_request, client):
    """
    When fireeye-nx-get-artifacts-by-alert command called with Content-Length is zero
    then it should return error message.
    """
    from FireEyeNX import get_artifacts_by_alert_command

    headers = {
        "X-FeApi-Token": API_TOKEN,
        "Content-Type": CONTENT_TYPE_ZIP,
        "Content-Length": 0,
    }
    args = {"uuid": "abc-def"}

    mock_request.return_value = MockResponse(status_code=200, headers=headers, content="test")
    cmd_result = get_artifacts_by_alert_command(client, args=args)

    assert cmd_result == "No artifacts data were found for the given argument(s)."


@patch("FireEyeNX.BaseClient._http_request")
def test_get_artifacts_by_alert_command_success(mock_request, client):
    """
    When fireeye-nx-get-artifacts-by-alert command called and passed with valid arguments, it should be successful.
    """
    from FireEyeNX import get_artifacts_by_alert_command

    args = {"uuid": "abc-def-ghI"}
    with open("TestData/test-get-artifacts-by-alert.zip", encoding="IBM437") as f:
        expected_res = f.read()

    headers = {
        "X-FeApi-Token": API_TOKEN,
        "Content-Type": CONTENT_TYPE_ZIP,
        "Content-Length": 56,
    }

    mock_request.return_value = mock_http_response(status=200, headers=headers, content=expected_res)

    result = get_artifacts_by_alert_command(client, args=args)

    assert result.get("File", "") != ""
    assert result.get("FileID", "") != ""


def test_is_supported_context_type_failure(client):
    """
    When is_supported_context_type() method called invalid argument then should return False.
    """
    assert not (client.is_supported_context_type("image/png"))


@pytest.mark.parametrize("context_type", [CONTENT_TYPE_ZIP, "text/csv", "application/pdf", "application/octet-stream"])
def test_is_supported_context_type_success(client, context_type):
    """
    When is_supported_context_type() method called valid argument then should return True.
    """
    assert client.is_supported_context_type(context_type)


@patch("FireEyeNX.Client.http_request")
def test_get_events_command_success(mock_request, client):
    """
    When fireeye-nx-get-events command executes successfully then context output and
    response should match.
    """
    from FireEyeNX import get_events_command

    args = {
        "duration": "48_hours",
        "mvx_correlated_only": "false",
        "end_time": "2020-08-10T06:31:00.000+00:00",
    }

    with open("TestData/get_events_response.json") as f:
        expected_res = json.load(f)

    mock_request.return_value = expected_res

    cmd_res = get_events_command(client, args)
    with open("TestData/get_events_context.json", encoding="utf-8") as f:
        expected_outputs = json.load(f)

    with open("TestData/get_events.md") as f:
        expected_hr = f.read()

    assert cmd_res.raw_response == expected_res
    assert cmd_res.outputs == expected_outputs
    assert cmd_res.readable_output == expected_hr


def test_add_time_suffix_into_arguments(client):
    """
    When add_time_suffix_into_arguments() method called it should add time suffix if format is suitable
    else return as it is.
    """
    from FireEyeNX import add_time_suffix_into_arguments

    args = {"start_time": "2020-05-20", "end_time": "2020-05-20"}
    add_time_suffix_into_arguments(args)
    actual_output = {
        "end_time": "2020-05-20T00:00:00.000-00:00",
        "start_time": "2020-05-20T00:00:00.000-00:00",
    }
    assert actual_output == args


def test_replace_alert_url_key_domain_to_instance_url():
    """
    When replace_alert_url_key_domain_to_instance_url() method called it should Change domain
    of 'alertUrl' to the instance URL.
    """
    from FireEyeNX import replace_alert_url_key_domain_to_instance_url

    alerts_resp = [
        {"alertUrl": "https://WWW.fireeye-1234/event/evenid=123"},
        {"alertUrl": "http://www.fireeye-1234/event/evenid=124"},  # NOSONAR
    ]
    instance_url = "https://example.com"

    actual_res = [
        {"alertUrl": "https://example.com/event/evenid=123"},
        {"alertUrl": "https://example.com/event/evenid=124"},
    ]

    replace_alert_url_key_domain_to_instance_url(alerts_resp, instance_url)

    assert actual_res == alerts_resp


@patch("FireEyeNX.replace_alert_url_key_domain_to_instance_url")
@patch("FireEyeNX.set_attachment_file")
@patch("FireEyeNX.BaseClient._http_request")
@patch("FireEyeNX.Client.get_api_token")
def test_fetch_incidents_for_alert_success(mock_api_token, mock_request, set_attachment, replace_url, client):
    """
    When fetch_incidents() method called with fetch_type='Alerts' and pass all required arg it success.
    """
    from FireEyeNX import API_SUPPORT_DATE_FORMAT, fetch_incidents

    # Configure
    start_time = datetime.strftime(datetime.now().replace(tzinfo=UTC), API_SUPPORT_DATE_FORMAT)
    mock_last_run = {"alerts": {"start_time": start_time, "alert_ids": ["1"]}}

    dummy_first_fetch = 1
    mock_fetch_limit = 12
    mock_malware_type = "malware-type"
    mock_api_token.return_value = API_TOKEN

    with open("TestData/fetch_incidents_alert_response.json") as f:
        dummy_response = f.read()

    resp = Response()
    resp._content = dummy_response.encode()
    resp.status_code = 200
    resp._ok = True
    resp.headers = {"Content-Type": CONTENT_TYPE_JSON}
    mock_request.return_value = resp

    set_attachment.return_value = None
    replace_url.return_value = None

    # Execute
    next_run, incidents = fetch_incidents(
        client=client,
        malware_type=mock_malware_type,
        last_run=mock_last_run,
        first_fetch=dummy_first_fetch,
        fetch_limit=mock_fetch_limit,
        fetch_type="Alerts",
        mvx_correlated=False,
        replace_alert_url=True,
        instance_url=SAMPLE_URL,
        fetch_artifacts=True,
        is_test=False,
    )

    # Assert
    assert len(incidents) == mock_fetch_limit
    assert next_run.get("alerts").get("start_time") is not None
    assert 8520 in next_run["alerts"]["alert_ids"]


@patch("FireEyeNX.Client.http_request")
def test_set_attachment_file(mock_request, client):
    # incident: dict, uuid: str, headers: dict
    from FireEyeNX import set_attachment_file

    uuid = "abc"
    headers = {}

    resp = Response()
    resp._ok = True
    resp.status_code = 200
    resp._content = b"a"
    resp.headers = {"Content-Length": "1"}

    mock_request.return_value = resp
    excepted_incident = {}

    set_attachment_file(client, excepted_incident, uuid, headers)
    assert excepted_incident != {}


def test_set_attachment_file_attachment_not_found(requests_mock, client):
    """
    Given: an incident with uuid 'abc' without attachment
    When: attempt to set attachment for incident
    Then: incident is not enriched and the command returns without error
    """
    from FireEyeNX import set_attachment_file

    uuid = "abc"
    requests_mock.get(
        f"{client._base_url}/artifacts/{uuid}",
        status_code=404,
        headers={"Content-Type": CONTENT_TYPE_ZIP},
        text="Could not fetch any artifacts for given uuid",
    )
    incident = {}

    set_attachment_file(client, incident, uuid, headers={})
    assert incident == {}


@patch("FireEyeNX.BaseClient._http_request")
@patch("FireEyeNX.Client.get_api_token")
def test_fetch_incidents_for_event_success(mock_api_token, mock_request, client):
    """
    When fetch_incidents() method called with fetch_type='Alerts' and pass all required arg it success.
    """
    from FireEyeNX import fetch_incidents

    # Configure
    mock_last_run = {"alerts": {"start_time": datetime.now().replace(tzinfo=UTC).timestamp(), "alert_ids": ["1"]}}
    dummy_first_fetch = 1
    mock_fetch_limit = 1
    mock_api_token.return_value = API_TOKEN

    with open("TestData/fetch_incidents_event_response.json") as f:
        dummy_response = f.read()

    resp = Response()
    resp._content = dummy_response.encode()
    resp.status_code = 200
    resp._ok = True
    resp.headers = {"Content-Type": CONTENT_TYPE_JSON}
    mock_request.return_value = resp

    next_run, incidents = fetch_incidents(
        client=client,
        malware_type=None,
        last_run=mock_last_run,
        first_fetch=dummy_first_fetch,
        fetch_limit=mock_fetch_limit,
        fetch_type="IPS Events",
        mvx_correlated=True,
        replace_alert_url=True,
        instance_url="",
        fetch_artifacts=False,
        is_test=False,
    )

    # Assert
    assert len(incidents) == mock_fetch_limit
    assert next_run.get("alerts").get("start_time") is not None


def test_update_start_time_within_last_forty_eight_hours():
    """
    Given:
        - Given a start time equals to 24 hours ago.
    When:
        - Running date_to_timestamp function.
    Then:
        - Shouldn't update the start time (should return the same start time).
    """

    from FireEyeNX import DATE_FORMAT, update_start_time

    current_time = datetime.utcnow()
    start_time = date_to_timestamp(current_time - timedelta(hours=24), DATE_FORMAT) / 1000.0
    result = update_start_time(start_time)
    assert result == start_time


def test_update_start_time_older_than_last_forty_eight_hours():
    """
    Given:
        - Given a start time equals to 72 hours ago.
    When:
        - Running date_to_timestamp function.
    Then:
        - Should update the start time to be in the last 48 hours (should return the updated start time).
    """
    from FireEyeNX import DATE_FORMAT, FORTY_EIGHT_HOURS_IN_SECOND, update_start_time

    current_time = datetime.utcnow()
    old_start_time = date_to_timestamp(current_time - timedelta(hours=72), DATE_FORMAT) / 1000.0
    result = update_start_time(old_start_time)
    expected_start_time = date_to_timestamp(current_time, DATE_FORMAT) / 1000.0 - FORTY_EIGHT_HOURS_IN_SECOND
    assert result == expected_start_time