ci(docs): add markdownlint foundation (prek + CI) (#11210)

Co-authored-by: Pablo F.G <pablo.fernandez@prowler.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Pablo Fernandez Guerra (PFE)
2026-05-27 16:42:01 +02:00
committed by GitHub
co-authored by Pablo F.G Claude Opus 4.7
parent 3252f9cf19
commit ad1261ce54
56 changed files with 418 additions and 313 deletions
+60
View File
@@ -0,0 +1,60 @@
name: 'Docs: Markdown Lint'
on:
push:
branches:
- 'master'
- 'v5.*'
pull_request:
branches:
- 'master'
- 'v5.*'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions: {}
jobs:
markdown-lint:
if: github.repository == 'prowler-cloud/prowler'
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
steps:
- name: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >
api.github.com:443
github.com:443
registry.npmjs.org:443
release-assets.githubusercontent.com:443
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version-file: ui/.nvmrc
- name: Setup pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
with:
package_json_file: ui/package.json
run_install: false
- name: Run markdownlint
# Pin must match .pre-commit-config.yaml so prek and CI behave identically.
# pnpm dlx doesn't accept --ignore-scripts as a flag; the env var
# disables postinstall scripts on transitives the same way.
env:
pnpm_config_ignore_scripts: 'true'
run: pnpm dlx markdownlint-cli@0.45.0 '**/*.md'
+10
View File
@@ -0,0 +1,10 @@
{
"extends": "markdownlint/style/prettier",
"first-line-h1": false,
"no-duplicate-heading": {
"siblings_only": true
},
"no-inline-html": false,
"line-length": false,
"no-bare-urls": false
}
+16
View File
@@ -0,0 +1,16 @@
node_modules/
ui/node_modules/
.git/
.venv/
**/.venv/
dist/
build/
htmlcov/
.next/
ui/.next/
ui/out/
contrib/
# Auto-generated content (keepachangelog format legitimately repeats section headings).
# Revisit with the team — see beads task on markdownlint rule triage.
**/CHANGELOG.md
+7
View File
@@ -133,6 +133,13 @@ repos:
pass_filenames: false pass_filenames: false
priority: 50 priority: 50
## MARKDOWN
- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.45.0
hooks:
- id: markdownlint
priority: 30
## CONTAINERS ## CONTAINERS
- repo: https://github.com/hadolint/hadolint - repo: https://github.com/hadolint/hadolint
rev: v2.14.0 rev: v2.14.0
+2
View File
@@ -11,6 +11,7 @@
Use these skills for detailed patterns on-demand: Use these skills for detailed patterns on-demand:
### Generic Skills (Any Project) ### Generic Skills (Any Project)
| Skill | Description | URL | | Skill | Description | URL |
|-------|-------------|-----| |-------|-------------|-----|
| `typescript` | Const types, flat interfaces, utility types | [SKILL.md](skills/typescript/SKILL.md) | | `typescript` | Const types, flat interfaces, utility types | [SKILL.md](skills/typescript/SKILL.md) |
@@ -28,6 +29,7 @@ Use these skills for detailed patterns on-demand:
| `tdd` | Test-Driven Development workflow | [SKILL.md](skills/tdd/SKILL.md) | | `tdd` | Test-Driven Development workflow | [SKILL.md](skills/tdd/SKILL.md) |
### Prowler-Specific Skills ### Prowler-Specific Skills
| Skill | Description | URL | | Skill | Description | URL |
|-------|-------------|-----| |-------|-------------|-----|
| `prowler` | Project overview, component navigation | [SKILL.md](skills/prowler/SKILL.md) | | `prowler` | Project overview, component navigation | [SKILL.md](skills/prowler/SKILL.md) |
+4 -3
View File
@@ -1,4 +1,4 @@
# Do you want to learn on how to... # Do you want to learn on how to
- [Contribute with your code or fixes to Prowler](https://docs.prowler.com/developer-guide/introduction) - [Contribute with your code or fixes to Prowler](https://docs.prowler.com/developer-guide/introduction)
- [Create a new provider](https://docs.prowler.com/developer-guide/provider) - [Create a new provider](https://docs.prowler.com/developer-guide/provider)
@@ -32,5 +32,6 @@ Provider-specific developer notes:
Want some swag as appreciation for your contribution? Want some swag as appreciation for your contribution?
# Prowler Developer Guide ## Prowler Developer Guide
https://goto.prowler.com/devguide
<https://goto.prowler.com/devguide>
+21 -21
View File
@@ -1,6 +1,6 @@
<p align="center"> <p align="center">
<img align="center" src="https://github.com/prowler-cloud/prowler/blob/master/docs/img/prowler-logo-black.png#gh-light-mode-only" width="50%" height="50%"> <img align="center" alt="Prowler logo" src="https://github.com/prowler-cloud/prowler/blob/master/docs/img/prowler-logo-black.png#gh-light-mode-only" width="50%" height="50%">
<img align="center" src="https://github.com/prowler-cloud/prowler/blob/master/docs/img/prowler-logo-white.png#gh-dark-mode-only" width="50%" height="50%"> <img align="center" alt="Prowler logo" src="https://github.com/prowler-cloud/prowler/blob/master/docs/img/prowler-logo-white.png#gh-dark-mode-only" width="50%" height="50%">
</p> </p>
<p align="center"> <p align="center">
<b><i>Prowler</b> is the Open Cloud Security Platform trusted by thousands to automate security and compliance in any cloud environment. With hundreds of ready-to-use checks and compliance frameworks, Prowler delivers real-time, customizable monitoring and seamless integrations, making cloud security simple, scalable, and cost-effective for organizations of any size. <b><i>Prowler</b> is the Open Cloud Security Platform trusted by thousands to automate security and compliance in any cloud environment. With hundreds of ready-to-use checks and compliance frameworks, Prowler delivers real-time, customizable monitoring and seamless integrations, making cloud security simple, scalable, and cost-effective for organizations of any size.
@@ -22,8 +22,8 @@
<a href="https://pypistats.org/packages/prowler"><img alt="PyPI Downloads" src="https://img.shields.io/pypi/dw/prowler.svg?label=downloads"></a> <a href="https://pypistats.org/packages/prowler"><img alt="PyPI Downloads" src="https://img.shields.io/pypi/dw/prowler.svg?label=downloads"></a>
<a href="https://hub.docker.com/r/toniblyx/prowler"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/toniblyx/prowler"></a> <a href="https://hub.docker.com/r/toniblyx/prowler"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/toniblyx/prowler"></a>
<a href="https://gallery.ecr.aws/prowler-cloud/prowler"><img width="120" height=19" alt="AWS ECR Gallery" src="https://user-images.githubusercontent.com/3985464/151531396-b6535a68-c907-44eb-95a1-a09508178616.png"></a> <a href="https://gallery.ecr.aws/prowler-cloud/prowler"><img width="120" height=19" alt="AWS ECR Gallery" src="https://user-images.githubusercontent.com/3985464/151531396-b6535a68-c907-44eb-95a1-a09508178616.png"></a>
<a href="https://codecov.io/gh/prowler-cloud/prowler"><img src="https://codecov.io/gh/prowler-cloud/prowler/graph/badge.svg?token=OflBGsdpDl"/></a> <a href="https://codecov.io/gh/prowler-cloud/prowler"><img alt="Codecov coverage" src="https://codecov.io/gh/prowler-cloud/prowler/graph/badge.svg?token=OflBGsdpDl"/></a>
<a href="https://insights.linuxfoundation.org/project/prowler-cloud-prowler"><img src="https://insights.linuxfoundation.org/api/badge/health-score?project=prowler-cloud-prowler"/></a> <a href="https://insights.linuxfoundation.org/project/prowler-cloud-prowler"><img alt="Linux Foundation insights health score" src="https://insights.linuxfoundation.org/api/badge/health-score?project=prowler-cloud-prowler"/></a>
</p> </p>
<p align="center"> <p align="center">
<a href="https://github.com/prowler-cloud/prowler/releases"><img alt="Version" src="https://img.shields.io/github/v/release/prowler-cloud/prowler"></a> <a href="https://github.com/prowler-cloud/prowler/releases"><img alt="Version" src="https://img.shields.io/github/v/release/prowler-cloud/prowler"></a>
@@ -36,7 +36,7 @@
</p> </p>
<hr> <hr>
<p align="center"> <p align="center">
<img align="center" src="/docs/img/prowler-cloud.gif" width="100%" height="100%"> <img align="center" alt="Prowler Cloud demo" src="/docs/img/prowler-cloud.gif" width="100%" height="100%">
</p> </p>
# Description # Description
@@ -146,11 +146,11 @@ Prowler App offers flexible installation methods tailored to various environment
### Docker Compose ### Docker Compose
**Requirements** #### Requirements
* `Docker Compose` installed: https://docs.docker.com/compose/install/. - `Docker Compose` installed: https://docs.docker.com/compose/install/.
**Commands** #### Commands
``` console ``` console
VERSION=$(curl -s https://api.github.com/repos/prowler-cloud/prowler/releases/latest | jq -r .tag_name) VERSION=$(curl -s https://api.github.com/repos/prowler-cloud/prowler/releases/latest | jq -r .tag_name)
@@ -175,14 +175,14 @@ You can find more information in the [Troubleshooting](./docs/troubleshooting.md
### From GitHub ### From GitHub
**Requirements** #### Requirements
* `git` installed. - `git` installed.
* `uv` installed: [uv installation](https://docs.astral.sh/uv/getting-started/installation/). - `uv` installed: [uv installation](https://docs.astral.sh/uv/getting-started/installation/).
* `pnpm` installed: [pnpm installation](https://pnpm.io/installation). - `pnpm` installed: [pnpm installation](https://pnpm.io/installation).
* `Docker Compose` installed: https://docs.docker.com/compose/install/. - `Docker Compose` installed: https://docs.docker.com/compose/install/.
**Commands to run the API** #### Commands to run the API
``` console ``` console
git clone https://github.com/prowler-cloud/prowler git clone https://github.com/prowler-cloud/prowler
@@ -199,7 +199,7 @@ gunicorn -c config/guniconf.py config.wsgi:application
> After completing the setup, access the API documentation at http://localhost:8080/api/v1/docs. > After completing the setup, access the API documentation at http://localhost:8080/api/v1/docs.
**Commands to run the API Worker** #### Commands to run the API Worker
``` console ``` console
git clone https://github.com/prowler-cloud/prowler git clone https://github.com/prowler-cloud/prowler
@@ -212,7 +212,7 @@ cd src/backend
python -m celery -A config.celery worker -l info -E python -m celery -A config.celery worker -l info -E
``` ```
**Commands to run the API Scheduler** #### Commands to run the API Scheduler
``` console ``` console
git clone https://github.com/prowler-cloud/prowler git clone https://github.com/prowler-cloud/prowler
@@ -225,7 +225,7 @@ cd src/backend
python -m celery -A config.celery beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler python -m celery -A config.celery beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler
``` ```
**Commands to run the UI** #### Commands to run the UI
``` console ``` console
git clone https://github.com/prowler-cloud/prowler git clone https://github.com/prowler-cloud/prowler
@@ -237,7 +237,7 @@ pnpm start
> Once configured, access the Prowler App at http://localhost:3000. Sign up using your email and password to get started. > Once configured, access the Prowler App at http://localhost:3000. Sign up using your email and password to get started.
**Pre-commit Hooks Setup** #### Pre-commit Hooks Setup
Some pre-commit hooks require tools installed on your system: Some pre-commit hooks require tools installed on your system:
@@ -257,14 +257,14 @@ prowler -v
### Containers ### Containers
**Available Versions of Prowler CLI** #### Available Versions of Prowler CLI
The following versions of Prowler CLI are available, depending on your requirements: The following versions of Prowler CLI are available, depending on your requirements:
- `latest`: Synchronizes with the `master` branch. Note that this version is not stable. - `latest`: Synchronizes with the `master` branch. Note that this version is not stable.
- `v4-latest`: Synchronizes with the `v4` branch. Note that this version is not stable. - `v4-latest`: Synchronizes with the `v4` branch. Note that this version is not stable.
- `v3-latest`: Synchronizes with the `v3` branch. Note that this version is not stable. - `v3-latest`: Synchronizes with the `v3` branch. Note that this version is not stable.
- `<x.y.z>` (release): Stable releases corresponding to specific versions. You can find the complete list of releases [here](https://github.com/prowler-cloud/prowler/releases). - `<x.y.z>` (release): Stable releases corresponding to specific versions. See the [complete list of Prowler releases](https://github.com/prowler-cloud/prowler/releases).
- `stable`: Always points to the latest release. - `stable`: Always points to the latest release.
- `v4-stable`: Always points to the latest release for v4. - `v4-stable`: Always points to the latest release for v4.
- `v3-stable`: Always points to the latest release for v3. - `v3-stable`: Always points to the latest release for v3.
@@ -338,7 +338,7 @@ Full configuration, per-provider authentication, and SARIF examples: [Prowler Gi
## Prowler CLI ## Prowler CLI
**Running Prowler** ### Running Prowler
Prowler can be executed across various environments, offering flexibility to meet your needs. It can be run from: Prowler can be executed across various environments, offering flexibility to meet your needs. It can be run from:
+4 -4
View File
@@ -10,7 +10,7 @@
> - [`jsonapi`](../skills/jsonapi/SKILL.md) - Strict JSON:API v1.1 spec compliance > - [`jsonapi`](../skills/jsonapi/SKILL.md) - Strict JSON:API v1.1 spec compliance
> - [`pytest`](../skills/pytest/SKILL.md) - Generic pytest patterns > - [`pytest`](../skills/pytest/SKILL.md) - Generic pytest patterns
### Auto-invoke Skills ## Auto-invoke Skills
When performing these actions, ALWAYS invoke the corresponding skill FIRST: When performing these actions, ALWAYS invoke the corresponding skill FIRST:
@@ -81,7 +81,7 @@ When performing these actions, ALWAYS invoke the corresponding skill FIRST:
## DECISION TREES ## DECISION TREES
### Serializer Selection ### Serializer Selection
``` ```text
Read → <Model>Serializer Read → <Model>Serializer
Create → <Model>CreateSerializer Create → <Model>CreateSerializer
Update → <Model>UpdateSerializer Update → <Model>UpdateSerializer
@@ -89,7 +89,7 @@ Nested read → <Model>IncludeSerializer
``` ```
### Task vs View ### Task vs View
``` ```text
< 100ms → View < 100ms → View
> 100ms or external API → Celery task > 100ms or external API → Celery task
Needs retry → Celery task Needs retry → Celery task
@@ -105,7 +105,7 @@ Django 5.1.x | DRF 3.15.x | djangorestframework-jsonapi 7.x | Celery 5.4.x | Pos
## PROJECT STRUCTURE ## PROJECT STRUCTURE
``` ```text
api/src/backend/ api/src/backend/
├── api/ # Main Django app ├── api/ # Main Django app
│ ├── v1/ # API version 1 (views, serializers, urls) │ ├── v1/ # API version 1 (views, serializers, urls)
+29 -29
View File
@@ -2,7 +2,7 @@
This repository contains the JSON API and Task Runner components for Prowler, which facilitate a complete backend that interacts with the Prowler SDK and is used by the Prowler UI. This repository contains the JSON API and Task Runner components for Prowler, which facilitate a complete backend that interacts with the Prowler SDK and is used by the Prowler UI.
# Components ## Components
The Prowler API is composed of the following components: The Prowler API is composed of the following components:
- The JSON API, which is an API built with Django Rest Framework. - The JSON API, which is an API built with Django Rest Framework.
@@ -10,13 +10,13 @@ The Prowler API is composed of the following components:
- The PostgreSQL database, which is used to store the data. - The PostgreSQL database, which is used to store the data.
- The Valkey database, which is an in-memory database which is used as a message broker for the Celery workers. - The Valkey database, which is an in-memory database which is used as a message broker for the Celery workers.
## Note about Valkey ### Note about Valkey
[Valkey](https://valkey.io/) is an open source (BSD) high performance key/value datastore. [Valkey](https://valkey.io/) is an open source (BSD) high performance key/value datastore.
Valkey exposes a Redis 7.2 compliant API. Any service that exposes the Redis API can be used with Prowler API. Valkey exposes a Redis 7.2 compliant API. Any service that exposes the Redis API can be used with Prowler API.
# Modify environment variables ## Modify environment variables
Under the root path of the project, you can find a file called `.env`. This file shows all the environment variables that the project uses. You should review it and set the values for the variables you want to change. Under the root path of the project, you can find a file called `.env`. This file shows all the environment variables that the project uses. You should review it and set the values for the variables you want to change.
@@ -24,7 +24,7 @@ If you don’t set `DJANGO_TOKEN_SIGNING_KEY` or `DJANGO_TOKEN_VERIFYING_KEY`, t
**Important note**: Every Prowler version (or repository branches and tags) could have different variables set in its `.env` file. Please use the `.env` file that corresponds with each version. **Important note**: Every Prowler version (or repository branches and tags) could have different variables set in its `.env` file. Please use the `.env` file that corresponds with each version.
## Local deployment ### Local deployment
Keep in mind if you export the `.env` file to use it with local deployment that you will have to do it within the context of the virtual environment, not before. Otherwise, variables will not be loaded properly. Keep in mind if you export the `.env` file to use it with local deployment that you will have to do it within the context of the virtual environment, not before. Otherwise, variables will not be loaded properly.
To do this, you can run: To do this, you can run:
@@ -34,12 +34,12 @@ set -a
source .env source .env
``` ```
# 🚀 Production deployment ## 🚀 Production deployment
## Docker deployment ### Docker deployment
This method requires `docker` and `docker compose`. This method requires `docker` and `docker compose`.
### Clone the repository #### Clone the repository
```console ```console
# HTTPS # HTTPS
@@ -50,13 +50,13 @@ git clone git@github.com:prowler-cloud/api.git
``` ```
### Build the base image #### Build the base image
```console ```console
docker compose --profile prod build docker compose --profile prod build
``` ```
### Run the production service #### Run the production service
This command will start the Django production server and the Celery worker and also the Valkey and PostgreSQL databases. This command will start the Django production server and the Celery worker and also the Valkey and PostgreSQL databases.
@@ -68,7 +68,7 @@ You can access the server in `http://localhost:8080`.
> **NOTE:** notice how the port is different. When developing using docker, the port will be `8080` to prevent conflicts. > **NOTE:** notice how the port is different. When developing using docker, the port will be `8080` to prevent conflicts.
### View the Production Server Logs #### View the Production Server Logs
To view the logs for any component (e.g., Django, Celery worker), you can use the following command with a wildcard. This command will follow logs for any container that matches the specified pattern: To view the logs for any component (e.g., Django, Celery worker), you can use the following command with a wildcard. This command will follow logs for any container that matches the specified pattern:
@@ -133,13 +133,13 @@ gunicorn -c config/guniconf.py config.wsgi:application
> By default, the Gunicorn server will try to use as many workers as your machine can handle. You can manually change that in the `src/backend/config/guniconf.py` file. > By default, the Gunicorn server will try to use as many workers as your machine can handle. You can manually change that in the `src/backend/config/guniconf.py` file.
# 🧪 Development guide ## 🧪 Development guide
## Local deployment ### Local deployment
To use this method, you'll need to set up a Python virtual environment (version ">=3.11,<3.13") and keep dependencies updated. Additionally, ensure that `uv` and `docker compose` are installed. To use this method, you'll need to set up a Python virtual environment (version ">=3.11,<3.13") and keep dependencies updated. Additionally, ensure that `uv` and `docker compose` are installed.
### Clone the repository #### Clone the repository
```console ```console
# HTTPS # HTTPS
@@ -150,7 +150,7 @@ git clone git@github.com:prowler-cloud/api.git
``` ```
### Start the PostgreSQL Database and Valkey #### Start the PostgreSQL Database and Valkey
The PostgreSQL database (version 16.3) and Valkey (version 7) are required for the development environment. To make development easier, we have provided a `docker-compose` file that will start these components for you. The PostgreSQL database (version 16.3) and Valkey (version 7) are required for the development environment. To make development easier, we have provided a `docker-compose` file that will start these components for you.
@@ -161,7 +161,7 @@ The PostgreSQL database (version 16.3) and Valkey (version 7) are required for t
docker compose up postgres valkey -d docker compose up postgres valkey -d
``` ```
### Install the Python dependencies #### Install the Python dependencies
> You must have uv installed > You must have uv installed
@@ -169,7 +169,7 @@ docker compose up postgres valkey -d
uv sync uv sync
``` ```
### Apply migrations #### Apply migrations
For migrations, you need to force the `admin` database router. Assuming you have the correct environment variables and Python virtual environment, run: For migrations, you need to force the `admin` database router. Assuming you have the correct environment variables and Python virtual environment, run:
@@ -178,7 +178,7 @@ cd src/backend
python manage.py migrate --database admin python manage.py migrate --database admin
``` ```
### Run the Django development server #### Run the Django development server
```console ```console
cd src/backend cd src/backend
@@ -188,7 +188,7 @@ python manage.py runserver
You can access the server in `http://localhost:8000`. You can access the server in `http://localhost:8000`.
All changes in the code will be automatically reloaded in the server. All changes in the code will be automatically reloaded in the server.
### Run the Celery worker #### Run the Celery worker
```console ```console
python -m celery -A config.celery worker -l info -E python -m celery -A config.celery worker -l info -E
@@ -196,11 +196,11 @@ python -m celery -A config.celery worker -l info -E
The Celery worker does not detect and reload changes in the code, so you need to restart it manually when you make changes. The Celery worker does not detect and reload changes in the code, so you need to restart it manually when you make changes.
## Docker deployment ### Docker deployment
This method requires `docker` and `docker compose`. This method requires `docker` and `docker compose`.
### Clone the repository #### Clone the repository
```console ```console
# HTTPS # HTTPS
@@ -211,13 +211,13 @@ git clone git@github.com:prowler-cloud/api.git
``` ```
### Build the base image #### Build the base image
```console ```console
docker compose --profile dev build docker compose --profile dev build
``` ```
### Run the development service #### Run the development service
This command will start the Django development server and the Celery worker and also the Valkey and PostgreSQL databases. This command will start the Django development server and the Celery worker and also the Valkey and PostgreSQL databases.
@@ -230,7 +230,7 @@ All changes in the code will be automatically reloaded in the server.
> **NOTE:** notice how the port is different. When developing using docker, the port will be `8080` to prevent conflicts. > **NOTE:** notice how the port is different. When developing using docker, the port will be `8080` to prevent conflicts.
### View the development server logs #### View the development server logs
To view the logs for any component (e.g., Django, Celery worker), you can use the following command with a wildcard. This command will follow logs for any container that matches the specified pattern: To view the logs for any component (e.g., Django, Celery worker), you can use the following command with a wildcard. This command will follow logs for any container that matches the specified pattern:
@@ -238,7 +238,7 @@ To view the logs for any component (e.g., Django, Celery worker), you can use th
docker logs -f $(docker ps --format "{{.Names}}" | grep 'api-') docker logs -f $(docker ps --format "{{.Names}}" | grep 'api-')
``` ```
## Applying migrations ### Applying migrations
For migrations, you need to force the `admin` database router. Assuming you have the correct environment variables and Python virtual environment, run: For migrations, you need to force the `admin` database router. Assuming you have the correct environment variables and Python virtual environment, run:
@@ -247,7 +247,7 @@ cd src/backend
uv run python manage.py migrate --database admin uv run python manage.py migrate --database admin
``` ```
## Apply fixtures ### Apply fixtures
Fixtures are used to populate the database with initial development data. Fixtures are used to populate the database with initial development data.
@@ -258,7 +258,7 @@ uv run python manage.py loaddata api/fixtures/0_dev_users.json --database admin
> The default credentials are `dev@prowler.com:Thisisapassword123@` or `dev2@prowler.com:Thisisapassword123@` > The default credentials are `dev@prowler.com:Thisisapassword123@` or `dev2@prowler.com:Thisisapassword123@`
## Run tests ### Run tests
Note that the tests will fail if you use the same `.env` file as the development environment. Note that the tests will fail if you use the same `.env` file as the development environment.
@@ -269,7 +269,7 @@ cd src/backend
uv run pytest uv run pytest
``` ```
# Custom commands ## Custom commands
Django provides a way to create custom commands that can be run from the command line. Django provides a way to create custom commands that can be run from the command line.
@@ -281,7 +281,7 @@ To run a custom command, you need to be in the `prowler/api/src/backend` directo
uv run python manage.py <command_name> uv run python manage.py <command_name>
``` ```
## Generate dummy data ### Generate dummy data
```console ```console
python manage.py findings --tenant python manage.py findings --tenant
@@ -298,7 +298,7 @@ This command creates, for a given tenant, a provider, scan and a set of findings
> >
> The last step is required to access the findings details, since the UI needs that to print all the information. > The last step is required to access the findings details, since the UI needs that to print all the information.
### Example #### Example
```console ```console
~/backend $ uv run python manage.py findings --tenant ~/backend $ uv run python manage.py findings --tenant
+2 -2
View File
@@ -134,7 +134,7 @@ Example 1 is vague and even potentially ambiguous. Verbs state your purpose and
Explicit use of second-person pronouns (you) and possessives (your) should be minimized whenever possible. Those constructions are best reserved for cases when instructions are directly given in an imperative form: Explicit use of second-person pronouns (you) and possessives (your) should be minimized whenever possible. Those constructions are best reserved for cases when instructions are directly given in an imperative form:
**Example of Improvement Through Avoiding Second Person Pronouns** ### Example of Improvement Through Avoiding Second Person Pronouns
**Original:** **Original:**
Prowler App can be installed in different ways, depending on your environment: Prowler App can be installed in different ways, depending on your environment:
@@ -236,7 +236,7 @@ The use of bullet points is highly recommended when:
* Information can be logically divided into multiple categories, each sharing characteristics, features, or other relevant classifications. * Information can be logically divided into multiple categories, each sharing characteristics, features, or other relevant classifications.
* Items are significant enough as standalone concepts to deserve their own bullet point. * Items are significant enough as standalone concepts to deserve their own bullet point.
**Example of Improvement Through Bullet Points** #### Example of Improvement Through Bullet Points
**Original:** **Original:**
It contains hundreds of controls covering CIS, NIST 800, NIST CSF, CISA, RBI, FedRAMS, PCI-DSS, GDPR, HIPAA, FFIEC, SOC2, GXP, AWS Well-Architected Framework Security Pillar, AWS Foundational Technical Review (FTR), ENS (Spanish National Security Scheme), and your custom security frameworks. It contains hundreds of controls covering CIS, NIST 800, NIST CSF, CISA, RBI, FedRAMS, PCI-DSS, GDPR, HIPAA, FFIEC, SOC2, GXP, AWS Well-Architected Framework Security Pillar, AWS Foundational Technical Review (FTR), ENS (Spanish National Security Scheme), and your custom security frameworks.
+2 -2
View File
@@ -2,7 +2,7 @@
> **Skills Reference**: See [`prowler-mcp`](../skills/prowler-mcp/SKILL.md) > **Skills Reference**: See [`prowler-mcp`](../skills/prowler-mcp/SKILL.md)
### Auto-invoke Skills ## Auto-invoke Skills
When performing these actions, ALWAYS invoke the corresponding skill FIRST: When performing these actions, ALWAYS invoke the corresponding skill FIRST:
@@ -68,7 +68,7 @@ Python 3.12+ | FastMCP 2.13.1 | httpx (async) | Pydantic | uv
## PROJECT STRUCTURE ## PROJECT STRUCTURE
``` ```text
mcp_server/prowler_mcp_server/ mcp_server/prowler_mcp_server/
├── server.py # Main orchestration ├── server.py # Main orchestration
├── prowler_hub/server.py # Hub tools (no auth) ├── prowler_hub/server.py # Hub tools (no auth)
+9 -6
View File
@@ -83,14 +83,14 @@ npm install --save-exact mcp-remote@0.1.38
### 2. Local STDIO Mode ### 2. Local STDIO Mode
**Run the server locally on your machine** Run the server locally on your machine:
- Runs as a subprocess of your MCP client - Runs as a subprocess of your MCP client
- Requires Python 3.12+ or Docker - Requires Python 3.12+ or Docker
### 3. Self-Hosted HTTP Mode ### 3. Self-Hosted HTTP Mode
**Deploy your own remote MCP server** Deploy your own remote MCP server:
- Full control over deployment - Full control over deployment
- Requires Python 3.12+ or Docker - Requires Python 3.12+ or Docker
@@ -132,7 +132,7 @@ All tools follow a consistent naming pattern with prefixes:
## Architecture ## Architecture
``` ```text
prowler_mcp_server/ prowler_mcp_server/
├── server.py # Main orchestrator (imports sub-servers with prefixes) ├── server.py # Main orchestrator (imports sub-servers with prefixes)
├── main.py # CLI entry point ├── main.py # CLI entry point
@@ -154,17 +154,20 @@ prowler_mcp_server/
The Prowler MCP Server enables powerful workflows through AI assistants: The Prowler MCP Server enables powerful workflows through AI assistants:
**Security Operations** ### Security Operations
- "Show me all critical findings from my AWS production accounts" - "Show me all critical findings from my AWS production accounts"
- "Register my new AWS account in Prowler and run a scheduled scan every day" - "Register my new AWS account in Prowler and run a scheduled scan every day"
- "List all muted findings and detect what findgings are muted by a not enough good reason in relation to their severity" - "List all muted findings and detect what findgings are muted by a not enough good reason in relation to their severity"
**Security Research** ### Security Research
- "Explain what the S3 bucket public access Prowler check does" - "Explain what the S3 bucket public access Prowler check does"
- "Find all Prowler checks related to encryption at rest" - "Find all Prowler checks related to encryption at rest"
- "What is the latest version of the CIS that Prowler is covering per provider?" - "What is the latest version of the CIS that Prowler is covering per provider?"
**Documentation & Learning** ### Documentation & Learning
- "How do I configure Prowler to scan my GCP organization?" - "How do I configure Prowler to scan my GCP organization?"
- "What authentication methods does Prowler support for Azure?" - "What authentication methods does Prowler support for Azure?"
- "How can I contribute with a new security check to Prowler?" - "How can I contribute with a new security check to Prowler?"
+4 -4
View File
@@ -28,12 +28,12 @@ This Terraform configuration creates the necessary IAM role and policies to allo
### Usage Examples ### Usage Examples
#### Basic deployment (without S3 integration): #### Basic deployment (without S3 integration)
```bash ```bash
terraform apply -var="external_id=your-external-id-here" terraform apply -var="external_id=your-external-id-here"
``` ```
#### With S3 integration enabled: #### With S3 integration enabled
```bash ```bash
terraform apply \ terraform apply \
-var="external_id=your-external-id-here" \ -var="external_id=your-external-id-here" \
@@ -42,14 +42,14 @@ terraform apply \
-var="s3_integration_bucket_account_id=123456789012" -var="s3_integration_bucket_account_id=123456789012"
``` ```
#### Using terraform.tfvars file (Recommended): #### Using terraform.tfvars file (Recommended)
```bash ```bash
cp terraform.tfvars.example terraform.tfvars cp terraform.tfvars.example terraform.tfvars
# Edit the file with your values # Edit the file with your values
terraform apply terraform apply
``` ```
#### Command line variables (Alternative): #### Command line variables (Alternative)
```bash ```bash
terraform apply -var="external_id=your-external-id-here" terraform apply -var="external_id=your-external-id-here"
``` ```
+3 -3
View File
@@ -7,7 +7,7 @@
> - [`prowler-compliance`](../skills/prowler-compliance/SKILL.md) - Compliance framework structure > - [`prowler-compliance`](../skills/prowler-compliance/SKILL.md) - Compliance framework structure
> - [`pytest`](../skills/pytest/SKILL.md) - Generic pytest patterns > - [`pytest`](../skills/pytest/SKILL.md) - Generic pytest patterns
### Auto-invoke Skills ## Auto-invoke Skills
When performing these actions, ALWAYS invoke the corresponding skill FIRST: When performing these actions, ALWAYS invoke the corresponding skill FIRST:
@@ -44,7 +44,7 @@ The Prowler SDK is the core Python engine powering cloud security assessments ac
### Provider Architecture ### Provider Architecture
``` ```text
prowler/providers/{provider}/ prowler/providers/{provider}/
├── {provider}_provider.py # Main provider class ├── {provider}_provider.py # Main provider class
├── models.py # Provider-specific models ├── models.py # Provider-specific models
@@ -91,7 +91,7 @@ Python 3.10+ | uv | pytest | moto (AWS mocking) | Pre-commit hooks (black, flake
## PROJECT STRUCTURE ## PROJECT STRUCTURE
``` ```text
prowler/ prowler/
├── __main__.py # CLI entry point ├── __main__.py # CLI entry point
├── config/ # Global configuration ├── config/ # Global configuration
+3 -3
View File
@@ -36,7 +36,7 @@ After running setup, restart your AI coding assistant to load the skills.
Skills are automatically discovered by the AI agent. To manually load a skill during a session: Skills are automatically discovered by the AI agent. To manually load a skill during a session:
``` ```text
Read skills/{skill-name}/SKILL.md Read skills/{skill-name}/SKILL.md
``` ```
@@ -90,7 +90,7 @@ Patterns tailored for Prowler development:
## Directory Structure ## Directory Structure
``` ```text
skills/ skills/
├── {skill-name}/ ├── {skill-name}/
│ ├── SKILL.md # Required - main instrunsction and metadata │ ├── SKILL.md # Required - main instrunsction and metadata
@@ -118,7 +118,7 @@ This reads `metadata.scope` and `metadata.auto_invoke` from each `SKILL.md` and
Use the `skill-creator` skill for guidance: Use the `skill-creator` skill for guidance:
``` ```text
Read skills/skill-creator/SKILL.md Read skills/skill-creator/SKILL.md
``` ```
+6 -6
View File
@@ -54,7 +54,7 @@ When implementing a new endpoint, review these patterns in order:
## Decision Trees ## Decision Trees
### Which Serializer? ### Which Serializer?
``` ```text
GET list/retrieve → <Model>Serializer GET list/retrieve → <Model>Serializer
POST create → <Model>CreateSerializer POST create → <Model>CreateSerializer
PATCH update → <Model>UpdateSerializer PATCH update → <Model>UpdateSerializer
@@ -62,7 +62,7 @@ PATCH update → <Model>UpdateSerializer
``` ```
### Which Base Serializer? ### Which Base Serializer?
``` ```text
Read-only serializer → BaseModelSerializerV1 Read-only serializer → BaseModelSerializerV1
Create with tenant_id → RLSSerializer + BaseWriteSerializer (auto-injects tenant_id on create) Create with tenant_id → RLSSerializer + BaseWriteSerializer (auto-injects tenant_id on create)
Update with validation → BaseWriteSerializer (tenant_id already exists on object) Update with validation → BaseWriteSerializer (tenant_id already exists on object)
@@ -70,14 +70,14 @@ Non-model data → BaseSerializerV1
``` ```
### Which Filter Base? ### Which Filter Base?
``` ```text
Direct FK to Provider → BaseProviderFilter Direct FK to Provider → BaseProviderFilter
FK via Scan → BaseScanProviderFilter FK via Scan → BaseScanProviderFilter
No provider relation → FilterSet No provider relation → FilterSet
``` ```
### Which Base ViewSet? ### Which Base ViewSet?
``` ```text
RLS-protected model → BaseRLSViewSet (most common) RLS-protected model → BaseRLSViewSet (most common)
Tenant operations → BaseTenantViewset Tenant operations → BaseTenantViewset
User operations → BaseUserViewset User operations → BaseUserViewset
@@ -85,7 +85,7 @@ No RLS required → BaseViewSet (rare)
``` ```
### Resource Name Format? ### Resource Name Format?
``` ```text
Single word model → plural lowercase (Provider → providers) Single word model → plural lowercase (Provider → providers)
Multi-word model → plural lowercase kebab (ProviderGroup → provider-groups) Multi-word model → plural lowercase kebab (ProviderGroup → provider-groups)
Through/join model → parent-child pattern (UserRoleRelationship → user-roles) Through/join model → parent-child pattern (UserRoleRelationship → user-roles)
@@ -490,7 +490,7 @@ When implementing or debugging, query these libraries via `mcp_context7_query-do
| **drf-spectacular** | `/tfranzel/drf-spectacular` | OpenAPI schema, `@extend_schema` | | **drf-spectacular** | `/tfranzel/drf-spectacular` | OpenAPI schema, `@extend_schema` |
**Example queries:** **Example queries:**
``` ```text
mcp_context7_query-docs(libraryId="/websites/django-rest-framework", query="ViewSet get_queryset best practices") mcp_context7_query-docs(libraryId="/websites/django-rest-framework", query="ViewSet get_queryset best practices")
mcp_context7_query-docs(libraryId="/tfranzel/drf-spectacular", query="extend_schema examples for custom actions") mcp_context7_query-docs(libraryId="/tfranzel/drf-spectacular", query="extend_schema examples for custom actions")
mcp_context7_query-docs(libraryId="/websites/djangoproject_en_5_2", query="model constraints and indexes") mcp_context7_query-docs(libraryId="/websites/djangoproject_en_5_2", query="model constraints and indexes")
@@ -16,7 +16,7 @@
## ViewSet Hierarchy ## ViewSet Hierarchy
``` ```text
BaseViewSet (minimal - no RLS/auth) BaseViewSet (minimal - no RLS/auth)
│ │
├── BaseRLSViewSet (+ tenant filtering, RLS-protected models) ├── BaseRLSViewSet (+ tenant filtering, RLS-protected models)
@@ -31,7 +31,7 @@ BaseViewSet (minimal - no RLS/auth)
## Serializer Hierarchy ## Serializer Hierarchy
``` ```text
BaseModelSerializerV1 (JSON:API defaults, read_only_fields) BaseModelSerializerV1 (JSON:API defaults, read_only_fields)
│ │
├── RLSSerializer (auto-injects tenant_id from request) ├── RLSSerializer (auto-injects tenant_id from request)
@@ -47,7 +47,7 @@ BaseModelSerializerV1 (JSON:API defaults, read_only_fields)
## Filter Hierarchy ## Filter Hierarchy
``` ```text
FilterSet (django-filter) FilterSet (django-filter)
│ │
├── CommonFindingFilters (mixin for date ranges, delta, status) ├── CommonFindingFilters (mixin for date ranges, delta, status)
@@ -2,7 +2,7 @@
## Content Type ## Content Type
``` ```http
Content-Type: application/vnd.api+json Content-Type: application/vnd.api+json
Accept: application/vnd.api+json Accept: application/vnd.api+json
``` ```
+2 -2
View File
@@ -364,7 +364,7 @@ Batch utilities: `api/db_utils.py` (`batch_delete`, `create_objects_in_batches`,
## Decision tree ## Decision tree
``` ```text
Auto-generated migration? Auto-generated migration?
├── Yes → Split it following the rules below ├── Yes → Split it following the rules below
└── No → Review it against the rules below └── No → Review it against the rules below
@@ -420,7 +420,7 @@ When implementing or debugging migration patterns, query these libraries via `mc
| django-postgres-extra | `/SectorLabs/django-postgres-extra` | Partitioned models, `PostgresPartitionedModel`, partition management | | django-postgres-extra | `/SectorLabs/django-postgres-extra` | Partitioned models, `PostgresPartitionedModel`, partition management |
**Example queries:** **Example queries:**
``` ```text
mcp_context7_query-docs(libraryId="/websites/djangoproject_en_5_1", query="migration operations AddIndex RunPython atomic") mcp_context7_query-docs(libraryId="/websites/djangoproject_en_5_1", query="migration operations AddIndex RunPython atomic")
mcp_context7_query-docs(libraryId="/websites/djangoproject_en_5_1", query="database indexes Meta class concurrently") mcp_context7_query-docs(libraryId="/websites/djangoproject_en_5_1", query="database indexes Meta class concurrently")
mcp_context7_query-docs(libraryId="/websites/postgresql_org_docs_current", query="CREATE INDEX CONCURRENTLY partitioned table") mcp_context7_query-docs(libraryId="/websites/postgresql_org_docs_current", query="CREATE INDEX CONCURRENTLY partitioned table")
+2 -2
View File
@@ -30,7 +30,7 @@ allowed-tools: Read, Edit, Write, Glob, Grep, Bash, WebFetch
## File Layout ## File Layout
``` ```text
.github/ .github/
├── workflows/ ├── workflows/
│ ├── {name}.md # Frontmatter + thin context dispatcher │ ├── {name}.md # Frontmatter + thin context dispatcher
@@ -308,7 +308,7 @@ After modifying any `.github/workflows/*.md`:
Add to repo root so lock files auto-resolve on merge: Add to repo root so lock files auto-resolve on merge:
``` ```text
.github/workflows/*.lock.yml linguist-generated=true merge=ours .github/workflows/*.lock.yml linguist-generated=true merge=ours
``` ```
+2 -2
View File
@@ -35,7 +35,7 @@ This skill focuses on **spec compliance**. For **implementation patterns** (View
If Context7 MCP is available, query the JSON:API spec directly: If Context7 MCP is available, query the JSON:API spec directly:
``` ```text
mcp_context7_resolve-library-id(query="jsonapi specification") mcp_context7_resolve-library-id(query="jsonapi specification")
mcp_context7_query-docs(libraryId="<resolved-id>", query="[specific topic: relationships, errors, etc.]") mcp_context7_query-docs(libraryId="<resolved-id>", query="[specific topic: relationships, errors, etc.]")
``` ```
@@ -44,7 +44,7 @@ mcp_context7_query-docs(libraryId="<resolved-id>", query="[specific topic: relat
If Context7 is not available, fetch from the official spec: If Context7 is not available, fetch from the official spec:
``` ```text
WebFetch(url="https://jsonapi.org/format/", prompt="Extract rules for [specific topic]") WebFetch(url="https://jsonapi.org/format/", prompt="Extract rules for [specific topic]")
``` ```
+1 -1
View File
@@ -14,7 +14,7 @@ allowed-tools: Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task
## App Router File Conventions ## App Router File Conventions
``` ```text
app/ app/
├── layout.tsx # Root layout (required) ├── layout.tsx # Root layout (required)
├── page.tsx # Home page (/) ├── page.tsx # Home page (/)
+3 -3
View File
@@ -36,7 +36,7 @@ allowed-tools: Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task
## File Structure ## File Structure
``` ```text
tests/ tests/
├── base-page.ts # Parent class for ALL pages ├── base-page.ts # Parent class for ALL pages
├── helpers.ts # Shared utilities ├── helpers.ts # Shared utilities
@@ -182,14 +182,14 @@ export class SignUpPage extends BasePage {
## Refactoring Guidelines ## Refactoring Guidelines
### Move to `BasePage` when: ### Move to `BasePage` when
- ✅ Navigation helpers used by multiple pages (`waitForPageLoad()`, `getCurrentUrl()`) - ✅ Navigation helpers used by multiple pages (`waitForPageLoad()`, `getCurrentUrl()`)
- ✅ Common UI interactions (notifications, modals, theme toggles) - ✅ Common UI interactions (notifications, modals, theme toggles)
- ✅ Verification patterns repeated across pages (`isVisible()`, `waitForVisible()`) - ✅ Verification patterns repeated across pages (`isVisible()`, `waitForVisible()`)
- ✅ Error handling that applies to all pages - ✅ Error handling that applies to all pages
- ✅ Screenshot utilities for debugging - ✅ Screenshot utilities for debugging
### Move to `helpers.ts` when: ### Move to `helpers.ts` when
- ✅ Test data generation (`generateUniqueEmail()`, `generateTestUser()`) - ✅ Test data generation (`generateUniqueEmail()`, `generateTestUser()`)
- ✅ Setup/teardown utilities (`createTestUser()`, `cleanupTestData()`) - ✅ Setup/teardown utilities (`createTestUser()`, `cleanupTestData()`)
- ✅ Custom assertions (`expectNotificationToContain()`) - ✅ Custom assertions (`expectNotificationToContain()`)
+3 -2
View File
@@ -225,7 +225,7 @@ Rebuild invalid indexes without locking writes:
REINDEX INDEX CONCURRENTLY index_name; REINDEX INDEX CONCURRENTLY index_name;
``` ```
### Understanding _ccnew and _ccold artifacts ### Understanding _ccnew and_ccold artifacts
When `CREATE INDEX CONCURRENTLY` or `REINDEX INDEX CONCURRENTLY` is interrupted, temporary indexes may remain: When `CREATE INDEX CONCURRENTLY` or `REINDEX INDEX CONCURRENTLY` is interrupted, temporary indexes may remain:
@@ -377,7 +377,8 @@ VACUUM (ANALYZE) table_name;
| PostgreSQL | `/websites/postgresql_org_docs_current` | Index types, EXPLAIN, partitioned table indexing, REINDEX | | PostgreSQL | `/websites/postgresql_org_docs_current` | Index types, EXPLAIN, partitioned table indexing, REINDEX |
**Example queries:** **Example queries:**
```
```text
mcp_context7_query-docs(libraryId="/websites/postgresql_org_docs_current", query="CREATE INDEX CONCURRENTLY partitioned table") mcp_context7_query-docs(libraryId="/websites/postgresql_org_docs_current", query="CREATE INDEX CONCURRENTLY partitioned table")
mcp_context7_query-docs(libraryId="/websites/postgresql_org_docs_current", query="EXPLAIN ANALYZE BUFFERS query plan") mcp_context7_query-docs(libraryId="/websites/postgresql_org_docs_current", query="EXPLAIN ANALYZE BUFFERS query plan")
mcp_context7_query-docs(libraryId="/websites/postgresql_org_docs_current", query="partial index WHERE clause") mcp_context7_query-docs(libraryId="/websites/postgresql_org_docs_current", query="partial index WHERE clause")
+6 -6
View File
@@ -61,7 +61,7 @@ Provider.objects.filter(connected=True) # Requires rls_transaction context
### RLS Transaction Flow ### RLS Transaction Flow
``` ```text
Request → Authentication → BaseRLSViewSet.initial() Request → Authentication → BaseRLSViewSet.initial()
│ │
├─ Extract tenant_id from JWT ├─ Extract tenant_id from JWT
@@ -92,7 +92,7 @@ When implementing Prowler-specific API features:
## Decision Trees ## Decision Trees
### Which Base Model? ### Which Base Model?
``` ```text
Tenant-scoped data → RowLevelSecurityProtectedModel Tenant-scoped data → RowLevelSecurityProtectedModel
Global/shared data → models.Model + BaseSecurityConstraint (rare) Global/shared data → models.Model + BaseSecurityConstraint (rare)
Partitioned time-series → PostgresPartitionedModel + RowLevelSecurityProtectedModel Partitioned time-series → PostgresPartitionedModel + RowLevelSecurityProtectedModel
@@ -100,14 +100,14 @@ Soft-deletable → Add is_deleted + ActiveProviderManager
``` ```
### Which Manager? ### Which Manager?
``` ```text
Normal queries → Model.objects (excludes deleted) Normal queries → Model.objects (excludes deleted)
Include deleted records → Model.all_objects Include deleted records → Model.all_objects
Celery task context → Must use rls_transaction() first Celery task context → Must use rls_transaction() first
``` ```
### Which Database? ### Which Database?
``` ```text
Standard API queries → default (automatic via ViewSet) Standard API queries → default (automatic via ViewSet)
Read-only operations → replica (automatic for GET in BaseRLSViewSet) Read-only operations → replica (automatic for GET in BaseRLSViewSet)
Auth/admin operations → MainRouter.admin_db Auth/admin operations → MainRouter.admin_db
@@ -115,7 +115,7 @@ Cross-tenant lookups → MainRouter.admin_db (use sparingly!)
``` ```
### Celery Task Decorator Order? ### Celery Task Decorator Order?
``` ```python
@shared_task(base=RLSTask, name="...", queue="...") @shared_task(base=RLSTask, name="...", queue="...")
@set_tenant # First: sets tenant context @set_tenant # First: sets tenant context
@handle_provider_deletion # Second: handles deleted providers @handle_provider_deletion # Second: handles deleted providers
@@ -496,7 +496,7 @@ When implementing or debugging Prowler-specific patterns, query these libraries
| **Django** | `/websites/djangoproject_en_5_2` | Models, ORM, constraints, indexes | | **Django** | `/websites/djangoproject_en_5_2` | Models, ORM, constraints, indexes |
**Example queries:** **Example queries:**
``` ```text
mcp_context7_query-docs(libraryId="/websites/celeryq_dev_en_stable", query="shared_task decorator retry patterns") mcp_context7_query-docs(libraryId="/websites/celeryq_dev_en_stable", query="shared_task decorator retry patterns")
mcp_context7_query-docs(libraryId="/celery/django-celery-beat", query="periodic task database scheduler") mcp_context7_query-docs(libraryId="/celery/django-celery-beat", query="periodic task database scheduler")
mcp_context7_query-docs(libraryId="/websites/djangoproject_en_5_2", query="model constraints CheckConstraint UniqueConstraint") mcp_context7_query-docs(libraryId="/websites/djangoproject_en_5_2", query="model constraints CheckConstraint UniqueConstraint")
@@ -2,7 +2,7 @@
## Settings File Structure ## Settings File Structure
``` ```text
api/src/backend/config/ api/src/backend/config/
├── django/ ├── django/
│ ├── base.py # Base settings (all environments) │ ├── base.py # Base settings (all environments)
@@ -247,7 +247,7 @@ class JSONAPIMeta:
## Decision Tree: New Model ## Decision Tree: New Model
``` ```text
Is it tenant-scoped data? Is it tenant-scoped data?
├── Yes → Inherit RowLevelSecurityProtectedModel ├── Yes → Inherit RowLevelSecurityProtectedModel
│ Add RowLevelSecurityConstraint │ Add RowLevelSecurityConstraint
+4 -4
View File
@@ -228,7 +228,7 @@ AWS_QUERIES: list[AttackPathsQueryDefinition] = [
**FIRST**, read all files in the queries module to understand the structure, type definitions, registration, and existing style: **FIRST**, read all files in the queries module to understand the structure, type definitions, registration, and existing style:
``` ```text
api/src/backend/api/attack_paths/queries/ api/src/backend/api/attack_paths/queries/
├── __init__.py # Module exports ├── __init__.py # Module exports
├── types.py # AttackPathsQueryDefinition, AttackPathsQueryParameterDefinition ├── types.py # AttackPathsQueryDefinition, AttackPathsQueryParameterDefinition
@@ -250,7 +250,7 @@ grep cartography api/pyproject.toml
Build the schema URL (ALWAYS use the specific tag, not master/main): Build the schema URL (ALWAYS use the specific tag, not master/main):
``` ```text
# Git dependency (prowler-cloud/cartography@0.126.1): # Git dependency (prowler-cloud/cartography@0.126.1):
https://raw.githubusercontent.com/prowler-cloud/cartography/refs/tags/0.126.1/docs/root/modules/{provider}/schema.md https://raw.githubusercontent.com/prowler-cloud/cartography/refs/tags/0.126.1/docs/root/modules/{provider}/schema.md
@@ -283,7 +283,7 @@ Add the constant to the `{PROVIDER}_QUERIES` list.
### Query ID ### Query ID
``` ```text
{provider}-{category}-{description} {provider}-{category}-{description}
``` ```
@@ -291,7 +291,7 @@ Examples: `aws-ec2-privesc-passrole-iam`, `aws-ec2-instances-internet-exposed`
### Query constant name ### Query constant name
``` ```text
{PROVIDER}_{CATEGORY}_{DESCRIPTION} {PROVIDER}_{CATEGORY}_{DESCRIPTION}
``` ```
+4 -4
View File
@@ -28,7 +28,7 @@ metadata:
## Commit Format ## Commit Format
``` ```text
type(scope): concise description type(scope): concise description
- Key change 1 - Key change 1
@@ -68,7 +68,7 @@ type(scope): concise description
### Title Line ### Title Line
``` ```text
# GOOD - Concise and clear # GOOD - Concise and clear
feat(api): add provider connection retry logic feat(api): add provider connection retry logic
fix(ui): resolve dashboard loading state fix(ui): resolve dashboard loading state
@@ -83,7 +83,7 @@ fix(ui): fix the bug in dashboard component on line 45
### Body (Bullet Points) ### Body (Bullet Points)
``` ```text
# GOOD - High-level changes # GOOD - High-level changes
- Add retry mechanism for failed connections - Add retry mechanism for failed connections
- Document task composition patterns - Document task composition patterns
@@ -132,7 +132,7 @@ fix(ui): fix the bug in dashboard component on line 45
## Decision Tree ## Decision Tree
``` ```text
Single file changed? Single file changed?
├─ Yes → May omit body, title only ├─ Yes → May omit body, title only
└─ No → Include body with key changes └─ No → Include body with key changes
+1 -1
View File
@@ -53,7 +53,7 @@ diff dashboard/compliance/{new_framework}.py \
## Decision Tree ## Decision Tree
``` ```text
JSON Valid? JSON Valid?
├── No → FAIL: Fix JSON syntax errors ├── No → FAIL: Fix JSON syntax errors
└── Yes ↓ └── Yes ↓
+8 -4
View File
@@ -59,7 +59,7 @@ See "Compliance Framework Location" and "Framework-Specific Attribute Structures
**Every framework directory follows this exact convention** — do not deviate: **Every framework directory follows this exact convention** — do not deviate:
``` ```text
{framework}/ {framework}/
├── __init__.py ├── __init__.py
├── {framework}.py # ONLY get_{framework}_table() — NO function docstring ├── {framework}.py # ONLY get_{framework}_table() — NO function docstring
@@ -85,7 +85,7 @@ See "Compliance Framework Location" and "Framework-Specific Attribute Structures
### The CLI Pipeline (end-to-end) ### The CLI Pipeline (end-to-end)
``` ```text
prowler aws --compliance ccc_aws prowler aws --compliance ccc_aws
↓ ↓
Compliance.get_bulk("aws") → parses prowler/compliance/aws/*.json Compliance.get_bulk("aws") → parses prowler/compliance/aws/*.json
@@ -483,6 +483,7 @@ Prowler ThreatScore is a custom security scoring framework developed by Prowler
## Available Compliance Frameworks ## Available Compliance Frameworks
### AWS (41 frameworks) ### AWS (41 frameworks)
| Framework | File Name | | Framework | File Name |
|-----------|-----------| |-----------|-----------|
| CIS 1.4, 1.5, 2.0, 3.0, 4.0, 5.0 | `cis_{version}_aws.json` | | CIS 1.4, 1.5, 2.0, 3.0, 4.0, 5.0 | `cis_{version}_aws.json` |
@@ -508,6 +509,7 @@ Prowler ThreatScore is a custom security scoring framework developed by Prowler
| NIS2 | `nis2_aws.json` | | NIS2 | `nis2_aws.json` |
### Azure (15+ frameworks) ### Azure (15+ frameworks)
| Framework | File Name | | Framework | File Name |
|-----------|-----------| |-----------|-----------|
| CIS 2.0, 2.1, 3.0, 4.0 | `cis_{version}_azure.json` | | CIS 2.0, 2.1, 3.0, 4.0 | `cis_{version}_azure.json` |
@@ -518,6 +520,7 @@ Prowler ThreatScore is a custom security scoring framework developed by Prowler
| NIST CSF 2.0 | `nist_csf_2.0_azure.json` | | NIST CSF 2.0 | `nist_csf_2.0_azure.json` |
### GCP (15+ frameworks) ### GCP (15+ frameworks)
| Framework | File Name | | Framework | File Name |
|-----------|-----------| |-----------|-----------|
| CIS 2.0, 3.0, 4.0 | `cis_{version}_gcp.json` | | CIS 2.0, 3.0, 4.0 | `cis_{version}_gcp.json` |
@@ -528,6 +531,7 @@ Prowler ThreatScore is a custom security scoring framework developed by Prowler
| NIST CSF 2.0 | `nist_csf_2.0_gcp.json` | | NIST CSF 2.0 | `nist_csf_2.0_gcp.json` |
### Kubernetes (6 frameworks) ### Kubernetes (6 frameworks)
| Framework | File Name | | Framework | File Name |
|-----------|-----------| |-----------|-----------|
| CIS 1.8, 1.10, 1.11 | `cis_{version}_kubernetes.json` | | CIS 1.8, 1.10, 1.11 | `cis_{version}_kubernetes.json` |
@@ -561,7 +565,7 @@ done
The sync tooling is split into three layers so adding a new framework only takes a YAML config (and optionally a new parser module for an unfamiliar upstream format): The sync tooling is split into three layers so adding a new framework only takes a YAML config (and optionally a new parser module for an unfamiliar upstream format):
``` ```text
skills/prowler-compliance/assets/ skills/prowler-compliance/assets/
├── sync_framework.py # generic runner — works for any framework ├── sync_framework.py # generic runner — works for any framework
├── configs/ ├── configs/
@@ -902,7 +906,7 @@ Add fixtures to `tests/lib/outputs/compliance/fixtures.py`: one `Compliance` obj
**The table dispatcher file (`{framework}.py`) MUST NOT import `Finding`** (directly or transitively). The cycle is: **The table dispatcher file (`{framework}.py`) MUST NOT import `Finding`** (directly or transitively). The cycle is:
``` ```text
compliance.compliance imports get_{framework}_table compliance.compliance imports get_{framework}_table
→ {framework}.py imports ComplianceOutput → {framework}.py imports ComplianceOutput
→ compliance_output imports Finding → compliance_output imports Finding
@@ -46,7 +46,7 @@ Each framework type has a specific Pydantic model in `compliance_models.py`:
## File Naming Convention ## File Naming Convention
``` ```text
{framework}_{version}_{provider}.json {framework}_{version}_{provider}.json
``` ```
+1 -1
View File
@@ -104,7 +104,7 @@ Reference without articles:
## Documentation Structure ## Documentation Structure
``` ```text
docs/ docs/
├── getting-started/ ├── getting-started/
├── tutorials/ ├── tutorials/
+1 -1
View File
@@ -25,7 +25,7 @@ Use this skill when:
Every provider MUST follow this structure: Every provider MUST follow this structure:
``` ```text
prowler/providers/{provider}/ prowler/providers/{provider}/
├── __init__.py ├── __init__.py
├── {provider}_provider.py # Main provider class ├── {provider}_provider.py # Main provider class
+1 -1
View File
@@ -34,7 +34,7 @@ python3 prowler-cli.py <provider> --list-<metric>
The CLI output ends with a summary line like: The CLI output ends with a summary line like:
``` ```text
There are 572 available checks. There are 572 available checks.
There is 1 available Compliance Framework. There is 1 available Compliance Framework.
``` ```
+2 -2
View File
@@ -16,7 +16,7 @@ allowed-tools: Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task
## Check Structure ## Check Structure
``` ```text
prowler/providers/{provider}/services/{service}/{check_name}/ prowler/providers/{provider}/services/{service}/{check_name}/
├── __init__.py ├── __init__.py
├── {check_name}.py ├── {check_name}.py
@@ -90,7 +90,7 @@ See `prowler-test-sdk` skill for test patterns (PASS, FAIL, no resources, error
## Check Naming Convention ## Check Naming Convention
``` ```text
{service}_{resource}_{security_control} {service}_{resource}_{security_control}
``` ```
+1 -1
View File
@@ -28,7 +28,7 @@ allowed-tools: Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task
## 1. Fixture Dependency Chain ## 1. Fixture Dependency Chain
``` ```text
create_test_user (session) ─► tenants_fixture (function) ─► authenticated_client create_test_user (session) ─► tenants_fixture (function) ─► authenticated_client
│ │
└─► providers_fixture ─► scans_fixture ─► findings_fixture └─► providers_fixture ─► scans_fixture ─► findings_fixture
@@ -14,7 +14,7 @@
## Fixture Dependency Graph ## Fixture Dependency Graph
``` ```text
create_test_user (session) create_test_user (session)
│ │
└─► tenants_fixture (function) └─► tenants_fixture (function)
+1 -1
View File
@@ -265,7 +265,7 @@ from tests.providers.kubernetes.kubernetes_fixtures import set_mocked_kubernetes
## Test File Structure ## Test File Structure
``` ```text
tests/providers/{provider}/services/{service}/ tests/providers/{provider}/services/{service}/
├── {service}_service_test.py # Service tests ├── {service}_service_test.py # Service tests
└── {check_name}/ └── {check_name}/
+6 -5
View File
@@ -19,7 +19,7 @@ allowed-tools: Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task
## Prowler UI Test Structure ## Prowler UI Test Structure
``` ```text
ui/tests/ ui/tests/
├── base-page.ts # Prowler-specific base page ├── base-page.ts # Prowler-specific base page
├── helpers.ts # Prowler test utilities ├── helpers.ts # Prowler test utilities
@@ -35,13 +35,13 @@ ui/tests/
**⚠️ ALWAYS verify BEFORE completing any E2E task:** **⚠️ ALWAYS verify BEFORE completing any E2E task:**
### When CREATING new tests: ### When CREATING new tests
- [ ] `{page-name}-page.ts` - Page Object created/updated - [ ] `{page-name}-page.ts` - Page Object created/updated
- [ ] `{page-name}.spec.ts` - Tests added with correct tags (@TEST-ID) - [ ] `{page-name}.spec.ts` - Tests added with correct tags (@TEST-ID)
- [ ] `{page-name}.md` - Documentation created with ALL test cases - [ ] `{page-name}.md` - Documentation created with ALL test cases
- [ ] Test IDs in `.md` match tags in `.spec.ts` - [ ] Test IDs in `.md` match tags in `.spec.ts`
### When MODIFYING existing tests: ### When MODIFYING existing tests
- [ ] `{page-name}.md` MUST be updated if: - [ ] `{page-name}.md` MUST be updated if:
- Test cases were added/removed - Test cases were added/removed
- Test flow changed (steps) - Test flow changed (steps)
@@ -49,7 +49,7 @@ ui/tests/
- Tags or priorities changed - Tags or priorities changed
- [ ] Test IDs synchronized between `.md` and `.spec.ts` - [ ] Test IDs synchronized between `.md` and `.spec.ts`
### Quick validation: ### Quick validation
```bash ```bash
# Verify .md exists for each test folder # Verify .md exists for each test folder
ls ui/tests/{feature}/{feature}.md ls ui/tests/{feature}/{feature}.md
@@ -59,7 +59,8 @@ grep -o "@[A-Z]*-E2E-[0-9]*" ui/tests/{feature}/{feature}.spec.ts | sort -u
grep -o "\`[A-Z]*-E2E-[0-9]*\`" ui/tests/{feature}/{feature}.md | sort -u grep -o "\`[A-Z]*-E2E-[0-9]*\`" ui/tests/{feature}/{feature}.md | sort -u
``` ```
**❌ An E2E change is NOT considered complete without updating the corresponding .md file** > [!IMPORTANT]
> ❌ An E2E change is NOT considered complete without updating the corresponding `.md` file.
--- ---
+5 -5
View File
@@ -27,7 +27,7 @@ allowed-tools: Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task
## Tech Stack (Versions) ## Tech Stack (Versions)
``` ```text
Next.js 16.2.3 | React 19.2.5 | Tailwind 4.1.18 | shadcn/ui Next.js 16.2.3 | React 19.2.5 | Tailwind 4.1.18 | shadcn/ui
Zod 4.1.11 | React Hook Form 7.62.0 | Zustand 5.0.8 Zod 4.1.11 | React Hook Form 7.62.0 | Zustand 5.0.8
NextAuth 5.0.0-beta.30 | Recharts 2.15.4 NextAuth 5.0.0-beta.30 | Recharts 2.15.4
@@ -43,7 +43,7 @@ HeroUI 2.8.4 (LEGACY - do not add new components)
### Component Placement ### Component Placement
``` ```text
New feature UI? → shadcn/ui + Tailwind New feature UI? → shadcn/ui + Tailwind
Existing HeroUI feature? → Keep HeroUI (don't mix) Existing HeroUI feature? → Keep HeroUI (don't mix)
Used 1 feature? → features/{feature}/components/ Used 1 feature? → features/{feature}/components/
@@ -54,7 +54,7 @@ Server component? → No directive needed
### Code Location ### Code Location
``` ```text
Server action → actions/{feature}/{feature}.ts Server action → actions/{feature}/{feature}.ts
Data transform → actions/{feature}/{feature}.adapter.ts Data transform → actions/{feature}/{feature}.adapter.ts
Types (shared 2+) → types/{domain}.ts Types (shared 2+) → types/{domain}.ts
@@ -69,7 +69,7 @@ HeroUI components → components/ui/ (LEGACY)
### Styling Decision ### Styling Decision
``` ```text
Tailwind class exists? → className Tailwind class exists? → className
Dynamic value? → style prop Dynamic value? → style prop
Conditional styles? → cn() Conditional styles? → cn()
@@ -85,7 +85,7 @@ Recharts/library? → CHART_COLORS constant + var()
## Project Structure ## Project Structure
``` ```text
ui/ ui/
├── app/ ├── app/
│ ├── (auth)/ # Auth pages (login, signup) │ ├── (auth)/ # Auth pages (login, signup)
+5 -5
View File
@@ -29,7 +29,7 @@ Create a skill when:
## Skill Structure ## Skill Structure
``` ```text
skills/{skill-name}/ skills/{skill-name}/
├── SKILL.md # Required - main skill file ├── SKILL.md # Required - main skill file
├── assets/ # Optional - templates, schemas, examples ├── assets/ # Optional - templates, schemas, examples
@@ -43,7 +43,7 @@ skills/{skill-name}/
## SKILL.md Template ## SKILL.md Template
```markdown ````markdown
--- ---
name: {skill-name} name: {skill-name}
description: > description: >
@@ -77,7 +77,7 @@ metadata:
- **Templates**: See [assets/](assets/) for {description} - **Templates**: See [assets/](assets/) for {description}
- **Documentation**: See [references/](references/) for local docs - **Documentation**: See [references/](references/) for local docs
``` ````
--- ---
@@ -94,7 +94,7 @@ metadata:
## Decision: assets/ vs references/ ## Decision: assets/ vs references/
``` ```text
Need code templates? → assets/ Need code templates? → assets/
Need JSON schemas? → assets/ Need JSON schemas? → assets/
Need example configs? → assets/ Need example configs? → assets/
@@ -108,7 +108,7 @@ Link to external guides? → references/ (with local path)
## Decision: Prowler-Specific vs Generic ## Decision: Prowler-Specific vs Generic
``` ```text
Patterns apply to ANY project? → Generic skill (e.g., pytest, typescript) Patterns apply to ANY project? → Generic skill (e.g., pytest, typescript)
Patterns are Prowler-specific? → prowler-{name} skill Patterns are Prowler-specific? → prowler-{name} skill
Generic skill needs Prowler info? → Add references/ pointing to Prowler docs Generic skill needs Prowler info? → Add references/ pointing to Prowler docs
@@ -38,7 +38,7 @@ Use this skill when:
## Decision Tree ## Decision Tree
``` ```text
{Question 1}? → {Action A} {Question 1}? → {Action A}
{Question 2}? → {Action B} {Question 2}? → {Action B}
Otherwise → {Default action} Otherwise → {Default action}
+1 -1
View File
@@ -14,7 +14,7 @@ allowed-tools: Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task
## Styling Decision Tree ## Styling Decision Tree
``` ```text
Tailwind class exists? → className="..." Tailwind class exists? → className="..."
Dynamic value? → style={{ width: `${x}%` }} Dynamic value? → style={{ width: `${x}%` }}
Conditional styles? → cn("base", condition && "variant") Conditional styles? → cn("base", condition && "variant")
+12 -12
View File
@@ -20,7 +20,7 @@ allowed-tools: Read, Edit, Write, Glob, Grep, Bash, Task
## TDD Cycle (MANDATORY) ## TDD Cycle (MANDATORY)
``` ```text
+-----------------------------------------+ +-----------------------------------------+
| RED -> GREEN -> REFACTOR | | RED -> GREEN -> REFACTOR |
| ^ | | | ^ | |
@@ -28,7 +28,7 @@ allowed-tools: Read, Edit, Write, Glob, Grep, Bash, Task
+-----------------------------------------+ +-----------------------------------------+
``` ```
**The question is NOT "should I write tests?" but "what tests do I need?"** The question is NOT "should I write tests?" but "what tests do I need?"
--- ---
@@ -94,7 +94,7 @@ uv run pytest api/src/backend/api/tests/test_models.py -v
### Decision Tree (All Stacks) ### Decision Tree (All Stacks)
``` ```text
+------------------------------------------+ +------------------------------------------+
| Does test file exist for this code? | | Does test file exist for this code? |
+----------+-----------------------+-------+ +----------+-----------------------+-------+
@@ -122,7 +122,7 @@ uv run pytest api/src/backend/api/tests/test_models.py -v
### For NEW Functionality ### For NEW Functionality
**UI (Vitest)** #### UI (Vitest)
```typescript ```typescript
describe("PriceCalculator", () => { describe("PriceCalculator", () => {
@@ -139,7 +139,7 @@ describe("PriceCalculator", () => {
}); });
``` ```
**SDK (pytest)** #### SDK (pytest)
```python ```python
class Test_ec2_ami_public: class Test_ec2_ami_public:
@@ -159,7 +159,7 @@ class Test_ec2_ami_public:
assert len(result) == 0 assert len(result) == 0
``` ```
**API (pytest-django)** #### API (pytest-django)
```python ```python
@pytest.mark.django_db @pytest.mark.django_db
@@ -192,18 +192,18 @@ Write a test that **reproduces the bug** first:
**API:** `assert response.status_code == 403 # Currently returns 200` **API:** `assert response.status_code == 403 # Currently returns 200`
**Run -> Should FAIL (reproducing the bug)** Run -> Should FAIL (reproducing the bug).
### For REFACTORING ### For REFACTORING
Capture ALL current behavior BEFORE refactoring: Capture ALL current behavior BEFORE refactoring:
``` ```text
# Any stack: run ALL existing tests, they should PASS # Any stack: run ALL existing tests, they should PASS
# This is your safety net - if any fail after refactoring, you broke something # This is your safety net - if any fail after refactoring, you broke something
``` ```
**Run -> All should PASS (baseline)** Run -> All should PASS (baseline).
--- ---
@@ -288,13 +288,13 @@ Tests GREEN -> Improve code quality WITHOUT changing behavior.
- Add types/validation - Add types/validation
- Reduce duplication - Reduce duplication
**Run tests after EACH change -> Must stay GREEN** Run tests after EACH change -> Must stay GREEN.
--- ---
## Quick Reference ## Quick Reference
``` ```text
+------------------------------------------------+ +------------------------------------------------+
| TDD WORKFLOW | | TDD WORKFLOW |
+------------------------------------------------+ +------------------------------------------------+
@@ -320,7 +320,7 @@ Tests GREEN -> Improve code quality WITHOUT changing behavior.
## Anti-Patterns (NEVER DO) ## Anti-Patterns (NEVER DO)
``` ```python
# ANY language: # ANY language:
# 1. Code first, tests after # 1. Code first, tests after
+1 -1
View File
@@ -181,7 +181,7 @@ expect(screen.getByRole("button")).toBeDisabled();
## File Organization ## File Organization
``` ```text
components/ components/
├── Button/ ├── Button/
│ ├── Button.tsx │ ├── Button.tsx
+4 -4
View File
@@ -15,7 +15,7 @@
> - [`vitest`](../skills/vitest/SKILL.md) - Unit testing with React Testing Library > - [`vitest`](../skills/vitest/SKILL.md) - Unit testing with React Testing Library
> - [`tdd`](../skills/tdd/SKILL.md) - TDD workflow (MANDATORY for UI tasks) > - [`tdd`](../skills/tdd/SKILL.md) - TDD workflow (MANDATORY for UI tasks)
### Auto-invoke Skills ## Auto-invoke Skills
When performing these actions, ALWAYS invoke the corresponding skill FIRST: When performing these actions, ALWAYS invoke the corresponding skill FIRST:
@@ -89,7 +89,7 @@ When performing these actions, ALWAYS invoke the corresponding skill FIRST:
### Component Placement ### Component Placement
``` ```text
New/Existing UI? → shadcn/ui + Tailwind (NEVER HeroUI for new code) New/Existing UI? → shadcn/ui + Tailwind (NEVER HeroUI for new code)
Used 1 feature? → features/{feature}/components | Used 2+? → components/{domain}/ Used 1 feature? → features/{feature}/components | Used 2+? → components/{domain}/
Needs state/hooks? → "use client" | Server component? → No directive Needs state/hooks? → "use client" | Server component? → No directive
@@ -97,7 +97,7 @@ Needs state/hooks? → "use client" | Server component? → No directive
### Code Location ### Code Location
``` ```text
Server action → actions/{feature}/{feature}.ts Server action → actions/{feature}/{feature}.ts
Data transform → actions/{feature}/{feature}.adapter.ts Data transform → actions/{feature}/{feature}.adapter.ts
Types (shared 2+) → types/{domain}.ts | Types (local 1) → {feature}/types.ts Types (shared 2+) → types/{domain}.ts | Types (local 1) → {feature}/types.ts
@@ -193,7 +193,7 @@ Zod 4.1.11 | React Hook Form 7.62.0 | Zustand 5.0.8 | NextAuth 5.0.0-beta.30 | R
## PROJECT STRUCTURE ## PROJECT STRUCTURE
``` ```text
ui/ ui/
├── app/(auth)/ # Auth pages ├── app/(auth)/ # Auth pages
├── app/(prowler)/ # Main app: compliance, findings, providers, scans ├── app/(prowler)/ # Main app: compliance, findings, providers, scans
+1 -1
View File
@@ -6,7 +6,7 @@ This directory contains all shadcn/ui based components for the Prowler applicati
Example of a custom component: Example of a custom component:
``` ```text
shadcn/ shadcn/
├── card/ ├── card/
│ ├── base-card/ │ ├── base-card/
+18 -18
View File
@@ -21,7 +21,7 @@
- Application is running. - Application is running.
- No active session (cookies cleared). - No active session (cookies cleared).
### Flow Steps: ### Flow Steps
1. Clear all cookies. 1. Clear all cookies.
2. Navigate to /sign-in. 2. Navigate to /sign-in.
@@ -29,7 +29,7 @@
4. Navigate to /sign-up. 4. Navigate to /sign-up.
5. Verify page loads. 5. Verify page loads.
### Expected Result: ### Expected Result
- Public routes are accessible without authentication. - Public routes are accessible without authentication.
@@ -50,7 +50,7 @@
- Application is running. - Application is running.
### Flow Steps: ### Flow Steps
1. Log in with valid credentials. 1. Log in with valid credentials.
2. Navigate to a protected route. 2. Navigate to a protected route.
@@ -58,7 +58,7 @@
4. Navigate to another protected route. 4. Navigate to another protected route.
5. Verify redirect to sign-in. 5. Verify redirect to sign-in.
### Expected Result: ### Expected Result
- Invalid session results in redirect to sign-in. - Invalid session results in redirect to sign-in.
@@ -79,13 +79,13 @@
- Application is running. - Application is running.
### Flow Steps: ### Flow Steps
1. Navigate to /sign-in with error=RefreshAccessTokenError query parameter. 1. Navigate to /sign-in with error=RefreshAccessTokenError query parameter.
2. Check for toast notification. 2. Check for toast notification.
3. Verify form elements are still visible. 3. Verify form elements are still visible.
### Expected Result: ### Expected Result
- Toast shows "Session Expired" message with "Please sign in again". - Toast shows "Session Expired" message with "Please sign in again".
- Sign-in form is displayed and functional. - Sign-in form is displayed and functional.
@@ -107,13 +107,13 @@
- Application is running. - Application is running.
### Flow Steps: ### Flow Steps
1. Navigate to /sign-in with error=MissingRefreshToken query parameter. 1. Navigate to /sign-in with error=MissingRefreshToken query parameter.
2. Check for toast notification. 2. Check for toast notification.
3. Verify email input is visible. 3. Verify email input is visible.
### Expected Result: ### Expected Result
- Toast shows "Session Error" message. - Toast shows "Session Error" message.
- Sign-in form is displayed. - Sign-in form is displayed.
@@ -135,12 +135,12 @@
- Application is running. - Application is running.
### Flow Steps: ### Flow Steps
1. Navigate to /sign-in with error=UnknownError query parameter. 1. Navigate to /sign-in with error=UnknownError query parameter.
2. Check for toast notification. 2. Check for toast notification.
### Expected Result: ### Expected Result
- Toast shows "Authentication Error" message with "Please sign in again". - Toast shows "Authentication Error" message with "Please sign in again".
@@ -162,7 +162,7 @@
- Application is running. - Application is running.
- Valid test user credentials. - Valid test user credentials.
### Flow Steps: ### Flow Steps
1. Log in with valid credentials. 1. Log in with valid credentials.
2. Navigate to a protected route (/scans). 2. Navigate to a protected route (/scans).
@@ -171,7 +171,7 @@
5. Navigate to another protected route (/providers) using fresh navigation. 5. Navigate to another protected route (/providers) using fresh navigation.
6. Verify redirect to sign-in includes callbackUrl parameter. 6. Verify redirect to sign-in includes callbackUrl parameter.
### Expected Result: ### Expected Result
- URL contains callbackUrl=/providers parameter. - URL contains callbackUrl=/providers parameter.
- User can sign in and be redirected back to the original destination. - User can sign in and be redirected back to the original destination.
@@ -194,7 +194,7 @@
- Application is running. - Application is running.
- Valid test user credentials. - Valid test user credentials.
### Flow Steps: ### Flow Steps
1. Log in with valid credentials. 1. Log in with valid credentials.
2. Verify home page is loaded. 2. Verify home page is loaded.
@@ -202,7 +202,7 @@
4. Reload the page. 4. Reload the page.
5. Verify session is still valid with same user data. 5. Verify session is still valid with same user data.
### Expected Result: ### Expected Result
- Session persists after reload. - Session persists after reload.
- User email, userId, and tenantId remain the same. - User email, userId, and tenantId remain the same.
@@ -225,14 +225,14 @@
- Application is running. - Application is running.
- Valid test user credentials. - Valid test user credentials.
### Flow Steps: ### Flow Steps
1. Log in with valid credentials. 1. Log in with valid credentials.
2. Capture initial session with permissions. 2. Capture initial session with permissions.
3. Reload the page. 3. Reload the page.
4. Verify permissions match initial session. 4. Verify permissions match initial session.
### Expected Result: ### Expected Result
- User permissions are identical before and after refresh. - User permissions are identical before and after refresh.
- User profile data (email, name, companyName) is preserved. - User profile data (email, name, companyName) is preserved.
@@ -255,14 +255,14 @@
- Application is running. - Application is running.
- Valid test user credentials. - Valid test user credentials.
### Flow Steps: ### Flow Steps
1. Log in with valid credentials. 1. Log in with valid credentials.
2. Verify session is valid. 2. Verify session is valid.
3. Clear all cookies. 3. Clear all cookies.
4. Check session status. 4. Check session status.
### Expected Result: ### Expected Result
- Session returns null after cookies are cleared. - Session returns null after cookies are cleared.
- User is effectively logged out. - User is effectively logged out.
+10 -10
View File
@@ -24,7 +24,7 @@ redirects to `/sign-in` with a `callbackUrl` that preserves the invitation token
- Application is running. - Application is running.
- No active session (cookies cleared). - No active session (cookies cleared).
### Flow Steps: ### Flow Steps
1. Clear all cookies. 1. Clear all cookies.
2. Navigate to `/invitation/accept?invitation_token=test-token`. 2. Navigate to `/invitation/accept?invitation_token=test-token`.
@@ -32,7 +32,7 @@ redirects to `/sign-in` with a `callbackUrl` that preserves the invitation token
4. Click the "I have an account — Sign in" button. 4. Click the "I have an account — Sign in" button.
5. Verify the redirect target and `callbackUrl` query param. 5. Verify the redirect target and `callbackUrl` query param.
### Expected Result: ### Expected Result
- Heading "You've Been Invited" is visible. - Heading "You've Been Invited" is visible.
- Description text "invited to join a tenant" is visible. - Description text "invited to join a tenant" is visible.
@@ -41,7 +41,7 @@ redirects to `/sign-in` with a `callbackUrl` that preserves the invitation token
- Decoded `callbackUrl` equals `/invitation/accept?invitation_token=test-token`. - Decoded `callbackUrl` equals `/invitation/accept?invitation_token=test-token`.
- Decoded `callbackUrl` contains `invitation_token=test-token`. - Decoded `callbackUrl` contains `invitation_token=test-token`.
### Key verification points: ### Key verification points
- `callbackUrl` preserves the original invitation path with token. - `callbackUrl` preserves the original invitation path with token.
@@ -65,7 +65,7 @@ form actually renders (no redirect loop back to `/invitation/accept`).
- Application is running. - Application is running.
- No active session (cookies cleared). - No active session (cookies cleared).
### Flow Steps: ### Flow Steps
1. Clear all cookies. 1. Clear all cookies.
2. Navigate to `/invitation/accept?invitation_token=test-token`. 2. Navigate to `/invitation/accept?invitation_token=test-token`.
@@ -73,17 +73,17 @@ form actually renders (no redirect loop back to `/invitation/accept`).
4. Click the button. 4. Click the button.
5. Verify the resulting URL and that the sign-up form is rendered. 5. Verify the resulting URL and that the sign-up form is rendered.
### Expected Result: ### Expected Result
- URL pathname is `/sign-up`. - URL pathname is `/sign-up`.
- Query param `invitation_token` equals `test-token`. - Query param `invitation_token` equals `test-token`.
- Sign-up form is rendered (email input and submit button visible). - Sign-up form is rendered (email input and submit button visible).
### Key verification points: ### Key verification points
- No redirect back to `/invitation/accept` (smart router does not loop). - No redirect back to `/invitation/accept` (smart router does not loop).
### Notes: ### Notes
- The legacy `action=signup` param is no longer emitted: the backward-compat - The legacy `action=signup` param is no longer emitted: the backward-compat
redirect from `/sign-up?invitation_token=...` to `/invitation/accept` was redirect from `/sign-up?invitation_token=...` to `/invitation/accept` was
@@ -111,7 +111,7 @@ that the "Go to Sign In" link redirects to `/sign-in`.
- Application is running. - Application is running.
- No active session (cookies cleared). - No active session (cookies cleared).
### Flow Steps: ### Flow Steps
1. Clear all cookies. 1. Clear all cookies.
2. Navigate to `/invitation/accept` (no query params). 2. Navigate to `/invitation/accept` (no query params).
@@ -119,13 +119,13 @@ that the "Go to Sign In" link redirects to `/sign-in`.
4. Click the "Go to Sign In" link. 4. Click the "Go to Sign In" link.
5. Verify redirect to `/sign-in`. 5. Verify redirect to `/sign-in`.
### Expected Result: ### Expected Result
- Heading "Invalid Invitation Link" is visible. - Heading "Invalid Invitation Link" is visible.
- Description "No invitation token was provided" is visible. - Description "No invitation token was provided" is visible.
- "Go to Sign In" link is visible and clickable. - "Go to Sign In" link is visible and clickable.
- After click, URL matches `/sign-in`. - After click, URL matches `/sign-in`.
### Key verification points: ### Key verification points
- Client-side render only: no API calls involved. - Client-side render only: no API calls involved.
+4 -4
View File
@@ -25,7 +25,7 @@
- `E2E_ORGANIZATION_ID` (expected organization for membership verification) - `E2E_ORGANIZATION_ID` (expected organization for membership verification)
- Application running with accessible UI/API endpoints - Application running with accessible UI/API endpoints
### Flow Steps: ### Flow Steps
1. Navigate to invitations page 1. Navigate to invitations page
2. Click "Send Invitation" button 2. Click "Send Invitation" button
@@ -40,7 +40,7 @@
11. Verify successful login 11. Verify successful login
12. Navigate to user profile and verify `organizationId` matches `E2E_ORGANIZATION_ID` 12. Navigate to user profile and verify `organizationId` matches `E2E_ORGANIZATION_ID`
### Expected Result: ### Expected Result
- Invitation is created and a valid share URL is provided - Invitation is created and a valid share URL is provided
- Invited user can sign up successfully using the invitation link - Invited user can sign up successfully using the invitation link
@@ -48,7 +48,7 @@
- Login succeeds with the new credentials - Login succeeds with the new credentials
- User profile shows membership in the expected organization - User profile shows membership in the expected organization
### Key verification points: ### Key verification points
- Invitations page loads and displays the heading - Invitations page loads and displays the heading
- Send Invitation form is visible (email + role select) - Send Invitation form is visible (email + role select)
@@ -58,7 +58,7 @@
- Login with the new account succeeds - Login with the new account succeeds
- Profile page shows the expected organization id - Profile page shows the expected organization id
### Notes: ### Notes
- Test uses a fresh browser context for the invitee to avoid admin session leakage - Test uses a fresh browser context for the invitee to avoid admin session leakage
- Email should be unique per run (the test uses a random suffix) - Email should be unique per run (the test uses a random suffix)
+68 -68
View File
@@ -24,7 +24,7 @@
- Remove any existing provider with the same Account ID before starting the test - Remove any existing provider with the same Account ID before starting the test
- This test must be run serially and never in parallel with other tests, as it requires the Account ID not to be already registered beforehand. - This test must be run serially and never in parallel with other tests, as it requires the Account ID not to be already registered beforehand.
### Flow Steps: ### Flow Steps
1. Navigate to providers page 1. Navigate to providers page
2. Click "Add Provider" button 2. Click "Add Provider" button
@@ -36,14 +36,14 @@
8. Verify redirect to Scans page 8. Verify redirect to Scans page
9. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan") 9. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan")
### Expected Result: ### Expected Result
- AWS provider successfully added with static credentials - AWS provider successfully added with static credentials
- Initial scan launched successfully - Initial scan launched successfully
- User redirected to Scans page - User redirected to Scans page
- Scheduled scan appears in Scans table with correct provider and scan name - Scheduled scan appears in Scans table with correct provider and scan name
### Key verification points: ### Key verification points
- Provider page loads correctly - Provider page loads correctly
- Connect account page displays AWS option - Connect account page displays AWS option
@@ -53,7 +53,7 @@
- Provider exists in Scans table (verified by account ID) - Provider exists in Scans table (verified by account ID)
- Scan name field contains "scheduled scan" - Scan name field contains "scheduled scan"
### Notes: ### Notes
- Test uses environment variables for AWS credentials - Test uses environment variables for AWS credentials
- Provider cleanup performed before each test to ensure clean state - Provider cleanup performed before each test to ensure clean state
@@ -80,7 +80,7 @@
- Remove any existing provider with the same Account ID before starting the test - Remove any existing provider with the same Account ID before starting the test
- This test must be run serially and never in parallel with other tests, as it requires the Account ID not to be already registered beforehand. - This test must be run serially and never in parallel with other tests, as it requires the Account ID not to be already registered beforehand.
### Flow Steps: ### Flow Steps
1. Navigate to providers page 1. Navigate to providers page
2. Click "Add Provider" button 2. Click "Add Provider" button
@@ -92,14 +92,14 @@
8. Verify redirect to Scans page 8. Verify redirect to Scans page
9. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan") 9. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan")
### Expected Result: ### Expected Result
- AWS provider successfully added with role credentials - AWS provider successfully added with role credentials
- Initial scan launched successfully - Initial scan launched successfully
- User redirected to Scans page - User redirected to Scans page
- Scheduled scan appears in Scans table with correct provider and scan name - Scheduled scan appears in Scans table with correct provider and scan name
### Key verification points: ### Key verification points
- Provider page loads correctly - Provider page loads correctly
- Connect account page displays AWS option - Connect account page displays AWS option
@@ -109,7 +109,7 @@
- Provider exists in Scans table (verified by account ID) - Provider exists in Scans table (verified by account ID)
- Scan name field contains "scheduled scan" - Scan name field contains "scheduled scan"
### Notes: ### Notes
- Test uses environment variables for AWS credentials and role ARN - Test uses environment variables for AWS credentials and role ARN
- Provider cleanup performed before each test to ensure clean state - Provider cleanup performed before each test to ensure clean state
@@ -137,7 +137,7 @@
- Remove any existing provider with the same Subscription ID before starting the test - Remove any existing provider with the same Subscription ID before starting the test
- This test must be run serially and never in parallel with other tests, as it requires the Subscription ID not to be already registered beforehand. - This test must be run serially and never in parallel with other tests, as it requires the Subscription ID not to be already registered beforehand.
### Flow Steps: ### Flow Steps
1. Navigate to providers page 1. Navigate to providers page
2. Click "Add Provider" button 2. Click "Add Provider" button
@@ -148,14 +148,14 @@
7. Verify redirect to Scans page 7. Verify redirect to Scans page
8. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan") 8. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan")
### Expected Result: ### Expected Result
- Azure provider successfully added with static credentials - Azure provider successfully added with static credentials
- Initial scan launched successfully - Initial scan launched successfully
- User redirected to Scans page - User redirected to Scans page
- Scheduled scan appears in Scans table with correct provider and scan name - Scheduled scan appears in Scans table with correct provider and scan name
### Key verification points: ### Key verification points
- Provider page loads correctly - Provider page loads correctly
- Connect account page displays Azure option - Connect account page displays Azure option
@@ -165,7 +165,7 @@
- Provider exists in Scans table (verified by subscription ID) - Provider exists in Scans table (verified by subscription ID)
- Scan name field contains "scheduled scan" - Scan name field contains "scheduled scan"
### Notes: ### Notes
- Test uses environment variables for Azure credentials - Test uses environment variables for Azure credentials
- Provider cleanup performed before each test to ensure clean state - Provider cleanup performed before each test to ensure clean state
@@ -193,7 +193,7 @@
- Remove any existing provider with the same Domain ID before starting the test - Remove any existing provider with the same Domain ID before starting the test
- This test must be run serially and never in parallel with other tests, as it requires the Domain ID not to be already registered beforehand. - This test must be run serially and never in parallel with other tests, as it requires the Domain ID not to be already registered beforehand.
### Flow Steps: ### Flow Steps
1. Navigate to providers page 1. Navigate to providers page
2. Click "Add Provider" button 2. Click "Add Provider" button
@@ -205,14 +205,14 @@
8. Verify redirect to Scans page 8. Verify redirect to Scans page
9. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan") 9. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan")
### Expected Result: ### Expected Result
- M365 provider successfully added with static credentials - M365 provider successfully added with static credentials
- Initial scan launched successfully - Initial scan launched successfully
- User redirected to Scans page - User redirected to Scans page
- Scheduled scan appears in Scans table with correct provider and scan name - Scheduled scan appears in Scans table with correct provider and scan name
### Key verification points: ### Key verification points
- Provider page loads correctly - Provider page loads correctly
- Connect account page displays M365 option - Connect account page displays M365 option
@@ -222,7 +222,7 @@
- Provider exists in Scans table (verified by domain ID) - Provider exists in Scans table (verified by domain ID)
- Scan name field contains "scheduled scan" - Scan name field contains "scheduled scan"
### Notes: ### Notes
- Test uses environment variables for M365 credentials - Test uses environment variables for M365 credentials
- Provider cleanup performed before each test to ensure clean state - Provider cleanup performed before each test to ensure clean state
@@ -250,7 +250,7 @@
- Remove any existing provider with the same Domain ID before starting the test - Remove any existing provider with the same Domain ID before starting the test
- This test must be run serially and never in parallel with other tests, as it requires the Domain ID not to be already registered beforehand. - This test must be run serially and never in parallel with other tests, as it requires the Domain ID not to be already registered beforehand.
### Flow Steps: ### Flow Steps
1. Navigate to providers page 1. Navigate to providers page
2. Click "Add Provider" button 2. Click "Add Provider" button
@@ -262,14 +262,14 @@
8. Verify redirect to Scans page 8. Verify redirect to Scans page
9. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan") 9. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan")
### Expected Result: ### Expected Result
- M365 provider successfully added with certificate credentials - M365 provider successfully added with certificate credentials
- Initial scan launched successfully - Initial scan launched successfully
- User redirected to Scans page - User redirected to Scans page
- Scheduled scan appears in Scans table with correct provider and scan name - Scheduled scan appears in Scans table with correct provider and scan name
### Key verification points: ### Key verification points
- Provider page loads correctly - Provider page loads correctly
- Connect account page displays M365 option - Connect account page displays M365 option
@@ -279,7 +279,7 @@
- Provider exists in Scans table (verified by domain ID) - Provider exists in Scans table (verified by domain ID)
- Scan name field contains "scheduled scan" - Scan name field contains "scheduled scan"
### Notes: ### Notes
- Test uses environment variables for M365 certificate credentials - Test uses environment variables for M365 certificate credentials
- Provider cleanup performed before each test to ensure clean state - Provider cleanup performed before each test to ensure clean state
@@ -308,7 +308,7 @@
- Remove any existing provider with the same Context before starting the test - Remove any existing provider with the same Context before starting the test
- This test must be run serially and never in parallel with other tests, as it requires the Context not to be already registered beforehand. - This test must be run serially and never in parallel with other tests, as it requires the Context not to be already registered beforehand.
### Flow Steps: ### Flow Steps
1. Navigate to providers page 1. Navigate to providers page
2. Click "Add Provider" button 2. Click "Add Provider" button
@@ -320,14 +320,14 @@
8. Verify redirect to Scans page 8. Verify redirect to Scans page
9. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan") 9. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan")
### Expected Result: ### Expected Result
- Kubernetes provider successfully added with kubeconfig content - Kubernetes provider successfully added with kubeconfig content
- Initial scan launched successfully - Initial scan launched successfully
- User redirected to Scans page - User redirected to Scans page
- Scheduled scan appears in Scans table with correct provider and scan name - Scheduled scan appears in Scans table with correct provider and scan name
### Key verification points: ### Key verification points
- Provider page loads correctly - Provider page loads correctly
- Connect account page displays Kubernetes option - Connect account page displays Kubernetes option
@@ -339,7 +339,7 @@
- Provider exists in Scans table (verified by context) - Provider exists in Scans table (verified by context)
- Scan name field contains "scheduled scan" - Scan name field contains "scheduled scan"
### Notes: ### Notes
- Test uses environment variables for Kubernetes context and kubeconfig file path - Test uses environment variables for Kubernetes context and kubeconfig file path
- Kubeconfig content is read from file and used for authentication - Kubeconfig content is read from file and used for authentication
@@ -369,7 +369,7 @@
- Remove any existing provider with the same Project ID before starting the test - Remove any existing provider with the same Project ID before starting the test
- This test must be run serially and never in parallel with other tests, as it requires the Project ID not to be already registered beforehand. - This test must be run serially and never in parallel with other tests, as it requires the Project ID not to be already registered beforehand.
### Flow Steps: ### Flow Steps
1. Navigate to providers page 1. Navigate to providers page
2. Click "Add Provider" button 2. Click "Add Provider" button
@@ -381,14 +381,14 @@
8. Verify redirect to Scans page 8. Verify redirect to Scans page
9. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan") 9. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan")
### Expected Result: ### Expected Result
- GCP provider successfully added with service account key - GCP provider successfully added with service account key
- Initial scan launched successfully - Initial scan launched successfully
- User redirected to Scans page - User redirected to Scans page
- Scheduled scan appears in Scans table with correct provider and scan name - Scheduled scan appears in Scans table with correct provider and scan name
### Key verification points: ### Key verification points
- Provider page loads correctly - Provider page loads correctly
- Connect account page displays GCP option - Connect account page displays GCP option
@@ -400,7 +400,7 @@
- Provider exists in Scans table (verified by project ID) - Provider exists in Scans table (verified by project ID)
- Scan name field contains "scheduled scan" - Scan name field contains "scheduled scan"
### Notes: ### Notes
- Test uses environment variables for GCP project ID and service account key - Test uses environment variables for GCP project ID and service account key
- Service account key is provided as base64 encoded JSON content - Service account key is provided as base64 encoded JSON content
@@ -431,7 +431,7 @@
- Remove any existing provider with the same Username before starting the test - Remove any existing provider with the same Username before starting the test
- This test must be run serially and never in parallel with other tests, as it requires the Username not to be already registered beforehand. - This test must be run serially and never in parallel with other tests, as it requires the Username not to be already registered beforehand.
### Flow Steps: ### Flow Steps
1. Navigate to providers page 1. Navigate to providers page
2. Click "Add Provider" button 2. Click "Add Provider" button
@@ -443,14 +443,14 @@
8. Verify redirect to Scans page 8. Verify redirect to Scans page
9. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan") 9. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan")
### Expected Result: ### Expected Result
- GitHub provider successfully added with personal access token - GitHub provider successfully added with personal access token
- Initial scan launched successfully - Initial scan launched successfully
- User redirected to Scans page - User redirected to Scans page
- Scheduled scan appears in Scans table with correct provider and scan name - Scheduled scan appears in Scans table with correct provider and scan name
### Key verification points: ### Key verification points
- Provider page loads correctly - Provider page loads correctly
- Connect account page displays GitHub option - Connect account page displays GitHub option
@@ -462,7 +462,7 @@
- Provider exists in Scans table (verified by username) - Provider exists in Scans table (verified by username)
- Scan name field contains "scheduled scan" - Scan name field contains "scheduled scan"
### Notes: ### Notes
- Test uses environment variables for GitHub username and personal access token - Test uses environment variables for GitHub username and personal access token
- Provider cleanup performed before each test to ensure clean state - Provider cleanup performed before each test to ensure clean state
@@ -491,7 +491,7 @@
- Remove any existing provider with the same Username before starting the test - Remove any existing provider with the same Username before starting the test
- This test must be run serially and never in parallel with other tests, as it requires the Username not to be already registered beforehand. - This test must be run serially and never in parallel with other tests, as it requires the Username not to be already registered beforehand.
### Flow Steps: ### Flow Steps
1. Navigate to providers page 1. Navigate to providers page
2. Click "Add Provider" button 2. Click "Add Provider" button
@@ -503,14 +503,14 @@
8. Verify redirect to Scans page 8. Verify redirect to Scans page
9. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan") 9. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan")
### Expected Result: ### Expected Result
- GitHub provider successfully added with GitHub App credentials - GitHub provider successfully added with GitHub App credentials
- Initial scan launched successfully - Initial scan launched successfully
- User redirected to Scans page - User redirected to Scans page
- Scheduled scan appears in Scans table with correct provider and scan name - Scheduled scan appears in Scans table with correct provider and scan name
### Key verification points: ### Key verification points
- Provider page loads correctly - Provider page loads correctly
- Connect account page displays GitHub option - Connect account page displays GitHub option
@@ -522,7 +522,7 @@
- Provider exists in Scans table (verified by username) - Provider exists in Scans table (verified by username)
- Scan name field contains "scheduled scan" - Scan name field contains "scheduled scan"
### Notes: ### Notes
- Test uses environment variables for GitHub username, App ID, and base64 encoded private key - Test uses environment variables for GitHub username, App ID, and base64 encoded private key
- Private key is base64 encoded and must be decoded before use - Private key is base64 encoded and must be decoded before use
@@ -552,7 +552,7 @@
- Remove any existing provider with the same Organization name before starting the test - Remove any existing provider with the same Organization name before starting the test
- This test must be run serially and never in parallel with other tests, as it requires the Organization name not to be already registered beforehand. - This test must be run serially and never in parallel with other tests, as it requires the Organization name not to be already registered beforehand.
### Flow Steps: ### Flow Steps
1. Navigate to providers page 1. Navigate to providers page
2. Click "Add Provider" button 2. Click "Add Provider" button
@@ -564,14 +564,14 @@
8. Verify redirect to Scans page 8. Verify redirect to Scans page
9. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan") 9. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan")
### Expected Result: ### Expected Result
- GitHub provider successfully added with organization personal access token - GitHub provider successfully added with organization personal access token
- Initial scan launched successfully - Initial scan launched successfully
- User redirected to Scans page - User redirected to Scans page
- Scheduled scan appears in Scans table with correct provider and scan name - Scheduled scan appears in Scans table with correct provider and scan name
### Key verification points: ### Key verification points
- Provider page loads correctly - Provider page loads correctly
- Connect account page displays GitHub option - Connect account page displays GitHub option
@@ -583,7 +583,7 @@
- Provider exists in Scans table (verified by organization name) - Provider exists in Scans table (verified by organization name)
- Scan name field contains "scheduled scan" - Scan name field contains "scheduled scan"
### Notes: ### Notes
- Test uses environment variables for GitHub organization name and organization access token - Test uses environment variables for GitHub organization name and organization access token
- Provider cleanup performed before each test to ensure clean state - Provider cleanup performed before each test to ensure clean state
@@ -612,7 +612,7 @@
- Remove any existing provider with the same Account ID before starting the test - Remove any existing provider with the same Account ID before starting the test
- This test must be run serially and never in parallel with other tests, as it requires the Account ID not to be already registered beforehand - This test must be run serially and never in parallel with other tests, as it requires the Account ID not to be already registered beforehand
### Flow Steps: ### Flow Steps
1. Navigate to providers page 1. Navigate to providers page
2. Click "Add Provider" button 2. Click "Add Provider" button
@@ -625,14 +625,14 @@
9. Verify redirect to Scans page 9. Verify redirect to Scans page
10. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan") 10. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan")
### Expected Result: ### Expected Result
- AWS provider successfully added using AWS SDK default credentials to assume the role - AWS provider successfully added using AWS SDK default credentials to assume the role
- Initial scan launched successfully - Initial scan launched successfully
- User redirected to Scans page - User redirected to Scans page
- Scheduled scan appears in Scans table with correct provider and scan name - Scheduled scan appears in Scans table with correct provider and scan name
### Key verification points: ### Key verification points
- Provider page loads correctly - Provider page loads correctly
- Connect account page displays AWS option - Connect account page displays AWS option
@@ -643,7 +643,7 @@
- Provider exists in Scans table (verified by account ID) - Provider exists in Scans table (verified by account ID)
- Scan name field contains "scheduled scan" - Scan name field contains "scheduled scan"
### Notes: ### Notes
- Test leverages AWS SDK default credential chain (environment-configured keys) for Access Key and Secret Key - Test leverages AWS SDK default credential chain (environment-configured keys) for Access Key and Secret Key
- Environment variable `E2E_AWS_PROVIDER_ROLE_ARN` must reference a valid assumable role - Environment variable `E2E_AWS_PROVIDER_ROLE_ARN` must reference a valid assumable role
@@ -671,7 +671,7 @@
- Remove any existing provider with the same Tenancy ID before starting the test - Remove any existing provider with the same Tenancy ID before starting the test
- This test must be run serially and never in parallel with other tests, as it requires the Tenancy ID not to be already registered beforehand. - This test must be run serially and never in parallel with other tests, as it requires the Tenancy ID not to be already registered beforehand.
### Flow Steps: ### Flow Steps
1. Navigate to providers page 1. Navigate to providers page
2. Click "Add Provider" button 2. Click "Add Provider" button
@@ -683,14 +683,14 @@
8. Verify redirect to Scans page 8. Verify redirect to Scans page
9. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan") 9. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan")
### Expected Result: ### Expected Result
- OCI provider successfully added with API Key credentials - OCI provider successfully added with API Key credentials
- Initial scan launched successfully - Initial scan launched successfully
- User redirected to Scans page - User redirected to Scans page
- Scheduled scan appears in Scans table with correct provider and scan name - Scheduled scan appears in Scans table with correct provider and scan name
### Key verification points: ### Key verification points
- Provider page loads correctly - Provider page loads correctly
- Connect account page displays OCI option - Connect account page displays OCI option
@@ -702,7 +702,7 @@
- Provider exists in Scans table (verified by tenancy ID) - Provider exists in Scans table (verified by tenancy ID)
- Scan name field contains "scheduled scan" - Scan name field contains "scheduled scan"
### Notes: ### Notes
- Test uses environment variables for OCI credentials - Test uses environment variables for OCI credentials
- Provider cleanup performed before each test to ensure clean state - Provider cleanup performed before each test to ensure clean state
@@ -730,7 +730,7 @@
- An OCI provider with the specified Tenancy ID must already exist (run PROVIDER-E2E-012 first) - An OCI provider with the specified Tenancy ID must already exist (run PROVIDER-E2E-012 first)
- This test must be run serially and never in parallel with other tests - This test must be run serially and never in parallel with other tests
### Flow Steps: ### Flow Steps
1. Navigate to providers page 1. Navigate to providers page
2. Verify OCI provider exists in the table 2. Verify OCI provider exists in the table
@@ -742,7 +742,7 @@
8. Click Next to submit 8. Click Next to submit
9. Verify successful navigation to test connection page 9. Verify successful navigation to test connection page
### Expected Result: ### Expected Result
- Update credentials page loads successfully - Update credentials page loads successfully
- OCI credentials form is displayed with all required fields - OCI credentials form is displayed with all required fields
@@ -750,7 +750,7 @@
- Credentials can be updated and submitted - Credentials can be updated and submitted
- User is redirected to test connection page after successful update - User is redirected to test connection page after successful update
### Key verification points: ### Key verification points
- Provider page loads correctly - Provider page loads correctly
- OCI provider row is visible in providers table - OCI provider row is visible in providers table
@@ -760,7 +760,7 @@
- Form submission succeeds (no silent failures due to missing provider UID) - Form submission succeeds (no silent failures due to missing provider UID)
- Successful redirect to test connection page - Successful redirect to test connection page
### Notes: ### Notes
- Test uses same environment variables as PROVIDER-E2E-012 (add OCI provider) - Test uses same environment variables as PROVIDER-E2E-012 (add OCI provider)
- Requires PROVIDER-E2E-012 to be run first to create the OCI provider - Requires PROVIDER-E2E-012 to be run first to create the OCI provider
@@ -788,7 +788,7 @@
- Remove any existing provider with the same Account ID before starting the test - Remove any existing provider with the same Account ID before starting the test
- This test must be run serially and never in parallel with other tests, as it requires the Account ID not to be already registered beforehand. - This test must be run serially and never in parallel with other tests, as it requires the Account ID not to be already registered beforehand.
### Flow Steps: ### Flow Steps
1. Navigate to providers page 1. Navigate to providers page
2. Click "Add Provider" button 2. Click "Add Provider" button
@@ -802,14 +802,14 @@
10. Verify redirect to Scans page 10. Verify redirect to Scans page
11. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan") 11. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan")
### Expected Result: ### Expected Result
- AlibabaCloud provider successfully added with static credentials - AlibabaCloud provider successfully added with static credentials
- Initial scan launched successfully - Initial scan launched successfully
- User redirected to Scans page - User redirected to Scans page
- Scheduled scan appears in Scans table with correct provider and scan name - Scheduled scan appears in Scans table with correct provider and scan name
### Key verification points: ### Key verification points
- Provider page loads correctly - Provider page loads correctly
- Connect account page displays AlibabaCloud option - Connect account page displays AlibabaCloud option
@@ -822,7 +822,7 @@
- Provider exists in Scans table (verified by account ID) - Provider exists in Scans table (verified by account ID)
- Scan name field contains "scheduled scan" - Scan name field contains "scheduled scan"
### Notes: ### Notes
- Test uses environment variables for AlibabaCloud credentials - Test uses environment variables for AlibabaCloud credentials
- Provider cleanup performed before each test to ensure clean state - Provider cleanup performed before each test to ensure clean state
@@ -850,7 +850,7 @@
- Remove any existing provider with the same Account ID before starting the test - Remove any existing provider with the same Account ID before starting the test
- This test must be run serially and never in parallel with other tests, as it requires the Account ID not to be already registered beforehand. - This test must be run serially and never in parallel with other tests, as it requires the Account ID not to be already registered beforehand.
### Flow Steps: ### Flow Steps
1. Navigate to providers page 1. Navigate to providers page
2. Click "Add Provider" button 2. Click "Add Provider" button
@@ -864,14 +864,14 @@
10. Verify redirect to Scans page 10. Verify redirect to Scans page
11. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan") 11. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan")
### Expected Result: ### Expected Result
- AlibabaCloud provider successfully added with RAM Role credentials - AlibabaCloud provider successfully added with RAM Role credentials
- Initial scan launched successfully - Initial scan launched successfully
- User redirected to Scans page - User redirected to Scans page
- Scheduled scan appears in Scans table with correct provider and scan name - Scheduled scan appears in Scans table with correct provider and scan name
### Key verification points: ### Key verification points
- Provider page loads correctly - Provider page loads correctly
- Connect account page displays AlibabaCloud option - Connect account page displays AlibabaCloud option
@@ -884,7 +884,7 @@
- Provider exists in Scans table (verified by account ID) - Provider exists in Scans table (verified by account ID)
- Scan name field contains "scheduled scan" - Scan name field contains "scheduled scan"
### Notes: ### Notes
- Test uses environment variables for AlibabaCloud RAM Role credentials - Test uses environment variables for AlibabaCloud RAM Role credentials
- Provider cleanup performed before each test to ensure clean state - Provider cleanup performed before each test to ensure clean state
@@ -914,7 +914,7 @@
- StackSet must be deployed in AWS Organizations and expose a valid IAM Role ARN for Prowler - StackSet must be deployed in AWS Organizations and expose a valid IAM Role ARN for Prowler
- This test must be run serially and never in parallel with other tests, as it requires the Organization ID not to be already registered beforehand. - This test must be run serially and never in parallel with other tests, as it requires the Organization ID not to be already registered beforehand.
### Flow Steps: ### Flow Steps
1. Navigate to providers page 1. Navigate to providers page
2. Click "Add Provider" button 2. Click "Add Provider" button
@@ -927,14 +927,14 @@
9. Verify organization launch step, choose single scan schedule, and launch 9. Verify organization launch step, choose single scan schedule, and launch
10. Verify redirect to Scans page 10. Verify redirect to Scans page
### Expected Result: ### Expected Result
- AWS Organizations flow completes successfully - AWS Organizations flow completes successfully
- Accounts are connected and launch step is displayed - Accounts are connected and launch step is displayed
- Scan scheduling selection is applied - Scan scheduling selection is applied
- User is redirected to Scans page after launch - User is redirected to Scans page after launch
### Key verification points: ### Key verification points
- Connect account page displays AWS option - Connect account page displays AWS option
- Organizations method selector is available - Organizations method selector is available
@@ -943,7 +943,7 @@
- Accounts connected launch step appears - Accounts connected launch step appears
- Successful redirect to Scans page after launching - Successful redirect to Scans page after launching
### Notes: ### Notes
- Organization ID must follow AWS format (e.g., o-abc123def4) - Organization ID must follow AWS format (e.g., o-abc123def4)
- Role ARN must belong to the StackSet deployment for Organizations flow - Role ARN must belong to the StackSet deployment for Organizations flow
@@ -970,7 +970,7 @@
- Remove any existing provider with the same Customer ID before starting the test - Remove any existing provider with the same Customer ID before starting the test
- This test must be run serially and never in parallel with other tests, as it requires the Customer ID not to be already registered beforehand. - This test must be run serially and never in parallel with other tests, as it requires the Customer ID not to be already registered beforehand.
### Flow Steps: ### Flow Steps
1. Navigate to providers page 1. Navigate to providers page
2. Click "Add Provider" button 2. Click "Add Provider" button
@@ -982,14 +982,14 @@
8. Verify redirect to Scans page 8. Verify redirect to Scans page
9. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan") 9. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan")
### Expected Result: ### Expected Result
- Google Workspace provider successfully added with Service Account credentials - Google Workspace provider successfully added with Service Account credentials
- Initial scan launched successfully - Initial scan launched successfully
- User redirected to Scans page - User redirected to Scans page
- Scheduled scan appears in Scans table with correct provider and scan name - Scheduled scan appears in Scans table with correct provider and scan name
### Key verification points: ### Key verification points
- Provider page loads correctly - Provider page loads correctly
- Connect account page displays Google Workspace option - Connect account page displays Google Workspace option
@@ -1003,7 +1003,7 @@
- Provider exists in Scans table (verified by customer ID) - Provider exists in Scans table (verified by customer ID)
- Scan name field contains "scheduled scan" - Scan name field contains "scheduled scan"
### Notes: ### Notes
- Test uses environment variables for Google Workspace credentials - Test uses environment variables for Google Workspace credentials
- Service Account JSON is provided as multi-line JSON string (not base64 encoded) - Service Account JSON is provided as multi-line JSON string (not base64 encoded)
+4 -4
View File
@@ -23,7 +23,7 @@
- Remove any existing AWS provider with the same Account ID before starting the test - Remove any existing AWS provider with the same Account ID before starting the test
- This test must be run serially and never in parallel with other tests, as it requires the Account ID Provider to be already registered. - This test must be run serially and never in parallel with other tests, as it requires the Account ID Provider to be already registered.
### Flow Steps: ### Flow Steps
1. Navigate to Scans page 1. Navigate to Scans page
2. Open provider selector and choose the entry whose text contains E2E_AWS_PROVIDER_ACCOUNT_ID 2. Open provider selector and choose the entry whose text contains E2E_AWS_PROVIDER_ACCOUNT_ID
@@ -32,13 +32,13 @@
5. Verify the success toast appears 5. Verify the success toast appears
6. Verify a row in the Scans table contains the provided scan label (or shows the new scan entry) 6. Verify a row in the Scans table contains the provided scan label (or shows the new scan entry)
### Expected Result: ### Expected Result
- Scan is launched successfully - Scan is launched successfully
- Success toast is displayed to the user - Success toast is displayed to the user
- Scans table displays the new scan entry (including the alias when provided) - Scans table displays the new scan entry (including the alias when provided)
### Key verification points: ### Key verification points
- Scans page loads correctly - Scans page loads correctly
- Provider select is available and lists the configured provider UID - Provider select is available and lists the configured provider UID
@@ -46,7 +46,7 @@
- Success toast message: "The scan was launched successfully." - Success toast message: "The scan was launched successfully."
- Table contains a row with the scan label or new scan state (queued/available/executing) - Table contains a row with the scan label or new scan state (queued/available/executing)
### Notes: ### Notes
- The table may take a short time to reflect the new scan; assertions look for a row containing the alias. - The table may take a short time to reflect the new scan; assertions look for a row containing the alias.
- Provider cleanup performed before each test to ensure clean state - Provider cleanup performed before each test to ensure clean state
+36 -36
View File
@@ -20,7 +20,7 @@
- Application is running. - Application is running.
### Flow Steps: ### Flow Steps
1. Navigate to the Sign in page. 1. Navigate to the Sign in page.
2. Verify page is loaded. 2. Verify page is loaded.
@@ -28,7 +28,7 @@
4. Verify social buttons (Google, GitHub). 4. Verify social buttons (Google, GitHub).
5. Verify navigation links. 5. Verify navigation links.
### Expected Result: ### Expected Result
- All form elements are visible and properly labeled. - All form elements are visible and properly labeled.
@@ -50,14 +50,14 @@
- Application is running. - Application is running.
- Valid test user credentials are configured via `ADMIN_USER` and `ADMIN_PASSWORD` environment variables. - Valid test user credentials are configured via `ADMIN_USER` and `ADMIN_PASSWORD` environment variables.
### Flow Steps: ### Flow Steps
1. Navigate to the Sign in page. 1. Navigate to the Sign in page.
2. Enter valid email and password. 2. Enter valid email and password.
3. Click the login button. 3. Click the login button.
4. Verify successful redirect to home page. 4. Verify successful redirect to home page.
### Expected Result: ### Expected Result
- User is authenticated and redirected to the home page. - User is authenticated and redirected to the home page.
@@ -78,14 +78,14 @@
- Application is running. - Application is running.
### Flow Steps: ### Flow Steps
1. Navigate to the Sign in page. 1. Navigate to the Sign in page.
2. Enter invalid email and password. 2. Enter invalid email and password.
3. Click the login button. 3. Click the login button.
4. Verify error message is displayed. 4. Verify error message is displayed.
### Expected Result: ### Expected Result
- Error message "Invalid email or password" is displayed. - Error message "Invalid email or password" is displayed.
- User remains on the sign-in page. - User remains on the sign-in page.
@@ -107,13 +107,13 @@
- Application is running. - Application is running.
### Flow Steps: ### Flow Steps
1. Navigate to the Sign in page. 1. Navigate to the Sign in page.
2. Click the login button without filling any fields. 2. Click the login button without filling any fields.
3. Verify validation errors are displayed. 3. Verify validation errors are displayed.
### Expected Result: ### Expected Result
- Form validation errors are shown. - Form validation errors are shown.
- User remains on the sign-in page. - User remains on the sign-in page.
@@ -135,14 +135,14 @@
- Application is running. - Application is running.
### Flow Steps: ### Flow Steps
1. Navigate to the Sign in page. 1. Navigate to the Sign in page.
2. Enter an invalid email format. 2. Enter an invalid email format.
3. Submit the form. 3. Submit the form.
4. Verify validation error is displayed. 4. Verify validation error is displayed.
### Expected Result: ### Expected Result
- Email format validation error is shown. - Email format validation error is shown.
@@ -163,14 +163,14 @@
- Application is running. - Application is running.
### Flow Steps: ### Flow Steps
1. Navigate to the Sign in page. 1. Navigate to the Sign in page.
2. Fill only the email field. 2. Fill only the email field.
3. Submit the form. 3. Submit the form.
4. Verify password required error is displayed. 4. Verify password required error is displayed.
### Expected Result: ### Expected Result
- "Password is required" error is shown. - "Password is required" error is shown.
@@ -191,7 +191,7 @@
- Application is running. - Application is running.
### Flow Steps: ### Flow Steps
1. Navigate to the Sign in page. 1. Navigate to the Sign in page.
2. Click "Continue with SAML SSO" button. 2. Click "Continue with SAML SSO" button.
@@ -199,7 +199,7 @@
4. Click back button. 4. Click back button.
5. Verify normal mode is restored. 5. Verify normal mode is restored.
### Expected Result: ### Expected Result
- SAML mode toggles correctly. - SAML mode toggles correctly.
- Password field visibility changes accordingly. - Password field visibility changes accordingly.
@@ -221,14 +221,14 @@
- Application is running. - Application is running.
### Flow Steps: ### Flow Steps
1. Navigate to the Sign in page. 1. Navigate to the Sign in page.
2. Fill valid credentials. 2. Fill valid credentials.
3. Submit the form. 3. Submit the form.
4. Verify loading state on button. 4. Verify loading state on button.
### Expected Result: ### Expected Result
- Login button shows loading state (disabled with aria-disabled). - Login button shows loading state (disabled with aria-disabled).
@@ -249,14 +249,14 @@
- Application is running. - Application is running.
### Flow Steps: ### Flow Steps
1. Navigate to the Sign in page. 1. Navigate to the Sign in page.
2. Toggle SAML mode. 2. Toggle SAML mode.
3. Enter SAML email. 3. Enter SAML email.
4. Submit the form. 4. Submit the form.
### Expected Result: ### Expected Result
- SAML flow is initiated (would redirect to IdP in real scenario). - SAML flow is initiated (would redirect to IdP in real scenario).
@@ -278,14 +278,14 @@
- Application is running. - Application is running.
- Valid test user credentials. - Valid test user credentials.
### Flow Steps: ### Flow Steps
1. Log in with valid credentials. 1. Log in with valid credentials.
2. Verify successful login. 2. Verify successful login.
3. Refresh the page. 3. Refresh the page.
4. Verify user is still logged in. 4. Verify user is still logged in.
### Expected Result: ### Expected Result
- Session persists after refresh. - Session persists after refresh.
- User remains on the authenticated page. - User remains on the authenticated page.
@@ -308,12 +308,12 @@
- Application is running. - Application is running.
- No active session. - No active session.
### Flow Steps: ### Flow Steps
1. Navigate directly to a protected route (e.g., /providers). 1. Navigate directly to a protected route (e.g., /providers).
2. Verify redirect to sign-in page. 2. Verify redirect to sign-in page.
### Expected Result: ### Expected Result
- User is redirected to /sign-in. - User is redirected to /sign-in.
@@ -335,7 +335,7 @@
- Application is running. - Application is running.
- User is logged in. - User is logged in.
### Flow Steps: ### Flow Steps
1. Log in with valid credentials. 1. Log in with valid credentials.
2. Click logout/sign out. 2. Click logout/sign out.
@@ -343,7 +343,7 @@
4. Attempt to access protected route. 4. Attempt to access protected route.
5. Verify redirect to sign-in. 5. Verify redirect to sign-in.
### Expected Result: ### Expected Result
- User is logged out. - User is logged out.
- Session is invalidated. - Session is invalidated.
@@ -366,7 +366,7 @@
- Application is running. - Application is running.
### Flow Steps: ### Flow Steps
1. Create authenticated context and log in. 1. Create authenticated context and log in.
2. Verify session exists. 2. Verify session exists.
@@ -374,7 +374,7 @@
4. Verify new context has no session. 4. Verify new context has no session.
5. Verify new context is redirected to sign-in. 5. Verify new context is redirected to sign-in.
### Expected Result: ### Expected Result
- Sessions are isolated between contexts. - Sessions are isolated between contexts.
- Unauthenticated context cannot access protected routes. - Unauthenticated context cannot access protected routes.
@@ -396,13 +396,13 @@
- Application is running. - Application is running.
### Flow Steps: ### Flow Steps
1. Navigate to the Sign in page. 1. Navigate to the Sign in page.
2. Click the "Sign up" link. 2. Click the "Sign up" link.
3. Verify redirect to sign-up page. 3. Verify redirect to sign-up page.
### Expected Result: ### Expected Result
- User is navigated to /sign-up. - User is navigated to /sign-up.
@@ -423,13 +423,13 @@
- Application is running. - Application is running.
### Flow Steps: ### Flow Steps
1. Navigate to the Sign up page. 1. Navigate to the Sign up page.
2. Click the login link. 2. Click the login link.
3. Verify redirect to sign-in page. 3. Verify redirect to sign-in page.
### Expected Result: ### Expected Result
- User is navigated to /sign-in. - User is navigated to /sign-in.
@@ -450,14 +450,14 @@
- Application is running. - Application is running.
### Flow Steps: ### Flow Steps
1. Navigate to the Sign in page. 1. Navigate to the Sign in page.
2. Navigate to the Sign up page. 2. Navigate to the Sign up page.
3. Click browser back button. 3. Click browser back button.
4. Verify return to sign-in page. 4. Verify return to sign-in page.
### Expected Result: ### Expected Result
- Browser history navigation works correctly. - Browser history navigation works correctly.
@@ -478,13 +478,13 @@
- Application is running. - Application is running.
### Flow Steps: ### Flow Steps
1. Navigate to the Sign in page. 1. Navigate to the Sign in page.
2. Use Tab key to navigate through form elements. 2. Use Tab key to navigate through form elements.
3. Verify focus moves correctly through elements. 3. Verify focus moves correctly through elements.
### Expected Result: ### Expected Result
- All interactive elements are reachable via keyboard. - All interactive elements are reachable via keyboard.
- Focus order is logical. - Focus order is logical.
@@ -506,12 +506,12 @@
- Application is running. - Application is running.
### Flow Steps: ### Flow Steps
1. Navigate to the Sign in page. 1. Navigate to the Sign in page.
2. Verify ARIA labels on form elements. 2. Verify ARIA labels on form elements.
### Expected Result: ### Expected Result
- Email input has proper label. - Email input has proper label.
- Password input has proper label. - Password input has proper label.
+4 -4
View File
@@ -22,7 +22,7 @@
- No existing data in Prowler is required; the test can run on a clean state. - No existing data in Prowler is required; the test can run on a clean state.
- `E2E_NEW_USER_PASSWORD` environment variable must be set with a valid password for the test. - `E2E_NEW_USER_PASSWORD` environment variable must be set with a valid password for the test.
### Flow Steps: ### Flow Steps
1. Navigate to the Sign up page. 1. Navigate to the Sign up page.
2. Fill the form with valid data (unique email, valid password, terms accepted). 2. Fill the form with valid data (unique email, valid password, terms accepted).
@@ -30,18 +30,18 @@
4. Verify redirect to the Login page. 4. Verify redirect to the Login page.
5. Log in with the newly created credentials. 5. Log in with the newly created credentials.
### Expected Result: ### Expected Result
- Sign-up succeeds and redirects to Login. - Sign-up succeeds and redirects to Login.
- User can log in successfully using the created credentials and reach the home page. - User can log in successfully using the created credentials and reach the home page.
### Key verification points: ### Key verification points
- After submitting sign-up, the URL changes to `/sign-in`. - After submitting sign-up, the URL changes to `/sign-in`.
- The newly created credentials can be used to sign in successfully. - The newly created credentials can be used to sign in successfully.
- After login, the user lands on the home (`/`) and main content is visible. - After login, the user lands on the home (`/`) and main content is visible.
### Notes: ### Notes
- Test data uses a random base36 suffix to avoid collisions with email. - Test data uses a random base36 suffix to avoid collisions with email.
- The test requires the `E2E_NEW_USER_PASSWORD` environment variable to be set before running. - The test requires the `E2E_NEW_USER_PASSWORD` environment variable to be set before running.
+5 -5
View File
@@ -429,7 +429,7 @@ This is useful for:
### Example Output ### Example Output
``` ```text
[1] ✅ Created provider (id=db9a8985-f9ec-4dd8-b5a0-e05ab3880bed) [1] ✅ Created provider (id=db9a8985-f9ec-4dd8-b5a0-e05ab3880bed)
[1] ✅ Created secret (id=466f76c6-5878-4602-a4bc-13f9522c1fd2) [1] ✅ Created secret (id=466f76c6-5878-4602-a4bc-13f9522c1fd2)
[1] ✅ Connection test: Connected [1] ✅ Connection test: Connected
@@ -454,25 +454,25 @@ python prowler_bulk_provisioning.py providers.yaml --dry-run
### Common Issues ### Common Issues
1. **Invalid API Key** 1. **Invalid API Key**
``` ```text
Error: 401 Unauthorized Error: 401 Unauthorized
Solution: Check your PROWLER_API_KEY environment variable or --api-key parameter Solution: Check your PROWLER_API_KEY environment variable or --api-key parameter
``` ```
2. **Network Timeouts** 2. **Network Timeouts**
``` ```text
Error: Request timeout Error: Request timeout
Solution: Increase --timeout value or check network connectivity Solution: Increase --timeout value or check network connectivity
``` ```
3. **Invalid Provider Configuration** 3. **Invalid Provider Configuration**
``` ```text
Error: Each item must include 'provider' and 'uid' Error: Each item must include 'provider' and 'uid'
Solution: Verify all required fields are present in your config file Solution: Verify all required fields are present in your config file
``` ```
4. **File Not Found Errors** 4. **File Not Found Errors**
``` ```text
Error: No such file or directory Error: No such file or directory
Solution: Check file paths for credentials files (JSON keys, kubeconfig, etc.) Solution: Check file paths for credentials files (JSON keys, kubeconfig, etc.)
``` ```