Skip to content

Commit

Permalink
Asset group edit: preset criticality and teams
Browse files Browse the repository at this point in the history
  • Loading branch information
MaKyOtOx committed Dec 7, 2021
1 parent 0918c3d commit 99cd78a
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 84 deletions.
5 changes: 3 additions & 2 deletions assets/forms.py
Expand Up @@ -68,7 +68,7 @@ def __init__(self, *args, **kwargs):
super(AssetGroupForm, self).__init__(*args, **kwargs)

# @Todo: RBAC_CHECK
assets = [(asset.id, asset.value) for asset in Asset.objects.for_user(self.user).all().order_by('value')]
assets = [Asset.objects.for_user(self.user).all().only('id', 'value').order_by('value').values()]
self.fields['assets'].widget = forms.CheckboxSelectMultiple(choices=assets)

# Check allowed teams (Available in Pro Edition)
Expand Down Expand Up @@ -96,7 +96,8 @@ def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user', None)
super(AssetOwnerForm, self).__init__(*args, **kwargs)

assets = [(asset.id, asset.value) for asset in Asset.objects.for_user(self.user).all()]
# assets = [(asset.id, asset.value) for asset in Asset.objects.for_user(self.user).all()]
assets = [Asset.objects.for_user(self.user).all().only('id', 'value').order_by('value').values()]
self.fields['assets'].widget = forms.CheckboxSelectMultiple(choices=assets)


Expand Down
89 changes: 45 additions & 44 deletions assets/models.py
Expand Up @@ -198,22 +198,23 @@ class Asset(models.Model):
objects = AssetManager()

# Attributes
value = models.TextField(max_length=2048, unique=True, null=False)
name = models.TextField(max_length=2048)
type = models.CharField(choices=ASSET_TYPES, default='ip', max_length=15) # ipv4, ipv6, domain, fqdn, url
criticity = models.CharField(choices=ASSET_CRITICITIES, default='low', max_length=10) # low, medium, high
exposure = models.CharField(choices=ASSET_EXPOSURES, default='unknown', max_length=16) # unknown, external, internal, restricted
risk_level = JSONField(default=get_default_risk_level)
owner = models.ForeignKey(get_user_model(), null=True, blank=True, on_delete=models.SET_NULL)
value = models.TextField(max_length=2048, unique=True, null=False)
name = models.TextField(max_length=2048)
type = models.CharField(choices=ASSET_TYPES, default='ip', max_length=15) # ipv4, ipv6, domain, fqdn, url
criticity = models.CharField(choices=ASSET_CRITICITIES, default='low', max_length=10) # low, medium, high
exposure = models.CharField(choices=ASSET_EXPOSURES, default='unknown', max_length=16) # unknown, external, internal, restricted
risk_level = JSONField(default=get_default_risk_level)
owner = models.ForeignKey(get_user_model(), null=True, blank=True, on_delete=models.SET_NULL)
description = models.CharField(max_length=256, null=True, blank=True)
status = models.CharField(max_length=30, null=True, blank=True, default="new")
categories = models.ManyToManyField(AssetCategory)
created_at = models.DateTimeField(default=timezone.now)
updated_at = models.DateTimeField(default=timezone.now)
teams = models.ManyToManyField('users.team', blank=True)
status = models.CharField(max_length=30, null=True, blank=True, default="new")
categories = models.ManyToManyField(AssetCategory)
created_at = models.DateTimeField(default=timezone.now)
updated_at = models.DateTimeField(default=timezone.now)
teams = models.ManyToManyField('users.team', blank=True)

class Meta:
"""Metadata: DB name."""

db_table = 'assets'

@classmethod
Expand Down Expand Up @@ -413,17 +414,17 @@ class AssetGroup(models.Model):
objects = AssetGroupManager()

