mirror of https://github.com/MISP/PyMISP
				
				
				
			
		
			
				
	
	
		
			64 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			64 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Python
		
	
	
| #!/usr/bin/env python
 | |
| 
 | |
| from __future__ import annotations
 | |
| 
 | |
| from datetime import datetime, date
 | |
| from dateutil.parser import parse
 | |
| 
 | |
| from typing import Any
 | |
| 
 | |
| from .. import MISPObject
 | |
| from ..exceptions import InvalidMISPObject
 | |
| 
 | |
| 
 | |
| class AbstractMISPObjectGenerator(MISPObject):
 | |
| 
 | |
|     def _detect_epoch(self, timestamp: str | int | float) -> bool:
 | |
|         try:
 | |
|             tmp = float(timestamp)
 | |
|             if tmp < 30000000:
 | |
|                 # Assuming the user doesn't want to report anything before datetime(1970, 12, 14, 6, 20)
 | |
|                 # The date is most probably in the format 20180301
 | |
|                 return False
 | |
|             return True
 | |
|         except ValueError:
 | |
|             return False
 | |
| 
 | |
|     def _sanitize_timestamp(self, timestamp: datetime | date | dict[str, Any] | str | int | float | None = None) -> datetime:
 | |
|         if not timestamp:
 | |
|             return datetime.now()
 | |
| 
 | |
|         if isinstance(timestamp, datetime):
 | |
|             return timestamp
 | |
|         elif isinstance(timestamp, date):
 | |
|             return datetime.combine(timestamp, datetime.min.time())
 | |
|         elif isinstance(timestamp, dict):
 | |
|             if not isinstance(timestamp['value'], datetime):
 | |
|                 timestamp['value'] = parse(timestamp['value'])
 | |
|             return timestamp['value']
 | |
|         else:  # Supported: float/int/string
 | |
|             if isinstance(timestamp, (str, int, float)) and self._detect_epoch(timestamp):
 | |
|                 # It converts to the *local* datetime, which is consistent with the rest of the code.
 | |
|                 return datetime.fromtimestamp(float(timestamp))
 | |
|             elif isinstance(timestamp, str):
 | |
|                 return parse(timestamp)
 | |
|             else:
 | |
|                 raise Exception(f'Unable to convert {timestamp} to a datetime.')
 | |
| 
 | |
|     def generate_attributes(self) -> None:
 | |
|         """Contains the logic where all the values of the object are gathered"""
 | |
|         if hasattr(self, '_parameters') and self._definition is not None:
 | |
|             for object_relation in self._definition['attributes']:
 | |
|                 value = self._parameters.pop(object_relation, None)
 | |
|                 if not value:
 | |
|                     continue
 | |
|                 if isinstance(value, dict):
 | |
|                     self.add_attribute(object_relation, **value)
 | |
|                 elif isinstance(value, list):
 | |
|                     self.add_attributes(object_relation, *value)
 | |
|                 else:
 | |
|                     # Assume it is the value only
 | |
|                     self.add_attribute(object_relation, value=value)
 | |
|             if self._strict and self._known_template and self._parameters:
 | |
|                 raise InvalidMISPObject('Some object relations are unknown in the template and could not be attached: {}'.format(', '.join(self._parameters)))
 |