mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-10-16 00:14:23 +00:00
Merge branch 'master' into PRWLR-6707-create-a-way-of-reporting-for-prowler-threatscore
This commit is contained in:
112 files changed
+7682
-405
No files matched your search
@@ -24,5 +24,18 @@
|
||||
"is_active": true,
|
||||
"date_joined": "2024-09-18T09:04:20.850Z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "api.user",
|
||||
"pk": "6d4f8a91-3c2e-4b5a-8f7d-1e9c5b2a4d6f",
|
||||
"fields": {
|
||||
"password": "pbkdf2_sha256$870000$Z63pGJ7nre48hfcGbk5S0O$rQpKczAmijs96xa+gPVJifpT3Fetb8DOusl5Eq6gxac=",
|
||||
"last_login": null,
|
||||
"name": "E2E Test User",
|
||||
"email": "e2e@prowler.com",
|
||||
"company_name": "Prowler E2E Tests",
|
||||
"is_active": true,
|
||||
"date_joined": "2024-01-01T00:00:00.850Z"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -46,5 +46,24 @@
|
||||
"role": "member",
|
||||
"date_joined": "2024-09-19T11:03:59.712Z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "api.tenant",
|
||||
"pk": "7c8f94a3-e2d1-4b3a-9f87-2c4d5e6f1a2b",
|
||||
"fields": {
|
||||
"inserted_at": "2024-01-01T00:00:00Z",
|
||||
"updated_at": "2024-01-01T00:00:00Z",
|
||||
"name": "E2E Test Tenant"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "api.membership",
|
||||
"pk": "9b1a2c3d-4e5f-6789-abc1-23456789def0",
|
||||
"fields": {
|
||||
"user": "6d4f8a91-3c2e-4b5a-8f7d-1e9c5b2a4d6f",
|
||||
"tenant": "7c8f94a3-e2d1-4b3a-9f87-2c4d5e6f1a2b",
|
||||
"role": "owner",
|
||||
"date_joined": "2024-01-01T00:00:00.000Z"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -149,5 +149,32 @@
|
||||
"user": "8b38e2eb-6689-4f1e-a4ba-95b275130200",
|
||||
"inserted_at": "2024-11-20T15:36:14.302Z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "api.role",
|
||||
"pk": "a5b6c7d8-9e0f-1234-5678-90abcdef1234",
|
||||
"fields": {
|
||||
"tenant": "7c8f94a3-e2d1-4b3a-9f87-2c4d5e6f1a2b",
|
||||
"name": "e2e_admin",
|
||||
"manage_users": true,
|
||||
"manage_account": true,
|
||||
"manage_billing": true,
|
||||
"manage_providers": true,
|
||||
"manage_integrations": true,
|
||||
"manage_scans": true,
|
||||
"unlimited_visibility": true,
|
||||
"inserted_at": "2024-01-01T00:00:00.000Z",
|
||||
"updated_at": "2024-01-01T00:00:00.000Z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "api.userrolerelationship",
|
||||
"pk": "f1e2d3c4-b5a6-9876-5432-10fedcba9876",
|
||||
"fields": {
|
||||
"tenant": "7c8f94a3-e2d1-4b3a-9f87-2c4d5e6f1a2b",
|
||||
"role": "a5b6c7d8-9e0f-1234-5678-90abcdef1234",
|
||||
"user": "6d4f8a91-3c2e-4b5a-8f7d-1e9c5b2a4d6f",
|
||||
"inserted_at": "2024-01-01T00:00:00.000Z"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,30 @@
|
||||
from functools import partial
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
from api.db_utils import create_index_on_partitions, drop_index_on_partitions
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
atomic = False
|
||||
|
||||
dependencies = [
|
||||
("api", "0039_resource_resources_failed_findings_idx"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(
|
||||
partial(
|
||||
create_index_on_partitions,
|
||||
parent_table="resource_finding_mappings",
|
||||
index_name="rfm_tenant_resource_idx",
|
||||
columns="tenant_id, resource_id",
|
||||
method="BTREE",
|
||||
),
|
||||
reverse_code=partial(
|
||||
drop_index_on_partitions,
|
||||
parent_table="resource_finding_mappings",
|
||||
index_name="rfm_tenant_resource_idx",
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,17 @@
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("api", "0040_rfm_tenant_resource_index_partitions"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddIndex(
|
||||
model_name="resourcefindingmapping",
|
||||
index=models.Index(
|
||||
fields=["tenant_id", "resource_id"],
|
||||
name="rfm_tenant_resource_idx",
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,23 @@
|
||||
from django.contrib.postgres.operations import AddIndexConcurrently
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
atomic = False
|
||||
|
||||
dependencies = [
|
||||
("api", "0041_rfm_tenant_resource_parent_partitions"),
|
||||
("django_celery_beat", "0019_alter_periodictasks_options"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
AddIndexConcurrently(
|
||||
model_name="scan",
|
||||
index=models.Index(
|
||||
condition=models.Q(("state", "completed")),
|
||||
fields=["tenant_id", "provider_id", "-inserted_at"],
|
||||
include=("id",),
|
||||
name="scans_prov_ins_desc_idx",
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,33 @@
|
||||
# Generated by Django 5.1.7 on 2025-07-09 14:44
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
import api.db_utils
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("api", "0042_scan_scans_prov_ins_desc_idx"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="provider",
|
||||
name="provider",
|
||||
field=api.db_utils.ProviderEnumField(
|
||||
choices=[
|
||||
("aws", "AWS"),
|
||||
("azure", "Azure"),
|
||||
("gcp", "GCP"),
|
||||
("kubernetes", "Kubernetes"),
|
||||
("m365", "M365"),
|
||||
("github", "GitHub"),
|
||||
],
|
||||
default="aws",
|
||||
),
|
||||
),
|
||||
migrations.RunSQL(
|
||||
"ALTER TYPE provider ADD VALUE IF NOT EXISTS 'github';",
|
||||
reverse_sql=migrations.RunSQL.noop,
|
||||
),
|
||||
]
|
||||
@@ -205,6 +205,7 @@ class Provider(RowLevelSecurityProtectedModel):
|
||||
GCP = "gcp", _("GCP")
|
||||
KUBERNETES = "kubernetes", _("Kubernetes")
|
||||
M365 = "m365", _("M365")
|
||||
GITHUB = "github", _("GitHub")
|
||||
|
||||
@staticmethod
|
||||
def validate_aws_uid(value):
|
||||
@@ -265,6 +266,16 @@ class Provider(RowLevelSecurityProtectedModel):
|
||||
pointer="/data/attributes/uid",
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def validate_github_uid(value):
|
||||
if not re.match(r"^[a-zA-Z0-9][a-zA-Z0-9-]{0,38}$", value):
|
||||
raise ModelValidationError(
|
||||
detail="GitHub provider ID must be a valid GitHub username or organization name (1-39 characters, "
|
||||
"starting with alphanumeric, containing only alphanumeric characters and hyphens).",
|
||||
code="github-uid",
|
||||
pointer="/data/attributes/uid",
|
||||
)
|
||||
|
||||
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
|
||||
inserted_at = models.DateTimeField(auto_now_add=True, editable=False)
|
||||
updated_at = models.DateTimeField(auto_now=True, editable=False)
|
||||
@@ -476,6 +487,13 @@ class Scan(RowLevelSecurityProtectedModel):
|
||||
condition=Q(state=StateChoices.COMPLETED),
|
||||
name="scans_prov_state_ins_desc_idx",
|
||||
),
|
||||
# TODO This might replace `scans_prov_state_ins_desc_idx` completely. Review usage
|
||||
models.Index(
|
||||
fields=["tenant_id", "provider_id", "-inserted_at"],
|
||||
condition=Q(state=StateChoices.COMPLETED),
|
||||
include=["id"],
|
||||
name="scans_prov_ins_desc_idx",
|
||||
),
|
||||
]
|
||||
|
||||
class JSONAPIMeta:
|
||||
@@ -860,6 +878,10 @@ class ResourceFindingMapping(PostgresPartitionedModel, RowLevelSecurityProtected
|
||||
fields=["tenant_id", "finding_id"],
|
||||
name="rfm_tenant_finding_idx",
|
||||
),
|
||||
models.Index(
|
||||
fields=["tenant_id", "resource_id"],
|
||||
name="rfm_tenant_resource_idx",
|
||||
),
|
||||
]
|
||||
constraints = [
|
||||
models.UniqueConstraint(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: Prowler API
|
||||
version: 1.10.1
|
||||
version: 1.11.0
|
||||
description: |-
|
||||
Prowler API specification.
|
||||
|
||||
@@ -544,6 +544,7 @@ paths:
|
||||
- aws
|
||||
- azure
|
||||
- gcp
|
||||
- github
|
||||
- kubernetes
|
||||
- m365
|
||||
description: |-
|
||||
@@ -552,6 +553,7 @@ paths:
|
||||
* `gcp` - GCP
|
||||
* `kubernetes` - Kubernetes
|
||||
* `m365` - M365
|
||||
* `github` - GitHub
|
||||
- in: query
|
||||
name: filter[provider_type__in]
|
||||
schema:
|
||||
@@ -562,6 +564,7 @@ paths:
|
||||
- aws
|
||||
- azure
|
||||
- gcp
|
||||
- github
|
||||
- kubernetes
|
||||
- m365
|
||||
description: |-
|
||||
@@ -572,6 +575,7 @@ paths:
|
||||
* `gcp` - GCP
|
||||
* `kubernetes` - Kubernetes
|
||||
* `m365` - M365
|
||||
* `github` - GitHub
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
@@ -1061,6 +1065,7 @@ paths:
|
||||
- aws
|
||||
- azure
|
||||
- gcp
|
||||
- github
|
||||
- kubernetes
|
||||
- m365
|
||||
description: |-
|
||||
@@ -1069,6 +1074,7 @@ paths:
|
||||
* `gcp` - GCP
|
||||
* `kubernetes` - Kubernetes
|
||||
* `m365` - M365
|
||||
* `github` - GitHub
|
||||
- in: query
|
||||
name: filter[provider_type__in]
|
||||
schema:
|
||||
@@ -1079,6 +1085,7 @@ paths:
|
||||
- aws
|
||||
- azure
|
||||
- gcp
|
||||
- github
|
||||
- kubernetes
|
||||
- m365
|
||||
description: |-
|
||||
@@ -1089,6 +1096,7 @@ paths:
|
||||
* `gcp` - GCP
|
||||
* `kubernetes` - Kubernetes
|
||||
* `m365` - M365
|
||||
* `github` - GitHub
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
@@ -1486,6 +1494,7 @@ paths:
|
||||
- aws
|
||||
- azure
|
||||
- gcp
|
||||
- github
|
||||
- kubernetes
|
||||
- m365
|
||||
description: |-
|
||||
@@ -1494,6 +1503,7 @@ paths:
|
||||
* `gcp` - GCP
|
||||
* `kubernetes` - Kubernetes
|
||||
* `m365` - M365
|
||||
* `github` - GitHub
|
||||
- in: query
|
||||
name: filter[provider_type__in]
|
||||
schema:
|
||||
@@ -1504,6 +1514,7 @@ paths:
|
||||
- aws
|
||||
- azure
|
||||
- gcp
|
||||
- github
|
||||
- kubernetes
|
||||
- m365
|
||||
description: |-
|
||||
@@ -1514,6 +1525,7 @@ paths:
|
||||
* `gcp` - GCP
|
||||
* `kubernetes` - Kubernetes
|
||||
* `m365` - M365
|
||||
* `github` - GitHub
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
@@ -1909,6 +1921,7 @@ paths:
|
||||
- aws
|
||||
- azure
|
||||
- gcp
|
||||
- github
|
||||
- kubernetes
|
||||
- m365
|
||||
description: |-
|
||||
@@ -1917,6 +1930,7 @@ paths:
|
||||
* `gcp` - GCP
|
||||
* `kubernetes` - Kubernetes
|
||||
* `m365` - M365
|
||||
* `github` - GitHub
|
||||
- in: query
|
||||
name: filter[provider_type__in]
|
||||
schema:
|
||||
@@ -1927,6 +1941,7 @@ paths:
|
||||
- aws
|
||||
- azure
|
||||
- gcp
|
||||
- github
|
||||
- kubernetes
|
||||
- m365
|
||||
description: |-
|
||||
@@ -1937,6 +1952,7 @@ paths:
|
||||
* `gcp` - GCP
|
||||
* `kubernetes` - Kubernetes
|
||||
* `m365` - M365
|
||||
* `github` - GitHub
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
@@ -2320,6 +2336,7 @@ paths:
|
||||
- aws
|
||||
- azure
|
||||
- gcp
|
||||
- github
|
||||
- kubernetes
|
||||
- m365
|
||||
description: |-
|
||||
@@ -2328,6 +2345,7 @@ paths:
|
||||
* `gcp` - GCP
|
||||
* `kubernetes` - Kubernetes
|
||||
* `m365` - M365
|
||||
* `github` - GitHub
|
||||
- in: query
|
||||
name: filter[provider_type__in]
|
||||
schema:
|
||||
@@ -2338,6 +2356,7 @@ paths:
|
||||
- aws
|
||||
- azure
|
||||
- gcp
|
||||
- github
|
||||
- kubernetes
|
||||
- m365
|
||||
description: |-
|
||||
@@ -2348,6 +2367,7 @@ paths:
|
||||
* `gcp` - GCP
|
||||
* `kubernetes` - Kubernetes
|
||||
* `m365` - M365
|
||||
* `github` - GitHub
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
@@ -3121,6 +3141,7 @@ paths:
|
||||
- aws
|
||||
- azure
|
||||
- gcp
|
||||
- github
|
||||
- kubernetes
|
||||
- m365
|
||||
description: |-
|
||||
@@ -3129,6 +3150,7 @@ paths:
|
||||
* `gcp` - GCP
|
||||
* `kubernetes` - Kubernetes
|
||||
* `m365` - M365
|
||||
* `github` - GitHub
|
||||
- in: query
|
||||
name: filter[provider_type__in]
|
||||
schema:
|
||||
@@ -3139,6 +3161,7 @@ paths:
|
||||
- aws
|
||||
- azure
|
||||
- gcp
|
||||
- github
|
||||
- kubernetes
|
||||
- m365
|
||||
description: |-
|
||||
@@ -3149,6 +3172,7 @@ paths:
|
||||
* `gcp` - GCP
|
||||
* `kubernetes` - Kubernetes
|
||||
* `m365` - M365
|
||||
* `github` - GitHub
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
@@ -3282,6 +3306,7 @@ paths:
|
||||
- aws
|
||||
- azure
|
||||
- gcp
|
||||
- github
|
||||
- kubernetes
|
||||
- m365
|
||||
description: |-
|
||||
@@ -3290,6 +3315,7 @@ paths:
|
||||
* `gcp` - GCP
|
||||
* `kubernetes` - Kubernetes
|
||||
* `m365` - M365
|
||||
* `github` - GitHub
|
||||
- in: query
|
||||
name: filter[provider_type__in]
|
||||
schema:
|
||||
@@ -3300,6 +3326,7 @@ paths:
|
||||
- aws
|
||||
- azure
|
||||
- gcp
|
||||
- github
|
||||
- kubernetes
|
||||
- m365
|
||||
description: |-
|
||||
@@ -3310,6 +3337,7 @@ paths:
|
||||
* `gcp` - GCP
|
||||
* `kubernetes` - Kubernetes
|
||||
* `m365` - M365
|
||||
* `github` - GitHub
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
@@ -3459,6 +3487,7 @@ paths:
|
||||
- aws
|
||||
- azure
|
||||
- gcp
|
||||
- github
|
||||
- kubernetes
|
||||
- m365
|
||||
description: |-
|
||||
@@ -3467,6 +3496,7 @@ paths:
|
||||
* `gcp` - GCP
|
||||
* `kubernetes` - Kubernetes
|
||||
* `m365` - M365
|
||||
* `github` - GitHub
|
||||
- in: query
|
||||
name: filter[provider_type__in]
|
||||
schema:
|
||||
@@ -3477,6 +3507,7 @@ paths:
|
||||
- aws
|
||||
- azure
|
||||
- gcp
|
||||
- github
|
||||
- kubernetes
|
||||
- m365
|
||||
description: |-
|
||||
@@ -3487,6 +3518,7 @@ paths:
|
||||
* `gcp` - GCP
|
||||
* `kubernetes` - Kubernetes
|
||||
* `m365` - M365
|
||||
* `github` - GitHub
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
@@ -4165,6 +4197,7 @@ paths:
|
||||
- aws
|
||||
- azure
|
||||
- gcp
|
||||
- github
|
||||
- kubernetes
|
||||
- m365
|
||||
description: |-
|
||||
@@ -4173,6 +4206,7 @@ paths:
|
||||
* `gcp` - GCP
|
||||
* `kubernetes` - Kubernetes
|
||||
* `m365` - M365
|
||||
* `github` - GitHub
|
||||
- in: query
|
||||
name: filter[provider__in]
|
||||
schema:
|
||||
@@ -4746,6 +4780,7 @@ paths:
|
||||
- aws
|
||||
- azure
|
||||
- gcp
|
||||
- github
|
||||
- kubernetes
|
||||
- m365
|
||||
description: |-
|
||||
@@ -4754,6 +4789,7 @@ paths:
|
||||
* `gcp` - GCP
|
||||
* `kubernetes` - Kubernetes
|
||||
* `m365` - M365
|
||||
* `github` - GitHub
|
||||
- in: query
|
||||
name: filter[provider_type__in]
|
||||
schema:
|
||||
@@ -4764,6 +4800,7 @@ paths:
|
||||
- aws
|
||||
- azure
|
||||
- gcp
|
||||
- github
|
||||
- kubernetes
|
||||
- m365
|
||||
description: |-
|
||||
@@ -4774,6 +4811,7 @@ paths:
|
||||
* `gcp` - GCP
|
||||
* `kubernetes` - Kubernetes
|
||||
* `m365` - M365
|
||||
* `github` - GitHub
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
@@ -6457,6 +6495,7 @@ paths:
|
||||
- aws
|
||||
- azure
|
||||
- gcp
|
||||
- github
|
||||
- kubernetes
|
||||
- m365
|
||||
description: |-
|
||||
@@ -6465,6 +6504,7 @@ paths:
|
||||
* `gcp` - GCP
|
||||
* `kubernetes` - Kubernetes
|
||||
* `m365` - M365
|
||||
* `github` - GitHub
|
||||
- in: query
|
||||
name: filter[provider_type__in]
|
||||
schema:
|
||||
@@ -6475,6 +6515,7 @@ paths:
|
||||
- aws
|
||||
- azure
|
||||
- gcp
|
||||
- github
|
||||
- kubernetes
|
||||
- m365
|
||||
description: |-
|
||||
@@ -6485,6 +6526,7 @@ paths:
|
||||
* `gcp` - GCP
|
||||
* `kubernetes` - Kubernetes
|
||||
* `m365` - M365
|
||||
* `github` - GitHub
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
@@ -11130,6 +11172,34 @@ components:
|
||||
encoded as a string.
|
||||
required:
|
||||
- kubeconfig_content
|
||||
- type: object
|
||||
title: GitHub Personal Access Token
|
||||
properties:
|
||||
personal_access_token:
|
||||
type: string
|
||||
description: GitHub personal access token for authentication.
|
||||
required:
|
||||
- personal_access_token
|
||||
- type: object
|
||||
title: GitHub OAuth App Token
|
||||
properties:
|
||||
oauth_app_token:
|
||||
type: string
|
||||
description: GitHub OAuth App token for authentication.
|
||||
required:
|
||||
- oauth_app_token
|
||||
- type: object
|
||||
title: GitHub App Credentials
|
||||
properties:
|
||||
github_app_id:
|
||||
type: integer
|
||||
description: GitHub App ID for authentication.
|
||||
github_app_key:
|
||||
type: string
|
||||
description: Path to the GitHub App private key file.
|
||||
required:
|
||||
- github_app_id
|
||||
- github_app_key
|
||||
writeOnly: true
|
||||
required:
|
||||
- secret
|
||||
@@ -12035,6 +12105,7 @@ components:
|
||||
- gcp
|
||||
- kubernetes
|
||||
- m365
|
||||
- github
|
||||
type: string
|
||||
description: |-
|
||||
* `aws` - AWS
|
||||
@@ -12042,6 +12113,7 @@ components:
|
||||
* `gcp` - GCP
|
||||
* `kubernetes` - Kubernetes
|
||||
* `m365` - M365
|
||||
* `github` - GitHub
|
||||
uid:
|
||||
type: string
|
||||
title: Unique identifier for the provider, set by the provider
|
||||
@@ -12149,6 +12221,7 @@ components:
|
||||
- gcp
|
||||
- kubernetes
|
||||
- m365
|
||||
- github
|
||||
type: string
|
||||
description: |-
|
||||
* `aws` - AWS
|
||||
@@ -12156,6 +12229,7 @@ components:
|
||||
* `gcp` - GCP
|
||||
* `kubernetes` - Kubernetes
|
||||
* `m365` - M365
|
||||
* `github` - GitHub
|
||||
uid:
|
||||
type: string
|
||||
title: Unique identifier for the provider, set by the provider
|
||||
@@ -12194,6 +12268,7 @@ components:
|
||||
- gcp
|
||||
- kubernetes
|
||||
- m365
|
||||
- github
|
||||
type: string
|
||||
description: |-
|
||||
* `aws` - AWS
|
||||
@@ -12201,6 +12276,7 @@ components:
|
||||
* `gcp` - GCP
|
||||
* `kubernetes` - Kubernetes
|
||||
* `m365` - M365
|
||||
* `github` - GitHub
|
||||
uid:
|
||||
type: string
|
||||
minLength: 3
|
||||
@@ -12852,6 +12928,34 @@ components:
|
||||
as a string.
|
||||
required:
|
||||
- kubeconfig_content
|
||||
- type: object
|
||||
title: GitHub Personal Access Token
|
||||
properties:
|
||||
personal_access_token:
|
||||
type: string
|
||||
description: GitHub personal access token for authentication.
|
||||
required:
|
||||
- personal_access_token
|
||||
- type: object
|
||||
title: GitHub OAuth App Token
|
||||
properties:
|
||||
oauth_app_token:
|
||||
type: string
|
||||
description: GitHub OAuth App token for authentication.
|
||||
required:
|
||||
- oauth_app_token
|
||||
- type: object
|
||||
title: GitHub App Credentials
|
||||
properties:
|
||||
github_app_id:
|
||||
type: integer
|
||||
description: GitHub App ID for authentication.
|
||||
github_app_key:
|
||||
type: string
|
||||
description: Path to the GitHub App private key file.
|
||||
required:
|
||||
- github_app_id
|
||||
- github_app_key
|
||||
writeOnly: true
|
||||
required:
|
||||
- secret_type
|
||||
@@ -13071,6 +13175,34 @@ components:
|
||||
encoded as a string.
|
||||
required:
|
||||
- kubeconfig_content
|
||||
- type: object
|
||||
title: GitHub Personal Access Token
|
||||
properties:
|
||||
personal_access_token:
|
||||
type: string
|
||||
description: GitHub personal access token for authentication.
|
||||
required:
|
||||
- personal_access_token
|
||||
- type: object
|
||||
title: GitHub OAuth App Token
|
||||
properties:
|
||||
oauth_app_token:
|
||||
type: string
|
||||
description: GitHub OAuth App token for authentication.
|
||||
required:
|
||||
- oauth_app_token
|
||||
- type: object
|
||||
title: GitHub App Credentials
|
||||
properties:
|
||||
github_app_id:
|
||||
type: integer
|
||||
description: GitHub App ID for authentication.
|
||||
github_app_key:
|
||||
type: string
|
||||
description: Path to the GitHub App private key file.
|
||||
required:
|
||||
- github_app_id
|
||||
- github_app_key
|
||||
writeOnly: true
|
||||
required:
|
||||
- secret_type
|
||||
@@ -13305,6 +13437,34 @@ components:
|
||||
as a string.
|
||||
required:
|
||||
- kubeconfig_content
|
||||
- type: object
|
||||
title: GitHub Personal Access Token
|
||||
properties:
|
||||
personal_access_token:
|
||||
type: string
|
||||
description: GitHub personal access token for authentication.
|
||||
required:
|
||||
- personal_access_token
|
||||
- type: object
|
||||
title: GitHub OAuth App Token
|
||||
properties:
|
||||
oauth_app_token:
|
||||
type: string
|
||||
description: GitHub OAuth App token for authentication.
|
||||
required:
|
||||
- oauth_app_token
|
||||
- type: object
|
||||
title: GitHub App Credentials
|
||||
properties:
|
||||
github_app_id:
|
||||
type: integer
|
||||
description: GitHub App ID for authentication.
|
||||
github_app_key:
|
||||
type: string
|
||||
description: Path to the GitHub App private key file.
|
||||
required:
|
||||
- github_app_id
|
||||
- github_app_key
|
||||
writeOnly: true
|
||||
required:
|
||||
- secret
|
||||
|
||||
@@ -966,6 +966,31 @@ class TestProviderViewSet:
|
||||
"uid": "subdomain1.subdomain2.subdomain3.subdomain4.domain.net",
|
||||
"alias": "test",
|
||||
},
|
||||
{
|
||||
"provider": "github",
|
||||
"uid": "test-user",
|
||||
"alias": "test",
|
||||
},
|
||||
{
|
||||
"provider": "github",
|
||||
"uid": "test-organization",
|
||||
"alias": "GitHub Org",
|
||||
},
|
||||
{
|
||||
"provider": "github",
|
||||
"uid": "prowler-cloud",
|
||||
"alias": "Prowler",
|
||||
},
|
||||
{
|
||||
"provider": "github",
|
||||
"uid": "microsoft",
|
||||
"alias": "Microsoft",
|
||||
},
|
||||
{
|
||||
"provider": "github",
|
||||
"uid": "a12345678901234567890123456789012345678",
|
||||
"alias": "Long Username",
|
||||
},
|
||||
]
|
||||
),
|
||||
)
|
||||
@@ -1079,6 +1104,42 @@ class TestProviderViewSet:
|
||||
"m365-uid",
|
||||
"uid",
|
||||
),
|
||||
(
|
||||
{
|
||||
"provider": "github",
|
||||
"uid": "-invalid-start",
|
||||
"alias": "test",
|
||||
},
|
||||
"github-uid",
|
||||
"uid",
|
||||
),
|
||||
(
|
||||
{
|
||||
"provider": "github",
|
||||
"uid": "invalid@username",
|
||||
"alias": "test",
|
||||
},
|
||||
"github-uid",
|
||||
"uid",
|
||||
),
|
||||
(
|
||||
{
|
||||
"provider": "github",
|
||||
"uid": "invalid_username",
|
||||
"alias": "test",
|
||||
},
|
||||
"github-uid",
|
||||
"uid",
|
||||
),
|
||||
(
|
||||
{
|
||||
"provider": "github",
|
||||
"uid": "a" * 40,
|
||||
"alias": "test",
|
||||
},
|
||||
"github-uid",
|
||||
"uid",
|
||||
),
|
||||
]
|
||||
),
|
||||
)
|
||||
|
||||
@@ -13,6 +13,7 @@ from prowler.providers.aws.aws_provider import AwsProvider
|
||||
from prowler.providers.azure.azure_provider import AzureProvider
|
||||
from prowler.providers.common.models import Connection
|
||||
from prowler.providers.gcp.gcp_provider import GcpProvider
|
||||
from prowler.providers.github.github_provider import GithubProvider
|
||||
from prowler.providers.kubernetes.kubernetes_provider import KubernetesProvider
|
||||
from prowler.providers.m365.m365_provider import M365Provider
|
||||
|
||||
@@ -55,14 +56,21 @@ def merge_dicts(default_dict: dict, replacement_dict: dict) -> dict:
|
||||
|
||||
def return_prowler_provider(
|
||||
provider: Provider,
|
||||
) -> [AwsProvider | AzureProvider | GcpProvider | KubernetesProvider | M365Provider]:
|
||||
) -> [
|
||||
AwsProvider
|
||||
| AzureProvider
|
||||
| GcpProvider
|
||||
| GithubProvider
|
||||
| KubernetesProvider
|
||||
| M365Provider
|
||||
]:
|
||||
"""Return the Prowler provider class based on the given provider type.
|
||||
|
||||
Args:
|
||||
provider (Provider): The provider object containing the provider type and associated secrets.
|
||||
|
||||
Returns:
|
||||
AwsProvider | AzureProvider | GcpProvider | KubernetesProvider | M365Provider: The corresponding provider class.
|
||||
AwsProvider | AzureProvider | GcpProvider | GithubProvider | KubernetesProvider | M365Provider: The corresponding provider class.
|
||||
|
||||
Raises:
|
||||
ValueError: If the provider type specified in `provider.provider` is not supported.
|
||||
@@ -78,6 +86,8 @@ def return_prowler_provider(
|
||||
prowler_provider = KubernetesProvider
|
||||
case Provider.ProviderChoices.M365.value:
|
||||
prowler_provider = M365Provider
|
||||
case Provider.ProviderChoices.GITHUB.value:
|
||||
prowler_provider = GithubProvider
|
||||
case _:
|
||||
raise ValueError(f"Provider type {provider.provider} not supported")
|
||||
return prowler_provider
|
||||
@@ -120,7 +130,14 @@ def get_prowler_provider_kwargs(
|
||||
def initialize_prowler_provider(
|
||||
provider: Provider,
|
||||
mutelist_processor: Processor | None = None,
|
||||
) -> AwsProvider | AzureProvider | GcpProvider | KubernetesProvider | M365Provider:
|
||||
) -> (
|
||||
AwsProvider
|
||||
| AzureProvider
|
||||
| GcpProvider
|
||||
| GithubProvider
|
||||
| KubernetesProvider
|
||||
| M365Provider
|
||||
):
|
||||
"""Initialize a Prowler provider instance based on the given provider type.
|
||||
|
||||
Args:
|
||||
@@ -128,8 +145,8 @@ def initialize_prowler_provider(
|
||||
mutelist_processor (Processor): The mutelist processor object containing the mutelist configuration.
|
||||
|
||||
Returns:
|
||||
AwsProvider | AzureProvider | GcpProvider | KubernetesProvider | M365Provider: An instance of the corresponding provider class
|
||||
(`AwsProvider`, `AzureProvider`, `GcpProvider`, `KubernetesProvider` or `M365Provider`) initialized with the
|
||||
AwsProvider | AzureProvider | GcpProvider | GithubProvider | KubernetesProvider | M365Provider: An instance of the corresponding provider class
|
||||
(`AwsProvider`, `AzureProvider`, `GcpProvider`, `GithubProvider`, `KubernetesProvider` or `M365Provider`) initialized with the
|
||||
provider's secrets.
|
||||
"""
|
||||
prowler_provider = return_prowler_provider(provider)
|
||||
|
||||
@@ -176,6 +176,43 @@ from rest_framework_json_api import serializers
|
||||
},
|
||||
"required": ["kubeconfig_content"],
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"title": "GitHub Personal Access Token",
|
||||
"properties": {
|
||||
"personal_access_token": {
|
||||
"type": "string",
|
||||
"description": "GitHub personal access token for authentication.",
|
||||
}
|
||||
},
|
||||
"required": ["personal_access_token"],
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"title": "GitHub OAuth App Token",
|
||||
"properties": {
|
||||
"oauth_app_token": {
|
||||
"type": "string",
|
||||
"description": "GitHub OAuth App token for authentication.",
|
||||
}
|
||||
},
|
||||
"required": ["oauth_app_token"],
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"title": "GitHub App Credentials",
|
||||
"properties": {
|
||||
"github_app_id": {
|
||||
"type": "integer",
|
||||
"description": "GitHub App ID for authentication.",
|
||||
},
|
||||
"github_app_key": {
|
||||
"type": "string",
|
||||
"description": "Path to the GitHub App private key file.",
|
||||
},
|
||||
},
|
||||
"required": ["github_app_id", "github_app_key"],
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1225,6 +1225,8 @@ class BaseWriteProviderSecretSerializer(BaseWriteSerializer):
|
||||
serializer = AzureProviderSecret(data=secret)
|
||||
elif provider_type == Provider.ProviderChoices.GCP.value:
|
||||
serializer = GCPProviderSecret(data=secret)
|
||||
elif provider_type == Provider.ProviderChoices.GITHUB.value:
|
||||
serializer = GithubProviderSecret(data=secret)
|
||||
elif provider_type == Provider.ProviderChoices.KUBERNETES.value:
|
||||
serializer = KubernetesProviderSecret(data=secret)
|
||||
elif provider_type == Provider.ProviderChoices.M365.value:
|
||||
@@ -1304,6 +1306,16 @@ class KubernetesProviderSecret(serializers.Serializer):
|
||||
resource_name = "provider-secrets"
|
||||
|
||||
|
||||
class GithubProviderSecret(serializers.Serializer):
|
||||
personal_access_token = serializers.CharField(required=False)
|
||||
oauth_app_token = serializers.CharField(required=False)
|
||||
github_app_id = serializers.IntegerField(required=False)
|
||||
github_app_key_content = serializers.CharField(required=False)
|
||||
|
||||
class Meta:
|
||||
resource_name = "provider-secrets"
|
||||
|
||||
|
||||
class AWSRoleAssumptionProviderSecret(serializers.Serializer):
|
||||
role_arn = serializers.CharField()
|
||||
external_id = serializers.CharField()
|
||||
|
||||
@@ -22,7 +22,7 @@ from django.conf import settings as django_settings
|
||||
from django.contrib.postgres.aggregates import ArrayAgg
|
||||
from django.contrib.postgres.search import SearchQuery
|
||||
from django.db import transaction
|
||||
from django.db.models import Count, F, Prefetch, Q, Sum
|
||||
from django.db.models import Count, F, Prefetch, Q, Subquery, Sum
|
||||
from django.db.models.functions import Coalesce
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import redirect
|
||||
@@ -2054,6 +2054,21 @@ class ResourceViewSet(PaginateByPkMixin, BaseRLSViewSet):
|
||||
)
|
||||
)
|
||||
|
||||
def _should_prefetch_findings(self) -> bool:
|
||||
fields_param = self.request.query_params.get("fields[resources]", "")
|
||||
include_param = self.request.query_params.get("include", "")
|
||||
return (
|
||||
fields_param == ""
|
||||
or "findings" in fields_param.split(",")
|
||||
or "findings" in include_param.split(",")
|
||||
)
|
||||
|
||||
def _get_findings_prefetch(self):
|
||||
findings_queryset = Finding.all_objects.defer("scan", "resources").filter(
|
||||
tenant_id=self.request.tenant_id
|
||||
)
|
||||
return [Prefetch("findings", queryset=findings_queryset)]
|
||||
|
||||
def get_serializer_class(self):
|
||||
if self.action in ["metadata", "metadata_latest"]:
|
||||
return ResourceMetadataSerializer
|
||||
@@ -2077,7 +2092,11 @@ class ResourceViewSet(PaginateByPkMixin, BaseRLSViewSet):
|
||||
filtered_queryset,
|
||||
manager=Resource.all_objects,
|
||||
select_related=["provider"],
|
||||
prefetch_related=["findings"],
|
||||
prefetch_related=(
|
||||
self._get_findings_prefetch()
|
||||
if self._should_prefetch_findings()
|
||||
else []
|
||||
),
|
||||
)
|
||||
|
||||
def retrieve(self, request, *args, **kwargs):
|
||||
@@ -2102,14 +2121,18 @@ class ResourceViewSet(PaginateByPkMixin, BaseRLSViewSet):
|
||||
tenant_id = request.tenant_id
|
||||
filtered_queryset = self.filter_queryset(self.get_queryset())
|
||||
|
||||
latest_scan_ids = (
|
||||
Scan.all_objects.filter(tenant_id=tenant_id, state=StateChoices.COMPLETED)
|
||||
latest_scans = (
|
||||
Scan.all_objects.filter(
|
||||
tenant_id=tenant_id,
|
||||
state=StateChoices.COMPLETED,
|
||||
)
|
||||
.order_by("provider_id", "-inserted_at")
|
||||
.distinct("provider_id")
|
||||
.values_list("id", flat=True)
|
||||
.values("provider_id")
|
||||
)
|
||||
|
||||
filtered_queryset = filtered_queryset.filter(
|
||||
tenant_id=tenant_id, provider__scan__in=latest_scan_ids
|
||||
provider_id__in=Subquery(latest_scans)
|
||||
)
|
||||
|
||||
return self.paginate_by_pk(
|
||||
@@ -2117,7 +2140,11 @@ class ResourceViewSet(PaginateByPkMixin, BaseRLSViewSet):
|
||||
filtered_queryset,
|
||||
manager=Resource.all_objects,
|
||||
select_related=["provider"],
|
||||
prefetch_related=["findings"],
|
||||
prefetch_related=(
|
||||
self._get_findings_prefetch()
|
||||
if self._should_prefetch_findings()
|
||||
else []
|
||||
),
|
||||
)
|
||||
|
||||
@action(detail=False, methods=["get"], url_name="metadata")
|
||||
|
||||
@@ -20,6 +20,7 @@ from prowler.lib.outputs.compliance.aws_well_architected.aws_well_architected im
|
||||
from prowler.lib.outputs.compliance.cis.cis_aws import AWSCIS
|
||||
from prowler.lib.outputs.compliance.cis.cis_azure import AzureCIS
|
||||
from prowler.lib.outputs.compliance.cis.cis_gcp import GCPCIS
|
||||
from prowler.lib.outputs.compliance.cis.cis_github import GithubCIS
|
||||
from prowler.lib.outputs.compliance.cis.cis_kubernetes import KubernetesCIS
|
||||
from prowler.lib.outputs.compliance.cis.cis_m365 import M365CIS
|
||||
from prowler.lib.outputs.compliance.ens.ens_aws import AWSENS
|
||||
@@ -93,6 +94,9 @@ COMPLIANCE_CLASS_MAP = {
|
||||
(lambda name: name == "prowler_threatscore_m365", ProwlerThreatScoreM365),
|
||||
(lambda name: name.startswith("iso27001_"), M365ISO27001),
|
||||
],
|
||||
"github": [
|
||||
(lambda name: name.startswith("cis_"), GithubCIS),
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user