Skip to content

Commit 02f6332

Browse files
committed
add: tlp:clear reports without apikey
1 parent 4056176 commit 02f6332

3 files changed

Lines changed: 23 additions & 99 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "python-catalyst"
3-
version = "0.1.0"
3+
version = "0.1.2"
44
description = "Python client for the PRODAFT CATALYST API"
55
readme = "README.md"
66
license = { file = "LICENSE" }

python_catalyst/client.py

Lines changed: 21 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Client for the CATALYST API."""
22

33
import logging
4+
import time
45
import uuid
56
from datetime import datetime
67
from typing import Dict, List, Optional, Tuple
@@ -17,7 +18,7 @@ class CatalystClient:
1718

1819
def __init__(
1920
self,
20-
api_key: str,
21+
api_key: str = None,
2122
base_url: str = "https://prod.blindspot.prodaft.com/api",
2223
proxy_url: Optional[str] = None,
2324
logger: Optional[logging.Logger] = None,
@@ -62,6 +63,7 @@ def __init__(
6263
# extra config params
6364
self.create_observables = create_observables
6465
self.create_indicators = create_indicators
66+
self._last_request_time = 0
6567

6668
def _handle_request(
6769
self, method: str, endpoint: str, params: Dict = None, data: Dict = None
@@ -83,6 +85,18 @@ def _handle_request(
8385
"""
8486
url = f"{self.base_url}/{endpoint.lstrip('/')}"
8587

88+
if not self.catalyst_authenticated:
89+
current_time = time.time()
90+
time_since_last_request = current_time - self._last_request_time
91+
if time_since_last_request < 20:
92+
sleep_time = 20 - time_since_last_request
93+
if self.logger:
94+
self.logger.debug(
95+
f"Sleeping for {sleep_time:.2f} seconds between requests" # noqa: E231
96+
)
97+
time.sleep(sleep_time)
98+
self._last_request_time = time.time()
99+
86100
try:
87101
self.logger.debug(f"Making {method} request to {url}")
88102
response = self.session.request(
@@ -499,7 +513,12 @@ def create_report_from_member_content_with_references(
499513
entity_id = threat_actor.get("id")
500514
entity_value = threat_actor.get("value")
501515
context = threat_actor.get("context")
502-
516+
if not self.catalyst_authenticated:
517+
if self.logger:
518+
self.logger.debug(
519+
f"Skipping threat actor {entity_value} because user is not authenticated... This will be implemented in the future."
520+
)
521+
continue
503522
if entity_id and entity_value:
504523
try:
505524
# Fetch detailed information for the threat actor
@@ -518,101 +537,6 @@ def create_report_from_member_content_with_references(
518537
report_reference=external_reference,
519538
)
520539

521-
# Process relationships from detailed threat actor data regardless of type
522-
"""
523-
# 1. Process attack patterns
524-
attack_pattern_data = detailed_threat_actor.get("attack_patterns", [])
525-
if isinstance(attack_pattern_data, list):
526-
for attack_pattern in attack_pattern_data:
527-
pattern_id = attack_pattern.get("id")
528-
pattern_name = attack_pattern.get("name")
529-
530-
if pattern_id and pattern_name:
531-
# Create the attack pattern
532-
attack_pattern_obj = self.converter.create_attack_pattern(
533-
pattern_id,
534-
pattern_name,
535-
attack_pattern.get("description"),
536-
report_reference=external_reference,
537-
)
538-
related_objects.append(attack_pattern_obj)
539-
collected_object_refs.append(attack_pattern_obj.id)
540-
541-
# Create relationship
542-
rel = self._create_relationship_objects(
543-
ta_object.id,
544-
attack_pattern_obj.id,
545-
"uses",
546-
external_reference
547-
)
548-
related_objects.append(rel)
549-
collected_object_refs.append(rel.id)
550-
551-
if self.logger:
552-
self.logger.debug(f"Added attack pattern {pattern_name} used by {entity_value}")
553-
554-
# 2. Process campaigns
555-
campaign_data = detailed_threat_actor.get("campaigns", [])
556-
if isinstance(campaign_data, list):
557-
for campaign in campaign_data:
558-
campaign_id = campaign.get("id")
559-
campaign_name = campaign.get("name")
560-
561-
if campaign_id and campaign_name:
562-
# Create the campaign
563-
campaign_obj = self.converter.create_campaign(
564-
campaign_id,
565-
campaign_name,
566-
campaign.get("description"),
567-
report_reference=external_reference,
568-
)
569-
related_objects.append(campaign_obj)
570-
collected_object_refs.append(campaign_obj.id)
571-
572-
# Create relationship with appropriate relationship type
573-
rel = self._create_relationship_objects(
574-
ta_object.id,
575-
campaign_obj.id,
576-
"attributed-to",
577-
external_reference
578-
)
579-
related_objects.append(rel)
580-
collected_object_refs.append(rel.id)
581-
582-
if self.logger:
583-
self.logger.debug(f"Added campaign {campaign_name} attributed to {entity_value}")
584-
585-
# 3. Process countries/suspected origins
586-
origin_data = detailed_threat_actor.get("suspected_origins", [])
587-
if isinstance(origin_data, list):
588-
for country in origin_data:
589-
country_id = country.get("id")
590-
country_name = country.get("name")
591-
592-
if country_id and country_name:
593-
# Create the location
594-
location_obj = self.converter.create_country_location(
595-
country_id,
596-
country_name,
597-
None,
598-
report_reference=external_reference,
599-
)
600-
related_objects.append(location_obj)
601-
collected_object_refs.append(location_obj.id)
602-
603-
# Create relationship
604-
rel = self._create_relationship_objects(
605-
ta_object.id,
606-
location_obj.id,
607-
"originates-from",
608-
external_reference
609-
)
610-
related_objects.append(rel)
611-
collected_object_refs.append(rel.id)
612-
613-
if self.logger:
614-
self.logger.debug(f"Added suspected origin {country_name} for {entity_value}")
615-
"""
616540
is_abstract = detailed_threat_actor.get(
617541
"is_abstract", False
618542
)

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setup(
77
name="python-catalyst",
8-
version="0.1.0",
8+
version="0.1.2",
99
description="Python client for the PRODAFT CATALYST API",
1010
long_description=long_description,
1111
long_description_content_type="text/markdown",

0 commit comments

Comments
 (0)