class Indicator(models.Model):
    name = models.CharField(max_length=255)
    creation_time = models.DateTimeField(auto_now_add=True)
    last_modified = models.DateTimeField(auto_now=True)
    description = models.TextField(null=True, blank=True)
    short_description = models.CharField(max_length=255, null=True, blank=True)
    indicator_id = models.CharField(max_length=255)
    namespace = models.ManyToManyField('Namespace', blank=True)
    indicator_types = models.ManyToManyField(Indicator_Type, blank=True)
    confidence = models.ManyToManyField(Confidence, blank=True)
    related_indicators = models.ManyToManyField('self', blank=True)
    indicator_composition_operator = models.CharField(max_length=3, default="OR")
    ttps = models.ManyToManyField('TTP', blank=True)
    produced_time = models.DateTimeField(null=True, blank=True)
    kill_chain_phases = models.ManyToManyField(Indicator_Kill_Chain_Phase, blank=True)

    def __unicode__(self):
        return u"%s" % (self.name) class Observable(models.Model):
    name = models.CharField(max_length=255)
    creation_time = models.DateTimeField(auto_now_add=True)
    last_modified = models.DateTimeField(auto_now=True)
    description = models.TextField(null=True, blank=True)
    short_description = models.CharField(max_length=255, null=True, blank=True)
    namespace = models.ManyToManyField('Namespace', blank=True)
    indicators = models.ManyToManyField(Indicator, blank=True)
    compositions = models.ManyToManyField(ObservableComposition, blank=True)
    observable_type = models.CharField(max_length=255, null=True, blank=True)
    observable_id = models.CharField(max_length=255, unique=True)

    def __unicode__(self):
        return u"%s" % (self.name) class Campaign(models.Model):
    name = models.CharField(max_length=255)
    creation_time = models.DateTimeField(auto_now_add=True)
    last_modified = models.DateTimeField(auto_now=True)
    description = models.TextField(null=True, blank=True)
    short_description = models.CharField(max_length=255, null=True, blank=True)
    namespace = models.ManyToManyField('Namespace', blank=True)
    status = models.CharField(max_length=255, default='Ongoing')
    campaign_id = models.CharField(max_length=255)
    confidence = models.ManyToManyField(Confidence, blank=True)
    related_indicators = models.ManyToManyField('Indicator', blank=True)
    related_ttps = models.ManyToManyField(TTP, through='RelationCampaignTTP', symmetrical=False, related_name='ttp_related_to_campaign', blank=True)
    associated_campaigns = models.ManyToManyField('self', blank=True)

    def add_related_ttp(self, ttp, relationship):
        rel_ttp, rel_ttp_created = RelationCampaignTTP.objects.get_or_create(
            campaign=self,
            ttp=ttp,
            relationship=relationship
        )
        return rel_ttp

    def __unicode__(self):
        return u"%s" % (self.name) class ThreatActor(models.Model):
    name = models.CharField(max_length=255)
    creation_time = models.DateTimeField(auto_now_add=True)
    last_modified = models.DateTimeField(auto_now=True)
    description = models.TextField(null=True, blank=True)
    short_description = models.CharField(max_length=255, null=True, blank=True)
    namespace = models.ManyToManyField('Namespace', blank=True)
    campaigns = models.ManyToManyField(Campaign, blank=True)
    associated_threat_actors = models.ManyToManyField('self', blank=True)
    threat_actor_id = models.CharField(max_length=255)
    observed_ttps = models.ManyToManyField(TTP, through='ObservedTTP', symmetrical=False, related_name='ttp_observed_at_ta', blank=True)

    def add_observed_ttp(self, ttp, relationship):
        obs_ttp, obs_ttp_created = ObservedTTP.objects.get_or_create(
            ta=self,
            ttp=ttp,
            relationship=relationship
        )
        return obs_ttp

    def __unicode__(self):
        return u"%s" % (self.name) class Package(models.Model):
    name = models.CharField(max_length=255)
    creation_time = models.DateTimeField(auto_now_add=True)
    last_modified = models.DateTimeField(auto_now=True)
    description = models.TextField(null=True, blank=True)
    short_description = models.CharField(max_length=255, null=True, blank=True)
    namespace = models.ManyToManyField('Namespace', blank=True)
    version = models.CharField(max_length=255)
    package_id = models.CharField(max_length=255)
    source = models.CharField(max_length=255)
    produced_time = models.DateTimeField(null=True, blank=True)
    threat_actors = models.ManyToManyField('ThreatActor', blank=True)
    campaigns = models.ManyToManyField('Campaign', blank=True)
    indicators = models.ManyToManyField('Indicator', blank=True)
    observables = models.ManyToManyField('Observable', blank=True)
    ttps = models.ManyToManyField('TTP', blank=True)

    def __unicode__(self):
        return u"%s" % (self.name) class ObservableComposition(models.Model):
    name = models.CharField(max_length=255)
    operator = models.CharField(max_length=3, default='OR')
    indicator = models.ManyToManyField(Indicator, blank=True)
    observables = models.ManyToManyField('Observable', blank=True)
    observable_compositions = models.ManyToManyField('self', blank=True)

    def __unicode__(self):
        return u"%s" % (self.name) class File_Object(models.Model):
    file_meta = models.ManyToManyField(File_Meta_Object, blank=True)
    file_custom = models.ManyToManyField(File_Custom_Properties, blank=True)
    md5_hash = models.CharField(max_length=32, null=True, blank=True)
    sha256_hash = models.CharField(max_length=64, null=True, blank=True)
    observables = models.ManyToManyField(Observable)

    def __unicode__(self):
        if self.md5_hash:
            return u"%s" % (self.md5_hash)
        elif self.sha256_hash:
            return u"%s" % (self.sha256_hash)
        else:
            return u"File Object"

    class Meta:
        index_together = (("md5_hash", "sha256_hash"),) class TTP(models.Model):
    """ Tools, Tactics, and Procedures
    """
    name = models.CharField(max_length=255)
    creation_time = models.DateTimeField(auto_now_add=True)
    last_modified = models.DateTimeField(auto_now=True)
    description = models.TextField(null=True, blank=True)
    short_description = models.CharField(max_length=255, null=True, blank=True)
    namespace = models.ManyToManyField('Namespace', blank=True)
    ttp_id = models.CharField(max_length=255)
    related_ttps = models.ManyToManyField('self', through='RelatedTTP', symmetrical=False, related_name='ttp_related_to_ttp', blank=True)

    def add_related_ttp(self, ttp, relationship):
        rel_ttp, rel_ttp_created = RelatedTTP.objects.get_or_create(from_ttp=self, to_ttp=ttp, relationship=relationship)
        return rel_ttp

    def __unicode__(self):
        return u"%s" % (self.name) class RelatedTTP(models.Model):
    from_ttp = models.ForeignKey(TTP, related_name='from_ttp', on_delete=models.CASCADE)
    to_ttp = models.ForeignKey(TTP, related_name='to_ttp', on_delete=models.CASCADE)
    relationship = models.CharField(max_length=255) class MalwareInstance(models.Model):
    ttp_ref = models.ForeignKey(TTP, on_delete=models.CASCADE)
    name = models.CharField(max_length=255)
    creation_time = models.DateTimeField(auto_now_add=True)
    last_modified = models.DateTimeField(auto_now=True)
    description = models.TextField(null=True, blank=True)
    short_description = models.CharField(max_length=255, null=True, blank=True)

    def __unicode__(self):
        return u"%s" % (self.name) class AttackPattern(models.Model):
    ttp_ref = models.ForeignKey(TTP, on_delete=models.CASCADE)
    name = models.CharField(max_length=255)
    creation_time = models.DateTimeField(auto_now_add=True)
    last_modified = models.DateTimeField(auto_now=True)
    description = models.TextField(null=True, blank=True)
    short_description = models.CharField(max_length=255, null=True, blank=True)
    capec_id = models.CharField(max_length=255) class Address_Object(models.Model):
    address_value = models.CharField(max_length=255)
    category = models.CharField(max_length=255, default="ipv4-addr")
    condition = models.CharField(max_length=255, default="equals")
    observables = models.ManyToManyField(Observable)

    def __unicode__(self):
        if self.address_value:
            return u"%s" % (self.address_value)
        else:
            return u"Address Object"

    class Meta:
        unique_together = (("address_value", "category", "condition"),) class URI_Object(models.Model):
    uri_value = models.CharField(max_length=255)
    uri_type = models.CharField(max_length=255)
    condition = models.CharField(max_length=255, default="equals")
    observables = models.ManyToManyField(Observable)

    def __unicode__(self):
        if self.uri_value:
            return u"%s" % (self.uri_value)
        else:
            return u"URI Object"

    class Meta:
        unique_together = (("uri_value", "uri_type", "condition"),) class CustomPaginator(pagination.PageNumberPagination):
    django_paginator_class = KrautCustomPaginator

    def get_page_size(self, request):
        if request.query_params:
            return int(request.query_params.get('length', 25))
        return 25

    def paginate_queryset(self, queryset, request, view=None):
        page_size = self.get_page_size(request)
        paginator = self.django_paginator_class(queryset, page_size)
        if request.query_params:
            page_number = int(int(request.query_params['start'])/int(page_size))+1
        else:
            page_number = 1
        try:
            self.page = paginator.page(page_number)
        except:
            self.page = 1
        self.request = request
        return list(self.page)

    def get_paginated_response(self, data):
        item_count = self.page.paginator.count
        return JsonResponse({
            "status": True,
            "code": status.HTTP_200_OK,
            "next": self.get_next_link(),
            "previous": self.get_previous_link(),
            "count": item_count,
            "iTotalRecords": item_count,
            "iTotalDisplayRecords": item_count,
            "results": data
        }, json_dumps_params={'indent': 2}) class IndicatorSerializer(serializers.ModelSerializer):
    indicator_types = serializers.StringRelatedField(many=True)

    class Meta:
        model = Indicator
        fields = ('id', 'name', 'description', 'short_description', 'namespace', 'indicator_types', 'confidence', 'related_indicators', 'creation_time', 'last_modified', 'indicator_composition_operator') class IndSerializer(serializers.ModelSerializer):
    creation_time = serializers.SerializerMethodField()
    last_modified = serializers.SerializerMethodField()
    namespace = serializers.SerializerMethodField()
    namespace_icon = serializers.SerializerMethodField()

    class Meta:
        model = Indicator
        fields = ('id', 'name', 'description', 'creation_time', 'last_modified', 'namespace', 'namespace_icon')

    def get_namespace_icon(self, obj):
        return get_icon_for_namespace(obj.namespace.last().namespace)

    def get_namespace(self, obj):
        return obj.namespace.last().namespace

    def get_creation_time(self, obj):
        return obj.creation_time.strftime("%Y-%m-%d %H:%M:%S")

    def get_last_modified(self, obj):
        return obj.creation_time.strftime("%Y-%m-%d %H:%M:%S") class Ind2Serializer(serializers.ModelSerializer):
    indicator_types = serializers.SerializerMethodField()
    confidence = serializers.SerializerMethodField()

    class Meta:
        model = Indicator
        fields = ('id', 'name', 'description', 'indicator_types', 'confidence')

    def get_indicator_types(self, obj):
        try:
            return obj.indicator_types.last().itype
        except:
            return None

    def get_confidence(self, obj):
        return obj.confidence.first().value class IndicatorCommentSerializer(serializers.ModelSerializer):
    author = serializers.SerializerMethodField()

    class Meta:
        model = IndicatorComment
        fields = ('id', 'author', 'creation_time', 'indicator_reference', 'ctext')

    def get_author(self, obj):
        return obj.author.username class ObservableSerializer(serializers.ModelSerializer):
    indicators = serializers.StringRelatedField(many=True)

    class Meta:
        model = Observable
        fields = ('id', 'name', 'description', 'short_description', 'namespace', 'creation_time', 'last_modified', 'indicators', 'observable_type') class ObsSerializer(serializers.ModelSerializer):
    creation_time = serializers.SerializerMethodField()
    last_modified = serializers.SerializerMethodField()
    short_name = serializers.SerializerMethodField()
    namespace = serializers.SerializerMethodField()
    namespace_icon = serializers.SerializerMethodField()

    class Meta:
        model = Observable
        fields = ('id', 'name', 'description', 'creation_time', 'last_modified', 'namespace', 'observable_type', 'short_name', 'namespace_icon')

    def get_namespace_icon(self, obj):
        return get_icon_for_namespace(obj.namespace.last().namespace)

    def get_namespace(self, obj):
        return obj.namespace.last().namespace

    def get_short_name(self, obj):
        if len(obj.name)>35:
            return "%s ..." % (obj.name[:35])
        return obj.name

    def get_creation_time(self, obj):
        return obj.creation_time.strftime("%Y-%m-%d %H:%M:%S")

    def get_last_modified(self, obj):
        return obj.creation_time.strftime("%Y-%m-%d %H:%M:%S") class ObservableCommentSerializer(serializers.ModelSerializer):
    author = serializers.SerializerMethodField()

    class Meta:
        model = ObservableComment
        fields = ('id', 'author', 'creation_time', 'observable_reference', 'ctext')

    def get_author(self, obj):
        return obj.author.username class ObservableCompositionSerializer(serializers.ModelSerializer):
    class Meta:
        model = ObservableComposition
        fields = ('id', 'name', 'operator') class CampaignSerializer(serializers.ModelSerializer):
    confidence = serializers.StringRelatedField(many=True)

    class Meta:
        model = Campaign
        fields = ('id', 'name', 'description', 'short_description', 'namespace', 'creation_time', 'last_modified', 'status', 'confidence', 'related_indicators', 'associated_campaigns') class CampSerializer(serializers.ModelSerializer):
    creation_time = serializers.SerializerMethodField()
    last_modified = serializers.SerializerMethodField()
    namespace = serializers.SerializerMethodField()
    namespace_icon = serializers.SerializerMethodField()
    confidence = serializers.SerializerMethodField()

    class Meta:
        model = Campaign
        fields = ('id', 'name', 'description', 'creation_time', 'last_modified', 'namespace', 'namespace_icon', 'confidence', 'status')

    def get_namespace_icon(self, obj):
        return get_icon_for_namespace(obj.namespace.last().namespace)

    def get_namespace(self, obj):
        return obj.namespace.last().namespace

    def get_creation_time(self, obj):
        return obj.creation_time.strftime("%Y-%m-%d %H:%M:%S")

    def get_last_modified(self, obj):
        return obj.creation_time.strftime("%Y-%m-%d %H:%M:%S")

    def get_confidence(self, obj):
        try:
            return obj.confidence.first().value
        except:
            return "Unknown" class CampaignCommentSerializer(serializers.ModelSerializer):
    author = serializers.SerializerMethodField()

    class Meta:
        model = CampaignComment
        fields = ('id', 'author', 'creation_time', 'campaign_reference', 'ctext')

    def get_author(self, obj):
        return obj.author.username class ThreatActorSerializer(serializers.ModelSerializer):
    campaigns = serializers.StringRelatedField(many=True)

    class Meta:
        model = ThreatActor
        fields = ('id', 'name', 'description', 'short_description', 'namespace', 'creation_time', 'last_modified', 'campaigns', 'associated_threat_actors') class TASerializer(serializers.ModelSerializer):
    creation_time = serializers.SerializerMethodField()
    last_modified = serializers.SerializerMethodField()
    namespace = serializers.SerializerMethodField()
    namespace_icon = serializers.SerializerMethodField()

    class Meta:
        model = ThreatActor
        fields = ('id', 'name', 'description', 'creation_time', 'last_modified', 'namespace', 'namespace_icon', 'short_description')

    def get_namespace_icon(self, obj):
        return get_icon_for_namespace(obj.namespace.last().namespace)

    def get_namespace(self, obj):
        return obj.namespace.last().namespace

    def get_creation_time(self, obj):
        return obj.creation_time.strftime("%Y-%m-%d %H:%M:%S")

    def get_last_modified(self, obj):
        return obj.creation_time.strftime("%Y-%m-%d %H:%M:%S") class ActorCommentSerializer(serializers.ModelSerializer):
    author = serializers.SerializerMethodField()

    class Meta:
        model = ThreatActorComment
        fields = ('id', 'author', 'creation_time', 'actor_reference', 'ctext')

    def get_author(self, obj):
        return obj.author.username class PackageSerializer(serializers.ModelSerializer):

    class Meta:
        model = Package
        fields = ('id', 'name', 'description', 'short_description', 'namespace', 'creation_time', 'last_modified', 'version', 'package_id', 'source', 'produced_time', 'threat_actors', 'campaigns', 'indicators', 'observables') class PackSerializer(serializers.ModelSerializer):
    creation_time = serializers.SerializerMethodField()
    last_modified = serializers.SerializerMethodField()
    namespace_icon = serializers.SerializerMethodField()
    namespace = serializers.SerializerMethodField()
    short_name = serializers.SerializerMethodField()

    class Meta:
        model = Package
        fields = ('id', 'name', 'description', 'creation_time', 'last_modified', 'namespace', 'namespace_icon', 'short_name')

    def get_namespace_icon(self, obj):
        return get_icon_for_namespace(obj.namespace.last().namespace)

    def get_namespace(self, obj):
        return obj.namespace.last().namespace

    def get_creation_time(self, obj):
        return obj.creation_time.strftime("%Y-%m-%d %H:%M:%S")

    def get_last_modified(self, obj):
        return obj.last_modified.strftime("%Y-%m-%d %H:%M:%S")

    def get_short_name(self, obj):
        if len(obj.name)>55:
            return "%s ..." % (obj.name[:55])
        return obj.name class PackageCommentSerializer(serializers.ModelSerializer):
    author = serializers.SerializerMethodField()

    class Meta:
        model = PackageComment
        fields = ('id', 'author', 'creation_time', 'package_reference', 'ctext')

    def get_author(self, obj):
        return obj.author.username class IncidentSerializer(serializers.ModelSerializer):
    status = serializers.StringRelatedField()
    category = serializers.StringRelatedField()
    severity = serializers.SerializerMethodField()

    class Meta:
        model = Incident
        fields = ('id', 'incident_number', 'title', 'creation_time', 'last_modified', 'status', 'category', 'severity')

    def get_severity(self, obj):
        if obj.severity == 'h':
            return 'High'
        elif obj.severity == 'm':
            return 'Medium'
        elif obj.severity == 'l':
            return 'Low'
        return obj.severity class ContactSerializer(serializers.ModelSerializer):
    class Meta:
        model = Contact
        fields = ('id', 'firstname', 'lastname') class HandlerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Handler
        fields = ('id', 'firstname', 'lastname') class TemplateTaskSerializer(serializers.ModelSerializer):
    class Meta:
        model = TemplateTask
        fields = ('id', 'name', 'description') class AddressObjectSerializer(serializers.ModelSerializer):
    observables = ObservableSerializer(many=True)

    class Meta:
        model = Address_Object
        fields = ('id', 'address_value', 'category', 'observables') class URIObjectSerializer(serializers.ModelSerializer):
    observables = ObservableSerializer(many=True)
    short_value = serializers.SerializerMethodField()

    class Meta:
        model = URI_Object
        fields = ('id', 'uri_value', 'uri_type', 'observables', 'short_value')

    def get_short_value(self, obj):
        if len(obj.uri_value)>70:
            return "%s ..." % (obj.uri_value[:70])
        return obj.uri_value class FileObjectSerializer(serializers.ModelSerializer):
    observables = ObservableSerializer(many=True)

    class Meta:
        model = File_Object
        fields = ('id', 'md5_hash', 'sha256_hash', 'observables') class TTPSerializer(serializers.ModelSerializer):
    creation_time = serializers.SerializerMethodField()
    last_modified = serializers.SerializerMethodField()
    namespace = serializers.SerializerMethodField()
    namespace_icon = serializers.SerializerMethodField()

    class Meta:
        model = TTP
        fields = ('id', 'name', 'description', 'short_description', 'namespace', 'namespace_icon', 'creation_time', 'last_modified', 'related_ttps')

    def get_namespace_icon(self, obj):
        return get_icon_for_namespace(obj.namespace.last().namespace)

    def get_namespace(self, obj):
        return obj.namespace.last().namespace

    def get_creation_time(self, obj):
        return obj.creation_time.strftime("%Y-%m-%d %H:%M:%S")

    def get_last_modified(self, obj):
        return obj.creation_time.strftime("%Y-%m-%d %H:%M:%S") class TTPCommentSerializer(serializers.ModelSerializer):
    author = serializers.SerializerMethodField()

    class Meta:
        model = TTPComment
        fields = ('id', 'author', 'creation_time', 'ttp_reference', 'ctext')

    def get_author(self, obj):
        return obj.author.username class MalwareInstanceSerializer(serializers.ModelSerializer):
    short_name = serializers.SerializerMethodField()
    creation_time = serializers.SerializerMethodField()
    last_modified = serializers.SerializerMethodField()
    subname = serializers.SerializerMethodField()
    mwitype = serializers.SerializerMethodField()

    class Meta:
        model = MalwareInstance
        fields = ('id', 'name', 'short_name', 'description', 'short_description', 'creation_time', 'last_modified', 'subname', 'mwitype')

    def get_short_name(self, obj):
        if len(obj.name)>55:
            return "%s ..." % (obj.name[:55])
        return obj.name

    def get_creation_time(self, obj):
        return obj.creation_time.strftime("%Y-%m-%d %H:%M:%S")

    def get_last_modified(self, obj):
        return obj.creation_time.strftime("%Y-%m-%d %H:%M:%S")

    def get_subname(self, obj):
        try:
            return obj.malwareinstancenames_set.first().name
        except:
            return "Unknown"

    def get_mwitype(self, obj):
        try:
            return obj.malwareinstancetypes_set.first()._type
        except:
            return "Unknown" class AttackPatternSerializer(serializers.ModelSerializer):
    short_name = serializers.SerializerMethodField()
    creation_time = serializers.SerializerMethodField()
    last_modified = serializers.SerializerMethodField()

    class Meta:
        model = AttackPattern
        fields = ('id', 'name', 'short_name', 'description', 'short_description', 'creation_time', 'last_modified', 'capec_id')

    def get_short_name(self, obj):
        if len(obj.name)>55:
            return "%s ..." % (obj.name[:55])
        return obj.name

    def get_creation_time(self, obj):
        return obj.creation_time.strftime("%Y-%m-%d %H:%M:%S")

    def get_last_modified(self, obj):
        return obj.creation_time.strftime("%Y-%m-%d %H:%M:%S") class CollectionSerializer(serializers.ModelSerializer):
    last_modified = serializers.SerializerMethodField()

    class Meta:
        model = TAXII_Remote_Collection
        fields = ('id', 'name', 'creation_time', 'last_modified', 'subscribed', 'collection_type', 'poll_period', 'begin_timestamp')

    def get_last_modified(self, obj):
        #delta = datetime.datetime.now() - obj.last_modified.replace(tzinfo=None)
        #return "%s days ago ..." % (delta.days)
        return obj.last_modified.strftime("%Y-%m-%d") class ServersSerializer(serializers.ModelSerializer):

    class Meta:
        model = TAXII_Remote_Server
        fields = ('id', 'name', 'host', 'path') def get_object_for_observable(observable_type, observable_object=None, object_id=None, no_hash=True):
    """ Return the list of objects belonging to a given observable or the object for a given id.
        The optional no_hash parameter determines if also file objects without a hash should be returned.

        TODO: support all observable types that are implemented!
    """
    return_list = []
    # create filter
    if observable_object:
        q_filter = Q(observables=observable_object)
    elif object_id:
        q_filter = Q(id=object_id)
    else:
        q_filter = Q(observables=observable_object)|Q(id=object_id)
    # check observable type and query
    if observable_type == 'FileObjectType':
        for obj in File_Object.objects.filter(q_filter):
            if no_hash:
                return_list.append(obj)
            else:
                if (obj.md5_hash and obj.md5_hash != 'No MD5') or (obj.sha256_hash and obj.sha256_hash != 'No SHA256'):
                    return_list.append(obj)
    elif observable_type == 'HTTPSessionObjectType':
        for obj in HTTPSession_Object.objects.filter(q_filter):
            return_list.append(obj)
    elif observable_type == 'URIObjectType' or observable_type == 'DomainNameObjectType':
        for obj in URI_Object.objects.filter(q_filter):
            return_list.append(obj)
    elif observable_type == 'AddressObjectType':
        for obj in Address_Object.objects.filter(q_filter):
            return_list.append(obj)
    elif observable_type == 'MutexObjectType':
        for obj in Mutex_Object.objects.filter(q_filter):
            return_list.append(obj)
    elif observable_type == 'CodeObjectType':
        for obj in Code_Object.objects.filter(q_filter):
            return_list.append(obj)
    elif observable_type == 'EmailMessageObjectType':
        for obj in EmailMessage_Object.objects.filter(q_filter):
            return_list.append(obj)
    elif observable_type == 'WindowsRegistryKeyObjectType':
        for obj in Win_Registry_Object.objects.filter(q_filter):
            return_list.append(obj)
    elif observable_type == 'DNSQueryObjectType':
        for obj in DNSQuery_Object.objects.filter(q_filter):
            return_list.append(obj)
    elif observable_type == 'WindowsDriverObjectType':
        for obj in Driver_Object.objects.filter(q_filter):
            return_list.append(obj)
    elif observable_type == 'LinkObjectType':
        for obj in Link_Object.objects.filter(q_filter):
            return_list.append(obj)
    elif observable_type == 'WindowsExecutableFileObjectType':
        for obj in WindowsExecutable_Object.objects.filter(q_filter):
            return_list.append(obj)

    return return_list def get_related_objects_for_object(object_id, object_type, quick=False):
    """ Return the list of related objects for a given object and type.
        The quick parameter will kind of normalize the return values so it can be used in the quick panel.
    """
    return_list = []
    try:
        related_objects_all = Related_Object.objects.filter(
            Q(object_one_id=object_id, object_one_type=object_type)|
            Q(object_two_id=object_id, object_two_type=object_type)
        )
    except Related_Object.DoesNotExist:
        return return_list
    for object_relation in related_objects_all:
        if object_relation.object_one_id == object_id:
            related_objects = get_object_for_observable(object_relation.object_two_type, object_id=object_relation.object_two_id)
        else:
            related_objects = get_object_for_observable(object_relation.object_one_type, object_id=object_relation.object_one_id)
        return_list.append({'objects': related_objects, 'relation': object_relation.relationship})
    return return_list class Contact(models.Model):
    """Describe a contact person
    """
    firstname = models.CharField(max_length=255)
    lastname = models.CharField(max_length=255)
    phone = models.CharField(max_length=255, blank=True)
    email = models.EmailField(max_length=255)
    description = models.TextField(null=True, blank=True)

    class Meta:
        unique_together = (("firstname", "lastname", "email"),) class Handler(models.Model):
    """Describe an incident handler person
    """
    firstname = models.CharField(max_length=255)
    lastname = models.CharField(max_length=255)
    phone = models.CharField(max_length=255, blank=True)
    email = models.EmailField(max_length=255)
    description = models.TextField(null=True, blank=True)

    class Meta:
        unique_together = (("firstname", "lastname", "email"),) class Incident(models.Model):
    """Describe a security incident
    """
    incident_number = models.IntegerField(unique=True, default=random_incident_number)
    title = models.CharField(max_length=255, default="Unnamed Incident")
    description = models.TextField(null=True, blank=True)
    creation_time = models.DateTimeField(auto_now_add=True)
    last_modified = models.DateTimeField(auto_now=True)
    status = models.ForeignKey(Incident_Status, on_delete=models.CASCADE)
    category = models.ForeignKey(Incident_Category, on_delete=models.CASCADE)
    affected_assets = models.ManyToManyField(Asset, blank=True)
    tasks = models.ManyToManyField(Task, blank=True)
    incident_handler = models.ManyToManyField(Handler, blank=True, related_name="incident_handler")
    contacts = models.ManyToManyField(Contact, blank=True, related_name="contacts")
    severity_choices = (
                ('h', 'High'),
                ('m', 'Medium'),
                ('l', 'Low'),
            )
    severity = models.CharField(max_length=2, choices=severity_choices, default='m')

    def __unicode__(self):
        return u"%s" % (self.title) class TemplateTask(models.Model):
    """Describe a template for a task to attach to an incident
    """
    name = models.CharField(max_length=255, default="Template Task")
    description = models.TextField(null=True, blank=True, default="Task Description") class PackageComment(models.Model):
    ctext = models.TextField()
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    creation_time = models.DateTimeField(auto_now_add=True)
    package_reference = models.ForeignKey(Package, on_delete=models.CASCADE) class NamespaceIcon(models.Model):
    namespace = models.CharField(max_length=255, unique=True)
    icon = models.CharField(max_length=255)

    def __unicode__(self):
        return u"%s (%s)" % (self.namespace, self.icon) class ThreatActorComment(models.Model):
    ctext = models.TextField()
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    creation_time = models.DateTimeField(auto_now_add=True)
    actor_reference = models.ForeignKey(ThreatActor, on_delete=models.CASCADE) class CampaignComment(models.Model):
    ctext = models.TextField()
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    creation_time = models.DateTimeField(auto_now_add=True)
    campaign_reference = models.ForeignKey(Campaign, on_delete=models.CASCADE) class TTPComment(models.Model):
    ctext = models.TextField()
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    creation_time = models.DateTimeField(auto_now_add=True)
    ttp_reference = models.ForeignKey(TTP, on_delete=models.CASCADE) class IndicatorComment(models.Model):
    ctext = models.TextField()
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    creation_time = models.DateTimeField(auto_now_add=True)
    indicator_reference = models.ForeignKey(Indicator, on_delete=models.CASCADE) class ObservableComment(models.Model):
    ctext = models.TextField()
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    creation_time = models.DateTimeField(auto_now_add=True)
    observable_reference = models.ForeignKey(Observable, on_delete=models.CASCADE) class TAXII_Remote_Server(models.Model):
    creation_time = models.DateTimeField(auto_now_add=True)
    name = models.CharField(max_length=255, help_text="""Name/Identifier""")
    host = models.CharField(max_length=255, help_text="""Hostname or IP address""")
    port = models.IntegerField(help_text="""Remote port""", default=80)
    protocol = models.CharField(max_length=5, help_text="""Protocol to use""", default="http")
    path = models.CharField(max_length=255, help_text="""Path to service""")
    version = models.CharField(max_length=5, help_text="""TAXII version to use""", default="1.1")
    auth_type = models.IntegerField(default=0, help_text="""Authentication to use""")
    last_discovery = models.DateTimeField(blank=True, null=True)
    # TODO: fields for authentication (foreign key)
    # TODO: proxy configuration

    def get_url(self):
        return "%s://%s:%i%s" % (self.protocol, self.host, self.port, self.path)

    def __unicode__(self):
        return u"%s (%s://%s:%i%s)" % (self.name, self.protocol, self.host, self.port, self.path)

    class Meta:
        unique_together = (("name", "host", "port", "protocol", "path"),) class TAXII_Remote_Collection(models.Model):
    creation_time = models.DateTimeField(auto_now_add=True)
    last_modified = models.DateTimeField(auto_now=True)
    name = models.CharField(max_length=255, help_text="""name of the collection""", unique=True)
    begin_timestamp = models.DateTimeField(blank=True, null=True)
    end_timestamp = models.DateTimeField(blank=True, null=True)
    server = models.ForeignKey("TAXII_Remote_Server", on_delete=models.CASCADE)
    subscribed = models.BooleanField(default=False)
    collection_type = models.CharField(max_length=255, default="DATA-FEED")
    poll_period = models.IntegerField(default=24, help_text="""poll period in hours (e.g. 24 = every 24 hours)""")

    def __unicode__(self):
        return u"%s" % (self.name) class DiscoveryForm(forms.Form):
    url = forms.URLField(label='Discovery URL', max_length='255', widget=forms.TextInput(attrs={'class': 'form-control', 'id': 'discoveryURL', 'name': 'discoveryURL'})) class CollectionRequest:

    def __init__(self, url):
        self.url = urlparse(url)

    def run(self):
        client = tc.HttpClient()
        # TODO: handle authentication stuff
        #client.set_auth_type(tc.AUTH_NONE)
        client.set_use_https(False)

        r = CollectionInformationRequest(generate_message_id())
        col_xml = r.to_xml(pretty_print=True)

        if ':' in self.url.netloc:
            host = self.url.netloc.split(':')[0]
            server_port = self.url.netloc.split(':')[1]
        else:
            host = self.url.netloc
            server_port = None
        if server_port:
            http_resp = client.call_taxii_service2(host, self.url.path, VID_TAXII_XML_11, col_xml, port = server_port)
        else:
            http_resp = client.call_taxii_service2(host, self.url.path, VID_TAXII_XML_11, col_xml)
        taxii_message = t.get_message_from_http_response(http_resp, r.message_id)
        return taxii_message.to_dict()