# Attributes
assets = models.ManyToManyField(Asset)
name = models.CharField(max_length=256, unique=True)
criticity = models.CharField(choices=ASSET_CRITICITIES, default='low', max_length=10)
risk_level = JSONField(default=get_default_risk_level)
owner = models.ForeignKey(get_user_model(), null=True, on_delete=models.SET_NULL)
assets = models.ManyToManyField(Asset)
name = models.CharField(max_length=256, unique=True)
criticity = models.CharField(choices=ASSET_CRITICITIES, default='low', max_length=10)
risk_level = JSONField(default=get_default_risk_level)
owner = models.ForeignKey(get_user_model(), null=True, on_delete=models.SET_NULL)
description = models.CharField(max_length=256, null=True, blank=True)
status = models.CharField(max_length=30, null=True, blank=True)
categories = models.ManyToManyField(AssetCategory, blank=True)
created_at = models.DateTimeField(default=timezone.now)
updated_at = models.DateTimeField(default=timezone.now)
teams = models.ManyToManyField('users.team', blank=True)
status = models.CharField(max_length=30, null=True, blank=True)
categories = models.ManyToManyField(AssetCategory, blank=True)
created_at = models.DateTimeField(default=timezone.now)
updated_at = models.DateTimeField(default=timezone.now)
teams = models.ManyToManyField('users.team', blank=True)

class Meta:
db_table = 'asset_groups'
Expand Down Expand Up @@ -563,16 +564,16 @@ def assetgroup_delete_log(sender, **kwargs):


class AssetOwnerContact(models.Model):
name = models.CharField(max_length=256)
name = models.CharField(max_length=256)
department = models.CharField(max_length=256, null=True, blank=True)
title = models.CharField(max_length=256, null=True, blank=True)
email = models.EmailField(null=True, blank=True)
phone = models.CharField(max_length=20, null=True, blank=True)
address = models.CharField(max_length=256, null=True, blank=True)
url = models.URLField(null=True, blank=True)
comments = models.CharField(max_length=256, null=True, blank=True)
title = models.CharField(max_length=256, null=True, blank=True)
email = models.EmailField(null=True, blank=True)
phone = models.CharField(max_length=20, null=True, blank=True)
address = models.CharField(max_length=256, null=True, blank=True)
url = models.URLField(null=True, blank=True)
comments = models.CharField(max_length=256, null=True, blank=True)
# owner = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
owner = models.ForeignKey(get_user_model(), null=True, on_delete=models.SET_NULL)
owner = models.ForeignKey(get_user_model(), null=True, on_delete=models.SET_NULL)
created_at = models.DateTimeField(default=timezone.now)
updated_at = models.DateTimeField(default=timezone.now)

Expand Down Expand Up @@ -617,14 +618,14 @@ def assetownercontact_delete_log(sender, **kwargs):


class AssetOwnerDocument(models.Model):
file = models.FileField(null=True, blank=True)
doctitle = models.CharField(max_length=256, null=True, blank=True)
filename = models.CharField(max_length=256, null=True, blank=True)
filepath = models.CharField(max_length=256, null=True, blank=True)
tlp_color = models.CharField(choices=TLP_COLORS, default='red', max_length=10)
comments = models.CharField(max_length=256, null=True, blank=True)
file = models.FileField(null=True, blank=True)
doctitle = models.CharField(max_length=256, null=True, blank=True)
filename = models.CharField(max_length=256, null=True, blank=True)
filepath = models.CharField(max_length=256, null=True, blank=True)
tlp_color = models.CharField(choices=TLP_COLORS, default='red', max_length=10)
comments = models.CharField(max_length=256, null=True, blank=True)
# owner = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
owner = models.ForeignKey(get_user_model(), null=True, on_delete=models.SET_NULL)
owner = models.ForeignKey(get_user_model(), null=True, on_delete=models.SET_NULL)
created_at = models.DateTimeField(default=timezone.now)
updated_at = models.DateTimeField(default=timezone.now)

Expand Down Expand Up @@ -665,14 +666,14 @@ def assetownerdoc_delete_log(sender, **kwargs):


class AssetOwner(models.Model):
assets = models.ManyToManyField(Asset)
contacts = models.ManyToManyField(AssetOwnerContact)
documents = models.ManyToManyField(AssetOwnerDocument)
assets = models.ManyToManyField(Asset)
contacts = models.ManyToManyField(AssetOwnerContact)
documents = models.ManyToManyField(AssetOwnerDocument)
# owner = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
owner = models.ForeignKey(get_user_model(), null=True, on_delete=models.SET_NULL)
name = models.CharField(max_length=256)
url = models.URLField(null=True, blank=True)
comments = models.CharField(max_length=256, null=True, blank=True)
owner = models.ForeignKey(get_user_model(), null=True, on_delete=models.SET_NULL)
name = models.CharField(max_length=256)
url = models.URLField(null=True, blank=True)
comments = models.CharField(max_length=256, null=True, blank=True)
created_at = models.DateTimeField(default=timezone.now)
updated_at = models.DateTimeField(default=timezone.now)

