class Test(Model): first = Keyword() @first.setter def first(self, value): assert isinstance(value, str) if value.startswith('cat'): raise CatError() return value
def get_random_tags() -> dict: desired_tag_types = [ 'attribution.actor', 'network.static.ip', 'network.dynamic.ip', 'network.static.domain', 'network.dynamic.domain', 'network.static.uri', 'network.dynamic.uri', 'av.virus_name', 'attribution.implant', 'file.rule.yara', 'file.behavior', 'attribution.exploit', 'technique.packer', 'technique.obfuscation' ] out = {} flat_fields = Tagging.flat_fields() # noinspection PyUnresolvedReferences flat_fields.pop('file.rule') tag_list = random.choices(list(flat_fields.keys()), k=random.randint(0, 2)) tag_list.extend(random.choices(desired_tag_types, k=random.randint(1, 2))) for key in tag_list: parts = key.split(".") d = out for part in parts[:-1]: if part not in d: d[part] = dict() d = d[part] if parts[-1] not in d: d[parts[-1]] = [] for _ in range(random.randint(1, 2)): d[parts[-1]].append(random_data_for_field(flat_fields.get(key, Keyword()), key.split(".")[-1])) return out
class Test(Model): first = Keyword() second = Integer()
class A(Model): fast = Integer(default=1) slow = Keyword(default='abc') count = List(Integer())
class Flag(Model): uuid = UUID() name = Keyword() fans = List(Integer(), default=[])
class A(Model): fast = Integer(default=1) slow = Keyword(default='abc') flags = List(Keyword(), default=['cat-snack'])
class SubModel(Model): default = Keyword() indexed = Keyword(index=True) not_indexed = Keyword(index=False)
class Test3(Model): default = Keyword() indexed = Keyword(index=True) not_indexed = Keyword(index=False)
class InnerB(Model): number = Integer() value = Keyword()
class InnerA(Model): number = Integer(default=10) value = Keyword()
class Entry(Model): value = Integer() key = Keyword()
class TestCompound(Model): key = Keyword() value = Keyword()
def _validate_operations(self, operations): """ Validate the different operations received for a partial update TODO: When the field is of type Mapping, the validation/check only works for depth 1. A full recursive solution is needed to support multi-depth cases. :param operations: list of operation tuples :raises: DatastoreException if operation not valid """ if self.model_class: fields = self.model_class.flat_fields(show_compound=True) if 'classification in fields': fields.update({ "__access_lvl__": Integer(), "__access_req__": List(Keyword()), "__access_grp1__": List(Keyword()), "__access_grp2__": List(Keyword()) }) else: fields = None ret_ops = [] for op, doc_key, value in operations: if op not in self.UPDATE_OPERATIONS: raise DataStoreException(f"Not a valid Update Operation: {op}") if fields is not None: prev_key = None if doc_key not in fields: if '.' in doc_key: prev_key = doc_key[:doc_key.rindex('.')] if prev_key in fields and not isinstance( fields[prev_key], Mapping): raise DataStoreException( f"Invalid field for model: {prev_key}") else: raise DataStoreException( f"Invalid field for model: {doc_key}") if prev_key: field = fields[prev_key].child_type else: field = fields[doc_key] if op in [self.UPDATE_APPEND, self.UPDATE_REMOVE]: try: value = field.check(value) except (ValueError, TypeError, AttributeError): raise DataStoreException( f"Invalid value for field {doc_key}: {value}") elif op in [self.UPDATE_SET, self.UPDATE_DEC, self.UPDATE_INC]: try: value = field.check(value) except (ValueError, TypeError): raise DataStoreException( f"Invalid value for field {doc_key}: {value}") if isinstance(value, Model): value = value.as_primitives() elif isinstance(value, datetime): value = value.isoformat() elif isinstance(value, ClassificationObject): value = str(value) ret_ops.append((op, doc_key, value)) return ret_ops