from django.http import JsonResponse, HttpResponse
from django.urls import reverse
from django.db.models import Q
from django.core.paginator import Paginator
from rest_framework import status
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework.authentication import SessionAuthentication
from kraut_parser.models import Indicator, Observable, Campaign, ThreatActor, Package, ObservableComposition, File_Object, TTP, RelatedTTP, MalwareInstance, AttackPattern
from kraut_parser.models import Address_Object, URI_Object
from kraut_api.paginators import CustomPaginator
from kraut_api.serializers import IndicatorSerializer, IndSerializer, Ind2Serializer, IndicatorCommentSerializer
from kraut_api.serializers import ObservableSerializer, ObsSerializer, ObservableCommentSerializer, ObservableCompositionSerializer
from kraut_api.serializers import CampaignSerializer, CampSerializer, CampaignCommentSerializer
from kraut_api.serializers import ThreatActorSerializer, TASerializer, ActorCommentSerializer
from kraut_api.serializers import PackageSerializer, PackSerializer, PackageCommentSerializer
from kraut_api.serializers import IncidentSerializer, ContactSerializer, HandlerSerializer, TemplateTaskSerializer
from kraut_api.serializers import AddressObjectSerializer, URIObjectSerializer, FileObjectSerializer
from kraut_api.serializers import TTPSerializer, TTPCommentSerializer
from kraut_api.serializers import MalwareInstanceSerializer, AttackPatternSerializer
from kraut_api.serializers import CollectionSerializer, ServersSerializer
from kraut_parser.utils import get_object_for_observable, get_related_objects_for_object
from kraut_incident.models import Contact, Handler, Incident, TemplateTask
from kraut_intel.models import PackageComment, NamespaceIcon, ThreatActorComment, CampaignComment, TTPComment, IndicatorComment, ObservableComment
from kraut_sharing.models import TAXII_Remote_Server, TAXII_Remote_Collection
from kraut_sharing.forms import DiscoveryForm
from kraut_sharing.feed import CollectionRequest
import json, csv
            order_by_column = 'name'
            order_direction = '-'
            search_value = None
        # construct queryset
        try:
            pack = Package.objects.get(pk=pk)
        except Package.DoesNotExist:
            return Response(status=status.HTTP_400_BAD_REQUEST)
        queryset = pack.indicators.all().order_by('%s%s' % (order_direction, order_by_column))
        if search_value:
            queryset = queryset.filter(
                Q(name__icontains=search_value)|
                Q(indicator_types__itype__istartswith=search_value)|
                Q(confidence__value__istartswith=search_value)
            )
        indicators = paginator.paginate_queryset(queryset, request)
        serializer_context = {'request': request}
        serializer = Ind2Serializer(instance=indicators, context=serializer_context, many=True)
        return paginator.get_paginated_response(serializer.data)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

