Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/aws/admin.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from django.contrib import admin
from .models import AWSAccount, AWSResource, AWSLogSource
from .models import AWSAccount, AWSResource, AWSLogSource, AWSCredential

# Register your models here.

admin.site.register(AWSAccount)
admin.site.register(AWSResource)
admin.site.register(AWSLogSource)

admin.site.register(AWSCredential)

54 changes: 52 additions & 2 deletions apps/aws/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 5.1.3 on 2024-12-25 11:56
# Generated by Django 5.1.3 on 2025-01-22 05:31

import django.db.models.deletion
from django.conf import settings
Expand Down Expand Up @@ -29,6 +29,21 @@ class Migration(migrations.Migration):
('case', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='aws_accounts', to='case.case')),
],
),
migrations.CreateModel(
name='AWSLogSource',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('service_name', models.CharField(max_length=100)),
('log_name', models.CharField(max_length=255)),
('log_details', models.JSONField(blank=True, null=True)),
('status', models.CharField(max_length=50)),
('aws_region', models.CharField(blank=True, max_length=50, null=True)),
('slug', models.SlugField(blank=True, max_length=255, unique=True)),
('discovered_at', models.DateTimeField(auto_now_add=True)),
('account', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='log_sources', to='aws.awsaccount')),
('case', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='aws_log_sources', to='case.case')),
],
),
migrations.CreateModel(
name='AWSResource',
fields=[
Expand All @@ -37,11 +52,46 @@ class Migration(migrations.Migration):
('resource_type', models.CharField(max_length=100)),
('resource_name', models.CharField(blank=True, max_length=200, null=True)),
('resource_details', models.JSONField(blank=True, null=True)),
('aws_region', models.CharField(default='us-east-1', max_length=50)),
('aws_region', models.CharField(blank=True, max_length=50, null=True)),
('slug', models.SlugField(blank=True, max_length=255, unique=True)),
('discovered_at', models.DateTimeField(auto_now_add=True)),
('account', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='resources', to='aws.awsaccount')),
('case', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='aws_resources', to='case.case')),
],
),
migrations.CreateModel(
name='AWSCredential',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('user', models.CharField(max_length=300)),
('user_arn', models.CharField(max_length=300)),
('user_creation_time', models.DateTimeField(blank=True, null=True)),
('password_enabled', models.BooleanField(default=False)),
('password_last_used', models.DateTimeField(blank=True, null=True)),
('password_last_changed', models.DateTimeField(blank=True, null=True)),
('password_next_rotation_date', models.DateTimeField(blank=True, null=True)),
('mfa_active', models.BooleanField(default=False)),
('access_key_1_active', models.BooleanField(default=False)),
('access_key_1_last_rotated', models.DateTimeField(blank=True, null=True)),
('access_key_1_last_used_date', models.DateTimeField(blank=True, null=True)),
('access_key_1_last_used_region', models.CharField(blank=True, max_length=300, null=True)),
('access_key_1_last_used_service', models.CharField(blank=True, max_length=300, null=True)),
('access_key_2_active', models.BooleanField(default=False)),
('access_key_2_last_rotated', models.DateTimeField(blank=True, null=True)),
('access_key_2_last_used_date', models.DateTimeField(blank=True, null=True)),
('access_key_2_last_used_region', models.CharField(blank=True, max_length=300, null=True)),
('access_key_2_last_used_service', models.CharField(blank=True, max_length=300, null=True)),
('cert_1_active', models.BooleanField(default=False)),
('cert_1_last_rotated', models.DateTimeField(blank=True, null=True)),
('cert_2_active', models.BooleanField(default=False)),
('cert_2_last_rotated', models.DateTimeField(blank=True, null=True)),
('slug', models.SlugField(blank=True, max_length=255, unique=True)),
('discovered_at', models.DateTimeField(auto_now_add=True)),
('account', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='credentials', to='aws.awsaccount')),
('case', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='aws_credentials', to='case.case')),
],
options={
'unique_together': {('account', 'user')},
},
),
]
18 changes: 0 additions & 18 deletions apps/aws/migrations/0002_alter_awsresource_aws_region.py

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 5.1.3 on 2025-01-24 03:15

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('aws', '0001_initial'),
('data', '0003_normalizedlog_tags'),
]

operations = [
migrations.AddField(
model_name='awscredential',
name='tags',
field=models.ManyToManyField(related_name='aws_credential', to='data.tag'),
),
migrations.AddField(
model_name='awslogsource',
name='tags',
field=models.ManyToManyField(related_name='aws_log_source', to='data.tag'),
),
migrations.AddField(
model_name='awsresource',
name='tags',
field=models.ManyToManyField(related_name='aws_resource', to='data.tag'),
),
]
30 changes: 0 additions & 30 deletions apps/aws/migrations/0003_awslogsource.py

This file was deleted.