Expand Down
4 changes: 2 additions & 2 deletions assets/templates/add-asset-group.html
Expand Up @@ -58,9 +58,9 @@

<!-- Teams -->
<div class="form-group">
<label class="col-sm-2 control-label" for="id_scan_team_list">Teams</label>
<label class="col-sm-2 control-label" for="id_teams">Teams</label>
<div class="col-sm-5">
<select class="form-control form-control-sm" id="id_scan_team_list" name="scan_team_list" disabled>
<select class="form-control form-control-sm" id="id_teams" name="teams" size="4" multiple>
{% for team in teams_list %}
<option value="{{team.id}}">{{team.name}}</option>
{% endfor %}
Expand Down
4 changes: 2 additions & 2 deletions assets/templates/details-asset-group.html
Expand Up @@ -231,7 +231,7 @@
<div class="row">
<div class="col-md-11">
<!-- <h4>Quick report</h4> -->
<p>
<!-- <p>
{% for scope, counter in asset_scopes %}
<a href="/findings/list?_scope={{ counter.id }}&_asset_group_id={{ asset_group.id }}" style="text-decoration:none;">
{% if counter.critical > 0 %}
Expand All @@ -248,7 +248,7 @@
</a>
{% endfor %}
<a href="#" data-toggle="modal" data-target="#modal-scopes-details">+ details</a>
</p>
</p> -->
</div>
</div>
</div>
Expand Down
14 changes: 10 additions & 4 deletions assets/templates/edit-asset-group.html
@@ -1,4 +1,5 @@
{% extends 'base.html' %}
{% load patrowl_tags %}
{% block content %}
<style>

Expand Down Expand Up @@ -42,11 +43,12 @@
<label class="col-sm-2 control-label" for="id_criticity">Criticality</label>
<div class="col-sm-5">
<select name="criticity" class="form-control form-control-sm" id="id_criticity">
<option value="low">low</option>
<option value="medium">medium</option>
<option value="high">high</option>
<option value="low" {% if asset_group.criticity == "low" %}selected{%endif%}>low</option>
<option value="medium" {% if asset_group.criticity == "medium" %}selected{%endif%}>medium</option>
<option value="high" {% if asset_group.criticity == "high" %}selected{%endif%}>high</option>
</select>
</div>

</div>

<!-- Teams -->
Expand All @@ -55,7 +57,11 @@
<div class="col-sm-5">
<select class="form-control form-control-sm" id="id_teams" name="teams" size="4" multiple>
{% for team in teams_list %}
<option value="{{team.id}}">{{team.name}}</option>
{% if team.name in asset_group.teams.all|attr:"name" %}
<option value="{{team.id}}" selected>{{team.name}}</option>
{% else %}
<option value="{{team.id}}">{{team.name}}</option>
{% endif %}
{% endfor %}
</select>
</div>
Expand Down
40 changes: 20 additions & 20 deletions assets/views.py
Expand Up @@ -322,7 +322,7 @@ def add_asset_group_view(request):
@pro_group_required('AssetsManager')
def edit_asset_group_view(request, assetgroup_id):
"""Edit an asset group."""
asset_group = get_object_or_404(AssetGroup.objects.for_user(request.user), id=assetgroup_id)
asset_group = get_object_or_404(AssetGroup.objects.for_user(request.user).prefetch_related('teams', 'assets'), id=assetgroup_id)

form = AssetGroupForm(user=request.user)
if request.method == 'GET':
Expand Down Expand Up @@ -665,16 +665,16 @@ def detail_asset_group_view(request, assetgroup_id):
})

