feat(Scan, Resource, Finding): PRWLR-4015 Implement on demand scans and findings/resources in database (#48)

* feat(Users): PRWLR-4718 make user email the default login username

* feat(Token): PRWLR-4718 add serializers, views and urls for access and refresh tokens

* feat(Token): PRWLR-4718 add first membership tenant in token if not present in json body

* feat(Users): PRWLR-4718 add company_name to model

* feat(Users): PRWLR-4718 create tenant and membership when creating new user

* fix(BaseView): PRWLR-4718 add tenant_id to serializer context

* fix(Tests): PRWLR-4718 use authorization with unit tests

* fix(Views): PRWLR-4718 fix tenant retrieval from request

* fix(Tests): PRWLR-4718 fix tests

* fix(Fixtures): PRWLR-4718 fix tenant memberships ordering

* chore(Tokens): PRWLR-4718 update token url

* chore(Spec): PRWLR-4718 update API spec

* feat(Tokens): PRWLR-4718 enable token refresh blacklisting

* feat(Tokens): PRWLR-4718 implement RS256 algorithm and dev valid keys

* chore(env): PRWLR-4718 update .env.example

* chore(Deps): PRWLR-4015 update prowler dep

* fix(Resources, Findings): PRWLR-4015 fix permission issues on models and migrations

* feat(Scans, Tasks, Resources, Findings): PRWLR-4015 perform whole flow when executing scans

* fix(Settings): PRWLR-4015 fix devel JWT settings

* chore(Scans, Tasks): PRWLR-4015 improve docs and responses format

* test(Scan, Provider): PRWLR-4015 fix unit tests

* chore(Environment): PRWLR-4015 fix .env.example values

* test(Scan): PRWLR-4015 add unit tests for scan task

* chore(Task): PRWLR-4015 give proper format to task result on scan perform

* feat(Provider, Scan): PRWLR-4015 add all provider types to connection check and scan

* fix(Logging): PRWLR-4015 fix API logger middleware to include tenant and user IDs
This commit is contained in:
Víctor Fernández Poyatos authored and GitHub committed 2024-10-03 18:36:42 +02:00
1 parent 54bb034cac
commit ded28baa2f
16 files changed
+836 -415

No files matched your search

+64 -55
View File
@@ -216,56 +216,6 @@ class Provider(RowLevelSecurityProtectedModel):
]
class Scan(RowLevelSecurityProtectedModel):
class TriggerChoices(models.TextChoices):
SCHEDULED = "scheduled", _("Scheduled")
MANUAL = "manual", _("Manual")
id = models.UUIDField(primary_key=True, default=uuid7, editable=False)
name = models.CharField(
blank=True, null=True, max_length=100, validators=[MinLengthValidator(3)]
)
provider = models.ForeignKey(
Provider,
on_delete=models.CASCADE,
related_name="scans",
related_query_name="scan",
)
trigger = ScanTriggerEnumField(
choices=TriggerChoices.choices,
)
state = StateEnumField(choices=StateChoices.choices, default=StateChoices.AVAILABLE)
unique_resource_count = models.IntegerField(default=0)
progress = models.IntegerField(default=0)
scanner_args = models.JSONField(default=dict)
duration = models.IntegerField(null=True, blank=True)
scheduled_at = models.DateTimeField(null=True, blank=True)
inserted_at = models.DateTimeField(auto_now_add=True, editable=False)
updated_at = models.DateTimeField(auto_now=True, editable=False)
started_at = models.DateTimeField(null=True, blank=True)
completed_at = models.DateTimeField(null=True, blank=True)
# TODO: task foreign key
# TODO: mutelist foreign key
class Meta(RowLevelSecurityProtectedModel.Meta):
db_table = "scans"
constraints = [
RowLevelSecurityConstraint(
field="tenant_id",
name="rls_on_%(class)s",
statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
),
]
indexes = [
models.Index(
fields=["provider", "state", "trigger", "scheduled_at"],
name="scans_prov_state_trig_sche_idx",
),
]
class Task(RowLevelSecurityProtectedModel):
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
inserted_at = models.DateTimeField(auto_now_add=True, editable=False)
@@ -297,6 +247,63 @@ class Task(RowLevelSecurityProtectedModel):
]
class Scan(RowLevelSecurityProtectedModel):
class TriggerChoices(models.TextChoices):
SCHEDULED = "scheduled", _("Scheduled")
MANUAL = "manual", _("Manual")
id = models.UUIDField(primary_key=True, default=uuid7, editable=False)
name = models.CharField(
blank=True, null=True, max_length=100, validators=[MinLengthValidator(3)]
)
provider = models.ForeignKey(
Provider,
on_delete=models.CASCADE,
related_name="scans",
related_query_name="scan",
)
task = models.ForeignKey(
Task,
on_delete=models.CASCADE,
related_name="scans",
related_query_name="scan",
null=True,
blank=True,
)
trigger = ScanTriggerEnumField(
choices=TriggerChoices.choices,
)
state = StateEnumField(choices=StateChoices.choices, default=StateChoices.AVAILABLE)
unique_resource_count = models.IntegerField(default=0)
progress = models.IntegerField(default=0)
scanner_args = models.JSONField(default=dict)
duration = models.IntegerField(null=True, blank=True)
scheduled_at = models.DateTimeField(null=True, blank=True)
inserted_at = models.DateTimeField(auto_now_add=True, editable=False)
updated_at = models.DateTimeField(auto_now=True, editable=False)
started_at = models.DateTimeField(null=True, blank=True)
completed_at = models.DateTimeField(null=True, blank=True)
# TODO: mutelist foreign key
class Meta(RowLevelSecurityProtectedModel.Meta):
db_table = "scans"
constraints = [
RowLevelSecurityConstraint(
field="tenant_id",
name="rls_on_%(class)s",
statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
),
]
indexes = [
models.Index(
fields=["provider", "state", "trigger", "scheduled_at"],
name="scans_prov_state_trig_sche_idx",
),
]
class ResourceTag(RowLevelSecurityProtectedModel):
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
inserted_at = models.DateTimeField(auto_now_add=True, editable=False)
@@ -329,7 +336,7 @@ class ResourceTag(RowLevelSecurityProtectedModel):
RowLevelSecurityConstraint(
field="tenant_id",
name="rls_on_%(class)s",
statements=["SELECT"],
statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
),
]
@@ -409,13 +416,13 @@ class Resource(RowLevelSecurityProtectedModel):
constraints = [
models.UniqueConstraint(
fields=("tenant_id", "provider_id", "uid"),
fields=("tenant_id", "provider_id", "uid", "region"),
name="unique_resources_by_provider",
),
RowLevelSecurityConstraint(
field="tenant_id",
name="rls_on_%(class)s",
statements=["SELECT"],
statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
),
]
@@ -444,7 +451,7 @@ class ResourceTagMapping(RowLevelSecurityProtectedModel):
RowLevelSecurityConstraint(
field="tenant_id",
name="rls_on_%(class)s",
statements=["SELECT"],
statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
),
]
@@ -485,9 +492,11 @@ class Finding(PostgresPartitionedModel, RowLevelSecurityProtectedModel):
impact_extended = models.TextField(blank=True, null=True)
raw_result = models.JSONField(default=dict)
# TODO: review usability
tags = models.JSONField(default=dict, null=True, blank=True)
check_id = models.CharField(max_length=100, blank=False, null=False)
# TODO: review usability
check_metadata = models.JSONField(default=dict, null=False)
# Relationships
@@ -591,6 +600,6 @@ class ResourceFindingMapping(PostgresPartitionedModel, RowLevelSecurityProtected
RowLevelSecurityConstraint(
field="tenant_id",
name="rls_on_%(class)s",
statements=["SELECT"],
statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
),
]