Skip to content

Commit

Permalink
Merge pull request #3 from DSecureMe/alpha2-es
Browse files Browse the repository at this point in the history
Removed Database Dependency for cve, exploits, cpe, assets, vulnerabitiies.
  • Loading branch information
mwalkowski authored Jan 13, 2020
2 parents 4432d2e + fc22993 commit c321c20
Show file tree
Hide file tree
Showing 47 changed files with 938 additions and 1,725 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
![Logo](https://dsecure.me/wp-content/uploads/2019/11/dSecure-1.png)

[![Build Status](https://travis-ci.com/DSecureMe/vmc.svg?branch=master)](https://travis-ci.com/DSecureMe/vmc) [![codecov](https://codecov.io/gh/DSecureMe/vmc/branch/master/graph/badge.svg)](https://codecov.io/gh/DSecureMe/vmc) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![PyPI version](https://badge.fury.io/py/vmcenter.svg)](https://badge.fury.io/py/vmcenter)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/7e6cbf0a970e4b19963bc3a63f843bf7)](https://www.codacy.com/gh/DSecureMe/vmc?utm_source=github.com&utm_medium=referral&utm_content=DSecureMe/vmc&utm_campaign=Badge_Grade)

**[VMC](https://dsecure.me)** (Vulnerability Management Center) is a platform designed to make vulnerability governance easier for any security specialists and SOC teams within their organisations. VMC is a great partner in any vulnerability management process, allowing automation and making your life easier. You can integrate VMC with vulnerability scanners and platforms like [TheHive](https://github.com/TheHive-Project/TheHive) (_Work in Progess_). Additionally, VMC takes care of asset management integrating with [Ralph](https://github.com/allegro/ralph) - _Work in Progress_, whole vulnerability reporting and dashboards ([Kibana](https://github.com/elastic/kibana)) for the clear overview. VMC allows you to focus on the most important vulnerability issues within your environment.

Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ django-celery-results==1.0.4
django-simple-history==2.7.3
pyyaml==5.1.2
mysqlclient==1.4.4
gunicorn==19.9.0
gunicorn==20.0.4
45 changes: 28 additions & 17 deletions src/vmc/assets/documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,39 @@
* under the License.
*
"""
from decimal import Decimal

from django_elasticsearch_dsl.registries import registry
from django_elasticsearch_dsl import Document, fields
from elasticsearch_dsl import Date, Keyword, InnerDoc
from vmc.common.enum import TupleValueEnum

from vmc.assets.models import Asset
from vmc.common.elastic.documents import Document, TupleValueField
from vmc.common.elastic.registers import registry


@registry.register_document
class AssetDocument(Document):
ip_address = fields.KeywordField()
os = fields.KeywordField()
confidentiality_requirement = fields.KeywordField(attr='get_confidentiality_requirement_display')
integrity_requirement = fields.KeywordField(attr='get_integrity_requirement_display')
availability_requirement = fields.KeywordField(attr='get_availability_requirement_display')
business_owner = fields.KeywordField()
technical_owner = fields.KeywordField()
hostname = fields.KeywordField()
created_date = fields.DateField()
modified_date = fields.DateField()
class Impact(TupleValueEnum):
LOW = ('L', Decimal('0.5'))
MEDIUM = ('M', Decimal('1.0'))
HIGH = ('H', Decimal('1.51'))
NOT_DEFINED = ('N', Decimal('1.0'))


class AssetInnerDoc(InnerDoc):
ip_address = Keyword()
os = Keyword()
cmdb_id = Keyword()
confidentiality_requirement = TupleValueField(choice_type=Impact)
integrity_requirement = TupleValueField(choice_type=Impact)
availability_requirement = TupleValueField(choice_type=Impact)
business_owner = Keyword()
technical_owner = Keyword()
hostname = Keyword()
created_date = Date()
modified_date = Date()
change_reason = Keyword()


@registry.register_document
class AssetDocument(AssetInnerDoc, Document):
class Index:
name = 'asset'

class Django:
model = Asset.history.model
35 changes: 0 additions & 35 deletions src/vmc/assets/fixtures/assets.json

This file was deleted.

70 changes: 0 additions & 70 deletions src/vmc/assets/migrations/0001_initial.py

This file was deleted.

66 changes: 0 additions & 66 deletions src/vmc/assets/models.py

This file was deleted.

94 changes: 45 additions & 49 deletions src/vmc/assets/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,17 @@
* under the License.
*
"""

from unittest import skipIf

from django.test import TestCase
from django_elasticsearch_dsl.test import ESTestCase
from parameterized import parameterized

from vmc.common.elastic.tests import ESTestCase
from vmc.assets.apps import AssetsConfig

from vmc.assets.documents import AssetDocument
from vmc.assets.documents import AssetDocument, Impact

from vmc.config.test_settings import elastic_configured
from vmc.assets.models import Asset, Impact


class AssetsConfigTest(TestCase):
Expand All @@ -36,65 +36,61 @@ def test_name(self):
self.assertEqual(AssetsConfig.name, 'vmc.assets')


class AssetTest(TestCase):
fixtures = ['assets.json']

@classmethod
def setUpTestData(cls):
cls.uut = Asset.objects.get(pk=1)
class ImpactTest(TestCase):

def test_call(self):
self.assertEqual(self.uut.__str__(), '10.10.10.1')
self.assertEqual(self.uut.confidentiality_requirement, Impact.NOT_DEFINED.value)
self.assertEqual(self.uut.get_confidentiality_requirement_display(), Impact.NOT_DEFINED.name)
self.assertEqual(self.uut.get_confidentiality_requirement_value(), Impact.NOT_DEFINED.float)
@parameterized.expand([
(Impact.LOW, 0.5),
(Impact.MEDIUM, 1.0),
(Impact.HIGH, 1.51),
(Impact.NOT_DEFINED, 1.0)
])
def test_values(self, first, second):
self.assertEqual(first.second_value, second)

self.assertEqual(self.uut.integrity_requirement, Impact.NOT_DEFINED.value)
self.assertEqual(self.uut.get_integrity_requirement_display(), Impact.NOT_DEFINED.name)
self.assertEqual(self.uut.get_integrity_requirement_value(), Impact.NOT_DEFINED.float)

self.assertEqual(self.uut.availability_requirement, Impact.NOT_DEFINED.value)
self.assertEqual(self.uut.get_availability_requirement_display(), Impact.NOT_DEFINED.name)
self.assertEqual(self.uut.get_availability_requirement_value(), Impact.NOT_DEFINED.float)
@parameterized.expand([
(Impact.LOW, 'LOW'),
(Impact.MEDIUM, 'MEDIUM'),
(Impact.HIGH, 'HIGH'),
(Impact.NOT_DEFINED, 'NOT_DEFINED')
])
def test_values_str(self, first, second):
self.assertEqual(first.name, second)


@skipIf(not elastic_configured(), 'Skip if elasticsearch is not configured')
class AssetDocumentTest(ESTestCase, TestCase):
fixtures = ['assets.json']

def test_model_class_added(self):
self.assertEqual(AssetDocument.django.model, Asset.history.model)

def test_document_index_name(self):
self.assertEqual(AssetDocument.Index.name, 'asset')

def test_document(self):
self.change_imported_object()
search = AssetDocument.search().filter("term", ip_address="10.10.10.1").execute()
self.assertEqual(len(search.hits), 1)

uut = search.hits[0]
AssetDocument(
ip_address='10.10.10.1',
os='Windows',
cmdb_id='1',
confidentiality_requirement='NOT_DEFINED',
integrity_requirement='NOT_DEFINED',
availability_requirement='NOT_DEFINED',
business_owner='test-business_owner',
technical_owner='test-technical_owner',
hostname='test-hostname',
change_reason='create'
).save(refresh=True)

result = AssetDocument.search().filter('term', ip_address='10.10.10.1').execute()
self.assertEqual(len(result.hits), 1)

uut = result.hits[0]
self.assertEqual(uut.os, 'Windows')
self.assertEqual(uut.confidentiality_requirement, 'NOT_DEFINED')
self.assertEqual(uut.integrity_requirement, 'NOT_DEFINED')
self.assertEqual(uut.availability_requirement, 'NOT_DEFINED')
self.assertEqual(uut.confidentiality_requirement.name, Impact.NOT_DEFINED.name)
self.assertEqual(uut.integrity_requirement.name, Impact.NOT_DEFINED.name)
self.assertEqual(uut.availability_requirement.name, Impact.NOT_DEFINED.name)
self.assertEqual(uut.confidentiality_requirement.second_value, Impact.NOT_DEFINED.second_value)
self.assertEqual(uut.integrity_requirement.second_value, Impact.NOT_DEFINED.second_value)
self.assertEqual(uut.availability_requirement.second_value, Impact.NOT_DEFINED.second_value)
self.assertEqual(uut.business_owner, 'test-business_owner')
self.assertEqual(uut.technical_owner, 'test-technical_owner')
self.assertEqual(uut.hostname, 'test-hostname')
self.assertEqual(uut.change_reason, 'create')
self.assertTrue(uut.created_date)
self.assertTrue(uut.modified_date)
prev_date = uut.modified_date

self.change_imported_object(hostname='test-hostname2')
search = AssetDocument.search().filter("term", ip_address="10.10.10.1").execute()
self.assertEqual(len(search.hits), 2)

uut = search.hits[1]
self.assertEqual(uut.hostname, 'test-hostname2')
self.assertNotEqual(uut.modified_date, prev_date)

@staticmethod
def change_imported_object(hostname='test-hostname'):
asset = Asset.objects.get(pk=1)
asset.hostname = hostname
asset.save()
19 changes: 19 additions & 0 deletions src/vmc/common/elastic/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""
* Licensed to DSecure.me under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. DSecure.me licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
"""
Loading

0 comments on commit c321c20

Please sign in to comment.