psengine 2.10.0__tar.gz → 2.11.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 (193) hide show
  1. {psengine-2.10.0 → psengine-2.11.0}/PKG-INFO +2 -2
  2. {psengine-2.10.0 → psengine-2.11.0}/psengine/common_models.py +1 -0
  3. {psengine-2.10.0 → psengine-2.11.0}/psengine/endpoints.py +5 -0
  4. psengine-2.11.0/psengine/risk_rules/__init__.py +17 -0
  5. psengine-2.11.0/psengine/risk_rules/errors.py +22 -0
  6. psengine-2.11.0/psengine/risk_rules/models.py +33 -0
  7. psengine-2.11.0/psengine/risk_rules/risk_rule.py +78 -0
  8. psengine-2.11.0/psengine/risk_rules/risk_rule_mgr.py +63 -0
  9. {psengine-2.10.0 → psengine-2.11.0}/pyproject.toml +4 -4
  10. {psengine-2.10.0 → psengine-2.11.0}/pyproject.toml.orig +4 -4
  11. {psengine-2.10.0 → psengine-2.11.0}/README.md +0 -0
  12. {psengine-2.10.0 → psengine-2.11.0}/psengine/__init__.py +0 -0
  13. {psengine-2.10.0 → psengine-2.11.0}/psengine/_sdk_id.py +0 -0
  14. {psengine-2.10.0 → psengine-2.11.0}/psengine/analyst_notes/__init__.py +0 -0
  15. {psengine-2.10.0 → psengine-2.11.0}/psengine/analyst_notes/constants.py +0 -0
  16. {psengine-2.10.0 → psengine-2.11.0}/psengine/analyst_notes/errors.py +0 -0
  17. {psengine-2.10.0 → psengine-2.11.0}/psengine/analyst_notes/helpers.py +0 -0
  18. {psengine-2.10.0 → psengine-2.11.0}/psengine/analyst_notes/markdown.py +0 -0
  19. {psengine-2.10.0 → psengine-2.11.0}/psengine/analyst_notes/models.py +0 -0
  20. {psengine-2.10.0 → psengine-2.11.0}/psengine/analyst_notes/note.py +0 -0
  21. {psengine-2.10.0 → psengine-2.11.0}/psengine/analyst_notes/note_mgr.py +0 -0
  22. {psengine-2.10.0 → psengine-2.11.0}/psengine/asi/__init__.py +0 -0
  23. {psengine-2.10.0 → psengine-2.11.0}/psengine/asi/asi.py +0 -0
  24. {psengine-2.10.0 → psengine-2.11.0}/psengine/asi/asi_mgr.py +0 -0
  25. {psengine-2.10.0 → psengine-2.11.0}/psengine/asi/client.py +0 -0
  26. {psengine-2.10.0 → psengine-2.11.0}/psengine/asi/constants.py +0 -0
  27. {psengine-2.10.0 → psengine-2.11.0}/psengine/asi/errors.py +0 -0
  28. {psengine-2.10.0 → psengine-2.11.0}/psengine/asi/models.py +0 -0
  29. {psengine-2.10.0 → psengine-2.11.0}/psengine/base_http_client.py +0 -0
  30. {psengine-2.10.0 → psengine-2.11.0}/psengine/classic_alerts/__init__.py +0 -0
  31. {psengine-2.10.0 → psengine-2.11.0}/psengine/classic_alerts/classic_alert.py +0 -0
  32. {psengine-2.10.0 → psengine-2.11.0}/psengine/classic_alerts/classic_alert_mgr.py +0 -0
  33. {psengine-2.10.0 → psengine-2.11.0}/psengine/classic_alerts/constants.py +0 -0
  34. {psengine-2.10.0 → psengine-2.11.0}/psengine/classic_alerts/errors.py +0 -0
  35. {psengine-2.10.0 → psengine-2.11.0}/psengine/classic_alerts/helpers.py +0 -0
  36. {psengine-2.10.0 → psengine-2.11.0}/psengine/classic_alerts/markdown/__init__.py +0 -0
  37. {psengine-2.10.0 → psengine-2.11.0}/psengine/classic_alerts/markdown/markdown.py +0 -0
  38. {psengine-2.10.0 → psengine-2.11.0}/psengine/classic_alerts/models.py +0 -0
  39. {psengine-2.10.0 → psengine-2.11.0}/psengine/collective_insights/__init__.py +0 -0
  40. {psengine-2.10.0 → psengine-2.11.0}/psengine/collective_insights/collective_insights.py +0 -0
  41. {psengine-2.10.0 → psengine-2.11.0}/psengine/collective_insights/constants.py +0 -0
  42. {psengine-2.10.0 → psengine-2.11.0}/psengine/collective_insights/errors.py +0 -0
  43. {psengine-2.10.0 → psengine-2.11.0}/psengine/collective_insights/insight.py +0 -0
  44. {psengine-2.10.0 → psengine-2.11.0}/psengine/collective_insights/models.py +0 -0
  45. {psengine-2.10.0 → psengine-2.11.0}/psengine/config/__init__.py +0 -0
  46. {psengine-2.10.0 → psengine-2.11.0}/psengine/config/config.py +0 -0
  47. {psengine-2.10.0 → psengine-2.11.0}/psengine/config/errors.py +0 -0
  48. {psengine-2.10.0 → psengine-2.11.0}/psengine/constants.py +0 -0
  49. {psengine-2.10.0 → psengine-2.11.0}/psengine/detection/__init__.py +0 -0
  50. {psengine-2.10.0 → psengine-2.11.0}/psengine/detection/detection_mgr.py +0 -0
  51. {psengine-2.10.0 → psengine-2.11.0}/psengine/detection/detection_rule.py +0 -0
  52. {psengine-2.10.0 → psengine-2.11.0}/psengine/detection/errors.py +0 -0
  53. {psengine-2.10.0 → psengine-2.11.0}/psengine/detection/helpers.py +0 -0
  54. {psengine-2.10.0 → psengine-2.11.0}/psengine/detection/models.py +0 -0
  55. {psengine-2.10.0 → psengine-2.11.0}/psengine/enrich/__init__.py +0 -0
  56. {psengine-2.10.0 → psengine-2.11.0}/psengine/enrich/constants.py +0 -0
  57. {psengine-2.10.0 → psengine-2.11.0}/psengine/enrich/errors.py +0 -0
  58. {psengine-2.10.0 → psengine-2.11.0}/psengine/enrich/lookup.py +0 -0
  59. {psengine-2.10.0 → psengine-2.11.0}/psengine/enrich/lookup_mgr.py +0 -0
  60. {psengine-2.10.0 → psengine-2.11.0}/psengine/enrich/models/__init__.py +0 -0
  61. {psengine-2.10.0 → psengine-2.11.0}/psengine/enrich/models/base_enriched_entity.py +0 -0
  62. {psengine-2.10.0 → psengine-2.11.0}/psengine/enrich/models/lookup.py +0 -0
  63. {psengine-2.10.0 → psengine-2.11.0}/psengine/enrich/models/soar.py +0 -0
  64. {psengine-2.10.0 → psengine-2.11.0}/psengine/enrich/soar.py +0 -0
  65. {psengine-2.10.0 → psengine-2.11.0}/psengine/enrich/soar_mgr.py +0 -0
  66. {psengine-2.10.0 → psengine-2.11.0}/psengine/entity_lists/__init__.py +0 -0
  67. {psengine-2.10.0 → psengine-2.11.0}/psengine/entity_lists/constants.py +0 -0
  68. {psengine-2.10.0 → psengine-2.11.0}/psengine/entity_lists/entity_list.py +0 -0
  69. {psengine-2.10.0 → psengine-2.11.0}/psengine/entity_lists/entity_list_mgr.py +0 -0
  70. {psengine-2.10.0 → psengine-2.11.0}/psengine/entity_lists/errors.py +0 -0
  71. {psengine-2.10.0 → psengine-2.11.0}/psengine/entity_lists/models.py +0 -0
  72. {psengine-2.10.0 → psengine-2.11.0}/psengine/entity_match/__init__.py +0 -0
  73. {psengine-2.10.0 → psengine-2.11.0}/psengine/entity_match/entity_match.py +0 -0
  74. {psengine-2.10.0 → psengine-2.11.0}/psengine/entity_match/entity_match_mgr.py +0 -0
  75. {psengine-2.10.0 → psengine-2.11.0}/psengine/entity_match/errors.py +0 -0
  76. {psengine-2.10.0 → psengine-2.11.0}/psengine/entity_match/models.py +0 -0
  77. {psengine-2.10.0 → psengine-2.11.0}/psengine/errors.py +0 -0
  78. {psengine-2.10.0 → psengine-2.11.0}/psengine/fusion/__init__.py +0 -0
  79. {psengine-2.10.0 → psengine-2.11.0}/psengine/fusion/errors.py +0 -0
  80. {psengine-2.10.0 → psengine-2.11.0}/psengine/fusion/fusion_mgr.py +0 -0
  81. {psengine-2.10.0 → psengine-2.11.0}/psengine/fusion/models.py +0 -0
  82. {psengine-2.10.0 → psengine-2.11.0}/psengine/helpers/__init__.py +0 -0
  83. {psengine-2.10.0 → psengine-2.11.0}/psengine/helpers/helpers.py +0 -0
  84. {psengine-2.10.0 → psengine-2.11.0}/psengine/identity/__init__.py +0 -0
  85. {psengine-2.10.0 → psengine-2.11.0}/psengine/identity/constants.py +0 -0
  86. {psengine-2.10.0 → psengine-2.11.0}/psengine/identity/errors.py +0 -0
  87. {psengine-2.10.0 → psengine-2.11.0}/psengine/identity/identity.py +0 -0
  88. {psengine-2.10.0 → psengine-2.11.0}/psengine/identity/identity_mgr.py +0 -0
  89. {psengine-2.10.0 → psengine-2.11.0}/psengine/identity/models/__init__.py +0 -0
  90. {psengine-2.10.0 → psengine-2.11.0}/psengine/identity/models/common_models.py +0 -0
  91. {psengine-2.10.0 → psengine-2.11.0}/psengine/identity/models/detections.py +0 -0
  92. {psengine-2.10.0 → psengine-2.11.0}/psengine/identity/models/incident_report.py +0 -0
  93. {psengine-2.10.0 → psengine-2.11.0}/psengine/identity/models/lookup.py +0 -0
  94. {psengine-2.10.0 → psengine-2.11.0}/psengine/links/__init__.py +0 -0
  95. {psengine-2.10.0 → psengine-2.11.0}/psengine/links/errors.py +0 -0
  96. {psengine-2.10.0 → psengine-2.11.0}/psengine/links/links.py +0 -0
  97. {psengine-2.10.0 → psengine-2.11.0}/psengine/links/links_mgr.py +0 -0
  98. {psengine-2.10.0 → psengine-2.11.0}/psengine/links/models.py +0 -0
  99. {psengine-2.10.0 → psengine-2.11.0}/psengine/logger/__init__.py +0 -0
  100. {psengine-2.10.0 → psengine-2.11.0}/psengine/logger/constants.py +0 -0
  101. {psengine-2.10.0 → psengine-2.11.0}/psengine/logger/errors.py +0 -0
  102. {psengine-2.10.0 → psengine-2.11.0}/psengine/logger/rf_logger.py +0 -0
  103. {psengine-2.10.0 → psengine-2.11.0}/psengine/malware_intel/__init__.py +0 -0
  104. {psengine-2.10.0 → psengine-2.11.0}/psengine/malware_intel/auto_sigma_mgr.py +0 -0
  105. {psengine-2.10.0 → psengine-2.11.0}/psengine/malware_intel/auto_yara_mgr.py +0 -0
  106. {psengine-2.10.0 → psengine-2.11.0}/psengine/malware_intel/constants.py +0 -0
  107. {psengine-2.10.0 → psengine-2.11.0}/psengine/malware_intel/errors.py +0 -0
  108. {psengine-2.10.0 → psengine-2.11.0}/psengine/malware_intel/helpers.py +0 -0
  109. {psengine-2.10.0 → psengine-2.11.0}/psengine/malware_intel/malware_intel.py +0 -0
  110. {psengine-2.10.0 → psengine-2.11.0}/psengine/malware_intel/malware_intel_mgr.py +0 -0
  111. {psengine-2.10.0 → psengine-2.11.0}/psengine/malware_intel/models.py +0 -0
  112. {psengine-2.10.0 → psengine-2.11.0}/psengine/markdown/__init__.py +0 -0
  113. {psengine-2.10.0 → psengine-2.11.0}/psengine/markdown/markdown.py +0 -0
  114. {psengine-2.10.0 → psengine-2.11.0}/psengine/markdown/markdown_strings.py +0 -0
  115. {psengine-2.10.0 → psengine-2.11.0}/psengine/markdown/models.py +0 -0
  116. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/__init__.py +0 -0
  117. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/constants.py +0 -0
  118. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/errors.py +0 -0
  119. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/helpers.py +0 -0
  120. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/mappings.py +0 -0
  121. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/__init__.py +0 -0
  122. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown.py +0 -0
  123. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown_code_repo.py +0 -0
  124. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown_compromised_bank_checks.py +0 -0
  125. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown_cyber_vulnerability.py +0 -0
  126. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown_domain_abuse.py +0 -0
  127. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown_geopolitics_facility.py +0 -0
  128. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown_identity_exposure.py +0 -0
  129. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown_malicious_sites.py +0 -0
  130. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown_malware_report.py +0 -0
  131. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown_third_party_risk.py +0 -0
  132. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/__init__.py +0 -0
  133. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/common_models.py +0 -0
  134. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/__init__.py +0 -0
  135. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/code_repo.py +0 -0
  136. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/common.py +0 -0
  137. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/domain_abuse.py +0 -0
  138. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/generic.py +0 -0
  139. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/geopolitics.py +0 -0
  140. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/malicious_sites.py +0 -0
  141. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/panel_log_v2.py +0 -0
  142. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/tpr.py +0 -0
  143. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/vulnerability.py +0 -0
  144. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_status.py +0 -0
  145. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/pba_code_repo_leak.py +0 -0
  146. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/pba_compromised_bank_checks.py +0 -0
  147. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/pba_cyber_vulnerability.py +0 -0
  148. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/pba_domain_abuse.py +0 -0
  149. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/pba_geopolitics_facility.py +0 -0
  150. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/pba_identity_exposures.py +0 -0
  151. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/pba_malicious_sites.py +0 -0
  152. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/pba_malware_report.py +0 -0
  153. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/pba_third_party_risk.py +0 -0
  154. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/search_endpoint.py +0 -0
  155. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/pa_category.py +0 -0
  156. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/playbook_alert_mgr.py +0 -0
  157. {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/playbook_alerts.py +0 -0
  158. {psengine-2.10.0 → psengine-2.11.0}/psengine/rf_client.py +0 -0
  159. {psengine-2.10.0 → psengine-2.11.0}/psengine/risk_history/__init__.py +0 -0
  160. {psengine-2.10.0 → psengine-2.11.0}/psengine/risk_history/errors.py +0 -0
  161. {psengine-2.10.0 → psengine-2.11.0}/psengine/risk_history/models.py +0 -0
  162. {psengine-2.10.0 → psengine-2.11.0}/psengine/risk_history/risk_history_mgr.py +0 -0
  163. {psengine-2.10.0 → psengine-2.11.0}/psengine/risklists/__init__.py +0 -0
  164. {psengine-2.10.0 → psengine-2.11.0}/psengine/risklists/constants.py +0 -0
  165. {psengine-2.10.0 → psengine-2.11.0}/psengine/risklists/errors.py +0 -0
  166. {psengine-2.10.0 → psengine-2.11.0}/psengine/risklists/models.py +0 -0
  167. {psengine-2.10.0 → psengine-2.11.0}/psengine/risklists/risklist_mgr.py +0 -0
  168. {psengine-2.10.0 → psengine-2.11.0}/psengine/sandbox/__init__.py +0 -0
  169. {psengine-2.10.0 → psengine-2.11.0}/psengine/sandbox/client.py +0 -0
  170. {psengine-2.10.0 → psengine-2.11.0}/psengine/sandbox/constants.py +0 -0
  171. {psengine-2.10.0 → psengine-2.11.0}/psengine/sandbox/errors.py +0 -0
  172. {psengine-2.10.0 → psengine-2.11.0}/psengine/sandbox/models/__init__.py +0 -0
  173. {psengine-2.10.0 → psengine-2.11.0}/psengine/sandbox/models/analysis.py +0 -0
  174. {psengine-2.10.0 → psengine-2.11.0}/psengine/sandbox/models/behavioral_report.py +0 -0
  175. {psengine-2.10.0 → psengine-2.11.0}/psengine/sandbox/models/overview_report.py +0 -0
  176. {psengine-2.10.0 → psengine-2.11.0}/psengine/sandbox/models/static_report.py +0 -0
  177. {psengine-2.10.0 → psengine-2.11.0}/psengine/sandbox/sandbox.py +0 -0
  178. {psengine-2.10.0 → psengine-2.11.0}/psengine/sandbox/sandbox_mgr.py +0 -0
  179. {psengine-2.10.0 → psengine-2.11.0}/psengine/stix2/__init__.py +0 -0
  180. {psengine-2.10.0 → psengine-2.11.0}/psengine/stix2/base_stix_entity.py +0 -0
  181. {psengine-2.10.0 → psengine-2.11.0}/psengine/stix2/complex_entity.py +0 -0
  182. {psengine-2.10.0 → psengine-2.11.0}/psengine/stix2/constants.py +0 -0
  183. {psengine-2.10.0 → psengine-2.11.0}/psengine/stix2/enriched_indicator.py +0 -0
  184. {psengine-2.10.0 → psengine-2.11.0}/psengine/stix2/errors.py +0 -0
  185. {psengine-2.10.0 → psengine-2.11.0}/psengine/stix2/helpers.py +0 -0
  186. {psengine-2.10.0 → psengine-2.11.0}/psengine/stix2/rf_bundle.py +0 -0
  187. {psengine-2.10.0 → psengine-2.11.0}/psengine/stix2/simple_entity.py +0 -0
  188. {psengine-2.10.0 → psengine-2.11.0}/psengine/stix2/util.py +0 -0
  189. {psengine-2.10.0 → psengine-2.11.0}/psengine/threat_maps/__init__.py +0 -0
  190. {psengine-2.10.0 → psengine-2.11.0}/psengine/threat_maps/errors.py +0 -0
  191. {psengine-2.10.0 → psengine-2.11.0}/psengine/threat_maps/models.py +0 -0
  192. {psengine-2.10.0 → psengine-2.11.0}/psengine/threat_maps/threat_map.py +0 -0
  193. {psengine-2.10.0 → psengine-2.11.0}/psengine/threat_maps/threat_map_mgr.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: psengine
3
- Version: 2.10.0
3
+ Version: 2.11.0
4
4
  Summary: psengine is a simple, yet elegant, library for rapid development of integrations with Recorded Future.
5
5
  Keywords: API,Recorded Future,Cyber Security Engineering,Threat Intelligence
6
6
  Author: Moise Medici, Patrick Kinsella, Ernest Bartosevic
@@ -25,7 +25,7 @@ Requires-Dist: stix2~=3.0.2
25
25
  Requires-Dist: python-dateutil>=2.7.0
26
26
  Requires-Dist: more-itertools>=9.0.0,<=11.1.0
27
27
  Requires-Dist: pydantic>=2.7,<3.0.0
28
- Requires-Dist: pydantic-settings[toml]>=2.14.2,<2.15.0
28
+ Requires-Dist: pydantic-settings[toml]>=2.14.2,<2.16.0
29
29
  Requires-Python: >=3.10, <3.15
30
30
  Project-URL: Homepage, https://recordedfuture-professionalservices.github.io/psengine/latest/
31
31
  Project-URL: Changelog, https://recordedfuture-professionalservices.github.io/psengine/latest/CHANGELOG/
@@ -93,6 +93,7 @@ class DetectionRuleType(Enum):
93
93
  sigma = 'sigma'
94
94
  yara = 'yara'
95
95
  snort = 'snort'
96
+ suricata = 'suricata'
96
97
 
97
98
 
98
99
  class ClearTextPassword(Secret[str]):
@@ -141,6 +141,11 @@ EP_AUTO_SIGMA_JOB_ID_RETRY = EP_AUTO_SIGMA_JOB_ID + '/retry'
141
141
  EP_RISK_HISTORY_BASE = BASE_URL + '/risk'
142
142
  EP_RISK_HISTORY = EP_RISK_HISTORY_BASE + '/history'
143
143
 
144
+ ###############################################################################
145
+ # Risk Rules API Endpoints
146
+ ###############################################################################
147
+ EP_RISK_RULES = CONNECT_API_BASE_URL + '/{}/riskrules'
148
+
144
149
  ###############################################################################
145
150
  # Links API Endpoints
146
151
  ###############################################################################
@@ -0,0 +1,17 @@
1
+ ##################################### TERMS OF USE ###########################################
2
+ # The following code is provided for demonstration purpose only, and should not be used #
3
+ # without independent verification. Recorded Future makes no representations or warranties, #
4
+ # express, implied, statutory, or otherwise, regarding any aspect of this code or of the #
5
+ # information it may retrieve, and provides it both strictly “as-is” and without assuming #
6
+ # responsibility for any information it may retrieve. Recorded Future shall not be liable #
7
+ # for, and you assume all risk of using, the foregoing. By using this code, Customer #
8
+ # represents that it is solely responsible for having all necessary licenses, permissions, #
9
+ # rights, and/or consents to connect to third party APIs, and that it is solely responsible #
10
+ # for having all necessary licenses, permissions, rights, and/or consents to any data #
11
+ # accessed from any third party API. #
12
+ ##############################################################################################
13
+
14
+ from .errors import RiskRuleError, RiskRuleFetchError
15
+ from .models import RiskRuleCategory, RiskRuleEntityType
16
+ from .risk_rule import RiskRule
17
+ from .risk_rule_mgr import RiskRuleMgr
@@ -0,0 +1,22 @@
1
+ ##################################### TERMS OF USE ###########################################
2
+ # The following code is provided for demonstration purpose only, and should not be used #
3
+ # without independent verification. Recorded Future makes no representations or warranties, #
4
+ # express, implied, statutory, or otherwise, regarding any aspect of this code or of the #
5
+ # information it may retrieve, and provides it both strictly “as-is” and without assuming #
6
+ # responsibility for any information it may retrieve. Recorded Future shall not be liable #
7
+ # for, and you assume all risk of using, the foregoing. By using this code, Customer #
8
+ # represents that it is solely responsible for having all necessary licenses, permissions, #
9
+ # rights, and/or consents to connect to third party APIs, and that it is solely responsible #
10
+ # for having all necessary licenses, permissions, rights, and/or consents to any data #
11
+ # accessed from any third party API. #
12
+ ##############################################################################################
13
+
14
+ from ..errors import RecordedFutureError
15
+
16
+
17
+ class RiskRuleError(RecordedFutureError):
18
+ """Base error for the risk_rules module."""
19
+
20
+
21
+ class RiskRuleFetchError(RecordedFutureError):
22
+ """Raised when the risk rules for an entity type cannot be fetched."""
@@ -0,0 +1,33 @@
1
+ ##################################### TERMS OF USE ###########################################
2
+ # The following code is provided for demonstration purpose only, and should not be used #
3
+ # without independent verification. Recorded Future makes no representations or warranties, #
4
+ # express, implied, statutory, or otherwise, regarding any aspect of this code or of the #
5
+ # information it may retrieve, and provides it both strictly “as-is” and without assuming #
6
+ # responsibility for any information it may retrieve. Recorded Future shall not be liable #
7
+ # for, and you assume all risk of using, the foregoing. By using this code, Customer #
8
+ # represents that it is solely responsible for having all necessary licenses, permissions, #
9
+ # rights, and/or consents to connect to third party APIs, and that it is solely responsible #
10
+ # for having all necessary licenses, permissions, rights, and/or consents to any data #
11
+ # accessed from any third party API. #
12
+ ##############################################################################################
13
+
14
+ from enum import Enum
15
+
16
+ from ..common_models import RFBaseModel
17
+
18
+
19
+ class RiskRuleEntityType(str, Enum):
20
+ """Enum of IOC entity types supported by the `/v2/{entity_type}/riskrules` endpoint."""
21
+
22
+ IP = 'ip'
23
+ DOMAIN = 'domain'
24
+ HASH = 'hash'
25
+ VULNERABILITY = 'vulnerability'
26
+ URL = 'url'
27
+
28
+
29
+ class RiskRuleCategory(RFBaseModel):
30
+ """A framework category attached to a risk rule (e.g. MITRE tactic or technique)."""
31
+
32
+ name: str
33
+ framework: str
@@ -0,0 +1,78 @@
1
+ ##################################### TERMS OF USE ###########################################
2
+ # The following code is provided for demonstration purpose only, and should not be used #
3
+ # without independent verification. Recorded Future makes no representations or warranties, #
4
+ # express, implied, statutory, or otherwise, regarding any aspect of this code or of the #
5
+ # information it may retrieve, and provides it both strictly “as-is” and without assuming #
6
+ # responsibility for any information it may retrieve. Recorded Future shall not be liable #
7
+ # for, and you assume all risk of using, the foregoing. By using this code, Customer #
8
+ # represents that it is solely responsible for having all necessary licenses, permissions, #
9
+ # rights, and/or consents to connect to third party APIs, and that it is solely responsible #
10
+ # for having all necessary licenses, permissions, rights, and/or consents to any data #
11
+ # accessed from any third party API. #
12
+ ##############################################################################################
13
+
14
+ from functools import total_ordering
15
+ from typing import Any
16
+
17
+ from pydantic import Field
18
+
19
+ from ..common_models import RFBaseModel
20
+ from .models import RiskRuleCategory
21
+
22
+
23
+ @total_ordering
24
+ class RiskRule(RFBaseModel):
25
+ """Validate data received from the `/v2/{entity_type}/riskrules` endpoint.
26
+
27
+ A Recorded Future risk rule is a scoring rule that contributes to the overall risk score of an
28
+ entity of a given IOC type (ip, domain, hash, url, vulnerability). Each rule has a criticality
29
+ level (1-3), a human readable label, a description of what it detects, and a count of entities
30
+ currently matching the rule.
31
+
32
+ This class supports hashing, equality comparison, string representation, and total ordering
33
+ of `RiskRule` instances.
34
+
35
+ Hashing:
36
+ Returns a hash value based on the tuple `(name, criticality)`.
37
+
38
+ Equality:
39
+ Two `RiskRule` instances are equal if they share the same `name` and `criticality`.
40
+
41
+ Greater-than Comparison:
42
+ A rule is "greater" than another if its `criticality` is higher. When two rules share the
43
+ same criticality, the one whose `name` sorts later alphabetically is considered greater.
44
+ Combined with `@total_ordering`, this yields most-critical-first when using `sorted()` in
45
+ reverse (or `sorted(rules, reverse=True)`).
46
+
47
+ String Representation:
48
+ Returns a compact one-line summary of the rule.
49
+
50
+ ```python
51
+ >>> print(risk_rule)
52
+ Risk Rule: bogusBgp, Criticality: 1 (Unusual), Count: 24590
53
+ ```
54
+ """
55
+
56
+ name: str
57
+ description: str
58
+ criticality: int
59
+ criticality_label: str = Field(alias='criticalityLabel')
60
+ count: int
61
+ categories: list[RiskRuleCategory] = []
62
+ related_entities: list[Any] = Field(alias='relatedEntities', default=[])
63
+
64
+ def __hash__(self):
65
+ return hash((self.name, self.criticality))
66
+
67
+ def __eq__(self, other: 'RiskRule'):
68
+ return (self.name, self.criticality) == (other.name, other.criticality)
69
+
70
+ def __gt__(self, other: 'RiskRule'):
71
+ return (self.criticality, self.name) > (other.criticality, other.name)
72
+
73
+ def __str__(self):
74
+ return (
75
+ f'Risk Rule: {self.name}, '
76
+ f'Criticality: {self.criticality} ({self.criticality_label}), '
77
+ f'Count: {self.count}'
78
+ )
@@ -0,0 +1,63 @@
1
+ ##################################### TERMS OF USE ###########################################
2
+ # The following code is provided for demonstration purpose only, and should not be used #
3
+ # without independent verification. Recorded Future makes no representations or warranties, #
4
+ # express, implied, statutory, or otherwise, regarding any aspect of this code or of the #
5
+ # information it may retrieve, and provides it both strictly “as-is” and without assuming #
6
+ # responsibility for any information it may retrieve. Recorded Future shall not be liable #
7
+ # for, and you assume all risk of using, the foregoing. By using this code, Customer #
8
+ # represents that it is solely responsible for having all necessary licenses, permissions, #
9
+ # rights, and/or consents to connect to third party APIs, and that it is solely responsible #
10
+ # for having all necessary licenses, permissions, rights, and/or consents to any data #
11
+ # accessed from any third party API. #
12
+ ##############################################################################################
13
+
14
+ import logging
15
+ from typing import Annotated
16
+
17
+ from pydantic import validate_call
18
+ from typing_extensions import Doc
19
+
20
+ from ..endpoints import EP_RISK_RULES
21
+ from ..helpers import debug_call
22
+ from ..helpers.helpers import connection_exceptions
23
+ from ..rf_client import RFClient
24
+ from .errors import RiskRuleFetchError
25
+ from .models import RiskRuleEntityType
26
+ from .risk_rule import RiskRule
27
+
28
+
29
+ class RiskRuleMgr:
30
+ """Manages requests for Recorded Future risk rules."""
31
+
32
+ def __init__(
33
+ self,
34
+ rf_token: Annotated[str | None, Doc('Recorded Future API token.')] = None,
35
+ ):
36
+ """Initializes the `RiskRuleMgr` object."""
37
+ self.log = logging.getLogger(__name__)
38
+ self.rf_client = RFClient(api_token=rf_token) if rf_token else RFClient()
39
+
40
+ @debug_call
41
+ @validate_call
42
+ @connection_exceptions(ignore_status_code=[], exception_to_raise=RiskRuleFetchError)
43
+ def fetch(
44
+ self,
45
+ entity_type: Annotated[
46
+ RiskRuleEntityType,
47
+ Doc('The IOC type to fetch risk rules for: ip, domain, hash, vulnerability, or url.'),
48
+ ],
49
+ ) -> Annotated[list[RiskRule], Doc('The list of risk rules for the given IOC type.')]:
50
+ """Fetch every risk rule defined for the given IOC type.
51
+
52
+ Endpoint:
53
+ `/v2/{entity_type}/riskrules`
54
+
55
+ Raises:
56
+ ValidationError: If `entity_type` is not one of the supported IOC types.
57
+ RiskRuleFetchError: If an API error occurs while fetching risk rules.
58
+ """
59
+ url = EP_RISK_RULES.format(entity_type.value)
60
+ self.log.info(f'Fetching risk rules for entity type: {entity_type.value}')
61
+ response = self.rf_client.request('get', url).json()
62
+ results = response['data']['results']
63
+ return [RiskRule.model_validate(r) for r in results]
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "psengine"
3
- version = "2.10.0"
3
+ version = "2.11.0"
4
4
  readme = "README.md"
5
5
  license = "MIT"
6
6
  requires-python = ">=3.10, <3.15"
@@ -33,7 +33,7 @@ dependencies = [
33
33
  "python-dateutil>=2.7.0",
34
34
  "more-itertools>=9.0.0, <=11.1.0",
35
35
  "pydantic>=2.7, <3.0.0",
36
- "pydantic-settings[toml]>=2.14.2,<2.15.0",
36
+ "pydantic-settings[toml]>=2.14.2,<2.16.0",
37
37
  ]
38
38
 
39
39
  [[project.authors]]
@@ -59,8 +59,8 @@ dev = [
59
59
  "pytest-mock==3.15.1",
60
60
  "pytest-md==0.2.0",
61
61
  "pytest-random-order==1.2.0",
62
- "pytest-httpdbg==0.10.2",
63
- "ruff~=0.15.8",
62
+ "pytest-httpdbg==0.10.3",
63
+ "ruff>=0.16.1,<0.17.0",
64
64
  "mimesis>=19.1.0",
65
65
  "freezegun>=1.5.5",
66
66
  ]
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "psengine"
3
- version = "2.10.0"
3
+ version = "2.11.0"
4
4
  readme = "README.md"
5
5
  license = "MIT"
6
6
  requires-python = ">=3.10, <3.15"
@@ -36,7 +36,7 @@ dependencies = [
36
36
  "python-dateutil>=2.7.0",
37
37
  "more-itertools>=9.0.0, <=11.1.0",
38
38
  "pydantic>=2.7, <3.0.0",
39
- "pydantic-settings[toml]>=2.14.2,<2.15.0",
39
+ "pydantic-settings[toml]>=2.14.2,<2.16.0",
40
40
  ]
41
41
 
42
42
 
@@ -52,8 +52,8 @@ dev = [
52
52
  "pytest-mock==3.15.1",
53
53
  "pytest-md==0.2.0",
54
54
  "pytest-random-order==1.2.0",
55
- "pytest-httpdbg==0.10.2",
56
- "ruff~=0.15.8",
55
+ "pytest-httpdbg==0.10.3",
56
+ "ruff>=0.16.1,<0.17.0",
57
57
  "mimesis>=19.1.0",
58
58
  "freezegun>=1.5.5",
59
59
  ]
File without changes
File without changes
File without changes
File without changes