diff --git a/.dryrunsecurity.yaml b/.dryrunsecurity.yaml index 1863e9a2027..8f9478eaf85 100644 --- a/.dryrunsecurity.yaml +++ b/.dryrunsecurity.yaml @@ -14,7 +14,8 @@ sensitiveCodepaths: - 'dojo/group/*.py' - 'dojo/importers/*.py' - 'dojo/importers/**/*.py' - - 'dojo/jira_link/*.py' + - 'dojo/jira/*.py' + - 'dojo/jira/**/*.py' - 'dojo/metrics/*.py' - 'dojo/note_type/*.py' - 'dojo/notes/*.py' @@ -40,8 +41,8 @@ sensitiveCodepaths: - 'dojo/middleware.py' - 'dojo/models.py' - 'dojo/okta.py' - - 'dojo/pipeline.py' - - 'dojo/remote_user.py' + - 'dojo/sso/pipeline.py' + - 'dojo/sso/remote_user.py' - 'dojo/tasks.py' - 'dojo/urls.py' - 'dojo/utils.py' diff --git a/.github/workflows/build-docker-images-for-testing.yml b/.github/workflows/build-docker-images-for-testing.yml index e9e6dba295e..9f81a64f830 100644 --- a/.github/workflows/build-docker-images-for-testing.yml +++ b/.github/workflows/build-docker-images-for-testing.yml @@ -53,7 +53,7 @@ jobs: - name: Build id: docker_build - uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0 + uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0 timeout-minutes: 15 env: DOCKER_BUILD_CHECKS_ANNOTATIONS: false @@ -67,7 +67,7 @@ jobs: # export docker images to be used in next jobs below - name: Upload image ${{ matrix.docker-image }} as artifact timeout-minutes: 15 - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: built-docker-image-${{ matrix.docker-image }}-${{ matrix.os }}-${{ env.PLATFORM }} path: ${{ matrix.docker-image }}-${{ matrix.os }}-${{ env.PLATFORM }}_img diff --git a/.github/workflows/fetch-oas.yml b/.github/workflows/fetch-oas.yml index 153c540bb84..7873716642e 100644 --- a/.github/workflows/fetch-oas.yml +++ b/.github/workflows/fetch-oas.yml @@ -55,7 +55,7 @@ jobs: run: docker compose down - name: Upload oas.${{ matrix.file-type }} as artifact - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: oas-${{ matrix.file-type }} path: oas.${{ matrix.file-type }} diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 3585388d680..0cd8d649bcd 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -22,12 +22,12 @@ jobs: extended: true - name: Setup Node - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: - node-version: '24.14.1' # TODO: Renovate helper might not be needed here - needs to be fully tested + node-version: '24.15.0' # TODO: Renovate helper might not be needed here - needs to be fully tested - name: Cache dependencies - uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 3300c1cb0bb..f0d466264d0 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -22,7 +22,6 @@ jobs: "tests/check_various_pages.py", "tests/close_old_findings_dedupe_test.py", "tests/close_old_findings_test.py", - "tests/credential_test.py", "tests/dashboard_test.py", "tests/dedupe_test.py", "tests/endpoint_extended_test.py", @@ -46,7 +45,6 @@ jobs: "tests/notification_webhook_test.py", "tests/notifications_test.py", "tests/object_test.py", - "tests/product_credential_test.py", "tests/product_group_test.py", "tests/product_member_test.py", "tests/product_metadata_test.py", diff --git a/.github/workflows/k8s-tests.yml b/.github/workflows/k8s-tests.yml index 89efe5c95ab..c4191d6f338 100644 --- a/.github/workflows/k8s-tests.yml +++ b/.github/workflows/k8s-tests.yml @@ -16,9 +16,9 @@ jobs: # databases, broker and k8s are independent, so we don't need to test each combination # lastest k8s version (https://kubernetes.io/releases/) and the oldest officially supported version # are tested (https://kubernetes.io/releases/) - - k8s: 'v1.35.3' # renovate: datasource=github-releases depName=kubernetes/kubernetes versioning=loose + - k8s: 'v1.35.4' # renovate: datasource=github-releases depName=kubernetes/kubernetes versioning=loose os: debian - - k8s: '1.33.10' # renovate: datasource=custom.endoflife-oldest-maintained depName=kubernetes + - k8s: '1.33.11' # renovate: datasource=custom.endoflife-oldest-maintained depName=kubernetes os: debian steps: - name: Checkout diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml index 824e7c14f44..264540f35f7 100644 --- a/.github/workflows/pr-labeler.yml +++ b/.github/workflows/pr-labeler.yml @@ -15,7 +15,7 @@ jobs: name: "Autolabeler" runs-on: ubuntu-latest steps: - - uses: actions/labeler@634933edcd8ababfe52f92936142cc22ac488b1b # v6.0.1 + - uses: actions/labeler@f27b608878404679385c85cfa523b85ccb86e213 # v6.1.0 with: repo-token: "${{ secrets.GITHUB_TOKEN }}" sync-labels: true diff --git a/.github/workflows/release-1-create-pr.yml b/.github/workflows/release-1-create-pr.yml index 33aaafecb26..14747b46cdf 100644 --- a/.github/workflows/release-1-create-pr.yml +++ b/.github/workflows/release-1-create-pr.yml @@ -93,7 +93,7 @@ jobs: grep -H version helm/defectdojo/Chart.yaml - name: Run helm-docs - uses: losisin/helm-docs-github-action@2ccf3e77eb70dc80d62f8cc26f15d0a96b75fef4 # v1.8.0 + uses: losisin/helm-docs-github-action@3a4528e97c49a5e83de6b78c50c61c8ee5c9f944 # v2 with: chart-search-root: "helm/defectdojo" @@ -107,11 +107,11 @@ jobs: branch: ${{ env.NEW_BRANCH }} - name: Create Pull Request - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - github.rest.pulls.create({ + const pr = await github.rest.pulls.create({ owner: '${{ env.GITHUB_ORG }}', repo: 'django-DefectDojo', title: 'Release: Merge release into master from: ${{ env.NEW_BRANCH }}', @@ -119,3 +119,9 @@ jobs: head: '${{ env.NEW_BRANCH }}', base: 'master' }) + await github.rest.issues.addLabels({ + owner: '${{ env.GITHUB_ORG }}', + repo: 'django-DefectDojo', + issue_number: pr.data.number, + labels: ['release-management'] + }) diff --git a/.github/workflows/release-3-master-into-dev.yml b/.github/workflows/release-3-master-into-dev.yml index f8e2c75682d..8ebdd193247 100644 --- a/.github/workflows/release-3-master-into-dev.yml +++ b/.github/workflows/release-3-master-into-dev.yml @@ -81,7 +81,7 @@ jobs: yq -i '.annotations."artifacthub.io/changes" = ""' helm/defectdojo/Chart.yaml - name: Run helm-docs - uses: losisin/helm-docs-github-action@2ccf3e77eb70dc80d62f8cc26f15d0a96b75fef4 # v1.8.0 + uses: losisin/helm-docs-github-action@3a4528e97c49a5e83de6b78c50c61c8ee5c9f944 # v2 with: chart-search-root: "helm/defectdojo" @@ -95,11 +95,11 @@ jobs: branch: ${{ env.NEW_BRANCH }} - name: Create Pull Request - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - github.rest.pulls.create({ + const pr = await github.rest.pulls.create({ owner: '${{ env.GITHUB_ORG }}', repo: 'django-DefectDojo', title: 'Release: Merge back ${{ inputs.release_number_new }} into dev from: ${{ env.NEW_BRANCH }}', @@ -107,6 +107,12 @@ jobs: head: '${{ env.NEW_BRANCH }}', base: 'dev' }) + await github.rest.issues.addLabels({ + owner: '${{ env.GITHUB_ORG }}', + repo: 'django-DefectDojo', + issue_number: pr.data.number, + labels: ['release-management'] + }) create_pr_for_merge_back_into_bugfix: runs-on: ubuntu-latest @@ -157,7 +163,7 @@ jobs: yq -i '.annotations."artifacthub.io/changes" = ""' helm/defectdojo/Chart.yaml - name: Run helm-docs - uses: losisin/helm-docs-github-action@2ccf3e77eb70dc80d62f8cc26f15d0a96b75fef4 # v1.8.0 + uses: losisin/helm-docs-github-action@3a4528e97c49a5e83de6b78c50c61c8ee5c9f944 # v2 with: chart-search-root: "helm/defectdojo" @@ -171,11 +177,11 @@ jobs: branch: ${{ env.NEW_BRANCH }} - name: Create Pull Request - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - github.rest.pulls.create({ + const pr = await github.rest.pulls.create({ owner: '${{ env.GITHUB_ORG }}', repo: 'django-DefectDojo', title: 'Release: Merge back ${{ inputs.release_number_new }} into bugfix from: ${{ env.NEW_BRANCH }}', @@ -183,3 +189,9 @@ jobs: head: '${{ env.NEW_BRANCH }}', base: 'bugfix' }) + await github.rest.issues.addLabels({ + owner: '${{ env.GITHUB_ORG }}', + repo: 'django-DefectDojo', + issue_number: pr.data.number, + labels: ['release-management'] + }) diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index c91df094fa5..aa349970286 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -27,7 +27,7 @@ jobs: steps: - name: Create Release id: create_release - uses: release-drafter/release-drafter@139054aeaa9adc52ab36ddf67437541f039b88e2 # v7.1.1 + uses: release-drafter/release-drafter@563bf132657a13ded0b01fcb723c5a58cdd824e2 # v7.2.1 with: version: ${{ inputs.version }} env: diff --git a/.github/workflows/release-x-manual-docker-containers.yml b/.github/workflows/release-x-manual-docker-containers.yml index f4897248757..14f0b259584 100644 --- a/.github/workflows/release-x-manual-docker-containers.yml +++ b/.github/workflows/release-x-manual-docker-containers.yml @@ -69,7 +69,7 @@ jobs: # we cannot set any tags here, those are set on the merged digest in release-x-manual-merge-container-digests.yml - name: Build and push images id: build - uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0 + uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0 env: DOCKER_BUILD_CHECKS_ANNOTATIONS: false with: @@ -90,7 +90,7 @@ jobs: # upload the digest file as artifact - name: Upload digest - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: digests-${{ matrix.docker-image}}-${{ matrix.os }}-${{ env.PLATFORM }} path: ${{ runner.temp }}/digests/* diff --git a/.github/workflows/release-x-manual-helm-chart.yml b/.github/workflows/release-x-manual-helm-chart.yml index c7c86c3907c..85052bd8a58 100644 --- a/.github/workflows/release-x-manual-helm-chart.yml +++ b/.github/workflows/release-x-manual-helm-chart.yml @@ -77,7 +77,7 @@ jobs: echo "chart_version=$(ls build | cut -d '-' -f 2,3 | sed 's|\.tgz||')" >> $GITHUB_ENV - name: Create release ${{ inputs.release_number }} - uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2.6.1 + uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0 with: name: '${{ inputs.release_number }} 🌈' tag_name: ${{ inputs.release_number }} diff --git a/.github/workflows/renovate.yaml b/.github/workflows/renovate.yaml index 6c69725340d..12334d34d2c 100644 --- a/.github/workflows/renovate.yaml +++ b/.github/workflows/renovate.yaml @@ -21,4 +21,4 @@ jobs: uses: suzuki-shunsuke/github-action-renovate-config-validator@ee9f69e1f683ed0d08225086482b34fc9abe9300 # v2.1.0 with: strict: "true" - validator_version: 43.110.14 # renovate: datasource=github-releases depName=renovatebot/renovate + validator_version: 43.141.6 # renovate: datasource=github-releases depName=renovatebot/renovate diff --git a/.github/workflows/test-helm-chart.yml b/.github/workflows/test-helm-chart.yml index 833c85fd777..c50866c303b 100644 --- a/.github/workflows/test-helm-chart.yml +++ b/.github/workflows/test-helm-chart.yml @@ -129,14 +129,14 @@ jobs: git commit -m "ci: update Chart annotations from PR #${{ github.event.pull_request.number }}" || echo "No changes to commit" - name: Run helm-docs (update) - uses: losisin/helm-docs-github-action@2ccf3e77eb70dc80d62f8cc26f15d0a96b75fef4 # v1.8.0 + uses: losisin/helm-docs-github-action@3a4528e97c49a5e83de6b78c50c61c8ee5c9f944 # v2 if: startsWith(github.head_ref, 'renovate/') || startsWith(github.head_ref, 'dependabot/') with: chart-search-root: "helm/defectdojo" git-push: true - name: Run helm-docs (check) - uses: losisin/helm-docs-github-action@2ccf3e77eb70dc80d62f8cc26f15d0a96b75fef4 # v1.8.0 + uses: losisin/helm-docs-github-action@3a4528e97c49a5e83de6b78c50c61c8ee5c9f944 # v2 if: ${{ !(startsWith(github.head_ref, 'renovate/') || startsWith(github.head_ref, 'dependabot/')) }} with: fail-on-diff: true @@ -155,7 +155,7 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Generate values schema json - uses: losisin/helm-values-schema-json-action@02bda41b469ccfb3f0abb35f4211e598b0b6ea3e # v2.5.0 + uses: losisin/helm-values-schema-json-action@39cdf80504f6c95ad3c4f317e2135e2509ea56bb # v3 with: fail-on-diff: true working-directory: "helm/defectdojo" diff --git a/.github/workflows/update-sample-data.yml b/.github/workflows/update-sample-data.yml index 525e892b605..c6f2027a26d 100644 --- a/.github/workflows/update-sample-data.yml +++ b/.github/workflows/update-sample-data.yml @@ -33,7 +33,7 @@ jobs: git config --global user.email "${{ env.GIT_EMAIL }}" - name: Create Pull Request - uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0 + uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1 with: token: ${{ secrets.GITHUB_TOKEN }} commit-message: "Update sample data" diff --git a/.github/workflows/validate_docs_build.yml b/.github/workflows/validate_docs_build.yml index ca6d54e6b27..a7ee3d90769 100644 --- a/.github/workflows/validate_docs_build.yml +++ b/.github/workflows/validate_docs_build.yml @@ -17,12 +17,12 @@ jobs: extended: true - name: Setup Node - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: - node-version: '24.14.1' # TODO: Renovate helper might not be needed here - needs to be fully tested + node-version: '24.15.0' # TODO: Renovate helper might not be needed here - needs to be fully tested - name: Cache dependencies - uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} diff --git a/.gitignore b/.gitignore index ad5fba05633..1cdf995c5f4 100644 --- a/.gitignore +++ b/.gitignore @@ -152,3 +152,4 @@ docs/.hugo_build.lock # claude etc MEMORY.md +.claude/ diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000000..64279977619 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,249 @@ +# DefectDojo Development Guide + +## Project Overview + +DefectDojo is a Django application (`dojo` app) for vulnerability management. The codebase is undergoing a modular reorganization to move from monolithic files toward self-contained domain modules. + +## Module Reorganization + +### Reference Pattern: `dojo/url/` + +All domain modules should match the structure of `dojo/url/`. This is the canonical example of a fully reorganized module. + +``` +dojo/{module}/ +├── __init__.py # import dojo.{module}.admin # noqa: F401 +├── models.py # Domain models, constants, factory methods +├── admin.py # @admin.register() for the module's models +├── services.py # Business logic (no HTTP concerns) +├── queries.py # Complex DB aggregations/annotations +├── signals.py # Django signal handlers +├── [manager.py] # Custom QuerySet/Manager if needed +├── [validators.py] # Field-level validators if needed +├── [helpers.py] # Async task wrappers, tag propagation, etc. +├── ui/ +│ ├── __init__.py # Empty +│ ├── forms.py # Django ModelForms +│ ├── filters.py # UI-layer django-filter classes +│ ├── views.py # Thin view functions — delegates to services.py +│ └── urls.py # URL routing +└── api/ + ├── __init__.py # path = "{module}" + ├── serializer.py # DRF serializers + ├── views.py # API ViewSets — delegates to services.py + ├── filters.py # API-layer filters + └── urls.py # add_{module}_urls(router) registration +``` + +### Architecture Principles + + +**services.py is the critical layer**: Both `ui/views.py` and `api/views.py` call `services.py` for business logic. Services accept domain objects and primitives — never request/response objects, forms, or serializers. + +**Backward-compatible re-exports**: When moving code out of monolithic files (`dojo/models.py`, `dojo/forms.py`, `dojo/filters.py`, `dojo/api_v2/serializers.py`, `dojo/api_v2/views.py`), always leave a re-export at the original location: +```python +from dojo.{module}.models import {Model} # noqa: F401 -- backward compat +``` +Never remove re-exports until all consumers are updated in a dedicated cleanup pass. + +### Current State + +Modules in various stages of reorganization: + +| Module | models.py | services.py | ui/ | api/ | Status | +|--------|-----------|-------------|-----|------|--------| +| **url** | In module | N/A | Done | Done | **Complete** | +| **location** | In module | N/A | N/A | Done | **Complete** | +| **product_type** | In dojo/models.py | Missing | Partial (views at root) | In dojo/api_v2/ | Needs work | +| **test** | In dojo/models.py | Missing | Partial (views at root) | In dojo/api_v2/ | Needs work | +| **engagement** | In dojo/models.py | Partial (32 lines) | Partial (views at root) | In dojo/api_v2/ | Needs work | +| **product** | In dojo/models.py | Missing | Partial (views at root) | In dojo/api_v2/ | Needs work | +| **finding** | In dojo/models.py | Missing | Partial (views at root) | In dojo/api_v2/ | Needs work | + +### Monolithic Files Being Decomposed + +These files still contain code for multiple modules. Extract code to the target module's subdirectory and leave a re-export stub. + +- `dojo/models.py` (4,973 lines) — All model definitions +- `dojo/forms.py` (4,127 lines) — All Django forms +- `dojo/filters.py` (4,016 lines) — All UI and API filter classes +- `dojo/api_v2/serializers.py` (3,387 lines) — All DRF serializers +- `dojo/api_v2/views.py` (3,519 lines) — All API viewsets + +--- + +## Reorganization Playbook + +When asked to reorganize a module, follow these phases in order. Each phase should be independently verifiable. + +### Phase 0: Pre-Flight (Read-Only) + +Before any changes, identify all code to extract: + +```bash +# 1. Model classes and line ranges in dojo/models.py +grep -n "class {Model}" dojo/models.py + +# 2. Form classes in dojo/forms.py +grep -n "class.*{Module}" dojo/forms.py +grep -n "model = {Model}" dojo/forms.py + +# 3. Filter classes in dojo/filters.py +grep -n "class.*{Module}\|class.*{Model}" dojo/filters.py + +# 4. Serializer classes +grep -n "class.*{Model}" dojo/api_v2/serializers.py + +# 5. ViewSet classes +grep -n "class.*{Model}\|class.*{Module}" dojo/api_v2/views.py + +# 6. Admin registrations +grep -n "admin.site.register({Model}" dojo/models.py + +# 7. All import sites (to verify backward compat) +grep -rn "from dojo.models import.*{Model}" dojo/ unittests/ + +# 8. Business logic in current views +# Scan dojo/{module}/views.py for: .save(), .delete(), create_notification(), +# jira_helper.*, dojo_dispatch_task(), multi-model workflows +``` + +### Phase 1: Extract Models + +1. Create `dojo/{module}/models.py` with the model class(es) and associated constants +2. Create `dojo/{module}/admin.py` with `admin.site.register()` calls (remove from `dojo/models.py`) +3. Update `dojo/{module}/__init__.py` to `import dojo.{module}.admin # noqa: F401` +4. Add re-exports in `dojo/models.py` +5. Remove original model code (keep re-export line) + +**Import rules for models.py:** +- Upward FKs (e.g., Test -> Engagement): import from `dojo.models` if not yet extracted, or `dojo.{module}.models` if already extracted +- Downward references (e.g., Product_Type querying Finding): use lazy imports inside method bodies +- Shared utilities (`copy_model_util`, `_manage_inherited_tags`, `get_current_date`, etc.): import from `dojo.models` +- Do NOT set `app_label` in Meta — all models inherit `dojo` app_label automatically + +**Verify:** +```bash +python manage.py check +python manage.py makemigrations --check +python -c "from dojo.{module}.models import {Model}" +python -c "from dojo.models import {Model}" +``` + +### Phase 2: Extract Services + +Create `dojo/{module}/services.py` with business logic extracted from UI views. + +**What belongs in services.py:** +- State transitions (close, reopen, status changes) +- Multi-step creation/update workflows +- External integration calls (JIRA, GitHub) +- Notification dispatching +- Copy/clone operations +- Bulk operations +- Merge operations + +**What stays in views:** +- HTTP request/response handling +- Form instantiation and validation +- Serialization/deserialization +- Authorization checks (`@user_is_authorized`, `user_has_permission_or_403`) +- Template rendering, redirects +- Pagination, breadcrumbs + +**Service function pattern:** +```python +def close_engagement(engagement: Engagement, user: User) -> Engagement: + engagement.active = False + engagement.status = "Completed" + engagement.save() + if jira_helper.get_jira_project(engagement): + dojo_dispatch_task(jira_helper.close_epic, engagement.id, push_to_jira=True) + return engagement +``` + +Update UI views and API viewsets to call the service instead of containing logic inline. + +### Phase 3: Extract Forms to `ui/forms.py` + +1. Create `dojo/{module}/ui/__init__.py` (empty) +2. Create `dojo/{module}/ui/forms.py` — move form classes from `dojo/forms.py` +3. Add re-exports in `dojo/forms.py` + +### Phase 4: Extract UI Filters to `ui/filters.py` + +1. Create `dojo/{module}/ui/filters.py` — move module-specific filters from `dojo/filters.py` +2. Shared base classes (`DojoFilter`, `DateRangeFilter`, `ReportBooleanFilter`) stay in `dojo/filters.py` +3. Add re-exports in `dojo/filters.py` + +### Phase 5: Move UI Views/URLs into `ui/` + +1. Move `dojo/{module}/views.py` -> `dojo/{module}/ui/views.py` +2. Move `dojo/{module}/urls.py` -> `dojo/{module}/ui/urls.py` +3. Update URL imports: + - product: update `dojo/asset/urls.py` + - product_type: update `dojo/organization/urls.py` + - others: update the include in `dojo/urls.py` + +### Phase 6: Extract API Serializers to `api/serializer.py` + +1. Create `dojo/{module}/api/__init__.py` with `path = "{module}"` +2. Create `dojo/{module}/api/serializer.py` — move from `dojo/api_v2/serializers.py` +3. Add re-exports in `dojo/api_v2/serializers.py` + +### Phase 7: Extract API Filters to `api/filters.py` + +1. Create `dojo/{module}/api/filters.py` — move `Api{Model}Filter` from `dojo/filters.py` +2. Add re-exports + +### Phase 8: Extract API ViewSets to `api/views.py` + +1. Create `dojo/{module}/api/views.py` — move from `dojo/api_v2/views.py` +2. Add re-exports in `dojo/api_v2/views.py` + +### Phase 9: Extract API URL Registration + +1. Create `dojo/{module}/api/urls.py`: + ```python + from dojo.{module}.api import path + from dojo.{module}.api.views import {ViewSet} + + def add_{module}_urls(router): + router.register(path, {ViewSet}, path) + return router + ``` +2. Update `dojo/urls.py` — replace `v2_api.register(...)` with `add_{module}_urls(v2_api)` + +### After Each Phase: Verify + +```bash +python manage.py check +python manage.py makemigrations --check +python -m pytest unittests/ -x --timeout=120 +``` + +--- + +## Cross-Module Dependencies + +The model hierarchy is: Product_Type -> Product -> Engagement -> Test -> Finding + +Extract in this order (top to bottom) so that upward FKs can import from already-extracted modules. The recommended order is: product_type, test, engagement, product, finding. + +For downward references (e.g., Product_Type's cached properties querying Finding), always use lazy imports: +```python +@cached_property +def critical_present(self): + from dojo.models import Finding # lazy import + return Finding.objects.filter(test__engagement__product__prod_type=self, severity="Critical").exists() +``` + +--- + +## Key Technical Details + +- **Single Django app**: Everything is under `app_label = "dojo"`. Moving models to subdirectories does NOT require migration changes. +- **Model discovery**: Triggered by `__init__.py` importing `admin.py`, which imports `models.py`. This is the same chain `dojo/url/` uses. +- **Signal registration**: Handled in `dojo/apps.py` via `import dojo.{module}.signals`. Already set up for test, engagement, product, product_type. +- **Watson search**: Uses `self.get_model("Product")` in `apps.py` — works via Django's model registry regardless of file location. +- **Admin registration**: Currently at the bottom of `dojo/models.py` (lines 4888-4973). Must be moved to `{module}/admin.py` and removed from `dojo/models.py` to avoid `AlreadyRegistered` errors. diff --git a/Dockerfile.django-alpine b/Dockerfile.django-alpine index a4ab7d00ea6..2ee92f81fdb 100644 --- a/Dockerfile.django-alpine +++ b/Dockerfile.django-alpine @@ -5,7 +5,7 @@ # Dockerfile.nginx to use the caching mechanism of Docker. # Ref: https://devguide.python.org/#branchstatus -FROM python:3.13.13-alpine3.22@sha256:ad3d69d8050bfec214b11221341ee6e88f4a2f2e82c08ab8e510e2df78487ffb AS base +FROM python:3.13.13-alpine3.22@sha256:e81548ac35b07a3bd4805f275107592ef458b1e893c0e04d45aedaa19416cca5 AS base FROM base AS build WORKDIR /app RUN \ diff --git a/Dockerfile.django-debian b/Dockerfile.django-debian index 1274c687712..8c67efd7b65 100644 --- a/Dockerfile.django-debian +++ b/Dockerfile.django-debian @@ -5,7 +5,7 @@ # Dockerfile.nginx to use the caching mechanism of Docker. # Ref: https://devguide.python.org/#branchstatus -FROM python:3.13.13-slim-trixie@sha256:f96eb0214ceab47efc2558b8351888ca01acf6193f4050ee7594c8250516cc8b AS base +FROM python:3.13.13-slim-trixie@sha256:d2462a6bed37b4fc6cabecf5a2132ae70df772fe03c7393c4d98a0c2fb48aa2e AS base FROM base AS build WORKDIR /app RUN \ diff --git a/Dockerfile.integration-tests-debian b/Dockerfile.integration-tests-debian index d288465122e..6732484886e 100644 --- a/Dockerfile.integration-tests-debian +++ b/Dockerfile.integration-tests-debian @@ -1,9 +1,9 @@ # code: language=Dockerfile -FROM openapitools/openapi-generator-cli:v7.21.0@sha256:ce308310f3c1f8761e65338b8ab87b651bf4862c6acb80de510f381fffc4510b AS openapitools +FROM openapitools/openapi-generator-cli:v7.22.0@sha256:1f459499a7c794aa0ea769c3c9b0eb54806c5ad2f68510a0ebb9338d0a626ced AS openapitools # currently only supports x64, no arm yet due to chrome and selenium dependencies -FROM python:3.13.13-slim-trixie@sha256:f96eb0214ceab47efc2558b8351888ca01acf6193f4050ee7594c8250516cc8b AS build +FROM python:3.13.13-slim-trixie@sha256:d2462a6bed37b4fc6cabecf5a2132ae70df772fe03c7393c4d98a0c2fb48aa2e AS build WORKDIR /app RUN \ apt-get -y update && \ diff --git a/Dockerfile.nginx-alpine b/Dockerfile.nginx-alpine index 48d0922635d..6df6efa8f82 100644 --- a/Dockerfile.nginx-alpine +++ b/Dockerfile.nginx-alpine @@ -5,7 +5,7 @@ # Dockerfile.django-alpine to use the caching mechanism of Docker. # Ref: https://devguide.python.org/#branchstatus -FROM python:3.13.13-alpine3.22@sha256:ad3d69d8050bfec214b11221341ee6e88f4a2f2e82c08ab8e510e2df78487ffb AS base +FROM python:3.13.13-alpine3.22@sha256:e81548ac35b07a3bd4805f275107592ef458b1e893c0e04d45aedaa19416cca5 AS base FROM base AS build WORKDIR /app RUN \ diff --git a/components/package.json b/components/package.json index 9abaf4184c6..57d14de8e23 100644 --- a/components/package.json +++ b/components/package.json @@ -1,6 +1,6 @@ { "name": "defectdojo", - "version": "2.58.0-dev", + "version": "2.59.0-dev", "license" : "BSD-3-Clause", "private": true, "dependencies": { @@ -12,12 +12,12 @@ "chosen-bootstrap": "https://github.com/dbtek/chosen-bootstrap", "chosen-js": "^1.8.7", "clipboard": "^2.0.11", - "datatables.net": "^2.3.7", + "datatables.net": "^2.3.8", "datatables.net-buttons-bs": "^3.2.6", "datatables.net-colreorder": "^2.1.2", "drmonty-datatables-plugins": "^1.0.0", "drmonty-datatables-responsive": "^1.0.0", - "easymde": "^2.20.0", + "easymde": "^2.21.0", "flot": "flot/flot#~0.8.3", "font-awesome": "^4.0.0", "fullcalendar": "^3.10.2", diff --git a/components/yarn.lock b/components/yarn.lock index 9224546730c..6791acee5b4 100644 --- a/components/yarn.lock +++ b/components/yarn.lock @@ -167,10 +167,10 @@ datatables.net@2.3.2: dependencies: jquery ">=1.7" -datatables.net@^2, datatables.net@^2.3.7: - version "2.3.7" - resolved "https://registry.yarnpkg.com/datatables.net/-/datatables.net-2.3.7.tgz#3cd34f6f5d1f40a46b5a20a4ba32604bdbcd6738" - integrity sha512-AvsjG/Nkp6OxeyBKYZauemuzQCPogE1kOtKwG4sYjvdqGCSLiGaJagQwXv4YxG+ts5vaJr6qKGG9ec3g6vTo3w== +datatables.net@^2, datatables.net@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/datatables.net/-/datatables.net-2.3.8.tgz#55a8dbe3bd2196951c498ab79bf44602a2bf3229" + integrity sha512-uhViowhlDlheAuo5a8TrkQqADsjrtGeOyvrigvr4t0+K3MyAWqClORXWAYIcN9VLX6iIX0C8O9gwJNd01hITRg== dependencies: jquery ">=1.7" @@ -198,10 +198,10 @@ drmonty-datatables-responsive@^1.0.0: dependencies: jquery ">=1.7.0" -easymde@^2.20.0: - version "2.20.0" - resolved "https://registry.yarnpkg.com/easymde/-/easymde-2.20.0.tgz#88b3161feab6e1900afa9c4dab3f1da352b0a26e" - integrity sha512-V1Z5f92TfR42Na852OWnIZMbM7zotWQYTddNaLYZFVKj7APBbyZ3FYJ27gBw2grMW3R6Qdv9J8n5Ij7XRSIgXQ== +easymde@^2.21.0: + version "2.21.0" + resolved "https://registry.yarnpkg.com/easymde/-/easymde-2.21.0.tgz#12e77962e27d401f9572296189bee21e0be086a8" + integrity sha512-5uE7I/DEN8gvGRwxaqAv7h1PMEK2ykNXVX5zL0dK3nCYROGja3AMbdQz8eCEELnfvCfy7tRkTmLuvyJG8uSWjQ== dependencies: "@types/codemirror" "^5.60.10" "@types/marked" "^4.0.7" diff --git a/docker-compose.override.dev.yml b/docker-compose.override.dev.yml index 409de9f5d69..6ee4738c26d 100644 --- a/docker-compose.override.dev.yml +++ b/docker-compose.override.dev.yml @@ -72,7 +72,7 @@ services: protocol: tcp mode: host "webhook.endpoint": - image: mccutchen/go-httpbin:2.21.0@sha256:809250d14e94397f4729f617931068a9ea048231fc1a11c9e3c7cb8c28bbab8d + image: mccutchen/go-httpbin:2.22.1@sha256:33aa5d2d563881a55f319cce4530de48ae518386ad742159f4390281a8277915 integration-tests: platform: "linux/amd64" profiles: diff --git a/docker-compose.yml b/docker-compose.yml index 5aaaa49e9aa..68d6e0905d0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -120,7 +120,7 @@ services: source: ./docker/extra_settings target: /app/docker/extra_settings postgres: - image: postgres:18.3-alpine@sha256:4da1a4828be12604092fa55311276f08f9224a74a62dcb4708bd7439e2a03911 + image: postgres:18.3-alpine@sha256:54451ecb8ab38c24c3ec123f2fd501303a3a1856a5c66e98cecf2460d5e1e9d7 environment: PGDATA: /var/lib/postgresql/data POSTGRES_DB: ${DD_DATABASE_NAME:-defectdojo} @@ -129,7 +129,7 @@ services: volumes: - defectdojo_postgres:/var/lib/postgresql/data valkey: - image: valkey/valkey:9.0.3-alpine@sha256:e1095c6c76ee982cb2d1e07edbb7fb2a53606630a1d810d5a47c9f646b708bf5 + image: valkey/valkey:9.0.4-alpine@sha256:d1cc70645bbcef743615463a2fa4616e841407545e18f560aed0c49671a90147 volumes: # we keep using the redis volume as renaming is not possible and copying data over # would require steps during downtime or complex commands in the intializer diff --git a/docs/assets/images/engagement_ss1.png b/docs/assets/images/engagement_ss1.png new file mode 100644 index 00000000000..c8bd16a7b13 Binary files /dev/null and b/docs/assets/images/engagement_ss1.png differ diff --git a/docs/assets/images/engagement_ss10.png b/docs/assets/images/engagement_ss10.png new file mode 100644 index 00000000000..3bbd3eb791f Binary files /dev/null and b/docs/assets/images/engagement_ss10.png differ diff --git a/docs/assets/images/engagement_ss11.png b/docs/assets/images/engagement_ss11.png new file mode 100644 index 00000000000..caa25a297c1 Binary files /dev/null and b/docs/assets/images/engagement_ss11.png differ diff --git a/docs/assets/images/engagement_ss12.png b/docs/assets/images/engagement_ss12.png new file mode 100644 index 00000000000..19437975252 Binary files /dev/null and b/docs/assets/images/engagement_ss12.png differ diff --git a/docs/assets/images/engagement_ss13.png b/docs/assets/images/engagement_ss13.png new file mode 100644 index 00000000000..1afea970231 Binary files /dev/null and b/docs/assets/images/engagement_ss13.png differ diff --git a/docs/assets/images/engagement_ss14.png b/docs/assets/images/engagement_ss14.png new file mode 100644 index 00000000000..e654afad2e8 Binary files /dev/null and b/docs/assets/images/engagement_ss14.png differ diff --git a/docs/assets/images/engagement_ss15.png b/docs/assets/images/engagement_ss15.png new file mode 100644 index 00000000000..86b3dca0010 Binary files /dev/null and b/docs/assets/images/engagement_ss15.png differ diff --git a/docs/assets/images/engagement_ss16.png b/docs/assets/images/engagement_ss16.png new file mode 100644 index 00000000000..f6eab0e4da5 Binary files /dev/null and b/docs/assets/images/engagement_ss16.png differ diff --git a/docs/assets/images/engagement_ss17.png b/docs/assets/images/engagement_ss17.png new file mode 100644 index 00000000000..96f1903e752 Binary files /dev/null and b/docs/assets/images/engagement_ss17.png differ diff --git a/docs/assets/images/engagement_ss18.png b/docs/assets/images/engagement_ss18.png new file mode 100644 index 00000000000..aaa6f62fe11 Binary files /dev/null and b/docs/assets/images/engagement_ss18.png differ diff --git a/docs/assets/images/engagement_ss19.png b/docs/assets/images/engagement_ss19.png new file mode 100644 index 00000000000..5f8e18c9429 Binary files /dev/null and b/docs/assets/images/engagement_ss19.png differ diff --git a/docs/assets/images/engagement_ss2.png b/docs/assets/images/engagement_ss2.png new file mode 100644 index 00000000000..2215e1baf73 Binary files /dev/null and b/docs/assets/images/engagement_ss2.png differ diff --git a/docs/assets/images/engagement_ss20.png b/docs/assets/images/engagement_ss20.png new file mode 100644 index 00000000000..ccfb376955a Binary files /dev/null and b/docs/assets/images/engagement_ss20.png differ diff --git a/docs/assets/images/engagement_ss21.png b/docs/assets/images/engagement_ss21.png new file mode 100644 index 00000000000..b712a139756 Binary files /dev/null and b/docs/assets/images/engagement_ss21.png differ diff --git a/docs/assets/images/engagement_ss22.png b/docs/assets/images/engagement_ss22.png new file mode 100644 index 00000000000..8c63a6bfaf2 Binary files /dev/null and b/docs/assets/images/engagement_ss22.png differ diff --git a/docs/assets/images/engagement_ss23.png b/docs/assets/images/engagement_ss23.png new file mode 100644 index 00000000000..a60d585b10b Binary files /dev/null and b/docs/assets/images/engagement_ss23.png differ diff --git a/docs/assets/images/engagement_ss3.png b/docs/assets/images/engagement_ss3.png new file mode 100644 index 00000000000..58ea499a259 Binary files /dev/null and b/docs/assets/images/engagement_ss3.png differ diff --git a/docs/assets/images/engagement_ss4.png b/docs/assets/images/engagement_ss4.png new file mode 100644 index 00000000000..99eb87ec4c7 Binary files /dev/null and b/docs/assets/images/engagement_ss4.png differ diff --git a/docs/assets/images/engagement_ss5.png b/docs/assets/images/engagement_ss5.png new file mode 100644 index 00000000000..0486ff3cedf Binary files /dev/null and b/docs/assets/images/engagement_ss5.png differ diff --git a/docs/assets/images/engagement_ss6.png b/docs/assets/images/engagement_ss6.png new file mode 100644 index 00000000000..63e01b0a007 Binary files /dev/null and b/docs/assets/images/engagement_ss6.png differ diff --git a/docs/assets/images/engagement_ss7.png b/docs/assets/images/engagement_ss7.png new file mode 100644 index 00000000000..755dde82df8 Binary files /dev/null and b/docs/assets/images/engagement_ss7.png differ diff --git a/docs/assets/images/engagement_ss8.png b/docs/assets/images/engagement_ss8.png new file mode 100644 index 00000000000..843ede296e3 Binary files /dev/null and b/docs/assets/images/engagement_ss8.png differ diff --git a/docs/assets/images/engagement_ss9.png b/docs/assets/images/engagement_ss9.png new file mode 100644 index 00000000000..965c1e7820f Binary files /dev/null and b/docs/assets/images/engagement_ss9.png differ diff --git a/docs/assets/images/tests_ss1.png b/docs/assets/images/tests_ss1.png new file mode 100644 index 00000000000..eca0001c846 Binary files /dev/null and b/docs/assets/images/tests_ss1.png differ diff --git a/docs/assets/images/tests_ss10.png b/docs/assets/images/tests_ss10.png new file mode 100644 index 00000000000..e2f494ca4a4 Binary files /dev/null and b/docs/assets/images/tests_ss10.png differ diff --git a/docs/assets/images/tests_ss11.png b/docs/assets/images/tests_ss11.png new file mode 100644 index 00000000000..8581bcc1f7a Binary files /dev/null and b/docs/assets/images/tests_ss11.png differ diff --git a/docs/assets/images/tests_ss12.png b/docs/assets/images/tests_ss12.png new file mode 100644 index 00000000000..024254bbb9b Binary files /dev/null and b/docs/assets/images/tests_ss12.png differ diff --git a/docs/assets/images/tests_ss13.png b/docs/assets/images/tests_ss13.png new file mode 100644 index 00000000000..8f6551a30ab Binary files /dev/null and b/docs/assets/images/tests_ss13.png differ diff --git a/docs/assets/images/tests_ss14.png b/docs/assets/images/tests_ss14.png new file mode 100644 index 00000000000..b7c28c60fc7 Binary files /dev/null and b/docs/assets/images/tests_ss14.png differ diff --git a/docs/assets/images/tests_ss15.png b/docs/assets/images/tests_ss15.png new file mode 100644 index 00000000000..3c2a0d495e7 Binary files /dev/null and b/docs/assets/images/tests_ss15.png differ diff --git a/docs/assets/images/tests_ss16.png b/docs/assets/images/tests_ss16.png new file mode 100644 index 00000000000..1cfd0c05552 Binary files /dev/null and b/docs/assets/images/tests_ss16.png differ diff --git a/docs/assets/images/tests_ss17.png b/docs/assets/images/tests_ss17.png new file mode 100644 index 00000000000..9334c622ddf Binary files /dev/null and b/docs/assets/images/tests_ss17.png differ diff --git a/docs/assets/images/tests_ss19.png b/docs/assets/images/tests_ss19.png new file mode 100644 index 00000000000..9568551e49d Binary files /dev/null and b/docs/assets/images/tests_ss19.png differ diff --git a/docs/assets/images/tests_ss2.png b/docs/assets/images/tests_ss2.png new file mode 100644 index 00000000000..13bf79426c1 Binary files /dev/null and b/docs/assets/images/tests_ss2.png differ diff --git a/docs/assets/images/tests_ss21.png b/docs/assets/images/tests_ss21.png new file mode 100644 index 00000000000..6e4f38ab942 Binary files /dev/null and b/docs/assets/images/tests_ss21.png differ diff --git a/docs/assets/images/tests_ss22.png b/docs/assets/images/tests_ss22.png new file mode 100644 index 00000000000..5b7a85ef356 Binary files /dev/null and b/docs/assets/images/tests_ss22.png differ diff --git a/docs/assets/images/tests_ss23.png b/docs/assets/images/tests_ss23.png new file mode 100644 index 00000000000..432cf6c5c21 Binary files /dev/null and b/docs/assets/images/tests_ss23.png differ diff --git a/docs/assets/images/tests_ss24.png b/docs/assets/images/tests_ss24.png new file mode 100644 index 00000000000..fbc798cb167 Binary files /dev/null and b/docs/assets/images/tests_ss24.png differ diff --git a/docs/assets/images/tests_ss25.png b/docs/assets/images/tests_ss25.png new file mode 100644 index 00000000000..b5b68075d6e Binary files /dev/null and b/docs/assets/images/tests_ss25.png differ diff --git a/docs/assets/images/tests_ss26.png b/docs/assets/images/tests_ss26.png new file mode 100644 index 00000000000..4d344fa6e1c Binary files /dev/null and b/docs/assets/images/tests_ss26.png differ diff --git a/docs/assets/images/tests_ss27.png b/docs/assets/images/tests_ss27.png new file mode 100644 index 00000000000..d9a57abe562 Binary files /dev/null and b/docs/assets/images/tests_ss27.png differ diff --git a/docs/assets/images/tests_ss28.png b/docs/assets/images/tests_ss28.png new file mode 100644 index 00000000000..29d28fced21 Binary files /dev/null and b/docs/assets/images/tests_ss28.png differ diff --git a/docs/assets/images/tests_ss29.png b/docs/assets/images/tests_ss29.png new file mode 100644 index 00000000000..e20aa1bde8b Binary files /dev/null and b/docs/assets/images/tests_ss29.png differ diff --git a/docs/assets/images/tests_ss3.png b/docs/assets/images/tests_ss3.png new file mode 100644 index 00000000000..d85f3409601 Binary files /dev/null and b/docs/assets/images/tests_ss3.png differ diff --git a/docs/assets/images/tests_ss30.png b/docs/assets/images/tests_ss30.png new file mode 100644 index 00000000000..1dcc9be81d6 Binary files /dev/null and b/docs/assets/images/tests_ss30.png differ diff --git a/docs/assets/images/tests_ss5.png b/docs/assets/images/tests_ss5.png new file mode 100644 index 00000000000..9e0632a5fc6 Binary files /dev/null and b/docs/assets/images/tests_ss5.png differ diff --git a/docs/assets/images/tests_ss6.png b/docs/assets/images/tests_ss6.png new file mode 100644 index 00000000000..ac6d86cb3a1 Binary files /dev/null and b/docs/assets/images/tests_ss6.png differ diff --git a/docs/assets/images/tests_ss7.png b/docs/assets/images/tests_ss7.png new file mode 100644 index 00000000000..edb436fbf49 Binary files /dev/null and b/docs/assets/images/tests_ss7.png differ diff --git a/docs/assets/images/tests_ss8.png b/docs/assets/images/tests_ss8.png new file mode 100644 index 00000000000..1fa15121168 Binary files /dev/null and b/docs/assets/images/tests_ss8.png differ diff --git a/docs/assets/images/tests_ss9.png b/docs/assets/images/tests_ss9.png new file mode 100644 index 00000000000..dadd878fc82 Binary files /dev/null and b/docs/assets/images/tests_ss9.png differ diff --git a/docs/content/admin/sso/PRO__saml.md b/docs/content/admin/sso/PRO__saml.md index 8c84a77f847..80c7952a732 100644 --- a/docs/content/admin/sso/PRO__saml.md +++ b/docs/content/admin/sso/PRO__saml.md @@ -45,6 +45,20 @@ If no group with a matching name exists, DefectDojo will automatically create on To activate group mapping, check the **Enable Group Mapping** checkbox at the bottom of the form. +## Cloud vs On-Premise Differences + +DefectDojo Cloud does not have the same level of SAML customization as DefectDojo On-Prem. The only variables that can be set are through the UI. Here are some of the key differences: + +| Capability | Cloud | On-Premise | +|---|---|---| +| **Username matching** | NameID only | NameID only (the `SAML_USE_NAME_ID_AS_USERNAME` env var applies to Open Source only, not Pro) | +| **SAML assertion encryption** | Not currently supported | Not currently supported | +| **SAML login logs** | Not available in the UI. Contact Support to request logs. | Available via application container logs (`docker logs dojo`) | +| **Configuration method** | Enterprise Settings UI only | Enterprise Settings UI, Django Admin, or Django Shell | +| **Environment variables** | Cannot be set by customers directly. Contact Support for changes. | Can be set via `dojo-compose-cli environment add` | + +If you need to match users on an attribute other than NameID (such as `uid` or `email`), configure your Identity Provider to send the desired value as the NameID rather than adjusting DefectDojo settings. + ## Additional Options * **Create Unknown User** — automatically create a new DefectDojo user if they are not found in the SAML response. diff --git a/docs/content/asset_modelling/engagements_tests/OS__engagements.md b/docs/content/asset_modelling/engagements_tests/OS__engagements.md new file mode 100644 index 00000000000..b6b28ddf0a6 --- /dev/null +++ b/docs/content/asset_modelling/engagements_tests/OS__engagements.md @@ -0,0 +1,181 @@ +--- +title: "Engagements" +description: "Understanding Engagements in DefectDojo OS" +audience: opensource +weight: 2 +--- +Product Types → Products → **ENGAGEMENTS** → Tests → Findings + +## Overview + +In DefectDojo’s product hierarchy, Engagements are time- or pipeline-bound containers that represent groups of related Tests within a specific Product. If you have a planned testing effort scheduled, whether on a routine or one-time basis, an Engagement offers you a place to store all of the related results. + +Examples of Engagements include: +- One-off penetration tests +- Recurring monthly or quarterly scans +- Bug bounty review periods +- CI/CD pipeline runs (for teams who treat each pipeline as its own Engagement) +- Code release cycles (e.g., “v4.2 release security review”) + +### Engagement Types + +DefectDojo supports two Engagement types: **Interactive** and **CI/CD**. These types determine how Tests are typically created and how scan results are imported. + +An Interactive Engagement is typically run by an engineer. Interactive Engagements are focused on testing an application while it’s running, using an automated test, human tester, or any activity “interacting” with the application functionality. + +A CI/CD Engagement is for automated integration with a CI/CD pipeline. CI/CD Engagements are meant to import data as an automated action, triggered by a step in the release process. + +| **Category** | **Interactive Engagements** | **CI/CD Engagements** | +|------------------------|--------------------------------------------------------------|--------------------------------------------------------------------| +| **Primary Use Case** | Manual or ad-hoc security testing | Automated, recurring security testing within pipelines | +| **Duration** | Time-bound and finite | Potentially infinite duration | +| **Frequency** | Periodic or one-off | Continuous or per-commit | +| **Workflow** | Human tester runs tool → manually imports results | Pipeline runs tool → automatically pushes results to DefectDojo | +| **Result Import Method** | Manual upload via UI or CLI | API-driven import via automation (e.g., CLI, connectors, cron jobs, pipeline scripts) | +| **Typical Testing Type** | Penetration tests, red team exercises, manual assessments | Static analysis, dependency scanning, container scanning | + +### Engagement Data + +As the containers that organize testing activity, Engagements can store or track a variety of data: + +- Target start and end dates +- Description and scope notes +- Status (ongoing, planned, completed, etc.) +- Assignee / Lead +- Associated Tests (e.g., scans, pen tests, manual tests, etc.) +- Findings and Finding Types (e.g., active, mitigated, risk accepted, duplicate, etc.) +- Threat models or risk acceptance info +- Tags +- Files and notes +- Jira project settings +- Environment details (e.g., staging vs. production) +- Build IDs (if linked to CI/CD) +- Historical data from past Tests within the Engagement + +## Accessing Engagements + +Engagements are accessible via the sidebar. The submenu provides access to Active Engagements and All Engagements, as well as the option to view Engagements as organized by Product, Test types, and Environments. + +![image](images/engagement_ss17.png) + +Alternatively, Engagements within a particular Product can be accessed from the submenu of the Engagements option in the top bar. + +![image](images/engagement_ss18.png) + +### Permissions + +Engagements sit below Products and above Tests in the object hierarchy. As such, access to a Product automatically grants access to all Engagements within that Product. Engagements do not have independent access control lists. + +## Engagement Lifecycle + +### Create Engagements + +There are multiple approaches to creating an Engagement. Each approach requires that you first create a Product to contain it. + +Once you’ve created a Product, you can add a new Interactive or CI/CD Engagement in the Engagements section of the Product’s navigation bar. + +![image](images/engagement_ss4.png) + +Every Engagement must have the following fields defined: +- Type (Interactive or CI/CD) +- A unique name +- Target start and end dates + - This will determine the Engagement’s appearance in the Calendar section +- Product +- Status + +#### Engagement Statuses + +Engagements can be tagged with different statuses upon creation. The status can also be changed afterward in the Engagement’s settings. + +An Engagement can have any one of the following statuses: +- Not Started +- Blocked +- Cancelled +- Completed +- In Progress +- On Hold +- Scheduled +- Waiting for Resource + +Changing an Engagement’s status to “Completed” will mean that most write operations (e.g., adding tests, importing scans) will become unavailable or hidden. Other statuses will not materially affect the functionality of the Engagement, and are more for filtering/informational purposes only. + +### Edit Engagements + +Engagements can be edited by clicking the **Edit** button within the Engagement’s settings. All ensuing fields that can be edited are also available when the Engagement is being created. + +### Copy Engagements + +You can easily duplicate Engagements by navigating to the list of Engagements within a Product and clicking the **Copy** button from within the ⋮ kebab menu next to the Engagement to be copied. This will create an exact copy of the original Engagement within the parent Product, including the metadata, Tests, and Findings within it. + +![image](images/engagement_ss19.png) + +### Close Engagements + +Engagements can be closed by navigating to the list of Engagements within a Product and clicking “Close” from within the ⋮ kebab menu of the chosen Engagement. + +![image](images/engagement_ss20.png) + +Once closed, the Engagement’s status will be changed to “Completed.” Nevertheless, most write operations (e.g., adding tests, importing scans) will remain available. + +Closing an Engagement does not change the status of the Findings within any of the Engagement’s Tests. Findings remain open, mitigated, or risk accepted according to their own lifecycle, and remain accessible for viewing and reporting. + +If the Engagement is linked to a Jira Epic (see **[Jira Integration: Enable Engagement Epic Mapping](/issue_tracking/jira/os__jira_guide/#enable-engagement-epic-mapping-for-products)**), closing the Engagement will trigger an asynchronous task that closes the associated Jira Epic in your connected Jira Space. + +### Reopen Engagements + +If an Engagement is closed, it can be reopened by clicking **Reopen** from within its ⋮ kebab menu in the Closed Engagements table. This will make the Engagement active again and return its status to “In Progress.” + +![image](images/engagement_ss21.png) + +### Expired Engagements + +An Engagement expires once its target end date passes. + +Engagement expiration has no direct impact on the Engagement’s functionality, and primarily serves as a monitoring/notification mechanism. + +Once expired, a red “X days overdue” notification will appear in the Engagement’s “Length” field, but it will not restrict any of the Engagement’s functionality. The Engagement’s status will still appear as “In Progress.” + +While it is not enabled by default, there is an option within the system settings to auto-close an Engagement once it has been expired for a certain number of days. + +![image](images/engagement_ss22.png) + +### Delete Engagements + +Deleting an Engagement can be performed by selecting **Delete** from the Engagement’s settings. This action can’t be undone. + +Deleting an Engagement will also delete the following: +- Any Tests associated with the Engagement +- All Findings within those Tests +- Any linked Jira Epic mappings (the Epic itself will remain in Jira, but the link between DefectDojo and Jira will be removed) +- All notes and file uploads associated with the Engagement + +For auditing purposes, it is recommended to close any completed Engagements, rather than deleting them. + +| **Operation** | **Results** | **Reversible** | +|----------|---------|------------| +| **Close** | Marks as inactive; data remains; can be reopened | Yes (reopen) | +| **Expire** | Visual warning only; optional auto-close; notifications | N/A | +| **Delete** | Permanently removes Engagement, Tests, Findings, notes, files, and any Jira Epic mappings (Epics remain in Jira) | No | + +## Jira Integration + +Engagements can be linked to a connected Jira Space, allowing Findings within the Engagement to be pushed to Jira as Issues. For a complete guide to setting up Jira, see **[Connecting DefectDojo to Jira](/issue_tracking/jira/os__jira_guide/)**. + +### Engagement Epic Mapping + +When **Enable Engagement Epic Mapping** is checked in a Product's Jira settings, Engagements will be pushed to Jira as Epics. Findings within the Engagement are pushed as child Issues underneath the Epic, mirroring DefectDojo's Engagement → Findings hierarchy in Jira's Epic → Issue structure. + +For more information on this setting, see **[Enable Engagement Epic Mapping](/issue_tracking/jira/os__jira_guide/#enable-engagement-epic-mapping-for-products)**. + +### Engagement-Level Jira Settings + +By default, Engagements inherit their Jira settings from their parent Product. However, individual Engagements can override these settings to use different Jira configurations. The following settings can be customized per-Engagement: + +- **Project Key** — route Findings to a different Jira Space +- **Issue Template** — use a different template for Issues created from this Engagement +- **Custom Fields** — apply different custom field mappings +- **Jira Labels** — tag Issues with Engagement-specific labels +- **Default Assignee** — assign Issues to a different team member + +These settings are accessible from the **Edit Engagement** page. For more details, see **[Engagement-Level Jira Settings](/issue_tracking/jira/os__jira_guide/#engagement-level-jira-settings)**. \ No newline at end of file diff --git a/docs/content/asset_modelling/engagements_tests/OS__tests.md b/docs/content/asset_modelling/engagements_tests/OS__tests.md new file mode 100644 index 00000000000..fe0f7e7078e --- /dev/null +++ b/docs/content/asset_modelling/engagements_tests/OS__tests.md @@ -0,0 +1,273 @@ +--- +title: "Tests" +description: "Understanding Tests in DefectDojo OS" +audience: opensource +weight: 2 +--- +Organizations → Assets → Engagements → **TESTS** → Findings + +## Overview + +A Test is a container for one or more scan executions, which are used to discover flaws in a Product. Tests are the final, most granular component of DefectDojo’s product hierarchy, serving as the container for the Findings that result from an execution of a security tool or manual assessment while also adding the context in which any such Findings were found (i.e., which tool reported it, when that tool was last run, etc.). + +Examples of Tests include: +- Static Application Security Testing +- Dynamic Application Security Testing +- Software Composition Analysis +- Container Security Scans +- Infrastructure / Network Scans +- Manual Penetration Tests +- CI/CD Pipeline Scans + +### Test Types + +There are two primary ways to create Tests in DefectDojo: +1. **Vendor-specific parsers** (e.g., Burp, OWASP ZAP, Acunetix, Invicti) +2. **Generic Findings Import** + +Each method can create new Tests or reimport Findings into existing Tests depending on configuration and deduplication strategy. + +While each method differs primarily in how scan data is parsed and ingested, they all ultimately result in Findings being associated with a Test. + +#### Parsers + +**Parsers** are components that process specific scan output formats (e.g., XML, JSON, CSV) and map it into DefectDojo’s internal Finding model. When scan results are imported, DefectDojo uses the selected parser to extract Findings and attach them to a newly created or existing Test. + +#### Generic Findings Import + +When no native parser exists for a given tool, **Generic Findings Import** allows you to import findings using a standardized JSON or CSV schema, regardless of the original source. + +DefectDojo parses the provided data, creates a new Test (or imports into an existing one), and attaches the Findings. A corresponding Test Type is also created in the format “{Test Name} (Generic Findings Import).” + +| | **Native Parsers** | **Generic Findings Import** | +|----------|---------------|------------------------| +| **Primary purpose** | Ingest supported tool outputs | Ingest unsupported/custom data via fixed schema | +| **Input format** | Tool-specific (e.g., ZAP XML, SARIF) | Strict JSON/CSV schema | +| **Who handles normalization** | DefectDojo (built-in parser) | User (must conform to schema) | +| **Test creation trigger** | Manual upload or API import | Manual upload or API import | +| **Test Type** | Predefined (e.g., "ZAP Scan") | Auto-created "Generic" type | +| **Setup effort** | Low | Moderate (data transformation required) | +| **Flexibility** | Low (only supported tools) | Medium | +| **Automation level** | Low–Moderate | Low–Moderate | +| **Typical use case** | Standard scanners (SAST, DAST, SCA) | Custom scripts, unsupported tools | + +Regardless of the ingestion method, all scan data in DefectDojo is ultimately represented as Findings attached to a Test, which serves as the unit of execution and lifecycle tracking. + +### Test Data + +Tests store a variety of metadata that helps to document various components of each testing effort, such as: +- Test title / name +- Test type +- Test description / notes +- Start and end date +- The Environment in which the Test was run (e.g., Development, Staging, Pre-Production, Production, etc.) +- Version / Branch / Build ID / Commit Hash +- API scan configuration +- Additional files that can be used for later audits or re-imports +- The parent Engagement, Asset, and Organization +- Import and reimport history + +Each Test maintains an import history, which records all scan imports and reimports associated with the Test. This includes metadata such as scan date, version, branch, commit hash, and build ID. + +This history provides traceability across multiple scan executions within the same Test. + +### Permissions + +Multiple Tests can be stored within a single Engagement, and Engagements are stored within Products. As such, access to a Product automatically grants access to all Tests (and Engagements) within that Product. Tests do not have independent access control lists. + +### Accessing Tests + +While Tests exist as an independent object in DefectDojo OS, they do not have a specific section dedicated to them within the UI. As such, each Test is primarily accessible through the Product and/or Engagement that contains it. + +### Test View + +The Test view hosts a variety of tables, including the parent Engagement, the import and reimport history, a list of Findings contained within the Test as well as any Finding Groups. + +There are also tables for Potential Findings, Files, and Notes, all of which can be added manually. + +#### Test Settings + +The following settings are available within each Test view: +- **Edit Test** + - Permits the editing of Test data, such as title, schedule, environment, and other various details. +- **Copy Test** + - Duplicates a Test, along with all associated metadata and Findings, and allow it to be attributed to a different Engagement. +- **Re-Upload Scan** + - Initiates the reimport process. More information on Reimporting is contained later in this article. +- **Add Notes** + - Allows the user to add a Note. A Notes table is also present at the bottom of the page. + - A Note can be toggled as Private, in which case it is prevented from pushing to Jira, Reports, and exports of Findings. +- **Report** + - Initiates the process of generating a Report, in which myriad filters can be applied in order to create a report of only the filtered Findings. +- **Add To Calendar** + - Downloads an .ics file of the chosen Test that can be added to your third-party calendar application. +- **View History** + - Opens a history of edits made to the Test for tracking, reporting, and auditing purposes. + +## Test Lifecycle + +### Create Tests + +Tests can be automatically created when scan data is imported directly into an Engagement, resulting in a new Test containing the scan data. Tests can also be created in anticipation of planning future Engagements, or for manually entered security findings requiring tracking and remediation. + +#### Manual Workflows + +There are several ways to create a Test in the OS version: + +- Select a Product and click “Import Scan Results” from the Findings menu in the navigation bar + - This will create an ad hoc Engagement to contain the Test + +![image](images/tests_ss5.png) + +- Select an Engagement within a Product, click the dropdown menu in the Tests subsection, and click either “Add Tests” or “Import Scan Results” + - This will create the ensuing Test directly within the chosen Engagement + +![image](images/tests_ss6.png) + +- While creating an Engagement + +![image](images/tests_ss7.png) + +Using the third method above, you can do the following while creating an Engagement: + +- Immediately import scan results +- Create a Test shell (into which you will later import a scan) +- Do neither and simply create the Engagement by clicking “Done” + +You will have the opportunity to add metadata while either importing a scan or creating a Test shell. Any metadata will be reflected in the Import History section of the Test View. + +#### Automated Workflows + +In automated workflows, Tests can be created programmatically as part of the scan import process, allowing pipelines to upload results without requiring a Test to be created manually in advance. + +When using the API to import scan results, a new Test can be created automatically by providing an engagement instead of a test. + +##### API + +curl -X POST `"https:///api/v2/import-scan/"` \ + -H `"Authorization: Token "` \ + -F `"engagement=45"` \ + -F `"scan_type=ZAP Scan"` \ + -F `"file=@report.xml"` + +Given the above, a new Test is created under the specified Engagement, and the scan results are attached to that Test. + +If a `test` ID is provided instead, the scan results will be added to an existing Test, which is common in reimport workflows. + +### Edit Tests + +Tests can be edited by either clicking **Edit Test** from the ⋮ kebab menu in the Tests table within the parent Engagement’s view, or from the settings menu within the Test’s view. All ensuing fields that can be edited are also available when the Test is being created. + +![image](images/tests_ss24.png) + +![image](images/tests_ss12.png) + +#### Manually Add Findings to a Test + +A Finding can be manually added to a two by either clicking **Add Finding to Test** from the ⋮ kebab menu next to the Test in the parent Engagement’s view, or from within the settings of the Findings table in the Test’s view. + +![image](images/tests_ss29.png) + +![image](images/tests_ss30.png) + +### Delete Tests + +Deleting a Test can be performed by selecting **Delete Test** from the ⋮ kebab menu next to the Test in the parent Engagement’s view, or from the settings menu within the Test’s view. This action can’t be undone. + +Deleting a Test will also delete any Findings contained within that Test. + +![image](images/tests_ss25.png) + +![image](images/tests_ss26.png) + +## Reimport + +Reimporting scans within Tests is fundamental to effective deduplication. When scan results are reimported into the same Test: + +- Existing Findings may be updated +- Duplicate Findings may be suppressed +- New Findings may be created if no match is found + +This behavior depends on the configured deduplication rules and the scan type. + +Creating a new Test instead of reimporting into an existing one may result in duplicate Findings being created rather than updated. + +#### Reimport vs. Import + +Reimport is typically used when: + +- Running recurring scans against the same target +- Tracking how Findings evolve over time +- Maintaining a continuous view of application security posture + +In contrast, importing (creating a new Test) is more appropriate for one-time or independent scan executions. + +### Reimporting Scan Results (UI) + +In order to add new data to an existing Test, you can either click **Re-Upload Scan Results** from the ⋮ kebab menu next to the Test in the parent Engagement’s view, or click **Re-Upload Scan** in the settings menu within the Test’s view. + +![image](images/tests_ss27.png) + +![image](images/tests_ss10.png) + +While completing the Reimport Scan form, you’ll have the option to update metadata for the scan being reimported, including the version, branch tag, commit hash, and build ID. + +These changes are reflected in the Import History section of the Test View, which will also include the same metadata from prior scan imports. + +For example, in the below screenshot, the branch tag, build ID, commit hash, and version were all manually updated between the initial import and the subsequent reimport. + +![image](images/tests_ss28.png) + +To edit the metadata of the most recently reimported scan, follow the prior instructions in the Edit Tests section above and update the metadata as desired. Only the most recent import’s metadata can be edited. + +### Reimporting Scan Results (API) + +When Tests are created or updated through a CI/CD pipeline, you’re able to include metadata from the pipeline run so that Tests can be properly linked to the code they scanned. This allows you to: +- Associate scan results with a specific commit or branch. +- Track how Findings evolve across code changes. +- Improve Deduplication by understanding when two scans apply to the same or different versions of the code. +- Support auditability by showing exactly what code was scanned and when. + +DefectDojo’s API accepts these values during import or reimport so they can be stored as part of the scan import and reflected in the Test’s import history. This metadata can be used to identify commit hashes or anything associated with any relevant repository information associated with a CI/CD run. + +#### Supported Metadata Fields + +The API supports a defined set of metadata fields that can be included during reimport. These include: + +- `tags` +- `version` +- `build_id` +- `branch_tag` +- `commit_hash` +- `scan_date` +- `minimum_severity` +- `active / verified` flags + +These fields represent the primary mechanism for attaching contextual metadata during a reimport operation. + +In automated pipelines, the most commonly supplied metadata includes: +- build_id (CI job identifier) +- commit_hash (source control reference) +- branch_tag (branch or environment context) +- tags (e.g., nightly, staging, production) + +These fields provide traceability across scans without requiring manual intervention. + +Although metadata can be updated manually through the Reimport Scan form, most automated environments will handle this by calling the `/api/v2/reimport-scan/` endpoint directly. This approach allows the pipeline to automatically attach metadata upon reimport. + +##### API Reimport with Metadata + +curl -X POST `"https:///api/v2/reimport-scan/"` \ + -H `"Authorization: Token "` \ + -F `"test=123"` \ + -F `"scan_type=ZAP Scan"` \ + -F `"file=@report.xml"` \ + -F `"tags=nightly,api-scan"` \ + -F `"version=1.4.2"` \ + -F `"build_id=jenkins-842"` \ + -F `"branch_tag=main"` \ + -F `"commit_hash=a1b2c3d4"` + +##### Metadata, Reimport, and Scheduled Scans + +Scans may also be scheduled to run at routine intervals, such as those triggered by cron jobs. Scheduled scans are not tied to repository activity, making metadata like commit hashes or branch names irrelevant unless explicitly injected by the script itself. Nevertheless, using reimport may still be useful if you prefer to keep a rolling record of your security posture within a single Test. \ No newline at end of file diff --git a/docs/content/asset_modelling/engagements_tests/PRO__engagements.md b/docs/content/asset_modelling/engagements_tests/PRO__engagements.md new file mode 100644 index 00000000000..8fcba6738ce --- /dev/null +++ b/docs/content/asset_modelling/engagements_tests/PRO__engagements.md @@ -0,0 +1,188 @@ +--- +title: "Engagements" +description: "Understanding Engagements in DefectDojo Pro" +audience: pro +weight: 2 +--- +Organizations → Assets → **ENGAGEMENTS** → Tests → Findings + +## Overview + +In DefectDojo’s Asset Hierarchy, Engagements are time- or pipeline-bound containers that represent groups of related Tests within a specific Asset. If you have a planned testing effort scheduled, whether on a routine or one-time basis, an Engagement offers you a place to store all of the related results. + +Examples of Engagements include: +- One-off penetration tests +- Recurring monthly or quarterly scans +- Bug bounty review periods +- CI/CD pipeline runs (for teams who treat each pipeline as its own Engagement) +- Code release cycles (e.g., “v4.2 release security review”) + +### Engagement Types + +DefectDojo supports two Engagement types: **Interactive** and **CI/CD**. These types determine how Tests are typically created and how scan results are imported. + +An Interactive Engagement is typically run by an engineer. Interactive Engagements are focused on testing an application while it’s running, using an automated test, human tester, or any activity “interacting” with the application functionality. + +A CI/CD Engagement is for automated integration with a CI/CD pipeline. CI/CD Engagements are meant to import data as an automated action, triggered by a step in the release process. + +| **Category** | **Interactive Engagements** | **CI/CD Engagements** | +|------------------------|--------------------------------------------------------------|--------------------------------------------------------------------| +| **Primary Use Case** | Manual or ad-hoc security testing | Automated, recurring security testing within pipelines | +| **Duration** | Time-bound and finite | Potentially infinite duration | +| **Frequency** | Periodic or one-off | Continuous or per-commit | +| **Workflow** | Human tester runs tool → manually imports results | Pipeline runs tool → automatically pushes results to DefectDojo | +| **Result Import Method** | Manual upload via UI or CLI | API-driven import via automation (e.g., CLI, connectors, cron jobs, pipeline scripts) | +| **Typical Testing Type** | Penetration tests, red team exercises, manual assessments | Static analysis, dependency scanning, container scanning | + +### Engagement Data + +As the containers that organize testing activity, Engagements can store or track a variety of data: + +- Target start and end dates +- Description and scope notes +- Status (ongoing, planned, completed, etc.) +- Assignee / Lead +- Associated Tests (e.g., scans, pen tests, manual tests, etc.) +- Findings and Finding Types (e.g., active, mitigated, risk accepted, duplicate, etc.) +- Threat models or risk acceptance info +- Tags +- Files and notes +- Jira project settings +- Environment details (e.g., staging vs. production) +- Build IDs (if linked to CI/CD) +- Historical data from past Tests within the Engagement + +## Accessing Engagements + +Engagements are accessible via the sidebar. The submenu provides access to Active Engagements and All Engagements, as well as the option to create new Engagements. + +![image](images/engagement_ss13.png) + +Alternatively, Engagements within an Asset can be accessed in the window at the bottom of the Asset’s view. + +![image](images/engagement_ss14.png) + +### Permissions + +Engagements sit below Assets and above Tests in the object hierarchy. As such, access to an Asset automatically grants access to all Engagements within that Asset. Engagements do not have independent access control lists. + +## Engagement Lifecycle + +### Create Engagements + +Before creating an Engagement, you must first have created an Asset to contain it. + +There are several ways to create an Engagement: + +- Within the Engagements dropdown in the Manage section of the sidebar + - You will have to select the Asset to which to attribute the Engagement when completing the New Engagement form + +![image](images/engagement_ss1.png) + +- The gear icon located at the top right corner of an Asset view + +![image](images/engagement_ss9.png) + +- The “+ New Engagement” button found in the list of Engagements within an Asset + +![image](images/engagement_ss2.png) + +- If you haven’t already created an Engagement within an Asset, you can do so while importing a scan. + +![image](images/engagement_ss3.png) + +Every Engagement must have the following fields defined: +- Type (Interactive or CI/CD) +- A unique name +- Target start and end dates + - This will determine the Engagement’s appearance in the Calendar section +- Asset +- Status + +#### Engagement Statuses + +Engagements can be tagged with different statuses upon creation. The status can also be changed afterward in the Engagement’s settings. + +An Engagement can have any one of the following statuses: +- Not Started +- Blocked +- Cancelled +- Completed +- In Progress +- On Hold +- Scheduled +- Waiting for Resource + +Changing an Engagement’s status to “Completed” will mean that most write operations (e.g., adding tests, importing scans) will become unavailable or hidden. Other statuses will not materially affect the functionality of the Engagement, and are more for filtering/informational purposes only. + +### Edit Engagements + +Engagements can be edited by clicking **Edit Engagement** from within the gear menu. All ensuing fields that can be edited are also available when the Engagement is being created. + +### Copy Engagements + +You can easily duplicate Engagements by selecting “Copy Engagement” within the Engagement’s settings. This will create an exact copy of the original Engagement within the parent Asset, including the metadata, Tests, and Findings within it. + +### Close Engagements + +Engagements are closed by selecting **Close Engagement** within the Engagement’s settings. Once closed, the Engagement’s status will be changed to “Completed.” Nevertheless, most write operations (e.g., adding tests, importing scans) will remain available. + +Closing an Engagement does not change the status of the Findings within any of the Engagement’s Tests. Findings remain open, mitigated, or risk accepted according to their own lifecycle, and remain accessible for viewing and reporting. + +If the Engagement is linked to a Jira Epic (see **[Jira Integration: Enable Engagement Epic Mapping](/issue_tracking/jira/pro__jira_guide/#enable-engagement-epic-mapping)**), closing the Engagement will trigger an asynchronous task that closes the associated Jira Epic in your connected Jira Space. + +### Reopen Engagements + +If an Engagement is closed, it can be reopened by selecting **Reopen Engagement** within its settings. This will make the Engagement active again and return its status to “In Progress.” + +### Expired Engagements + +An Engagement expires once its target end date passes. + +Compared to closing or deleting an Engagement, an Engagement expiring has no direct impact on its functionality, and primarily serves as a monitoring/notification mechanism. + +Once expired, an “Overdue” tag will appear next to the Engagement, but it will not restrict any of the Engagement’s functionality. The Engagement’s status will still appear as “In Progress.” + +While it is not enabled by default, there is an option within the system settings to auto-close an Engagement once it has been expired for a certain number of days. + +![image](images/engagement_ss15.png) + +### Delete Engagements + +Deleting an Engagement can be performed by selecting **Delete Engagement** from the Engagement’s settings. This action can’t be undone. + +Deleting an Engagement will also delete the following: +Any Tests associated with the Engagement +All Findings within those Tests +Any linked Jira Epic mappings (the Epic itself will remain in Jira, but the link between DefectDojo and Jira will be removed) +All notes and file uploads associated with the Engagement + +For auditing purposes, it is recommended to close any completed Engagements, rather than deleting them. + +| **Operation** | **Results** | **Reversible** | +|----------|---------|------------| +| **Close** | Marks as inactive; data remains; can be reopened | Yes (reopen) | +| **Expire** | Visual warning only; optional auto-close; notifications | N/A | +| **Delete** | Permanently removes Engagement, Tests, Findings, notes, files, and any Jira Epic mappings (Epics remain in Jira) | No | + +## Jira Integration + +Engagements can be linked to a connected Jira Space, allowing Findings within the Engagement to be pushed to Jira as Issues. For a complete guide to setting up Jira, see **[Connecting DefectDojo to Jira](/issue_tracking/jira/pro__jira_guide/)**. + +### Engagement Epic Mapping + +When **Enable Engagement Epic Mapping** is checked in a Product’s Jira settings, Engagements will be pushed to Jira as Epics. Findings within the Engagement are pushed as child Issues underneath the Epic, mirroring DefectDojo’s Engagement → Findings hierarchy in Jira’s Epic → Issue structure. + +For more information on this setting, see **[Enable Engagement Epic Mapping](/issue_tracking/jira/pro__jira_guide/#enable-engagement-epic-mapping)**. + +### Engagement-Level Jira Settings + +By default, Engagements inherit their Jira settings from their parent Asset (Product). However, individual Engagements can override these settings to use different Jira configurations. The following settings can be customized per-Engagement: + +- **Project Key** — route Findings to a different Jira Space +- **Issue Template** — use a different template for Issues created from this Engagement +- **Custom Fields** — apply different custom field mappings +- **Jira Labels** — tag Issues with Engagement-specific labels +- **Default Assignee** — assign Issues to a different team member + +These settings are accessible from the **Edit Engagement** page. For more details, see **[Engagement-Level Jira Settings](/issue_tracking/jira/pro__jira_guide/#engagement-level-jira-settings)**. diff --git a/docs/content/asset_modelling/engagements_tests/PRO__tests.md b/docs/content/asset_modelling/engagements_tests/PRO__tests.md new file mode 100644 index 00000000000..dbe4e3f9629 --- /dev/null +++ b/docs/content/asset_modelling/engagements_tests/PRO__tests.md @@ -0,0 +1,284 @@ +--- +title: "Tests" +description: "Understanding Tests in DefectDojo Pro" +audience: pro +weight: 2 +--- +Organizations → Assets → Engagements → **TESTS** → Findings + +## Overview + +A Test is a container for one or more scan executions, which are used to discover flaws in an Asset. Tests are the final, most granular component of DefectDojo’s object hierarchy, serving as the container for the Findings that result from an execution of a security tool or manual assessment while also adding the context in which any such Findings were found (i.e., which tool reported it, when that tool was last run, etc.). + +Examples of Tests include: +- Static Application Security Testing +- Dynamic Application Security Testing +- Software Composition Analysis +- Container Security Scans +- Infrastructure / Network Scans +- Manual Penetration Tests +- CI/CD Pipeline Scans + +### Test Types + +There are several ways to create Tests in DefectDojo, including **vendor-specific parsers** (e.g., Burp, OWASP ZAP, Acunetix, Invicti), **Generic Findings Import**, **Universal Parser**, and **Connectors**. + +These methods can create new Tests or reimport Findings into existing Tests depending on configuration and deduplication strategy. + +While each method differs primarily in how scan data is parsed and ingested, they all ultimately result in Findings being associated with a Test. + +#### Parsers + +**Parsers** are components that process specific scan output formats (e.g., XML, JSON, CSV) and map it into DefectDojo’s internal Finding model. When scan results are imported, DefectDojo uses the selected parser to extract Findings and attach them to a newly created or existing Test. + +#### Generic Findings Import + +When no native parser exists for a given tool, [**Generic Findings Import**](/supported_tools/parsers/generic_findings_import) allows you to import findings using a standardized JSON or CSV schema, regardless of the original source. + +DefectDojo parses the provided data, creates a new Test (or imports into an existing one), and attaches the Findings. A corresponding Test Type is also created in the format “`{Test Name}` (Generic Findings Import).” + +#### Universal Parser + +[**Universal Parser**](/supported_tools/parsers/universal_parser) allows users to define how arbitrary input data maps into DefectDojo’s Finding model. After configuring the parser and uploading scan data, DefectDojo applies the mapping rules to extract Findings, creates a Test (or updates an existing one), and associates the Findings with that Test. + +#### Connectors + +[**Connectors**](/import_data/pro/connectors/about_connectors) can be used to automatically ingest and organize vulnerability data from external tools via API calls. Once configured, a Connector fetches scan results, parses the data, and creates new Tests or updates existing Tests depending on its configuration. Findings are then attached to the corresponding Test. + +#### Test Creation Mechanism Comparison + +| | **Native Parsers** | **Generic Findings Import** | **Universal Parser (Pro)** | **Connectors** | +|----------|---------------|------------------------|------------------------|------------| +| **Primary purpose** | Ingest supported tool outputs | Ingest unsupported/custom data via fixed schema | Ingest arbitrary formats via configurable mappings | Continuously sync external systems | +| **Input format** | Tool-specific (e.g., ZAP XML, SARIF) | Strict JSON/CSV schema | Arbitrary (JSON, XML, etc.) | External API responses | +| **Who handles normalization** | DefectDojo (built-in parser) | User (must conform to schema) | DefectDojo (via parser config) | External tool + DefectDojo | +| **Test creation trigger** | Manual upload or API import | Manual upload or API import | Manual upload or API import | Automated sync (scheduled or event-driven) | +| **Test Type** | Predefined (e.g., "ZAP Scan") | Auto-created "Generic" type | Derived from parser configuration | Depends on connector / underlying parser | +| **Setup effort** | Low | Moderate (data transformation required) | High (parser configuration) | Moderate–High (integration setup) | +| **Flexibility** | Low (only supported tools) | Medium | High | Medium–High | +| **Automation level** | Low–Moderate | Low–Moderate | Low–Moderate | High | +| **Typical use case** | Standard scanners (SAST, DAST, SCA) | Custom scripts, unsupported tools | Complex/custom formats at scale | CI/CD, SCM, or platform integrations | + +Regardless of the ingestion method, all scan data in DefectDojo is ultimately represented as Findings attached to a Test, which serves as the unit of execution and lifecycle tracking. + +### Test Data + +Tests store a variety of metadata that helps to document various components of each testing effort, such as: +- Test title / name +- Test type +- Test description / notes +- Start and end date +- The Environment in which the Test was run (e.g., Development, Staging, Pre-Production, Production, etc.) +- Version / Branch / Build ID / Commit Hash +- API scan configuration +- Personnel associated with the Test +- Additional files that can be used for later audits or re-imports +- The parent Engagement, Asset, and Organization +- Import and reimport history + +Each Test maintains an import history, which records all scan imports and reimports associated with the Test. Each History item includes metadata such as scan date, version, branch, commit hash, and build ID. + +This history provides traceability across multiple scan executions within the same Test. + +### Permissions + +Multiple Tests can be stored within a single Engagement, and Engagements are stored within Assets. As such, access to an Asset automatically grants access to all Tests (and Engagements) within that Asset. Tests do not have independent access control lists. + +## Accessing Tests + +Tests can be accessed from various sections of the DefectDojo UI. + +- The sidebar + +![image](images/tests_ss13.png) + +- Within an Engagement + +![image](images/tests_ss14.png) + +- The top bar of an Asset + +![image](images/tests_ss15.png) + +- The Metadata table within a Finding’s view + +![image](images/tests_ss16.png) + +## Test Lifecycle + +### Create Tests + +Tests can be automatically created when scan data is imported directly into an Engagement, resulting in a new Test containing the scan data. Tests can also be created in anticipation of planning future Engagements, or for manually entered security findings requiring tracking and remediation. + +#### Manual Workflows + +In order to make a Test, an Engagement must be made to contain it, as well as an Asset that will contain that Engagement. Afterwards, there are several ways to create a Test: + +- In the sidebar, under Tests within the **Manage** subsection + - You will have to select the pre-existing Engagement to attribute the Test to when completing the New Test form. + +![image](images/tests_ss1.png) + +- The settings dropdown at the top right corner of an Asset view + - **Import Scan** will automatically create a Test once a scan file has been added to the Import Scan form. You will have the opportunity to either attribute the Test to a pre-existing Engagement or create and name a new Engagement to contain the new Test. + - While completing the Import Scan form, you may add metadata such as the version, branch tag, commit hash, and build ID. This will be reflected in the Import History section of the Test View. + +![image](images/tests_ss2.png) + +- The settings dropdown at the top right of an Engagement view + - **Import Scan** will follow the same workflow as Assets, but will automatically place the Test object within the Engagement in which you clicked Import Scan. + - **Add Test** will create a Test object but does not require that a scan be uploaded to the Test itself, which is useful in anticipation of planning future Tests or for manually entered security findings requiring tracking and remediation. + +![image](images/tests_ss3.png) + +If you select Add Test and later wish to manually import the results of a scan to a Test, you can do so by opening the Test and clicking the Reimport Findings button in the Test’s settings or the Reimport Scan button in the Findings table. + +![image](images/tests_ss21.png) + +#### Automated Workflows + +In automated workflows, Tests can be created programmatically as part of the scan import process, allowing pipelines to upload results without requiring a Test to be created manually in advance. + +When using the API or CLI to import scan results, a new Test can be created automatically by providing an `engagement` instead of a `test`. + +##### API + +curl -X POST `"https:///api/v2/import-scan/"` \ + -H `"Authorization: Token "` \ + -F `"engagement=45"` \ + -F `"scan_type=ZAP Scan"` \ + -F `"file=@report.xml"` + +Given the above, a new Test is created under the specified Engagement, and the scan results are attached to that Test. + +If a `test` ID is provided instead, the scan results will be added to an existing Test, which is common in reimport workflows. + +##### CLI + +Using the DefectDojo CLI, this behavior is handled automatically based on the arguments provided. + +defectdojo-cli import \ + --engagement-id 45 \ + --scan-type `"ZAP Scan"` \ +GOog --file report.xml + +Given the above, providing an `engagement-id` creates a new Test, and providing a `test-id` reuses an existing Test and reimports scan results into that Test. + +See [DefectDojo-CLI](/import_data/pro/specialized_import/external_tools/#defectdojo-cli) for more details on required flags. + +### Edit Tests + +Tests can be edited by clicking **Edit Test** from within the gear menu. All ensuing fields that can be edited are also available when the Test is being created. + +### Delete Tests + +Deleting a Test can be performed by selecting **Delete Test** from the Test’s settings. This action can’t be undone. + +Deleting a Test will also delete any Findings contained within that Test. + +### Reimporting Scan Results (UI) + +In order to add new data to an existing Test, open the Test you’re adding new data to and click the Reimport Findings button in the Test’s settings or the Reimport Scan button in the Findings table. + +![image](images/tests_ss21.png) + +While completing the Reimport Scan form, you’ll have the option to update metadata for the scan being reimported, including the version, branch tag, commit hash, and build ID. These changes are reflected in the Import History section of the Test View, which will also include the same metadata from prior scan imports. + +For example, in the below screenshot, the branch tag, build ID, commit hash, and version were all manually updated between the initial import and the subsequent reimport. + +![image](images/tests_ss23.png) + +To edit the metadata of the most recently reimported scan, click the gear icon located at the top right corner of an Engagement View and select “Edit Test.” Only the most recent import’s metadata can be edited. + +### Reimporting Scan Results (API/CLI) + +When Tests are created or updated through a CI/CD pipeline, you’re able to include metadata from the pipeline run so that Tests can be properly linked to the code they scanned. This allows you to: +- Associate scan results with a specific commit or branch. +- Track how Findings evolve across code changes. +- Improve Deduplication by understanding when two scans apply to the same or different versions of the code. +- Support auditability by showing exactly what code was scanned and when. + +DefectDojo’s CLI and API accept these values during import or reimport so they can be stored as part of the scan import and reflected in the Test’s import history. This metadata can be used to identify commit hashes or anything associated with any relevant repository information associated with a CI/CD run. + +#### Supported Metadata Fields + +The API and CLI support a defined set of metadata fields that can be included during reimport. These include: + +- `tags` +- `version` +- `build_id` +- `branch_tag` +- `commit_hash` +- `scan_date` +- `minimum_severity` +- `active / verified` flags + +These fields represent the primary mechanism for attaching contextual metadata during a reimport operation. + +In automated pipelines, the most commonly supplied metadata includes: +- `build_id` (CI job identifier) +- `commit_hash` (source control reference) +- `branch_tag` (branch or environment context) +- `tags` (e.g., `nightly`, `staging`, `production`) + +These fields provide traceability across scans without requiring manual intervention. + +Although metadata can be updated manually through the Reimport Scan form, most automated environments will handle this by calling the `/api/v2/reimport-scan/` endpoint directly or using the DefectDojo CLI (`defectdojo-cli reimport`) as part of the build process. This approach allows the pipeline to automatically attach metadata upon reimport. + +##### API Reimport with Metadata + +curl -X POST `"https:///api/v2/reimport-scan/"` \ + -H `"Authorization: Token "` \ + -F `"test=123"` \ + -F `"scan_type=ZAP Scan"` \ + -F `"file=@report.xml"` \ + -F `"tags=nightly,api-scan"` \ + -F `"version=1.4.2"` \ + -F `"build_id=jenkins-842"` \ + -F `"branch_tag=main"` \ + -F `"commit_hash=a1b2c3d4"` + +##### CLI Reimport with Metadata + +defectdojo-cli import \ + --test-id 123 \ + --scan-type "ZAP Scan" \ + --file report.xml \ + --tag nightly \ + --tag api \ + --build-id jenkins-842 \ + --branch main \ + --commit a1b2c3d4 + +The CLI maps directly to the same API endpoint and supports the same set of metadata fields. + +There are some limitations to be aware of when working with metadata during reimport: +- The API/CLI only supports predefined parameters. Custom key-value metadata cannot be added during reimport +- Additional metadata may be extracted from the scan file itself, depending on the scan type and parser. +- Metadata provided during reimport does not behave as a direct update to the Test object in the same way as manual edits in the UI. + +##### Metadata, Reimport, and Scheduled Scans + +Scans may also be scheduled to run at routine intervals, such as those triggered by cron jobs. Scheduled scans are not tied to repository activity, making metadata like commit hashes or branch names irrelevant unless explicitly injected by the script itself. Nevertheless, using reimport may still be useful if you prefer to keep a rolling record of your security posture within a single Test. + +## Reimport and Deduplication + +Reimporting scans within Tests is fundamental to effective deduplication. When scan results are reimported into the same Test: + +- Existing Findings may be updated +- Duplicate Findings may be suppressed +- New Findings may be created if no match is found + +This behavior depends on the configured deduplication rules and the scan type. + +Creating a new Test instead of reimporting into an existing one may result in duplicate Findings being created rather than updated. + +### Reimport vs. Import + +Reimport is typically used when: + +- Running recurring scans against the same target +- Tracking how Findings evolve over time +- Maintaining a continuous view of application security posture + +In contrast, importing (creating a new Test) is more appropriate for one-time or independent scan executions. \ No newline at end of file diff --git a/docs/content/asset_modelling/hierarchy/PRO__assets_organizations.md b/docs/content/asset_modelling/hierarchy/PRO__assets_organizations.md index c1588159dce..bffdd35984c 100644 --- a/docs/content/asset_modelling/hierarchy/PRO__assets_organizations.md +++ b/docs/content/asset_modelling/hierarchy/PRO__assets_organizations.md @@ -8,7 +8,24 @@ aliases: --- DefectDojo Pro is extending the Product/Product Type object classes to provide greater flexibility with the data model. -Currently, this feature is in Beta. Pro users who are interested in opting in can do so by emailing [support@defectdojo.com](mailto:support@defectdojo.com). +Currently, this feature is in Beta. + +## Enabling the Hierarchy Feature + +Hierarchy features ship with new versions of DefectDojo Pro by default, but existing customers who wish to migrate these features can do so using the following methods + +### Cloud Customers + +The hierarchy feature and label changes must be enabled by DefectDojo Support. Email [support@defectdojo.com](mailto:support@defectdojo.com) with your instance URL and request: + +1. **Asset Hierarchy** — enables parent/child relationships between Assets. Once enabled, the hierarchy can be viewed and managed from the **Product** tab in the navigation. +2. **Label Changes** (optional) — renames "Product Type" to "Organization" and "Product" to "Asset" throughout the UI. This is a separate step from enabling the hierarchy and can be requested at the same time or later. + +Note that label changes are cosmetic only: API endpoints and field names remain unchanged, so existing automation will continue to work. + +### On-Premise Customers + + Contact Support for guidance on enabling these features via your instance configuration. ## Significant Changes diff --git a/docs/content/automation/api/api-v2-docs.md b/docs/content/automation/api/api-v2-docs.md index 1d55a413a7b..b88e744a0cd 100644 --- a/docs/content/automation/api/api-v2-docs.md +++ b/docs/content/automation/api/api-v2-docs.md @@ -264,6 +264,34 @@ A classic way of reimporting a scan is by specifying the ID of the test instead: } ``` +## Asynchronous Deletion Behavior + +Deletions in DefectDojo (via both the API and UI) are processed **asynchronously** by Celery background workers. When you delete an Engagement, Test, or other object, the API or UI returns a success response immediately, but the actual deletion runs in the background. + +This means: +- Objects may still appear in queries for a period of time after deletion is confirmed. +- Cascade deletions (e.g., deleting an Engagement also deletes its Tests and Findings) are processed as a chain of background tasks. Child objects are removed in dependency order: Findings, then Tests, then Engagements. +- For large Engagements with many Findings, this process can take several minutes to complete. + +There is no need to build custom scripts to delete objects in dependency order. A single `DELETE` request on an Engagement will cascade to all child objects automatically. Simply allow time for the background tasks to complete. + +## API Pagination Limits + +DefectDojo Pro enforces a maximum page size of **250** results per API request. Setting `limit` higher than 250 may result in HTTP 502 errors due to query timeouts. + +Open Source DefectDojo instances may also experience timeouts with very large page sizes depending on dataset size and server resources. + +For large result sets, use pagination with a page size of 50-250 and add short delays between paginated requests to avoid saturating the worker pool. + +## Large-Scale Import Best Practices + +When importing scan results at scale (e.g., SBOM pipelines with thousands of components), consider the following: + +- **Use `background_import=true`** for large payloads. Synchronous imports tie up a uwsgi worker for the duration of the import, which can degrade performance for all users. +- **Target payload sizes under 1 MB per import** where possible. Split large SBOMs into smaller files per product or component group. +- **Add delays between consecutive API calls** to avoid worker pool exhaustion, which causes HTTP 502 errors. +- **Use Reimport** (`/api/v2/reimport-scan/`) for recurring scans to update existing findings rather than creating duplicates. + ## Using the Scan Completion Date (API: `scan_date`) field DefectDojo offers a plethora of supported scanner reports, but not all of them contain the diff --git a/docs/content/en/open_source/upgrading/2.59.md b/docs/content/en/open_source/upgrading/2.59.md new file mode 100644 index 00000000000..e51e9faa82d --- /dev/null +++ b/docs/content/en/open_source/upgrading/2.59.md @@ -0,0 +1,7 @@ +--- +title: 'Upgrading to DefectDojo Version 2.59.x' +toc_hide: true +weight: -20260504 +description: No special instructions. +--- +There are no special instructions for upgrading to 2.59.x. Check the [Release Notes](https://github.com/DefectDojo/django-DefectDojo/releases/tag/2.59.0) for the contents of the release. diff --git a/docs/content/issue_tracking/intro/intro.md b/docs/content/issue_tracking/intro/intro.md index f307850524d..1fbfc616137 100644 --- a/docs/content/issue_tracking/intro/intro.md +++ b/docs/content/issue_tracking/intro/intro.md @@ -10,8 +10,8 @@ The DefectDojo issue tracking integrations connect your vulnerability management | Edition | Supported Issue Tracking Integrations | |--------------|---------------------------------------| -| Community Edition | * Jira | -| Pro | * Jira
* Azure DevOps
* GitHub
* GitLab Boards
* ServiceNow | +| Community Edition | * [Jira](/issue_tracking/jira/os__jira_guide/) | +| Pro | * [Jira](/issue_tracking/jira/pro__jira_guide/)
* [Azure DevOps](/issue_tracking/pro_integration/integrations_toolreference/#azure-devops-boards)
* [GitHub](/issue_tracking/pro_integration/integrations_toolreference/#github)
* [GitLab Boards](/issue_tracking/pro_integration/integrations_toolreference/#gitlab)
* [ServiceNow](/issue_tracking/pro_integration/integrations_toolreference/#servicenow) | When enabled, DefectDojo can create issues automatically, or selectively from Products or Engagement. As Findings are updated in DefectDojo—resolved, mitigated, or reactivated—the corresponding issues can be kept in sync, ensuring both systems reflect the current state of risk. diff --git a/docs/content/issue_tracking/jira/troubleshooting_jira.md b/docs/content/issue_tracking/jira/troubleshooting_jira.md index 552c70f9eed..5d68776e48a 100644 --- a/docs/content/issue_tracking/jira/troubleshooting_jira.md +++ b/docs/content/issue_tracking/jira/troubleshooting_jira.md @@ -55,6 +55,12 @@ For example: curl -H "Authorization: Bearer ATATT1234567890abcdefghijklmnopqrstuvwxyz" https://.atlassian.net/rest/api/latest/issue//transitions?expand=transitions.fields ``` +## Jira Service Accounts Are Not Supported + +Jira Cloud Service Accounts (created via Atlassian's admin console) use a different API host than standard user accounts and are **not currently supported** by DefectDojo's Jira integration. Attempting to use a Service Account API token or OAuth 2.0 credentials from a Service Account will result in HTTP 403 errors. + +To set up the Jira integration, create a standard Jira user account (with a valid email address) and generate an API token from that account. If you want to clearly identify issues created by DefectDojo, create a dedicated user named something like "DefectDojo" and use its API token for the integration. + ## I can't find an Epic Name ID for my Space Certain Spaces in Jira, such as Team-Managed Spaces, do not use Epics and therefore will not have an Epic Name ID. In this case, set Epic Name ID to 0 in DefectDojo. diff --git a/docs/content/issue_tracking/pro_integration/integrations.md b/docs/content/issue_tracking/pro_integration/integrations.md index a52b35848fb..4be4e89b1e5 100644 --- a/docs/content/issue_tracking/pro_integration/integrations.md +++ b/docs/content/issue_tracking/pro_integration/integrations.md @@ -5,6 +5,8 @@ audience: pro aliases: - /en/share_your_findings/integrations --- +**Availability:** Integrations is currently in **Beta** and is only available for **Cloud-hosted** DefectDojo Pro instances. On-premise deployments do not yet have the required infrastructure to support Integrations. If you are an on-premise customer interested in this feature, please contact [support@defectdojo.com](mailto:support@defectdojo.com) for updates on availability. + DefectDojo Pro's Integrations let you push your Findings and Finding Groups to ticket tracking systems to easily integrate security remediation with your teams existing development workflow. Supported Integrations: diff --git a/docs/content/metrics_reports/dashboards/Introduction_dashboard.md b/docs/content/metrics_reports/dashboards/Introduction_dashboard.md index 3599392f46a..927d27de0e4 100644 --- a/docs/content/metrics_reports/dashboards/Introduction_dashboard.md +++ b/docs/content/metrics_reports/dashboards/Introduction_dashboard.md @@ -62,7 +62,7 @@ Select **Reset Dashboard Configuration** from the same menu to restore defaults. * **Customizable Dashboard Tiles**, which you can use to visualize the metrics which are relevant to you. * **Pre\-built Dashboard Charts**, which visualize your team’s overall performance. -Each team member shares a single dashboard, but the results of the dashboard are restricted by their role and Product Membership. Team members will only see calculated stats for the Products, Engagements, Findings or other objects that they have access to. For more information, see our guides on [User Permissions and Roles](https://docs.defectdojo.com/en/user_management/about-permissions--roles/). +Each team member shares a single dashboard, but the results of the dashboard are restricted by their role and Product Membership. Team members will only see calculated stats for the Products, Engagements, Findings or other objects that they have access to. For more information, see our guides on [User Permissions and Roles](/admin/user_management/about_perms_and_roles). ### Dashboard Tiles @@ -78,7 +78,7 @@ Tiles can: Tiles are pinned to the top section of your **🏠 Home** page. -To learn how to add and use dashboard tiles, see our [guide](../about_custom_dashboard_tiles). +To learn how to add and use dashboard tiles, see our [guide](/metrics_reports/dashboards/about_custom_dashboard_tiles). ### Dashboard Charts @@ -90,7 +90,7 @@ Located beneath Dashboard Tiles, DefectDojo has five pre\-built charts: * **Top 10 Graded Products** table * **Bottom 10 Graded Products** table -These charts can be added or removed from the dashboard via **[Dashboard Configuration](https://docs.defectdojo.com/en/dashboard/how-to-edit-dashboard-configuration/)**. +These charts can be added or removed from the dashboard via **Dashboard Configuration**. #### Historical Finding Severity diff --git a/docs/content/releases/os_upgrading/2.58.md b/docs/content/releases/os_upgrading/2.58.md new file mode 100644 index 00000000000..7155dca47bd --- /dev/null +++ b/docs/content/releases/os_upgrading/2.58.md @@ -0,0 +1,28 @@ +--- +title: 'Upgrading to DefectDojo Version 2.58.x' +toc_hide: true +weight: -20260504 +description: Notification .tpl templates relocated under dojo/notifications/ +--- + +## Notification `.tpl` templates relocated + +The notification domain has been consolidated under a new `dojo/notifications/` package, and the 62 channel `.tpl` templates that drive alert, mail, MS Teams, Slack, and webhook notifications have moved on disk. The Django template lookup name (e.g. `notifications/mail/scan_added.tpl`) is unchanged, so most customizations keep working without any edits — but operators who override `.tpl` files by mounting them into the source tree need to update their paths. + +### What moved + +The channel templates under `alert/`, `mail/`, `msteams/`, `slack/`, `webhooks/`, and `webhooks_summary/` have been relocated: + +| Old on-disk location | New on-disk location | +| --- | --- | +| `dojo/templates/notifications/{channel}/{event}.tpl` | `dojo/notifications/templates/notifications/{channel}/{event}.tpl` | + +For example, `dojo/templates/notifications/mail/scan_added.tpl` now lives at `dojo/notifications/templates/notifications/mail/scan_added.tpl`. A new `TEMPLATES["DIRS"]` entry pointing at `dojo/notifications/templates/` is registered automatically, so the lookup path used by `render_to_string()` (e.g. `notifications/slack/sla_breach.tpl`) resolves exactly as before. + +### Required actions + +- **Customizing `.tpl` files via your own templates directory (recommended pattern):** No action required. Overrides resolved by lookup name continue to take precedence. +- **Customizing `.tpl` files via a Docker volume mount or in-tree patch at the old `dojo/templates/notifications/...` path:** Update the mount/patch target to the new `dojo/notifications/templates/notifications/...` path, or move your override into a project-level templates directory keyed by the lookup name. +- **No customizations:** No action required. + +For more information, check the [Release Notes](https://github.com/DefectDojo/django-DefectDojo/releases/tag/2.58.0). diff --git a/docs/content/releases/pro/changelog.md b/docs/content/releases/pro/changelog.md index 4caa1e784f5..db40a8f77a9 100644 --- a/docs/content/releases/pro/changelog.md +++ b/docs/content/releases/pro/changelog.md @@ -10,6 +10,62 @@ Here are the release notes for **DefectDojo Pro (Cloud Version)**. These release For Open Source release notes, please see the [Releases page on GitHub](https://github.com/DefectDojo/django-DefectDojo/releases), or alternatively consult the Open Source [upgrade notes](/releases/os_upgrading/upgrading_guide/). +## Apr 2026: v2.57 + +### Apr 27, 2026: v2.57.3 + +* **(Pro UI)** Asset menu now shows the Permissions tab for users with an inherited Organization role. +* **(Pro UI)** Added an Environment column to the Test list and Findings list. +* **(Pro UI)** Asset hierarchy refreshes immediately after editing an asset, so changes are reflected without a manual reload. +* **(Pro UI)** Standardized the "Test Type" label and split Test and Test Type into separate columns on the test list. +* **(Pro UI)** Corrected the Product column label on the Group page under the V3 relabeling. +* **(Pro UI)** Removed the duplicate greeting message shown after login. +* **(Performance)** Create-path notifications are now dispatched asynchronously, removing a source of slow POST latency. +* **(Deployment)** On premise deployments now include the Orchestrator services. +* **(Notifications)** Improved the format and display of SLA breach notifications. +* **(Engineer Metrics)** Fixed a KeyError that could be raised when loading the Engineer Metrics page. +* **(Tools)** Contrast parser no longer collapses distinct findings that share a rule name. +* **(Tools)** Dependency Track parser no longer drops vulnerability IDs when `aliases` is empty. +* **(Tools)** Added WatchGuard security advisories as a supported Vulnerability ID source. + +### Apr 20, 2026: v2.57.2 + +* **(Pro UI)** Search and filter state is now preserved when closing a Finding from a Finding list, so you don't lose your place after editing. +* **(Risk Acceptance)** Bulk Edit no longer leaves Simple Risk Acceptance findings in an inconsistent "Active + Risk Accepted" state. Reactivating a previously risk-accepted Finding now behaves correctly. +* **(Risk SLA)** Creating a Risk SLA no longer silently coerces unchecked `enforce_*_risk` options to `True`. +* **(Surveys)** Fixed survey access for both authenticated users and anonymous links. +* **(Universal Parser)** Non-ASCII scan names no longer cause a `UnicodeEncodeError` on import. CSV files with `""`-escaped quotes in multiline fields now parse correctly. +* **(API)** Import/Reimport now validates consistency between ID-based and name-based identifiers, catching mismatched payloads earlier. +* **(Permissions)** Moving an Engagement between Products now requires appropriate permission on both the source and target Product. +* **(Reports)** Fixed a CSS overflow issue in rendered reports. Cleaned up endpoint template rendering for user fields. +* **(Tools)** `govulncheck` parser now records `fix_available` and `fix_version`. Risk Recon parser now validates URLs via a shared SSRF utility. Added Mozilla Foundation security advisories as a supported Vulnerability ID source. + +### Apr 13, 2026: v2.57.1 + +* **(Pro UI)** Object-level history views no longer default to a 31-day date filter, so the full history is visible on load. +* **(Pro UI)** Audit Log "changes" filter now searches only the names of changed fields, reducing false matches. +* **(Pro UI)** Predefined Finding filters now sync UI state correctly, so the active filter indicator reflects the applied filter. +* **(Deduplication)** Added a UI for global component deduplication settings, behind a feature flag. +* **(Rules Engine)** Fixed a preview timeout that occurred when rules were previewed against large Finding sets. +* **(Universal Parser)** CSV/XML query path now displays correctly in the Universal Parser UI. +* **(Import)** Additional parameters are now stored in import settings, making them available for reuse on reimport. +* **(Tools)** Wazuh 4.8 parser now correctly attaches endpoints and locations to findings. +* **(Tools)** Invicti parser now uses `FirstSeenDate` when populating Finding dates when `DD_USE_FIRST_SEEN` is enabled. +* **(Tools)** `govulncheck` parser fixed for NDJSON output. +* **(Tools)** Added CNNVD as a supported Vulnerability ID source. + +### Apr 7, 2026: v2.57.0 + +* **(Custom Enrichment)** On-prem administrators can now configure custom URLs for EPSS and KEV enrichment data sources under **Settings → Finding Enrichment Settings**. Each source (EPSS scores and CISA Known Exploited Vulnerabilities) can be independently enabled and pointed to an internal mirror or proxy. A **Test Configuration** button validates connectivity before saving. Findings with CVE IDs are automatically enriched with EPSS score/percentile and KEV status during enrichment runs. +* **(Performance)** Optimized API response times across all endpoints with selective field loading and conditional prefetches. +* **(Performance)** Improved Dashboard load times by eliminating redundant authorization queries and caching license lookups. +* **(Performance)** Improved deduplication performance by batching duplicate marking and deferring large text fields. +* **(Performance)** Improved false-positive history processing performance during async imports by using batch operations. +* **(Pro UI)** Asset hierarchy filter dropdowns now only show relevant options (e.g., Parent filter shows only assets that have children). +* **(Security)** Hardened container configurations for improved runtime security. +* **(Universal Parser)** Added a list view and field mappings modal to the Pro UI for managing Universal Parser configurations. +* **(Universal Parser)** Added support for 7 new fields: `file_path`, `component_name`, `component_version`, `line`, `steps_to_reproduce`, `severity_justification`, and CVSSv4 vectors. + ## Mar 2026: v2.56 ### Mar 30, 2026: v2.56.4 @@ -107,23 +163,23 @@ No significant UX changes. ## Dec 2025: v2.53 -### Dec 29, 2025: v2.53.5 +#### Dec 29, 2025: v2.53.5 * **(Pro UI)** Added Finding count columns to Engagement table. * **(Pro UI)** Enter/Return no longer automatically submits forms. -### Dec 22, 2025: v2.53.4 +#### Dec 22, 2025: v2.53.4 * **(Pro UI)** Asset Hierarchy now uses separate tabs for Asset selection and for the rendered Asset tree: ![image](images/asset-hierarchy-2.53.4.png) -### Dec 15, 2025: v2.53.3 +#### Dec 15, 2025: v2.53.3 *DefectDojo v2.53.2 does not have a corresponding Pro release.* * **(Connectors)** Support for private CA certificates has been added to Connectors to assist with connectivity. -### Dec 8, 2025: v2.53.1 +#### Dec 8, 2025: v2.53.1 * **(Assets/Organizations)** Introduced overhaul to Products/Product Types, added the ability to create and diagram relationships between Assets. See [Assets/Organizations documentation](/asset_modelling/hierarchy/pro__assets_organizations/) for details, and information on opting in to the Beta. * **(Findings)** Added new KEV fields for ransomware, exploits, and date handling. @@ -131,7 +187,7 @@ No significant UX changes. ![image](images/pro_tablepreferences.png) -### Dec 1, 2025: v2.53.0 +#### Dec 1, 2025: v2.53.0 * **(Pro UI)** Added Asset Hierarchy. * **(Priority)** Priority and Risk can now be overridden manually, or through Rules Engine. diff --git a/docs/content/releases/pro/ddorch-database.md b/docs/content/releases/pro/ddorch-database.md new file mode 100644 index 00000000000..299d493a458 --- /dev/null +++ b/docs/content/releases/pro/ddorch-database.md @@ -0,0 +1,174 @@ +--- +title: "Adding the dd-orch Database on Upgrade" +toc_hide: true +weight: -20260501 +description: "Provisioning the dojodb-ddorch PostgreSQL database and pointing DefectDojo Pro at it on an existing self-hosted installation." +audience: pro +--- + +Starting with 2.57.3, DefectDojo Pro requires a second PostgreSQL database, `dojodb-ddorch`, used by the new `ddorch` orchestrator service. The existing `dojodb` database continues to be used by the main Django application. + +This guide walks through adding `dojodb-ddorch` to an existing self-hosted PostgreSQL instance and pointing DefectDojo at it. + +## Prerequisites + +- PostgreSQL 16 is already installed and running on the DB server. +- The `dojodbusr` role already exists with a known password. +- `dojodb` is already created and reachable from the DefectDojo app server. +- `listen_addresses` in `postgresql.conf` is already configured for remote access. +- You have upgraded to the release that ships the `ddorch` and `ddorch-workers` services. + +> **A note on the database name:** `dojodb-ddorch` contains a hyphen, so it must be double-quoted in every SQL statement (`"dojodb-ddorch"`). + +## Part 1: Provision the Database + +### 1. Create the new database + +On the PostgreSQL server, open a `psql` session as the `postgres` superuser: + +```bash +sudo -i -u postgres psql --username postgres +``` + +Create the database, grant privileges to the existing `dojodbusr` role, and transfer ownership: + +```sql +CREATE DATABASE "dojodb-ddorch"; +GRANT ALL PRIVILEGES ON DATABASE "dojodb-ddorch" TO dojodbusr; +ALTER DATABASE "dojodb-ddorch" OWNER TO dojodbusr; +\q +``` + +**Example session:** + +``` +root@dbserver:~# sudo -i -u postgres psql --username postgres +psql (16.8) +Type "help" for help. + +postgres=# CREATE DATABASE "dojodb-ddorch"; +CREATE DATABASE +postgres=# GRANT ALL PRIVILEGES ON DATABASE "dojodb-ddorch" TO dojodbusr; +GRANT +postgres=# ALTER DATABASE "dojodb-ddorch" OWNER TO dojodbusr; +ALTER DATABASE +postgres=# \q +``` + +> **PostgreSQL 15+ note:** Ownership covers schema rights for the owner, but if you ever connect as a non-owner role you will also need to grant schema privileges inside the new database: +> +> ```sql +> \c "dojodb-ddorch" +> GRANT ALL ON SCHEMA public TO dojodbusr; +> ``` + +### 2. Allow the app server to connect + +Edit `/etc/postgresql/16/main/pg_hba.conf` and add a new line for `dojodb-ddorch` next to the existing `dojodb` entry. + +**(a) Preferred — restrict to the DefectDojo app server's IP.** + +Supposing the app server's IP is `9.9.9.9`, add: + +``` +host dojodb-ddorch dojodbusr 9.9.9.9/32 scram-sha-256 +host postgres dojodbusr 9.9.9.9/32 scram-sha-256 +``` + +**(b) Alternative — allow from any host.** + +``` +host dojodb-ddorch dojodbusr 0.0.0.0/0 scram-sha-256 +host postgres dojodbusr 0.0.0.0/0 scram-sha-256 +``` + +> **Note:** The lines in `pg_hba.conf` are whitespace-delimited. The easiest way to add this line is to copy/paste the existing `dojodb` line and change the database name. + +**Alternative using `echo` (if no text editor is available):** + +```bash +# For specific IP (replace 9.9.9.9 with your app server IP): +echo "host dojodb-ddorch dojodbusr 9.9.9.9/32 scram-sha-256" | sudo tee -a /etc/postgresql/16/main/pg_hba.conf +echo "host postgres dojodbusr 9.9.9.9/32 scram-sha-256" | sudo tee -a /etc/postgresql/16/main/pg_hba.conf + +# OR for all hosts: +echo "host dojodb-ddorch dojodbusr 0.0.0.0/0 scram-sha-256" | sudo tee -a /etc/postgresql/16/main/pg_hba.conf +echo "host postgres dojodbusr 0.0.0.0/0 scram-sha-256" | sudo tee -a /etc/postgresql/16/main/pg_hba.conf + +``` + +### 3. Reload PostgreSQL + +Changes to `pg_hba.conf` only require a reload — no restart is needed: + +```bash +sudo systemctl reload postgresql +``` + +Verify the reload was picked up: + +```bash +sudo systemctl status postgresql +``` + +### 4. Verify connectivity from the app server + +From the **DefectDojo app server**, confirm `dojodbusr` can reach the new database. Replace `` with your DB server's IP and `` with the password set for `dojodbusr`: + +```bash +psql "host= dbname=dojodb-ddorch user=dojodbusr password=" -c "SELECT 1;" +``` + +A successful response of `?column?` with a value of `1` confirms the database is reachable and the credentials are valid. + +## Part 2: Point DefectDojo at the New Database + +Only the `ddorch` service connects to the new database directly. The main Django application reaches the orchestrator over gRPC, so `DD_DATABASE_URL` does **not** change. + +### 1. Set the orchestrator database URL + +The `ddorch` service reads its connection string from the `DD_DATABASE_URL` environment variable and **automatically appends `-ddorch` to the database name** in whatever URL you pass it. This means you can reuse the same connection string you already use for the main Django application — no need to construct a second URL by hand. + +On startup, ddorch rewrites the database name in this URL from `dojodb` to `dojodb-ddorch` and connects to the database you created in Part 1. + +### 2. Restart the orchestrator services + +From the deployment directory, recreate the two orchestrator containers so they pick up the new environment: + +```bash +docker compose up -d ddorch ddorch-workers +``` + +Docker Compose will detect the environment change and recreate the containers. The `ddorch` service runs its own schema migrations against `dojodb-ddorch` on startup — no manual migration command is required. + +### 3. Verify ddorch connected and migrated the new database + +The most direct signal that the database is correctly wired up is the ddorch startup log. Check the last hundred lines: + +```bash +docker compose logs ddorch --tail=100 +``` + +Look for three log lines in sequence: + +``` +{"level":"INFO","msg":"Appending database name to DATABASE_URL","from":"dojodb","to":"dojodb-ddorch"} +INFO Running migrations current_schema_version= next_version= migrations_to_apply= +{"level":"INFO","msg":"starting server","port":9871} +``` + +What each line proves: + +- **`Appending database name to DATABASE_URL ... to: dojodb-ddorch`** — ddorch received your URL and derived the orch database name correctly. +- **`Running migrations ... migrations_to_apply=0`** — ddorch connected to `dojodb-ddorch` and found the schema at the expected version. On a first-ever boot against a fresh database you may see `migrations_to_apply=` with a non-zero value and no subsequent error — this means ddorch just created the tables from scratch. Both outcomes indicate success. +- **`starting server ... port:9871`** — ddorch is up and listening. + +If instead you see an error such as `FATAL: password authentication failed`, `no pg_hba.conf entry for host`, or `database "dojodb-ddorch" does not exist`, the database is not reachable — revisit Part 1 before proceeding. + +Also confirm both orchestrator containers are running: + +```bash +docker compose ps ddorch ddorch-workers +``` + +Both should report `Up`. With ddorch migrated and the workers container running, your installation is now using the new `dojodb-ddorch` database. diff --git a/docs/content/supported_tools/parsers/api/sonarqube.md b/docs/content/supported_tools/parsers/api/sonarqube.md index c6299ad9f18..2d0117ea6f1 100644 --- a/docs/content/supported_tools/parsers/api/sonarqube.md +++ b/docs/content/supported_tools/parsers/api/sonarqube.md @@ -31,6 +31,23 @@ In `Add API Scan Configuration` - If using SonarCloud, the organization ID can be used from step 1, but it can be overridden by supplying a different organization ID in the `Service key 2` input field. +## Disabling Hotspot Imports + +By default, the SonarQube API Import includes both security issues and security hotspots. To import only security issues and exclude hotspots, set the following environment variable on your DefectDojo instance: + +``` +DD_SONARQUBE_API_PARSER_HOTSPOTS=False +``` + +For on-premise installations using the dojo-compose-cli: + +```bash +dojo-compose-cli environment add --key DD_SONARQUBE_API_PARSER_HOTSPOTS --value "False" +dojo-compose-cli app stop && dojo-compose-cli app start +``` + +Note that this setting is instance-wide and affects all SonarQube API imports. There is currently no per-tool-configuration or per-import toggle for hotspots. If you need hotspots for some projects but not others, you will need to build a custom middleware to filter results before importing. + ## Multiple SonarQube API Configurations In the import or re-import dialog, you can select which `API Scan diff --git a/docs/content/supported_tools/parsers/file/qualys_vmdr.md b/docs/content/supported_tools/parsers/file/qualys_vmdr.md new file mode 100644 index 00000000000..a4ac41fc283 --- /dev/null +++ b/docs/content/supported_tools/parsers/file/qualys_vmdr.md @@ -0,0 +1,149 @@ +--- +title: "Qualys VMDR" +toc_hide: true +--- + +The [Qualys VMDR](https://www.qualys.com/apps/vulnerability-management-detection-response/) parser for DefectDojo supports imports from CSV format. This parser handles both QID-centric and CVE-centric export variants from Qualys VMDR (Vulnerability Management, Detection, and Response). + +## Supported File Types + +The Qualys VMDR parser accepts CSV file format in two variants: + +**QID Format:** Primary vulnerability identifier is the Qualys QID +**CVE Format:** Includes CVE identifiers and CVSS scores from NVD + +To generate these files from Qualys VMDR: + +1. Log into your Qualys VMDR console +2. Navigate to Vulnerabilities > Vulnerability Management +3. Select the assets or vulnerabilities to export +4. Click "Download" and select CSV format +5. Choose either QID-centric or CVE-centric export option +6. Upload the downloaded CSV file to DefectDojo + +## Default Deduplication + +The parser uses `DEDUPE_ALGO_UNIQUE_ID_FROM_TOOL_OR_HASH_CODE`, which tries `unique_id_from_tool` (populated with the Qualys QID) first and falls back to hashcode deduplication. + +**Hashcode fields:** `title`, `component_name`, `vuln_id_from_tool` + +For more information, see [About Deduplication](https://docs.defectdojo.com/en/working_with_findings/finding_deduplication/about_deduplication/). + +### Sample Scan Data + +Sample Qualys VMDR scans can be found in the [sample scan data folder](https://github.com/DefectDojo/django-DefectDojo/tree/master/unittests/scans/qualys_vmdr). + +## Link To Tool + +- [Qualys VMDR](https://www.qualys.com/apps/vulnerability-management-detection-response/) +- [Qualys Documentation](https://www.qualys.com/documentation/) + +## QID Format (Primary Export) + +### QID Format Field Mapping + +
+Click to expand Field Mapping Table + +| Source Field | DefectDojo Field | Notes | +| ------------ | ---------------- | ----- | +| Title | title | Truncated to 500 characters | +| Severity | severity | Mapped: 1=Info, 2=Low, 3=Medium, 4=High, 5=Critical | +| Severity | severity_justification | Preserved as "Qualys Severity: X" | +| QID | unique_id_from_tool | Native Qualys vulnerability identifier | +| QID | vuln_id_from_tool | Also used as vulnerability ID | +| First Detected | date | Parsed to date object | +| Status | active | True if "ACTIVE", False otherwise | +| Solution | mitigation | Remediation guidance | +| Threat | impact | Threat description | +| Asset Name | component_name | Asset/server name | +| Category | service | Vulnerability category | +| Asset IPV4 | unsaved_endpoints | Multiple endpoints if comma-separated | +| Asset IPV6 | unsaved_endpoints | Fallback if no IPv4 | +| Asset Tags | unsaved_tags | Split on comma | +| Results | description | Included in structured description | + +
+ +### Additional Finding Settings (QID Format) + +| Finding Field | Default Value | Notes | +|---------------|---------------|-------| +| static_finding | True | Vulnerability scan data | +| dynamic_finding | False | Not dynamic testing | + +## CVE Format (Extended Export) + +### CVE Format Field Mapping + +
+Click to expand Field Mapping Table + +| Source Field | DefectDojo Field | Notes | +| ------------ | ---------------- | ----- | +| CVE | vuln_id_from_tool | CVE identifier (e.g., CVE-2021-44228) | +| CVE | unsaved_vulnerability_ids | Also added for CVE tracking | +| CVE-Description | description | Prepended to structured description | +| CVSSv3.1 Base (nvd) | cvssv3_score | Numeric CVSS score | +| Title | title | Truncated to 500 characters | +| Severity | severity | Mapped: 1=Info, 2=Low, 3=Medium, 4=High, 5=Critical | +| Severity | severity_justification | Preserved as "Qualys Severity: X" | +| QID | unique_id_from_tool | Native Qualys vulnerability identifier | +| First Detected | date | Parsed to date object | +| Status | active | True if "ACTIVE", False otherwise | +| Solution | mitigation | Remediation guidance | +| Threat | impact | Threat description | +| Asset Name | component_name | Asset/server name | +| Category | service | Vulnerability category | +| Asset IPV4 | unsaved_endpoints | Multiple endpoints if comma-separated | +| Asset IPV6 | unsaved_endpoints | Fallback if no IPv4 | +| Asset Tags | unsaved_tags | Split on comma | +| Results | description | Included in structured description | + +
+ +### Additional Finding Settings (CVE Format) + +| Finding Field | Default Value | Notes | +|---------------|---------------|-------| +| static_finding | True | Vulnerability scan data | +| dynamic_finding | False | Not dynamic testing | + +## Special Processing Notes + +### Severity Conversion + +Qualys severity levels (1-5 numeric scale) are converted to DefectDojo severity levels: +- `1` → Info +- `2` → Low +- `3` → Medium +- `4` → High +- `5` → Critical + +The original Qualys severity is preserved in the severity_justification field as "Qualys Severity: X". + +### Endpoint Handling + +The parser creates Endpoint objects from IP addresses: +- Multiple IPv4 addresses (comma-separated) create multiple endpoints +- Falls back to IPv6 if no IPv4 address is present + +### CSV Format Handling + +Qualys VMDR exports use a non-standard CSV format where each row is wrapped in outer quotes and fields are delimited by `,""` instead of standard `","`. The parser automatically detects and handles both standard and non-standard CSV formats. + +**Multi-line records:** Qualys fields such as Results and Threat may contain embedded newlines. The parser correctly assembles multi-line records that span multiple lines in the CSV file, including records containing malformed quote patterns in fields like Results. + +**Metadata lines:** Some Qualys exports include 3 metadata lines (report title, date range, column count) before the header row. The parser auto-detects whether metadata is present and skips it accordingly. + +### Data Cleaning + +- **HTML tags** in fields like Threat (mapped to impact) are stripped automatically +- **Qualys null markers** (`'-`) are filtered and treated as empty values +- **Stray quotes** left by the non-standard CSV format are cleaned from field values + +### Format Detection + +The parser automatically detects whether the import file is QID format or CVE format by examining the first column of the header row: +- If first column is "QID" → QID format parser is used +- If first column is "CVE" → CVE format parser is used diff --git a/docs/content/supported_tools/parsers/file/snyk.md b/docs/content/supported_tools/parsers/file/snyk.md index 717cf64323b..07e128f3fab 100644 --- a/docs/content/supported_tools/parsers/file/snyk.md +++ b/docs/content/supported_tools/parsers/file/snyk.md @@ -2,16 +2,119 @@ title: "Snyk" toc_hide: true --- -Snyk output file (snyk test \--json \> snyk.json) can be imported in -JSON format. Only SCA (Software Composition Analysis) report is supported (SAST report not supported yet). + +Snyk output file can be imported in JSON format. Snyk is a developer-first +security platform that identifies vulnerabilities in open source dependencies +(SCA) and application code (SAST). DefectDojo currently supports the SCA +report format via the Snyk parser. For SAST findings, use the +[Snyk Code](../snyk_code) parser instead. ### Sample Scan Data + Sample Snyk scans can be found [here](https://github.com/DefectDojo/django-DefectDojo/tree/master/unittests/scans/snyk). -### Default Deduplication Hashcode Fields -By default, DefectDojo identifies duplicate Findings using these [hashcode fields](https://docs.defectdojo.com/en/working_with_findings/finding_deduplication/about_deduplication/): +--- + +## Supported Report Types + +| Report Type | Supported | Parser | +|---|---|---| +| Snyk SCA (Open Source) | ✅ Yes | Snyk | +| Snyk SAST (Code) | ✅ Yes | Snyk Code | +| Snyk Issue API | ✅ Yes | Snyk Issue API | + +This page covers the **Snyk SCA (Open Source)** parser only. + +--- + +## How to Export from Snyk + +### Option 1 — Snyk Web UI (Recommended for Enterprise Use) + +1. Log in to your Snyk account at **app.snyk.io** +2. Navigate to your **Organization** and select the **Project** you want + to export +3. Click on the project to open the vulnerability list +4. Click the **Export** button at the top right of the findings list +5. Select **JSON** as the export format +6. Save the exported file + +### Option 2 — Snyk CLI + +If you prefer to export via the command line: + +```bash +snyk test --json > snyk.json +``` + +For monorepos or projects with multiple package managers, scan all +projects at once: + +```bash +snyk test --all-projects --json > snyk.json +``` + +For specific package managers: + +```bash +# For npm projects +snyk test --json --file=package.json > snyk.json + +# For Maven projects +snyk test --json --file=pom.xml > snyk.json + +# For Python projects +snyk test --json --file=requirements.txt > snyk.json +``` + +Once you have the JSON file, upload it into DefectDojo under your chosen +Engagement using **Import Scan > Snyk Scan**. + +--- + +## Severity Mapping + +Snyk uses its own severity model which maps to DefectDojo as follows: + +| Snyk Severity | DefectDojo Severity | +|---|---| +| Critical | Critical | +| High | High | +| Medium | Medium | +| Low | Low | + +--- + +## Recommended Workflow for Enterprise Use + +For teams running Snyk across multiple applications and repositories: + +1. **Use Reimport** (not Import) for recurring scans on the same target + to track finding status over time rather than creating duplicate records +2. **Export at the project level** rather than the organization level + to maintain clean engagement boundaries in DefectDojo +3. **Set SLA thresholds** in DefectDojo aligned to Snyk severity levels + so that Critical and High findings trigger appropriate remediation + timelines automatically +4. **Use Snyk's CI/CD integration** to export JSON automatically as part + of your pipeline and feed results into DefectDojo via the API for + continuous vulnerability tracking + +--- + +## Default Deduplication Hashcode Fields + +By default, DefectDojo identifies duplicate Findings using these +[hashcode fields](https://docs.defectdojo.com/en/working_with_findings/finding_deduplication/about_deduplication/): - vuln id from tool - file path - component name - component version + +### Note on Deduplication + +Snyk can report the same vulnerability across multiple projects or +package versions. When importing findings from multiple Snyk projects +into the same DefectDojo product, review your deduplication settings +to avoid over-counting the same underlying vulnerability. diff --git a/docs/content/supported_tools/parsers/file/xygeni.md b/docs/content/supported_tools/parsers/file/xygeni.md new file mode 100644 index 00000000000..1b8ec32f116 --- /dev/null +++ b/docs/content/supported_tools/parsers/file/xygeni.md @@ -0,0 +1,79 @@ +--- +title: "Xygeni" +toc_hide: true +--- +### About Xygeni +[Xygeni](https://xygeni.io) is a Software Supply Chain Security platform whose +scanners produce JSON reports for code vulnerabilities (SAST), open-source +dependency vulnerabilities (SCA), hard-coded secrets, IaC flaws, web-application +vulnerabilities (DAST), CI/CD and SCM misconfigurations, and malicious or +suspect components. + +This parser handles three Xygeni scan kinds in phase 1: **SAST**, **SCA**, and +**Secrets**. All three share a common `metadata` envelope; the parser +dispatches on `metadata.scanType`. + +### Scan Types +| Scan type | `metadata.scanType` | Xygeni CLI command (typical) | +| ------------------------ | ------------------- | ---------------------------- | +| `Xygeni SAST Scan` | `sast` | `xygeni scan --scan-type=sast --format=json` | +| `Xygeni SCA Scan` | `deps` | `xygeni scan --scan-type=deps --format=json` | +| `Xygeni Secrets Scan` | `secrets` | `xygeni scan --scan-type=secrets --format=json` | + +See the Xygeni documentation at for installation and +the full set of CLI options. + +### Acceptable JSON Format +All three scan types share the same envelope: + +~~~ +{ + "metadata": { + "uuid": "...", + "timestamp": "2026-04-26T07:08:29Z", + "projectName": "...", + "scanType": "sast" | "deps" | "secrets", + "format": "-xygeni", + "reportProperties": { + "tool.name": "Xygeni", + "tool.version": "..." + } + }, + ... +} +~~~ + +The kind-specific payload then follows: + +- **SAST** — `vulnerabilities[]` — each entry carries `detector` (the rule id), + `severity`, `location.{filepath, beginLine, endLine, code}`, `cwe` / + `cwes[]`, `tags[]`, `explanation`, `uniqueHash`, `issueId`, and an optional + `codeFlows[]` block describing source / sink frames and the data path. +- **SCA** — `dependencies[]` — each dependency has `name`, `version`, + `ecosystem`, and a nested `vulnerabilities[]` of CVE/GHSA advisories with + `cve`, `cwes`, `fixedVersion`, `aliases`, `overallCvssScore`, `references`, + `description`, `uniqueHash`, `issueId`. +- **Secrets** — `secrets[]` — each entry has `type` (e.g. + `aws_access_key`), `detector`, `severity`, `location` (same shape as SAST), + `description`, `tags`, `uniqueHash`, `issueId`. The `secret` value and + `location.code` are already redacted by the Xygeni CLI before serialisation. + +### Sample Scan Data +Sample Xygeni JSON reports can be found +[here](https://github.com/DefectDojo/django-DefectDojo/tree/master/unittests/scans/xygeni). + +### Deduplication + +Every finding carries `unique_id_from_tool` (set from Xygeni's vendor-stable +`uniqueHash`) and `vuln_id_from_tool` (set from `issueId`). The deduplication +algorithm is configured per scan type: + +| Scan type | Algorithm | Hash-code fields (fallback) | +| -------------------- | ---------------------------------- | -------------------------------------------------------------- | +| Xygeni SAST Scan | `unique_id_from_tool` | n/a | +| Xygeni SCA Scan | `unique_id_from_tool_or_hash_code` | `vulnerability_ids`, `component_name`, `component_version` | +| Xygeni Secrets Scan | `unique_id_from_tool` | n/a | + +For SCA the hash-code fallback enables cross-tool deduplication: the same +CVE on the same package@version reported by Xygeni and another SCA scanner +(Snyk, Trivy, etc.) collapse into a single Finding. diff --git a/docs/content/triage_findings/finding_deduplication/PRO__deduplication_tuning.md b/docs/content/triage_findings/finding_deduplication/PRO__deduplication_tuning.md index 998b44bb7d4..93ee79443c1 100644 --- a/docs/content/triage_findings/finding_deduplication/PRO__deduplication_tuning.md +++ b/docs/content/triage_findings/finding_deduplication/PRO__deduplication_tuning.md @@ -34,7 +34,7 @@ To adjust Same Tool Deduplication: ### Available Deduplication Algorithms -DefectDojo Pro offers three deduplication methods for same-tool deduplication: +DefectDojo Pro offers the following deduplication methods for same-tool deduplication: #### Hash Code Uses a combination of selected fields to generate a unique hash. When selected, a third dropdown will appear showing the fields being used to calculate the hash. @@ -47,6 +47,9 @@ This algorithm can be useful when working with SAST scanners, or situations wher #### Unique ID From Tool or Hash Code Attempts to use the tool's unique ID first, then falls back to the hash code if no unique ID is available. This provides the most flexible deduplication option. +#### Global Component +Matches findings by component name and version across **all Products** in the instance, rather than within a single Product or Engagement. Intended for SCA tools where the same vulnerable dependency appears in many Products. This algorithm is off by default and must be enabled by DefectDojo Support. See [Global Component Deduplication](/triage_findings/finding_deduplication/pro__global_component_deduplication/) for details. + ## Cross Tool Deduplication Cross Tool Deduplication is disabled by default, as deduplication between different security tools requires careful configuration due to variations in how tools report the same vulnerabilities. @@ -59,7 +62,7 @@ To enable Cross Tool Deduplication: 2. Change the **Deduplication Algorithm** from "Disabled" to "Hash Code" 3. Select which fields should be used for generating the hash in the **Hash Code Fields** dropdown -Unlike Same Tool Deduplication, Cross Tool Deduplication only supports the Hash Code algorithm, as different tools rarely share compatible unique identifiers. +Cross Tool Deduplication supports the Hash Code algorithm, which is suitable for most workflows, as different tools rarely share compatible unique identifiers. For SCA tools reporting the same dependencies, [Global Component Deduplication](/triage_findings/finding_deduplication/pro__global_component_deduplication/) is also available as a cross-tool option (off by default). ## Reimport Deduplication @@ -76,7 +79,7 @@ When configuring Reimport Deduplication: 1. Select the **Security Tool** (Universal or Generic Parser) 2. Choose the appropriate **Deduplication Algorithm** -The same three algorithm options are available for Reimport Deduplication as for Same Tool Deduplication: +The following algorithm options are available for Reimport Deduplication: - Hash Code - Unique ID From Tool - Unique ID From Tool or Hash Code diff --git a/docs/content/triage_findings/finding_deduplication/PRO__global_component_deduplication.md b/docs/content/triage_findings/finding_deduplication/PRO__global_component_deduplication.md new file mode 100644 index 00000000000..3fc4116287d --- /dev/null +++ b/docs/content/triage_findings/finding_deduplication/PRO__global_component_deduplication.md @@ -0,0 +1,87 @@ +--- +title: "Global Component Deduplication (Pro)" +description: "Deduplicate Software Composition Analysis Findings by component name and version across all Products" +weight: 5 +audience: pro +--- + +Global Component Deduplication is a DefectDojo Pro algorithm that identifies duplicate Findings across **all Products** based on the component name and version they reference. It is intended for Software Composition Analysis (SCA) tools, where the same vulnerable dependency (for example, `timespan@2.3.0`) may appear in many Products, and you want DefectDojo to treat those occurrences as duplicates of a single original Finding. + +Unlike the other deduplication algorithms, Global Component matching is **not scoped to a single Product or Engagement**. A Finding imported into Product B can be marked as a duplicate of an older Finding in Product A, even if the two Products are unrelated. + +## Enabling the Global Component Algorithm + +Global Component Deduplication is gated behind a feature flag and is **off by default**. To request that it be enabled on your instance, contact [DefectDojo Support](mailto:support@defectdojo.com). + +Once the feature is enabled, **Global Component** will become available as an option in the **Deduplication Algorithm** dropdown for both Same Tool and Cross Tool Deduplication settings in the Tuner. + +## Configuring Global Component Deduplication + +Global Component can be applied to Same-Tool Deduplication, Cross-Tool Deduplication, or both, and is configured per security tool from **Settings > Pro Settings > Deduplication Settings**. + +### Same-Tool + +Use Same-Tool Deduplication with the Global Component algorithm when you want to deduplicate findings from a single SCA tool across multiple Products. + +1. Open the **Same Tool Deduplication** tab. +2. Select the SCA tool from the **Security Tool** dropdown (for example, `Dependency Track Finding Packaging Format (FPF) Export`). +3. Set the **Deduplication Algorithm** to **Global Component**. +4. Submit the form. + +Hash Code Fields are not used by this algorithm and are hidden when it is selected. + +### Cross-Tool + +Use Cross-Tool Deduplication with the Global Component algorithm when you want to deduplicate findings of the same component across different SCA tools and Products. + +Cross-tool matching requires Global Component to be configured on **each** tool that should participate. + +1. Open the **Cross Tool Deduplication** tab. +2. For each tool to include: select it from the **Security Tool** dropdown, set the algorithm to **Global Component**, and submit. + +## How Matching Works + +A new Finding is marked as a duplicate of an existing Finding when: + +- The component name and component version match exactly, **and** +- An older Finding with the same component name and version exists anywhere in the DefectDojo instance — in any Product or Engagement. + +Component version matching is exact. A Finding for `timespan@2.3.0` will **not** deduplicate against one for `timespan@2.3.1`. + +The Engagement-scoped deduplication setting is ignored for this algorithm; matching is always global. + +## Example + +Assume Global Component is enabled on `Dependency Track Finding Packaging Format (FPF) Export` (Same Tool) and on a Generic Findings Import tool (Cross Tool): + +| Step | Import | Into Product | Result | +| --- | --- | --- | --- | +| 1 | Dependency Track scan for `timespan@2.3.0` | Application 0 | 1 active Finding created | +| 2 | Same Dependency Track scan | Application 1 | 1 Finding created, marked as duplicate of the Application 0 Finding | +| 3 | Generic Findings Import for `timespan@2.3.0` | Application 2 | 1 Finding created, marked as duplicate of the Application 0 Finding (cross-tool match) | +| 4 | Dependency Track scan for `timespan@2.3.1` | Application 3 | 1 active Finding created — different version, no match | + +Each duplicate Finding shows its original at the bottom of the Finding page in the duplicate chain. + +## Cross-Product Visibility + +Because Global Component matching crosses Product boundaries, the original Finding in a duplicate chain may live in a Product that the user viewing the duplicate does not have permission to access. + +In that case, the Finding is visible and labelled as a duplicate, but the user will not be able to open or navigate to the original. Consider this before enabling Global Component on tools whose Findings are sensitive to Product-level access controls. + +## Reverting + +To stop using Global Component for a given tool, open its Deduplication Settings and switch the algorithm back to one of the scoped options. + +For **Same Tool** Deduplication: + +- Hash Code +- Unique ID From Tool +- Unique ID From Tool or Hash Code + +For **Cross Tool** Deduplication: + +- Hash Code +- Disabled + +Changing the algorithm triggers a background recalculation of deduplication hashes for the tool's existing Findings. diff --git a/docs/content/triage_findings/finding_deduplication/about_deduplication.md b/docs/content/triage_findings/finding_deduplication/about_deduplication.md index da338a8bb12..7050711dcd1 100644 --- a/docs/content/triage_findings/finding_deduplication/about_deduplication.md +++ b/docs/content/triage_findings/finding_deduplication/about_deduplication.md @@ -145,4 +145,5 @@ Sometimes, Deduplication does not work as expected. Here are some examples of w | Reimport closes an old Finding and creates a new one when only the line number changed | Reimport matching uses unstable fields (for example, line number) | Reimport Deduplication (prefer stable IDs or stable hash fields) | | Multiple Findings are created in the same Test that you believe should be duplicates | Deduplication matching is not configured for that tool or scope | Same Tool Deduplication (and consider “Delete Deduplicate Findings” behavior) | | Duplicates are created across different tools | Cross-tool matching is disabled or too strict | Cross Tool Deduplication (Pro only) (hash-based matching) | +| The same SCA dependency imported into multiple Products creates separate Findings instead of duplicates | Deduplication is scoped per Product by default | Global Component Deduplication (Pro only) ([enable for your SCA tools](/triage_findings/finding_deduplication/pro__global_component_deduplication/)) | | Excess duplicates of the same Finding are being created, across Tests | Asset Hierarchy is not set up correctly | [Consider Reimport for continual testing](/triage_findings/finding_deduplication/avoid_excess_duplicates/) | diff --git a/docs/layouts/_partials/head/script-header.html b/docs/layouts/_partials/head/script-header.html index fd66f21e56c..b977aee216a 100644 --- a/docs/layouts/_partials/head/script-header.html +++ b/docs/layouts/_partials/head/script-header.html @@ -1,7 +1,7 @@ - - - - -{% endblock %} diff --git a/dojo/templates/dojo/snippets/endpoints.html b/dojo/templates/dojo/snippets/endpoints.html index e7d4d740ea8..84f10304d00 100644 --- a/dojo/templates/dojo/snippets/endpoints.html +++ b/dojo/templates/dojo/snippets/endpoints.html @@ -72,13 +72,13 @@
Mitigated Endpoints / Systems ({{ finding.mitigated_endpoint_count }})
{% if V3_FEATURE_LOCATIONS %} {{ endpoint.location }}{% if endpoint.is_broken %} 🚩{% endif %} {{ endpoint.status }} - {{ endpoint.auditor|safe }} + {{ endpoint.auditor }} {{ endpoint.audit_time|date }} {% else %} - {% comment %} TODO: Delete this after the move to Locations {% endcomment %} + {% comment %} TODO: Delete this after the move to Locations {% endcomment %} {{ endpoint }}{% if endpoint.endpoint.is_broken %} 🚩{% endif %} {{ endpoint.status }} - {{ endpoint.mitigated_by|safe }} + {{ endpoint.mitigated_by }} {{ endpoint.mitigated_time|date }} {% endif %} @@ -256,7 +256,7 @@

Mitigated Endpoints / Systems ({{ finding.mitigated_endpoint_count }}) {% include "dojo/snippets/tags.html" with tags=endpoint.location.tags.all %} {{ endpoint.get_status_display }} - {{ endpoint.auditor|safe }} + {{ endpoint.auditor }} {{ endpoint.audit_time|date }} {% else %} {% comment %} TODO: Delete this after the move to Locations {% endcomment %} @@ -265,7 +265,7 @@

Mitigated Endpoints / Systems ({{ finding.mitigated_endpoint_count }}) {% include "dojo/snippets/tags.html" with tags=endpoint.endpoint.tags.all %} {{ endpoint.status }} - {{ endpoint.mitigated_by|safe }} + {{ endpoint.mitigated_by }} {{ endpoint.mitigated_time|date }} {% endif %} diff --git a/dojo/templates/dojo/test_pdf_report.html b/dojo/templates/dojo/test_pdf_report.html index 17af82137bc..986ec8fccaa 100644 --- a/dojo/templates/dojo/test_pdf_report.html +++ b/dojo/templates/dojo/test_pdf_report.html @@ -325,15 +325,15 @@

{% if finding.cvssv3 %}
CVSS v3
-
{{ finding.cvssv3|markdown_render }}
+
{{ finding.cvssv3|markdown_render }}
{% endif %}
Description
-
{{ finding.description|markdown_render }}
+
{{ finding.description|markdown_render }}
{% if finding.mitigation %}
Mitigation
-
{{ finding.mitigation|markdown_render }}
+
{{ finding.mitigation|markdown_render }}
{% endif %} {% if finding.get_report_requests %} @@ -350,22 +350,22 @@
Response {{forloop.counter}}
{% if finding.impact %}
Impact
-
{{ finding.impact|markdown_render }}
+
{{ finding.impact|markdown_render }}
{% endif %} {% if finding.steps_to_reproduce %}
Steps to Reproduce
-
{{ finding.steps_to_reproduce|markdown_render }}
+
{{ finding.steps_to_reproduce|markdown_render }}
{% endif %} {% if finding.severity_justification %}
Severity Justification
-
{{ finding.severity_justification|markdown_render }}
+
{{ finding.severity_justification|markdown_render }}
{% endif %} {% if finding.references %}
References
-
{{ finding.references|markdown_render }}
+
{{ finding.references|markdown_render }}
{% endif %} {% if include_finding_images %} diff --git a/dojo/templates/dojo/view_cred.html b/dojo/templates/dojo/view_cred.html deleted file mode 100644 index 2282d283e48..00000000000 --- a/dojo/templates/dojo/view_cred.html +++ /dev/null @@ -1,96 +0,0 @@ -{% extends "base.html" %} -{% load navigation_tags %} -{% load get_config_setting %} -{% load authorization_tags %} -{% block content %} - {{ block.super }} -
-
-
-
-

- Credential Manager - {% if "DB_KEY"|get_config_setting == True and "dojo.add_cred_user"|has_configuration_permission:request %} - - {% endif %} -

-
- -
- {% if confs %} - -
- {% include "dojo/paging_snippet.html" with page=confs page_size=True %} -
-
- - - - - - - - - - - - - {% for conf in confs %} - - - - - - - - - {% endfor %} - -
NameUsernameRoleEnvironmentValidDetails
- {{ conf.name }} - {{ conf.username }}{{ conf.role }}{{ conf.environment }}{{ conf.is_valid }} -
- View - {% if "dojo.change_cred_user"|has_configuration_permission:request %} - Edit - {% endif %} - {% if "dojo.delete_cred_user"|has_configuration_permission:request %} - Delete - {% endif %} -
-
-
-
- {% include "dojo/paging_snippet.html" with page=confs page_size=True %} -
- {% else %} -

No credentials configured.

- {% endif %} - {% if "DB_KEY"|get_config_setting == False %} -

Please configure a randomly generated key called DB_KEY and add to settings.py in dojo/settings/.


- {% endif %} -
-
-{% endblock %} -{% block postscript %} - {{ block.super }} - {% include "dojo/filter_js_snippet.html" %} -{% endblock %} diff --git a/dojo/templates/dojo/view_cred_all_details.html b/dojo/templates/dojo/view_cred_all_details.html deleted file mode 100644 index d75a25b845d..00000000000 --- a/dojo/templates/dojo/view_cred_all_details.html +++ /dev/null @@ -1,308 +0,0 @@ -{% extends "base.html" %} -{% load display_tags %} -{% load get_config_setting %} -{% load static %} -{% block add_styles %} - {{ block.super }} - ul#select_by_severity a:hover, ul#bulk_edit a:hover { - cursor: pointer; - } -{% endblock %} -{% block content %} - {{ block.super }} -
-
-
-

{{cred_type}} Credential

- - -
-
-
- - - - - - - - - - - - - - - - - - - - -
NameAlternate URLUsernamePasswordRoleEnvironmentValid Login
{{ cred.cred_id.name }} - {% if cred_product.url %} - Alternate URL - {% else %} - None Configured - {% endif %} - {{ cred.cred_id.username }}{{ cred.cred_id.password|get_pwd }}{{ cred.cred_id.role }}{{ cred.cred_id.environment }}{{ cred.cred_id.is_valid }}
-
-
- -
-
-
-
-

Login Details

-
-
- - - - - - - - - - - - - - - -
Authentication ProviderAuthentication TypeHTTP AuthenticationLogin RegExLogout RegEx
{{ cred_product.is_authn_provider }}{{ cred.cred_id.authentication }}{{ cred.cred_id.http_authentication }}{{ cred.cred_id.login_regex }}{{ cred.cred_id.logout_regex }}
-
-
-
-
- -
-
-
-
-

Description

-
-
- {{ cred.cred_id.description }} -
-
-
-
- -
-
-

Notes

-
- {% if notes %} - - - - - - - - - - {% for note in notes %} - - - - - - {% endfor %} - - -
UserDateNote
- {{ note.author.username }} - - {{ note.date }} - - {{ note }} -
- {% else %} - -

No notes found.

- {% endif %} -
- -
{% csrf_token %} - {% include "dojo/form_fields.html" with form=form %} -
-
- - -
-
-
-
-
-
-{% endblock %} - -{% block postscript %} - {{ block.super }} - - -{% endblock %} diff --git a/dojo/templates/dojo/view_cred_details.html b/dojo/templates/dojo/view_cred_details.html deleted file mode 100644 index 43d68ef1a70..00000000000 --- a/dojo/templates/dojo/view_cred_details.html +++ /dev/null @@ -1,328 +0,0 @@ -{% extends "base.html" %} -{% load display_tags %} -{% load get_config_setting %} -{% load static %} -{% block add_styles %} - {{ block.super }} - ul#select_by_severity a:hover, ul#bulk_edit a:hover { - cursor: pointer; - } -{% endblock %} -{% block content %} - {{ block.super }} -
-
-
-

Credential

- - -
-
-
- - - - - - - - - - - - - - - - - - - -
NameAlternate URLUsernamePasswordRoleEnvironmentValid Login
{{ cred.name }} - {% if cred.url %} - Alternate URL - {% endif %} - {{ cred.username }}{{ cred.password|get_pwd }}{{ cred.role }}{{ cred.environment }}{{ cred.is_valid }}
-
-
- -
-
-
-
-

Login Details

-
-
- - - - - - - - - - - - - -
Authentication TypeHTTP AuthenticationLogin RegExLogout RegEx
{{ cred.authentication }}{{ cred.http_authentication }}{{ cred.login_regex }}{{ cred.logout_regex }}
-
-
-
-
- -
-
-

Associated Products

-
-
- {% if cred_products %} - - - - - - - {% for cred in cred_products %} - - - - - - {% endfor %} - -
Product NameAlernate URLAuthentication Provider
- {{ cred.product }} - - {% if cred.url %} - Alternate URL - {% else %} - None Configured - {% endif %} - {{ cred.is_authn_provider }}
- {% else %} -
-

No products associated with this credential.

-
- {% endif %} -
-
- -
-
-

Notes

-
-
- {% if notes %} - - - - - - - - - - {% for note in notes %} - - - - - - {% endfor %} - -
UserDateNote
- {{ note.author.username }} - - {{ note.date }} - - {{ note }} - {% if person == note.author.username %} -
-
- {% csrf_token %} - - -
-
- {% endif %} -
- {% else %} -

No notes found.

- {% endif %} -
-
{% csrf_token %} - {% include "dojo/form_fields.html" with form=form %} -
-
- -
-
-
-
-
-{% endblock %} - -{% block postscript %} - {{ block.super }} - - -{% endblock %} diff --git a/dojo/templates/dojo/view_cred_prod.html b/dojo/templates/dojo/view_cred_prod.html deleted file mode 100644 index b76d97c5cf8..00000000000 --- a/dojo/templates/dojo/view_cred_prod.html +++ /dev/null @@ -1,61 +0,0 @@ -{% extends "base.html" %} -{% load navigation_tags %} -{% load get_config_setting %} -{% block content %} - {{ block.super }} -
-
-
-
-

Credentials - -

-
- {% if creds %} - - - - - - - - - - - - - - {% for cred in creds %} - - - - - - - - - - {% endfor %} - -
NameUsernameRoleEnvironmentAuthentication ProviderLogin ValidActions
- {{ cred.cred_id.name }} - {{ cred.cred_id.username }}{{ cred.cred_id.role }}{{ cred.cred_id.environment }}{{ cred.is_authn_provider }}{{ cred.cred_id.is_valid }} -
- View - Edit - Delete -
-
- {% else %} -
-

No credentials configured.

-
- {% endif %} -
-
-
-{% endblock %} diff --git a/dojo/templates/dojo/view_eng.html b/dojo/templates/dojo/view_eng.html index 71f660809ac..f53d3161824 100644 --- a/dojo/templates/dojo/view_eng.html +++ b/dojo/templates/dojo/view_eng.html @@ -927,110 +927,6 @@