psengine 2.3.1__tar.gz → 2.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. {psengine-2.3.1 → psengine-2.4.0}/PKG-INFO +1 -1
  2. {psengine-2.3.1 → psengine-2.4.0}/psengine/_version.py +1 -1
  3. {psengine-2.3.1 → psengine-2.4.0}/psengine/analyst_notes/note_mgr.py +1 -1
  4. {psengine-2.3.1 → psengine-2.4.0}/psengine/enrich/lookup.py +2 -0
  5. {psengine-2.3.1 → psengine-2.4.0}/psengine/enrich/models/lookup.py +39 -0
  6. {psengine-2.3.1 → psengine-2.4.0}/psengine/entity_match/entity_match.py +17 -0
  7. {psengine-2.3.1 → psengine-2.4.0}/psengine/entity_match/entity_match_mgr.py +2 -2
  8. {psengine-2.3.1 → psengine-2.4.0}/psengine.egg-info/PKG-INFO +1 -1
  9. {psengine-2.3.1 → psengine-2.4.0}/pyproject.toml +1 -1
  10. {psengine-2.3.1 → psengine-2.4.0}/LICENSE +0 -0
  11. {psengine-2.3.1 → psengine-2.4.0}/README.md +0 -0
  12. {psengine-2.3.1 → psengine-2.4.0}/psengine/__init__.py +0 -0
  13. {psengine-2.3.1 → psengine-2.4.0}/psengine/_sdk_id.py +0 -0
  14. {psengine-2.3.1 → psengine-2.4.0}/psengine/analyst_notes/__init__.py +0 -0
  15. {psengine-2.3.1 → psengine-2.4.0}/psengine/analyst_notes/constants.py +0 -0
  16. {psengine-2.3.1 → psengine-2.4.0}/psengine/analyst_notes/errors.py +0 -0
  17. {psengine-2.3.1 → psengine-2.4.0}/psengine/analyst_notes/helpers.py +0 -0
  18. {psengine-2.3.1 → psengine-2.4.0}/psengine/analyst_notes/markdown.py +0 -0
  19. {psengine-2.3.1 → psengine-2.4.0}/psengine/analyst_notes/models.py +0 -0
  20. {psengine-2.3.1 → psengine-2.4.0}/psengine/analyst_notes/note.py +0 -0
  21. {psengine-2.3.1 → psengine-2.4.0}/psengine/base_http_client.py +0 -0
  22. {psengine-2.3.1 → psengine-2.4.0}/psengine/classic_alerts/__init__.py +0 -0
  23. {psengine-2.3.1 → psengine-2.4.0}/psengine/classic_alerts/classic_alert.py +0 -0
  24. {psengine-2.3.1 → psengine-2.4.0}/psengine/classic_alerts/classic_alert_mgr.py +0 -0
  25. {psengine-2.3.1 → psengine-2.4.0}/psengine/classic_alerts/constants.py +0 -0
  26. {psengine-2.3.1 → psengine-2.4.0}/psengine/classic_alerts/errors.py +0 -0
  27. {psengine-2.3.1 → psengine-2.4.0}/psengine/classic_alerts/helpers.py +0 -0
  28. {psengine-2.3.1 → psengine-2.4.0}/psengine/classic_alerts/markdown/__init__.py +0 -0
  29. {psengine-2.3.1 → psengine-2.4.0}/psengine/classic_alerts/markdown/markdown.py +0 -0
  30. {psengine-2.3.1 → psengine-2.4.0}/psengine/classic_alerts/models.py +0 -0
  31. {psengine-2.3.1 → psengine-2.4.0}/psengine/collective_insights/__init__.py +0 -0
  32. {psengine-2.3.1 → psengine-2.4.0}/psengine/collective_insights/collective_insights.py +0 -0
  33. {psengine-2.3.1 → psengine-2.4.0}/psengine/collective_insights/constants.py +0 -0
  34. {psengine-2.3.1 → psengine-2.4.0}/psengine/collective_insights/errors.py +0 -0
  35. {psengine-2.3.1 → psengine-2.4.0}/psengine/collective_insights/insight.py +0 -0
  36. {psengine-2.3.1 → psengine-2.4.0}/psengine/collective_insights/models.py +0 -0
  37. {psengine-2.3.1 → psengine-2.4.0}/psengine/common_models.py +0 -0
  38. {psengine-2.3.1 → psengine-2.4.0}/psengine/config/__init__.py +0 -0
  39. {psengine-2.3.1 → psengine-2.4.0}/psengine/config/config.py +0 -0
  40. {psengine-2.3.1 → psengine-2.4.0}/psengine/config/errors.py +0 -0
  41. {psengine-2.3.1 → psengine-2.4.0}/psengine/constants.py +0 -0
  42. {psengine-2.3.1 → psengine-2.4.0}/psengine/detection/__init__.py +0 -0
  43. {psengine-2.3.1 → psengine-2.4.0}/psengine/detection/detection_mgr.py +0 -0
  44. {psengine-2.3.1 → psengine-2.4.0}/psengine/detection/detection_rule.py +0 -0
  45. {psengine-2.3.1 → psengine-2.4.0}/psengine/detection/errors.py +0 -0
  46. {psengine-2.3.1 → psengine-2.4.0}/psengine/detection/helpers.py +0 -0
  47. {psengine-2.3.1 → psengine-2.4.0}/psengine/detection/models.py +0 -0
  48. {psengine-2.3.1 → psengine-2.4.0}/psengine/endpoints.py +0 -0
  49. {psengine-2.3.1 → psengine-2.4.0}/psengine/enrich/__init__.py +0 -0
  50. {psengine-2.3.1 → psengine-2.4.0}/psengine/enrich/constants.py +0 -0
  51. {psengine-2.3.1 → psengine-2.4.0}/psengine/enrich/errors.py +0 -0
  52. {psengine-2.3.1 → psengine-2.4.0}/psengine/enrich/lookup_mgr.py +0 -0
  53. {psengine-2.3.1 → psengine-2.4.0}/psengine/enrich/models/__init__.py +0 -0
  54. {psengine-2.3.1 → psengine-2.4.0}/psengine/enrich/models/base_enriched_entity.py +0 -0
  55. {psengine-2.3.1 → psengine-2.4.0}/psengine/enrich/models/soar.py +0 -0
  56. {psengine-2.3.1 → psengine-2.4.0}/psengine/enrich/soar.py +0 -0
  57. {psengine-2.3.1 → psengine-2.4.0}/psengine/enrich/soar_mgr.py +0 -0
  58. {psengine-2.3.1 → psengine-2.4.0}/psengine/entity_lists/__init__.py +0 -0
  59. {psengine-2.3.1 → psengine-2.4.0}/psengine/entity_lists/constants.py +0 -0
  60. {psengine-2.3.1 → psengine-2.4.0}/psengine/entity_lists/entity_list.py +0 -0
  61. {psengine-2.3.1 → psengine-2.4.0}/psengine/entity_lists/entity_list_mgr.py +0 -0
  62. {psengine-2.3.1 → psengine-2.4.0}/psengine/entity_lists/errors.py +0 -0
  63. {psengine-2.3.1 → psengine-2.4.0}/psengine/entity_lists/models.py +0 -0
  64. {psengine-2.3.1 → psengine-2.4.0}/psengine/entity_match/__init__.py +0 -0
  65. {psengine-2.3.1 → psengine-2.4.0}/psengine/entity_match/errors.py +0 -0
  66. {psengine-2.3.1 → psengine-2.4.0}/psengine/entity_match/models.py +0 -0
  67. {psengine-2.3.1 → psengine-2.4.0}/psengine/errors.py +0 -0
  68. {psengine-2.3.1 → psengine-2.4.0}/psengine/fusion/__init__.py +0 -0
  69. {psengine-2.3.1 → psengine-2.4.0}/psengine/fusion/errors.py +0 -0
  70. {psengine-2.3.1 → psengine-2.4.0}/psengine/fusion/fusion_mgr.py +0 -0
  71. {psengine-2.3.1 → psengine-2.4.0}/psengine/fusion/models.py +0 -0
  72. {psengine-2.3.1 → psengine-2.4.0}/psengine/helpers/__init__.py +0 -0
  73. {psengine-2.3.1 → psengine-2.4.0}/psengine/helpers/helpers.py +0 -0
  74. {psengine-2.3.1 → psengine-2.4.0}/psengine/identity/__init__.py +0 -0
  75. {psengine-2.3.1 → psengine-2.4.0}/psengine/identity/constants.py +0 -0
  76. {psengine-2.3.1 → psengine-2.4.0}/psengine/identity/errors.py +0 -0
  77. {psengine-2.3.1 → psengine-2.4.0}/psengine/identity/identity.py +0 -0
  78. {psengine-2.3.1 → psengine-2.4.0}/psengine/identity/identity_mgr.py +0 -0
  79. {psengine-2.3.1 → psengine-2.4.0}/psengine/identity/models/__init__.py +0 -0
  80. {psengine-2.3.1 → psengine-2.4.0}/psengine/identity/models/common_models.py +0 -0
  81. {psengine-2.3.1 → psengine-2.4.0}/psengine/identity/models/detections.py +0 -0
  82. {psengine-2.3.1 → psengine-2.4.0}/psengine/identity/models/incident_report.py +0 -0
  83. {psengine-2.3.1 → psengine-2.4.0}/psengine/identity/models/lookup.py +0 -0
  84. {psengine-2.3.1 → psengine-2.4.0}/psengine/logger/__init__.py +0 -0
  85. {psengine-2.3.1 → psengine-2.4.0}/psengine/logger/constants.py +0 -0
  86. {psengine-2.3.1 → psengine-2.4.0}/psengine/logger/errors.py +0 -0
  87. {psengine-2.3.1 → psengine-2.4.0}/psengine/logger/rf_logger.py +0 -0
  88. {psengine-2.3.1 → psengine-2.4.0}/psengine/malware_intel/__init__.py +0 -0
  89. {psengine-2.3.1 → psengine-2.4.0}/psengine/malware_intel/errors.py +0 -0
  90. {psengine-2.3.1 → psengine-2.4.0}/psengine/malware_intel/malware_intel.py +0 -0
  91. {psengine-2.3.1 → psengine-2.4.0}/psengine/malware_intel/malware_intel_mgr.py +0 -0
  92. {psengine-2.3.1 → psengine-2.4.0}/psengine/malware_intel/models.py +0 -0
  93. {psengine-2.3.1 → psengine-2.4.0}/psengine/markdown/__init__.py +0 -0
  94. {psengine-2.3.1 → psengine-2.4.0}/psengine/markdown/markdown.py +0 -0
  95. {psengine-2.3.1 → psengine-2.4.0}/psengine/markdown/models.py +0 -0
  96. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/__init__.py +0 -0
  97. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/constants.py +0 -0
  98. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/errors.py +0 -0
  99. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/helpers.py +0 -0
  100. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/mappings.py +0 -0
  101. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/markdown/__init__.py +0 -0
  102. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/markdown/markdown.py +0 -0
  103. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/markdown/markdown_code_repo.py +0 -0
  104. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/markdown/markdown_cyber_vulnerability.py +0 -0
  105. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/markdown/markdown_domain_abuse.py +0 -0
  106. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/markdown/markdown_geopolitics_facility.py +0 -0
  107. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/markdown/markdown_identity_exposure.py +0 -0
  108. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/markdown/markdown_malware_report.py +0 -0
  109. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/markdown/markdown_third_party_risk.py +0 -0
  110. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/models/__init__.py +0 -0
  111. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/models/common_models.py +0 -0
  112. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/models/panel_log.py +0 -0
  113. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/models/panel_status.py +0 -0
  114. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/models/pba_code_repo_leak.py +0 -0
  115. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/models/pba_cyber_vulnerability.py +0 -0
  116. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/models/pba_domain_abuse.py +0 -0
  117. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/models/pba_geopolitics_facility.py +0 -0
  118. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/models/pba_identity_exposures.py +0 -0
  119. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/models/pba_malware_report.py +0 -0
  120. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/models/pba_third_party_risk.py +0 -0
  121. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/models/search_endpoint.py +0 -0
  122. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/pa_category.py +0 -0
  123. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/playbook_alert_mgr.py +0 -0
  124. {psengine-2.3.1 → psengine-2.4.0}/psengine/playbook_alerts/playbook_alerts.py +0 -0
  125. {psengine-2.3.1 → psengine-2.4.0}/psengine/py.typed +0 -0
  126. {psengine-2.3.1 → psengine-2.4.0}/psengine/rf_client.py +0 -0
  127. {psengine-2.3.1 → psengine-2.4.0}/psengine/risk_history/__init__.py +0 -0
  128. {psengine-2.3.1 → psengine-2.4.0}/psengine/risk_history/errors.py +0 -0
  129. {psengine-2.3.1 → psengine-2.4.0}/psengine/risk_history/models.py +0 -0
  130. {psengine-2.3.1 → psengine-2.4.0}/psengine/risk_history/risk_history_mgr.py +0 -0
  131. {psengine-2.3.1 → psengine-2.4.0}/psengine/risklists/__init__.py +0 -0
  132. {psengine-2.3.1 → psengine-2.4.0}/psengine/risklists/constants.py +0 -0
  133. {psengine-2.3.1 → psengine-2.4.0}/psengine/risklists/errors.py +0 -0
  134. {psengine-2.3.1 → psengine-2.4.0}/psengine/risklists/models.py +0 -0
  135. {psengine-2.3.1 → psengine-2.4.0}/psengine/risklists/risklist_mgr.py +0 -0
  136. {psengine-2.3.1 → psengine-2.4.0}/psengine/stix2/__init__.py +0 -0
  137. {psengine-2.3.1 → psengine-2.4.0}/psengine/stix2/base_stix_entity.py +0 -0
  138. {psengine-2.3.1 → psengine-2.4.0}/psengine/stix2/complex_entity.py +0 -0
  139. {psengine-2.3.1 → psengine-2.4.0}/psengine/stix2/constants.py +0 -0
  140. {psengine-2.3.1 → psengine-2.4.0}/psengine/stix2/enriched_indicator.py +0 -0
  141. {psengine-2.3.1 → psengine-2.4.0}/psengine/stix2/errors.py +0 -0
  142. {psengine-2.3.1 → psengine-2.4.0}/psengine/stix2/helpers.py +0 -0
  143. {psengine-2.3.1 → psengine-2.4.0}/psengine/stix2/rf_bundle.py +0 -0
  144. {psengine-2.3.1 → psengine-2.4.0}/psengine/stix2/simple_entity.py +0 -0
  145. {psengine-2.3.1 → psengine-2.4.0}/psengine/stix2/util.py +0 -0
  146. {psengine-2.3.1 → psengine-2.4.0}/psengine.egg-info/SOURCES.txt +0 -0
  147. {psengine-2.3.1 → psengine-2.4.0}/psengine.egg-info/dependency_links.txt +0 -0
  148. {psengine-2.3.1 → psengine-2.4.0}/psengine.egg-info/requires.txt +0 -0
  149. {psengine-2.3.1 → psengine-2.4.0}/psengine.egg-info/top_level.txt +0 -0
  150. {psengine-2.3.1 → psengine-2.4.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: psengine
3
- Version: 2.3.1
3
+ Version: 2.4.0
4
4
  Summary: psengine is a simple, yet elegant, library for rapid development of integrations with Recorded Future.
5
5
  Author-email: Moise Medici <moise.medici@recordedfuture.com>, Patrick Kinsella <patrick.kinsella@recordedfuture.com>, Ernest Bartosevic <ernest.bartosevic@recordedfuture.com>
6
6
  License-Expression: MIT
@@ -11,4 +11,4 @@
11
11
  # accessed from any third party API. #
12
12
  ##############################################################################################
13
13
 
14
- __version__ = '2.3.0'
14
+ __version__ = '2.4.0'
@@ -111,7 +111,7 @@ class AnalystNoteMgr:
111
111
  'label': label,
112
112
  'source': source,
113
113
  'serialization': serialization,
114
- 'taggedText': tagged_text,
114
+ 'tagged_text': tagged_text,
115
115
  'limit': min(max_results, notes_per_page),
116
116
  }