@api_view(['GET'])
@authentication_classes((SessionAuthentication, ))
@permission_classes((IsAuthenticated,))
def package_detail_campaigns(request, pk, format=None):
    if request.method == 'GET':
        paginator = CustomPaginator()
        max_items = 10
        page = request.query_params.get('page')
        if request.query_params:
            # number of items to retrieve
            if 'length' in request.query_params:
                max_items = int(request.query_params['length'])
            # page to show
            if 'start' in request.query_params:
                page = int(int(request.query_params['start'])/int(max_items))+1
            # order
            if 'order[0][column]' in request.query_params and 'order[0][dir]' in request.query_params:
                order_by_column = request.query_params['columns['+str(request.query_params['order[0][column]'])+'][data]']
                if request.query_params['order[0][dir]'] == 'desc':
                    order_direction = '-'
                else:
                    order_direction = ''
            else:
                order_direction = '-'
                order_by_column = 'name'
            # search
            if 'search[value]' in request.query_params:
                search_value = request.query_params['search[value]']
            else:
                search_value = None
        else:
            order_by_column = 'name'
            order_direction = '-'
            search_value = None
        # construct queryset
        try:
            pack = Package.objects.get(pk=pk)
        except Package.DoesNotExist:
            return Response(status=status.HTTP_400_BAD_REQUEST)
        queryset = pack.campaigns.all().order_by('%s%s' % (order_direction, order_by_column))
        if search_value:
            queryset = queryset.filter(
                Q(name__icontains=search_value)|
                Q(status__istartswith=search_value)|
                Q(confidence__value__istartswith=search_value)
            )
        indicators = paginator.paginate_queryset(queryset, request)
        serializer_context = {'request': request}
        serializer = CampSerializer(instance=indicators, context=serializer_context, many=True)
        return paginator.get_paginated_response(serializer.data)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