60 changes: 60 additions & 0 deletions apps/aws/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from django.conf import settings
from apps.case.models import Case
from django.utils.text import slugify
from apps.data.models import Tag

# Used to show and access the AWS account for the case
class AWSAccount(models.Model):
Expand Down Expand Up @@ -29,6 +30,9 @@ class AWSResource(models.Model):
slug = models.SlugField(max_length=255, unique=True, blank=True)
discovered_at = models.DateTimeField(auto_now_add=True)

# Tags
tags = models.ManyToManyField(Tag, related_name='aws_resource')

def save(self, *args, **kwargs):
if not self.slug:
base_slug = slugify(f"{self.resource_type}-{self.resource_id}")
Expand All @@ -55,6 +59,9 @@ class AWSLogSource(models.Model):
slug = models.SlugField(max_length=255, unique=True, blank=True)
discovered_at = models.DateTimeField(auto_now_add=True)

# Tags
tags = models.ManyToManyField(Tag, related_name='aws_log_source')

def save(self, *args, **kwargs):
if not self.slug:
base_slug = slugify(f"{self.service_name}-{self.log_name}")
Expand All @@ -68,3 +75,56 @@ def save(self, *args, **kwargs):

def __str__(self):
return f"{self.service_name} - {self.log_name or self.status} for Account {self.account.account_id}"

# Model to store credentials pulled from credential report api
class AWSCredential(models.Model):
account = models.ForeignKey(AWSAccount, on_delete=models.CASCADE, related_name='credentials')
case = models.ForeignKey(Case, on_delete=models.CASCADE, related_name='aws_credentials')
user = models.CharField(max_length=300)
user_arn = models.CharField(max_length=300)
user_creation_time = models.DateTimeField(null=True, blank=True)
password_enabled = models.BooleanField(default=False)
password_last_used = models.DateTimeField(null=True, blank=True)
password_last_changed = models.DateTimeField(null=True, blank=True)
password_next_rotation_date = models.DateTimeField(null=True, blank=True)
mfa_active = models.BooleanField(default=False)
access_key_1_active = models.BooleanField(default=False)
access_key_1_last_rotated = models.DateTimeField(null=True, blank=True)
access_key_1_last_used_date = models.DateTimeField(null=True, blank=True)
access_key_1_last_used_region = models.CharField(max_length=300, null=True, blank=True)
access_key_1_last_used_service = models.CharField(max_length=300, null=True, blank=True)
access_key_2_active = models.BooleanField(default=False)
access_key_2_last_rotated = models.DateTimeField(null=True, blank=True)
access_key_2_last_used_date = models.DateTimeField(null=True, blank=True)
access_key_2_last_used_region = models.CharField(max_length=300, null=True, blank=True)
access_key_2_last_used_service = models.CharField(max_length=300, null=True, blank=True)
cert_1_active = models.BooleanField(default=False)
cert_1_last_rotated = models.DateTimeField(null=True, blank=True)
cert_2_active = models.BooleanField(default=False)
cert_2_last_rotated = models.DateTimeField(null=True, blank=True)
slug = models.SlugField(max_length=255, unique=True, blank=True)
discovered_at = models.DateTimeField(auto_now_add=True)

# Tags
tags = models.ManyToManyField(Tag, related_name='aws_credential')

class Meta:
unique_together = ('account', 'user')

def save(self, *args, **kwargs):
if not self.slug:
base_slug = slugify(f"{self.user}-{self.user_arn}")
unique_slug = base_slug
num = 1
while AWSCredential.objects.filter(slug=unique_slug).exists():
unique_slug = f"{base_slug}-{num}"
num += 1
self.slug = unique_slug
super().save(*args, **kwargs)

def __str__(self):
return f"{self.user} - {self.user_arn} for Account {self.account.account_id}"




5 changes: 3 additions & 2 deletions apps/aws/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@
path('accounts/<int:account_id>/delete/', views.delete_account, name='delete_account'),
path('accounts/<int:account_id>/pull-resources/', views.pull_resources_view, name='pull_aws_resources'),
path('resources/<int:resource_id>/details/', views.aws_resource_details, name='aws_resource_details'),
path('accounts/<int:account_id>/account-details/', views.account_details, name='account_details'),
path('accounts/<int:account_id>/account-resources/', views.account_resources, name='account_resources'),
path('logsource/<slug:slug>//details/', views.aws_logsource_details, name='aws_logsource_details'),
path('fetch-management-events/<int:account_id>/', views.trigger_management_event_fetch, name='fetch_management_events'),
path('browse-s3-structure/', views.browse_s3_structure, name='browse_s3_structure'),
path('fetch-logs/<int:account_id>/', views.fetch_cloudtrail_logs, name='fetch_cloudtrail_logs'),

path('accounts/<int:account_id>/logs/', views.normalized_logs_view, name='normalized_logs'),
path('credential/<slug:slug>/', views.aws_credential_details, name='aws_credential_details'),
]

Loading
Loading