117
117
  data = {key: val for key, val in data.items() if val is not None}
@@ -33,6 +33,7 @@ from .models.lookup import (
33
33
  RawRisk,
34
34
  RiskMapping,
35
35
  RiskyCIDRPIP,
36
+ Scanner,
36
37
  )
37
38
 
38
39
 
@@ -47,6 +48,7 @@ class EnrichedIP(BaseEnrichedEntity):
47
48
  dns_port_cert: Optional[DnsPortCert] = Field(alias='dnsPortCert', default=None)
48
49
  location: Optional[IPLocation] = None
49
50
  risky_cidr_ips: Optional[list[RiskyCIDRPIP]] = Field(alias='riskyCIDRIPs', default=None)
51
+ scanner: Optional[Scanner] = None
50
52
 
51
53
 
52
54
  class EnrichedDomain(BaseEnrichedEntity):
@@ -304,6 +304,45 @@ class DnsPortCert(RFBaseModel):
304
304
  ports: Optional[list[Port]] = None
305
305
 
306
306
 
307
+ ###########################################################
308
+ # Scanner
309
+ ###########################################################
310
+ class Tag(RFBaseModel):
311
+ verdict_details: Optional[list[str]] = Field(default=None, alias='verdictDetails')
312
+ entity: list[IdNameType]
313
+
314
+
315
+ class Ports(RFBaseModel):
316
+ tcp: list[int]
317
+
318
+
319
+ class Evidence(RFBaseModel):
320
+ name: str = Field(alias='Name')
321
+ mitigation_string: str = Field(default=None, alias='MitigationString')
322
+ evidence_string: str = Field(alias='EvidenceString', default=None)
323
+ rule: str = Field(alias='Rule')
324
+ criticality: float = Field(alias='Criticality')
325
+ timestamp: datetime = Field(alias='Timestamp')
326
+ criticality_label: str = Field(alias='CriticalityLabel')
327
+ sources_count: float = Field(alias='SourcesCount')
328
+ sightings_count: float = Field(alias='SightingsCount')
329
+ sources: list[str] = Field(alias='Sources')
330
+
331
+
332
+ class Scanner(RFBaseModel):
333
+ last_seen: str = Field(alias='lastSeen')
334
+ tags: Tag
335
+ verdict: str
336
+ scanned_ip_countries: list[str] = Field(alias='scannedIpCountries')
337
+ rdns: list[str]
338
+ scanner_country: str = Field(alias='scannerCountry')
339
+ ports: Ports
340
+ global_scanner: bool = Field(alias='globalScanner')
341
+ user_agents: list[str] = Field(alias='userAgents', default=None)
342
+ web_requests: list[str] = Field(alias='webRequests', default=None)
343
+ evidence: Optional[list[Evidence]] = []
344
+
345
+
307
346
  ###########################################################