@api_view(['GET'])
@authentication_classes((SessionAuthentication, ))
@permission_classes((IsAuthenticated,))
def package_detail_ttps(request, pk, format=None):
    if request.method == 'GET':
        paginator = CustomPaginator()
        max_items = 10
        page = request.query_params.get('page')
        if request.query_params:
            # number of items to retrieve
            if 'length' in request.query_params:
                max_items = int(request.query_params['length'])
            # page to show
            if 'start' in request.query_params:
                page = int(int(request.query_params['start'])/int(max_items))+1
            # order
            if 'order[0][column]' in request.query_params and 'order[0][dir]' in request.query_params:
                order_by_column = request.query_params['columns['+str(request.query_params['order[0][column]'])+'][data]']
                if request.query_params['order[0][dir]'] == 'desc':
                    order_direction = '-'
                else:
                    order_direction = ''
            else:
                order_direction = '-'
                order_by_column = 'name'
            # search
            if 'search[value]' in request.query_params:
                search_value = request.query_params['search[value]']
            else:
                search_value = None
        else:
            order_by_column = 'name'
            order_direction = '-'
            search_value = None
        # construct queryset
        try:
            pack = Package.objects.get(pk=pk)
        except Package.DoesNotExist:
            return Response(status=status.HTTP_400_BAD_REQUEST)
        queryset = pack.ttps.all().order_by('%s%s' % (order_direction, order_by_column))
        if search_value:
            queryset = queryset.filter(
                Q(name__icontains=search_value)|
                Q(short_description__istartswith=search_value)
            )
        ttps = paginator.paginate_queryset(queryset, request)
        serializer_context = {'request': request}

        serializer = TTPSerializer(instance=ttps, context=serializer_context, many=True)