engines_scopes_filter_agg = {}
scope_names = EnginePolicyScope.objects.values_list('name', flat=True)
for scope in scope_names:
engines_scopes_filter_agg.update({
f"scope_{scope}_total": Count('id', filter=Q(scopes__name=scope)),
f"scope_{scope}_info": Count('id', filter=Q(scopes__name=scope, severity='info')),
f"scope_{scope}_low": Count('id', filter=Q(scopes__name=scope, severity='low')),
f"scope_{scope}_medium": Count('id', filter=Q(scopes__name=scope, severity='medium')),
f"scope_{scope}_high": Count('id', filter=Q(scopes__name=scope, severity='high')),
f"scope_{scope}_critical": Count('id', filter=Q(scopes__name=scope, severity='critical')),
})
# scope_names = EnginePolicyScope.objects.values_list('name', flat=True)
# for scope in scope_names:
# engines_scopes_filter_agg.update({
# f"scope_{scope}_total": Count('id', filter=Q(scopes__name=scope)),
# f"scope_{scope}_info": Count('id', filter=Q(scopes__name=scope, severity='info')),
# f"scope_{scope}_low": Count('id', filter=Q(scopes__name=scope, severity='low')),
# f"scope_{scope}_medium": Count('id', filter=Q(scopes__name=scope, severity='medium')),
# f"scope_{scope}_high": Count('id', filter=Q(scopes__name=scope, severity='high')),
# f"scope_{scope}_critical": Count('id', filter=Q(scopes__name=scope, severity='critical')),
# })

# Sorry...
findings_stats = findings.aggregate(
Expand All @@ -691,15 +691,15 @@ def detail_asset_group_view(request, assetgroup_id):
)

# Sorry again...
for scope in scope_names:
asset_scopes[scope].update({
'total': findings_stats['scope_'+scope+'_total'],
'info': findings_stats['scope_'+scope+'_info'],
'low': findings_stats['scope_'+scope+'_low'],
'medium': findings_stats['scope_'+scope+'_medium'],
'high': findings_stats['scope_'+scope+'_high'],
'critical': findings_stats['scope_'+scope+'_critical'],
})
# for scope in scope_names:
# asset_scopes[scope].update({
# 'total': findings_stats['scope_'+scope+'_total'],
# 'info': findings_stats['scope_'+scope+'_info'],
# 'low': findings_stats['scope_'+scope+'_low'],
# 'medium': findings_stats['scope_'+scope+'_medium'],
# 'high': findings_stats['scope_'+scope+'_high'],
# 'critical': findings_stats['scope_'+scope+'_critical'],
# })

# Scans
scan_defs = ScanDefinition.objects.filter(
Expand Down
30 changes: 20 additions & 10 deletions templatetags/common_tags.py
Expand Up @@ -22,13 +22,23 @@ def keyvalue(dict, key):
return dict[key]


@register.filter
def attr(objs, attrib):
"""Return the attribute value for an array of object."""
vals = []
for obj in objs:
if hasattr(obj, attrib):
vals.append(getattr(obj, attrib))
return vals


@register.filter
def perc(nb, total):
"""Return a percentage."""
if not str(nb).isdigit():
return 0
if total > 0:
return nb*100/float(total)
return nb * 100 / float(total)
else:
return 0

Expand Down Expand Up @@ -132,21 +142,21 @@ def ref_url(ref, typeref):

@register.filter(name='proper_paginate')
def proper_paginate(paginator, current_page, neighbors=8):
if paginator.num_pages > 2*neighbors:
start_index = max(1, current_page-neighbors)
if paginator.num_pages > 2 * neighbors:
start_index = max(1, current_page - neighbors)
end_index = min(paginator.num_pages, current_page + neighbors)
if end_index < start_index + 2*neighbors:
end_index = start_index + 2*neighbors
elif start_index > end_index - 2*neighbors:
start_index = end_index - 2*neighbors
if end_index < start_index + 2 * neighbors:
end_index = start_index + 2 * neighbors
elif start_index > end_index - 2 * neighbors:
start_index = end_index - 2 * neighbors
if start_index < 1:
end_index -= start_index
start_index = 1
elif end_index > paginator.num_pages:
start_index -= (end_index-paginator.num_pages)
start_index -= (end_index - paginator.num_pages)
end_index = paginator.num_pages
page_list = [f for f in range(start_index, end_index+1)]
return page_list[:(2*neighbors + 1)]
page_list = [f for f in range(start_index, end_index + 1)]
return page_list[:(2 * neighbors + 1)]
return paginator.page_range


Expand Down

0 comments on commit 99cd78a

Please sign in to comment.