308
347
  # NVD
309
348
  ###########################################################
@@ -68,6 +68,13 @@ class ResolvedEntity(RFBaseModel):
68
68
 
69
69
  This class supports string representation of `ResolvedEntity` instances.
70
70
 
71
+ Hashing:
72
+ Returns a hash value based on the entity `id_` if found, else the hash of the name.
73
+
74
+ Equality:
75
+ Checks equality between two `ResolvedEntity` instances based on the `id_` if the entity was
76
+ found else the name.
77
+
71
78
  String Representation:
72
79
  Returns a string representation of the `ResolvedEntity` instance including the
73
80
  entity match name, type, and ID.
@@ -91,3 +98,13 @@ class ResolvedEntity(RFBaseModel):
91
98
  if isinstance(self.content, IdNameType):
92
99
  return f'Entity: {self.entity}, Type: {self.content.type_}, ID: {self.content.id_}'
93
100
  return f'Entity: {self.entity}, {self.content}'
101
+
102
+ def __hash__(self):
103
+ if hasattr(self.content, 'id_'):
104
+ return hash(self.content.id_)
105
+ return hash(self.entity)
106
+
107
+ def __eq__(self, other: 'ResolvedEntity'):
108
+ if hasattr(self.content, 'id_') and hasattr(other.content, 'id_'):
109
+ return self.content.id_ == other.content.id_
110
+ return self.entity == other.entity
@@ -48,7 +48,7 @@ class EntityMatchMgr:
48
48
  Optional[Union[list, str]], Doc('Type or list of types of the entity, if known.')
49
49
  ] = None,
50
50
  limit: Annotated[int, Doc('Maximum number of matches to return.')] = DEFAULT_LIMIT,
51
- ) -> Annotated[list[ResolvedEntity], Doc('List of resolved entity matches.')]:
51
+ ) -> Annotated[list[ResolvedEntity], Doc('List of deduplicated resolved entity matches.')]:
52
52
  """Match a text string using the entity match API.
53
53
 
54
54
  Endpoint:
@@ -65,7 +65,7 @@ class EntityMatchMgr:
65
65
  response = self.rf_client.request('post', EP_ENTITY_MATCH, data=request_body.json())
66
66
  response = [IdNameType.model_validate(d) for d in response.json()]
67
67
  return (
68
- [ResolvedEntity(entity=d.name, is_found=bool(d.id_), content=d) for d in response]
68
+ list({ResolvedEntity(entity=d.name, is_found=bool(d.id_), content=d) for d in response})
69
69
  if response
70
70
  else [ResolvedEntity(entity=entity_name, is_found=False, content='Entity ID not found')]
71
71
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: psengine
3
- Version: 2.3.1
3
+ Version: 2.4.0
4
4
  Summary: psengine is a simple, yet elegant, library for rapid development of integrations with Recorded Future.
5
5
  Author-email: Moise Medici <moise.medici@recordedfuture.com>, Patrick Kinsella <patrick.kinsella@recordedfuture.com>, Ernest Bartosevic <ernest.bartosevic@recordedfuture.com>
6
6
  License-Expression: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "psengine"
3
- version = "2.3.1"
3
+ version = "2.4.0"
4
4
  readme = "README.md"
5
5
  license = "MIT"
6
6
  requires-python = ">=3.9, <3.14"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes