Skip to content

Single Findings API Endpoint #1516

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 10, 2025
Merged

Single Findings API Endpoint #1516

merged 3 commits into from
Jul 10, 2025

Conversation

zinic
Copy link
Contributor

@zinic zinic commented May 29, 2025

Description

Support for adding a new Audit enumeration value for supporting export of all findings from BHE.

Motivation and Context

Resolves BED-5973

Types of changes

  • New feature (non-breaking change which adds functionality)

Checklist:

Summary by CodeRabbit

  • New Features

    • Added a new API endpoint to retrieve all attack path findings with detailed documentation and associated assets.
    • Introduced a unified finding schema to standardize finding data across endpoints.
    • Added a new audit log action for exporting all risks.
  • Refactor

    • Improved SQL filter construction for more robust and maintainable query generation.
  • Bug Fixes

    • Updated tests to align with the new SQL filter format, ensuring accurate test coverage and reliability.

Copy link
Contributor

coderabbitai bot commented May 29, 2025

Walkthrough

This update introduces a new API endpoint for retrieving detailed attack path findings, along with supporting schemas and documentation updates. The SQL filter construction logic in the backend was refactored to use a typed AST-based approach; related unit tests were consolidated and updated to match the new SQL filter string format. A new audit log action constant was added.

Changes

Files/Groups Change Summary
cmd/api/src/model/filter.go, cmd/api/src/model/filter_test.go Refactored SQL filter construction to use a typed AST-based approach; added conversion method and helper functions; consolidated and replaced existing tests with table-driven tests.
cmd/api/src/api/v2/agi_test.go, cmd/api/src/api/v2/assetgrouptags_test.go, cmd/api/src/api/v2/audit_test.go, cmd/api/src/api/v2/auth/auth_test.go, cmd/api/src/api/v2/auth/sso_test.go, cmd/api/src/api/v2/fileingest_test.go, cmd/api/src/database/assetgrouptags_test.go, cmd/api/src/database/sso_providers_test.go Updated test mocks to expect SQL filters with inlined literal values instead of parameterized queries, removing Params slices.
cmd/api/src/model/audit.go Added new audit log action constant: AuditLogActionExportAllRisks.
packages/go/openapi/doc/openapi.json, packages/go/openapi/src/openapi.yaml, packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml, packages/go/openapi/src/schemas/api.response.all-findings.yaml, packages/go/openapi/src/schemas/model.unified-finding.yaml Added new API endpoint /api/v2/attack-paths/details with PUT operation GetAllAttackPathFindings and supporting schemas defining unified findings and their assets.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant API_Server
    participant DB

    Client->>API_Server: PUT /api/v2/attack-paths/details
    API_Server->>DB: Query all attack path findings and assets
    DB-->>API_Server: Findings and assets data
    API_Server-->>Client: 200 OK (api.response.all-findings)
Loading

Suggested labels

api, enhancement, documentation

Suggested reviewers

  • superlinkx

Poem

A rabbit hops through code so bright,
New endpoints gleam in morning light.
SQL filters now are neat and clear,
Attack path findings soon appear!
With schemas fresh and tests in line,
This patch is truly quite divine.
🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b9cbd2d and 2c2c5a1.

📒 Files selected for processing (16)
  • cmd/api/src/api/v2/agi_test.go (2 hunks)
  • cmd/api/src/api/v2/assetgrouptags_test.go (2 hunks)
  • cmd/api/src/api/v2/audit_test.go (1 hunks)
  • cmd/api/src/api/v2/auth/auth_test.go (7 hunks)
  • cmd/api/src/api/v2/auth/sso_test.go (1 hunks)
  • cmd/api/src/api/v2/fileingest_test.go (1 hunks)
  • cmd/api/src/database/assetgrouptags_test.go (4 hunks)
  • cmd/api/src/database/sso_providers_test.go (2 hunks)
  • cmd/api/src/model/audit.go (1 hunks)
  • cmd/api/src/model/filter.go (2 hunks)
  • cmd/api/src/model/filter_test.go (1 hunks)
  • packages/go/openapi/doc/openapi.json (2 hunks)
  • packages/go/openapi/src/openapi.yaml (1 hunks)
  • packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml (1 hunks)
  • packages/go/openapi/src/schemas/api.response.all-findings.yaml (1 hunks)
  • packages/go/openapi/src/schemas/model.unified-finding.yaml (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • packages/go/openapi/src/openapi.yaml
  • cmd/api/src/api/v2/auth/sso_test.go
🚧 Files skipped from review as they are similar to previous changes (10)
  • cmd/api/src/api/v2/audit_test.go
  • cmd/api/src/api/v2/fileingest_test.go
  • cmd/api/src/api/v2/agi_test.go
  • cmd/api/src/database/sso_providers_test.go
  • cmd/api/src/api/v2/assetgrouptags_test.go
  • cmd/api/src/model/audit.go
  • cmd/api/src/database/assetgrouptags_test.go
  • cmd/api/src/api/v2/auth/auth_test.go
  • packages/go/openapi/doc/openapi.json
  • cmd/api/src/model/filter.go
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: zinic
PR: SpecterOps/BloodHound#1573
File: packages/go/dawgs/drivers/pg/query/sql/schema_up.sql:514-581
Timestamp: 2025-06-12T15:42:11.258Z
Learning: Contributor "zinic" prefers not to receive automated refactor suggestions/comments on their pull requests.
packages/go/openapi/src/schemas/model.unified-finding.yaml (2)
Learnt from: elikmiller
PR: SpecterOps/BloodHound#1563
File: packages/go/graphschema/azure/azure.go:24-24
Timestamp: 2025-06-06T23:12:14.181Z
Learning: In BloodHound, files in packages/go/graphschema/*/`*.go` are generated from CUE schemas. When `just prepare-for-codereview` is run, it triggers code generation that may automatically add import aliases or other formatting changes. These changes are legitimate outputs of the generation process, not manual edits that would be overwritten.
Learnt from: zinic
PR: SpecterOps/BloodHound#1573
File: packages/go/dawgs/drivers/pg/query/sql/schema_up.sql:514-581
Timestamp: 2025-06-12T15:42:11.258Z
Learning: Contributor "zinic" prefers not to receive automated refactor suggestions/comments on their pull requests.
cmd/api/src/model/filter_test.go (4)
Learnt from: superlinkx
PR: SpecterOps/BloodHound#1503
File: cmd/api/src/services/job/jobs_test.go:19-143
Timestamp: 2025-05-27T16:58:33.295Z
Learning: Tests in cmd/api/src/services/job/jobs_test.go have been found to be flaky in the past and are due for rewrite. They should be skipped with t.Skip() until they can be properly rewritten.
Learnt from: LawsonWillard
PR: SpecterOps/BloodHound#1595
File: cmd/api/src/api/v2/saved_queries_test.go:2594-2594
Timestamp: 2025-06-17T22:37:36.389Z
Learning: In Go table-driven tests, there's a distinction between main test function parallelism and subtest parallelism. Main test functions can safely use t.Parallel() for performance benefits, but individual subtests within table-driven tests may need to run sequentially to avoid race conditions with mocks, deferred functions, or shared resources.
Learnt from: LawsonWillard
PR: SpecterOps/BloodHound#1595
File: cmd/api/src/api/v2/saved_queries_test.go:2197-2197
Timestamp: 2025-06-17T22:37:50.192Z
Learning: In Go tests using table-driven patterns, t.Parallel() at the function level allows test functions to run in parallel with other test functions, which is generally beneficial. However, when subtests contain deferred goroutines, the individual t.Run() calls should not use t.Parallel() to avoid flakiness. The comment "Tests will be flaky if run in parallel due to use of go routine in deferred function" specifically refers to subtest parallelization, not function-level parallelization.
Learnt from: elikmiller
PR: SpecterOps/BloodHound#1563
File: packages/go/graphschema/azure/azure.go:24-24
Timestamp: 2025-06-06T23:12:14.181Z
Learning: In BloodHound, files in packages/go/graphschema/*/`*.go` are generated from CUE schemas. When `just prepare-for-codereview` is run, it triggers code generation that may automatically add import aliases or other formatting changes. These changes are legitimate outputs of the generation process, not manual edits that would be overwritten.
packages/go/openapi/src/schemas/api.response.all-findings.yaml (1)
Learnt from: elikmiller
PR: SpecterOps/BloodHound#1563
File: packages/go/graphschema/azure/azure.go:24-24
Timestamp: 2025-06-06T23:12:14.181Z
Learning: In BloodHound, files in packages/go/graphschema/*/`*.go` are generated from CUE schemas. When `just prepare-for-codereview` is run, it triggers code generation that may automatically add import aliases or other formatting changes. These changes are legitimate outputs of the generation process, not manual edits that would be overwritten.
🧬 Code Graph Analysis (1)
cmd/api/src/model/filter_test.go (1)
cmd/api/src/model/filter.go (4)
  • Filters (446-446)
  • SQLFilter (96-99)
  • Filter (441-444)
  • BuildSQLFilter (198-269)
🪛 YAMLlint (1.37.1)
packages/go/openapi/src/schemas/model.unified-finding.yaml

[error] 1-1: wrong new line character: expected \n

(new-lines)

packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml

[error] 1-1: wrong new line character: expected \n

(new-lines)

packages/go/openapi/src/schemas/api.response.all-findings.yaml

[error] 1-1: wrong new line character: expected \n

(new-lines)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Build BloodHound Container Image / Build and Package Container
  • GitHub Check: run-tests
  • GitHub Check: run-analysis
  • GitHub Check: build-ui
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
cmd/api/src/model/audit.go (1)

76-79: Add documentation and tests for new audit log action

The new AuditLogActionExportAllRisks constant follows the existing naming pattern. Please ensure you also:

  • Update the OpenAPI enum/schema for audit logs to include "ExportAllRisks".
  • Add or extend unit/integration tests to cover the new action in your logging workflows.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 292a0f1 and f5fa2cb.

📒 Files selected for processing (1)
  • cmd/api/src/model/audit.go (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Build BloodHound Container Image / Build and Package Container
  • GitHub Check: run-analysis
  • GitHub Check: run-tests
  • GitHub Check: build-ui

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
packages/go/openapi/src/schemas/api.response.all-findings.yaml (1)

1-16: License header is correct.
The Apache 2.0 license header is present and properly formatted.

To satisfy the YAML linter error (wrong new line character: expected \n), normalize line endings to LF (\n) across this file.

🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 1-1: wrong new line character: expected \n

(new-lines)

packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml (1)

1-16: License header is correct.
The Apache 2.0 header is correctly applied.

Align line endings to LF (\n) to resolve the YAML linting warning on new line characters.

🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 1-1: wrong new line character: expected \n

(new-lines)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f5fa2cb and 2d85484.

📒 Files selected for processing (10)
  • cmd/api/src/model/audit.go (1 hunks)
  • packages/go/openapi/doc/openapi.json (2 hunks)
  • packages/go/openapi/src/openapi.yaml (1 hunks)
  • packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml (1 hunks)
  • packages/go/openapi/src/schemas/api.response.all-findings.yaml (1 hunks)
  • packages/javascript/bh-shared-ui/src/test-utils.jsx (1 hunks)
  • packages/javascript/bh-shared-ui/src/utils/index.ts (1 hunks)
  • packages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/types.ts (1 hunks)
  • packages/javascript/bh-shared-ui/src/views/TierManagement/Summary/SummaryCard.test.tsx (1 hunks)
  • packages/javascript/bh-shared-ui/src/views/TierManagement/Summary/SummaryCard.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (6)
  • packages/javascript/bh-shared-ui/src/views/TierManagement/Summary/SummaryCard.test.tsx
  • packages/javascript/bh-shared-ui/src/utils/index.ts
  • packages/javascript/bh-shared-ui/src/views/TierManagement/Summary/SummaryCard.tsx
  • packages/javascript/bh-shared-ui/src/test-utils.jsx
  • packages/go/openapi/src/openapi.yaml
  • packages/go/openapi/doc/openapi.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • cmd/api/src/model/audit.go
🧰 Additional context used
🪛 Biome (1.9.4)
packages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/types.ts

[error] 15-19: Expected a statement but instead found '<<<<<<< Updated upstream

Stashed changes'.

Expected a statement here.

(parse)

🪛 GitHub Actions: Build UI
packages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/types.ts

[error] 16-16: SyntaxError: Merge conflict marker encountered. Conflict markers <<<<<<<, =======, >>>>>>> found in the file.

🪛 GitHub Actions: Static Code Analysis
packages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/types.ts

[error] 16-16: Parsing error: Merge conflict marker encountered.

🪛 GitHub Actions: Run Tests
packages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/types.ts

[error] 16-16: Transform failed: Unexpected '<<' found in source code indicating unresolved merge conflict markers.

🪛 YAMLlint (1.37.1)
packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml

[error] 1-1: wrong new line character: expected \n

(new-lines)

packages/go/openapi/src/schemas/api.response.all-findings.yaml

[error] 1-1: wrong new line character: expected \n

(new-lines)

🔇 Additional comments (1)
packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml (1)

17-25: Verify use of PUT without a request body.
This endpoint uses PUT but defines no requestBody. If no payload is required, using GET is more semantically appropriate for a read operation. If you intend to accept a JSON body (e.g., to filter findings), add a requestBody definition.

Please confirm that PUT without a body aligns with the API design guidelines.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (3)
packages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/types.ts (1)

16-19: ⚠️ Potential issue

Critical: Unresolved Git merge conflict markers are still blocking the pipeline.

The merge conflict markers identified in the previous review remain unresolved and are causing multiple pipeline failures. This is preventing the PR from being merged and must be addressed immediately.

Please remove all conflict marker lines to resolve this issue.

🧰 Tools
🪛 Biome (1.9.4)

[error] 15-19: Expected a statement but instead found '<<<<<<< Updated upstream

Stashed changes'.

Expected a statement here.

(parse)

🪛 GitHub Actions: Build UI

[error] 16-16: SyntaxError: Merge conflict marker encountered. Conflict markers <<<<<<<, =======, >>>>>>> found in the file.

🪛 GitHub Actions: Run Tests

[error] 16-16: Transform failed: Unexpected '<<' found in source code, indicating unresolved merge conflict markers. Please resolve the conflict in this file.

🪛 GitHub Actions: Static Code Analysis

[error] 16-16: Parsing error: Merge conflict marker encountered.

packages/go/openapi/src/schemas/api.response.all-findings.yaml (1)

17-24: Define detailed schema for array and object properties and mark them as required.
The findings array lacks an items definition and the finding_assets object is missing an additionalProperties schema. Additionally, neither property is marked as required, which may break code generation or validation.

Apply this patch:

 type: object
 properties:
   findings:
     type: array
+    items:
+      $ref: '#/components/schemas/UnifiedFinding'
     description: List of unified findings.
   finding_assets:
     type: object
+    additionalProperties:
+      type: string
+      format: byte
     description: Directory structure of Base64 encoded assets related to each finding organized by finding name.
+required:
+  - findings
+  - finding_assets
packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml (1)

26-28: ⚠️ Potential issue

Fix response object structure for HTTP 200.
Referencing a schema directly under the 200 response is invalid in OpenAPI 3.0. A proper response object must include a description and a content block with the schema.

Apply this patch:

 responses:
-  200:
-    $ref: './../schemas/api.response.all-findings.yaml'
+  200:
+    description: Successful retrieval of all attack path findings.
+    content:
+      application/json:
+        schema:
+          $ref: './../schemas/api.response.all-findings.yaml'
🧹 Nitpick comments (2)
packages/go/openapi/src/schemas/api.response.all-findings.yaml (1)

1-1: Normalize newline characters to Unix-style LF.
YAMLlint reports wrong new line character: expected \n. Ensure this file uses LF line endings to avoid linter errors.

🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 1-1: wrong new line character: expected \n

(new-lines)

packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml (1)

1-1: Normalize newline characters to Unix-style LF.
YAMLlint reports wrong new line character: expected \n. Convert this file to use LF line endings.

🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 1-1: wrong new line character: expected \n

(new-lines)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2d85484 and c90fa80.

📒 Files selected for processing (10)
  • cmd/api/src/model/audit.go (1 hunks)
  • packages/go/openapi/doc/openapi.json (2 hunks)
  • packages/go/openapi/src/openapi.yaml (1 hunks)
  • packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml (1 hunks)
  • packages/go/openapi/src/schemas/api.response.all-findings.yaml (1 hunks)
  • packages/javascript/bh-shared-ui/src/test-utils.jsx (1 hunks)
  • packages/javascript/bh-shared-ui/src/utils/index.ts (1 hunks)
  • packages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/types.ts (1 hunks)
  • packages/javascript/bh-shared-ui/src/views/TierManagement/Summary/SummaryCard.test.tsx (1 hunks)
  • packages/javascript/bh-shared-ui/src/views/TierManagement/Summary/SummaryCard.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • packages/javascript/bh-shared-ui/src/views/TierManagement/Summary/SummaryCard.tsx
  • packages/go/openapi/src/openapi.yaml
🚧 Files skipped from review as they are similar to previous changes (5)
  • packages/javascript/bh-shared-ui/src/utils/index.ts
  • packages/javascript/bh-shared-ui/src/views/TierManagement/Summary/SummaryCard.test.tsx
  • packages/javascript/bh-shared-ui/src/test-utils.jsx
  • cmd/api/src/model/audit.go
  • packages/go/openapi/doc/openapi.json
🧰 Additional context used
🪛 YAMLlint (1.37.1)
packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml

[error] 1-1: wrong new line character: expected \n

(new-lines)

packages/go/openapi/src/schemas/api.response.all-findings.yaml

[error] 1-1: wrong new line character: expected \n

(new-lines)

🪛 Biome (1.9.4)
packages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/types.ts

[error] 15-19: Expected a statement but instead found '<<<<<<< Updated upstream

Stashed changes'.

Expected a statement here.

(parse)

🪛 GitHub Actions: Build UI
packages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/types.ts

[error] 16-16: SyntaxError: Merge conflict marker encountered. Conflict markers <<<<<<<, =======, >>>>>>> found in the file.

🪛 GitHub Actions: Run Tests
packages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/types.ts

[error] 16-16: Transform failed: Unexpected '<<' found in source code, indicating unresolved merge conflict markers. Please resolve the conflict in this file.

🪛 GitHub Actions: Static Code Analysis
packages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/types.ts

[error] 16-16: Parsing error: Merge conflict marker encountered.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (4)
packages/go/openapi/src/schemas/api.response.all-findings.yaml (3)

17-25: 🛠️ Refactor suggestion

Mark required properties at the root
Ensure both findings and finding_assets are mandatory in the response:

 type: object
 properties:
   findings: …
   finding_assets: …
+required:
+  - findings
+  - finding_assets

19-21: 🛠️ Refactor suggestion

Define items schema for findings array
Without an items definition, tools can’t infer the element type for the array, breaking codegen and validation.
Apply this diff:

  findings:
    type: array
+   items:
+     $ref: '#/components/schemas/UnifiedFinding'
    description: List of unified findings.

22-24: 🛠️ Refactor suggestion

Add additionalProperties schema for finding_assets
Currently the object has no constraints on its values. Specify that each asset entry is a Base64-encoded string:

  finding_assets:
    type: object
+   additionalProperties:
+     type: string
+     format: byte
    description: Directory structure of Base64 encoded assets related to each finding organized by finding name.
packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml (1)

27-28: 🛠️ Refactor suggestion

Use a full response object instead of direct schema $ref
In OpenAPI 3, each response must include description and content.
Replace:

responses:
    $ref: './../schemas/api.response.all-findings.yaml'

With:

responses:
    description: Successful retrieval of all attack path findings.
    content:
      application/json:
        schema:
          $ref: './../schemas/api.response.all-findings.yaml'
🧹 Nitpick comments (2)
packages/go/openapi/src/schemas/api.response.all-findings.yaml (1)

1-1: Use Unix-style LF line endings
YAMLlint reports wrong new line characters. Convert CRLF to LF to satisfy the linter.

🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 1-1: wrong new line character: expected \n

(new-lines)

packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml (1)

1-1: Use Unix-style LF line endings
Ensure the file uses LF line endings to satisfy YAMLlint.

🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 1-1: wrong new line character: expected \n

(new-lines)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c90fa80 and eed819e.

📒 Files selected for processing (5)
  • cmd/api/src/model/audit.go (1 hunks)
  • packages/go/openapi/doc/openapi.json (2 hunks)
  • packages/go/openapi/src/openapi.yaml (1 hunks)
  • packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml (1 hunks)
  • packages/go/openapi/src/schemas/api.response.all-findings.yaml (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/go/openapi/src/openapi.yaml
🚧 Files skipped from review as they are similar to previous changes (2)
  • cmd/api/src/model/audit.go
  • packages/go/openapi/doc/openapi.json
🧰 Additional context used
🪛 YAMLlint (1.37.1)
packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml

[error] 1-1: wrong new line character: expected \n

(new-lines)

packages/go/openapi/src/schemas/api.response.all-findings.yaml

[error] 1-1: wrong new line character: expected \n

(new-lines)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Build BloodHound Container Image / Build and Package Container
  • GitHub Check: run-tests

@zinic zinic force-pushed the BP-1611 branch 3 times, most recently from e663ca0 to 279cb1e Compare June 5, 2025 20:44
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
cmd/api/src/model/filter.go (1)

198-268: Consider enhancing error messages for better debugging.

The error messages could include the operator value for easier debugging.

Enhance the error message:

 default:
-	return SQLFilter{}, fmt.Errorf("invalid operator specified")
+	return SQLFilter{}, fmt.Errorf("invalid operator specified: %s", filter.Operator)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eed819e and 279cb1e.

📒 Files selected for processing (4)
  • cmd/api/src/api/v2/model.go (1 hunks)
  • cmd/api/src/model/audit.go (1 hunks)
  • cmd/api/src/model/filter.go (2 hunks)
  • cmd/api/src/model/filter_test.go (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • cmd/api/src/api/v2/model.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • cmd/api/src/model/audit.go
🧰 Additional context used
🧬 Code Graph Analysis (2)
cmd/api/src/model/filter_test.go (1)
cmd/api/src/model/filter.go (4)
  • Filters (445-445)
  • SQLFilter (96-99)
  • Filter (440-443)
  • BuildSQLFilter (198-268)
cmd/api/src/model/filter.go (3)
packages/go/cypher/models/pgsql/model.go (7)
  • Literal (175-179)
  • NullLiteral (182-188)
  • NewLiteral (190-195)
  • AsLiteral (213-231)
  • OptionalAnd (1210-1218)
  • NewBinaryExpression (321-327)
  • Identifier (587-587)
packages/go/cypher/models/pgsql/pgtypes.go (3)
  • Int8 (83-83)
  • Float8 (85-85)
  • Boolean (86-86)
packages/go/cypher/models/pgsql/operators.go (1)
  • OperatorLike (92-92)
🪛 golangci-lint (1.64.8)
cmd/api/src/model/filter.go

[error] 166-166: SA5000: assignment to nil map

(staticcheck)

⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Build BloodHound Container Image / Build and Package Container
  • GitHub Check: run-analysis
  • GitHub Check: run-tests
  • GitHub Check: build-ui
🔇 Additional comments (2)
cmd/api/src/model/filter.go (2)

172-194: Well-structured type parsing logic.

The function correctly handles type conversion with appropriate fallback to string literals.


270-272: Clean delegation pattern for backward compatibility.

The method appropriately delegates to the new implementation while maintaining the existing API.

@zinic zinic force-pushed the BP-1611 branch 3 times, most recently from 1989879 to 1935cd4 Compare June 5, 2025 21:25
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

♻️ Duplicate comments (1)
packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml (1)

27-28: Response object must include description and content, not a bare schema $ref.

OpenAPI 3 requires:

responses:
    description: Successful retrieval of all attack path findings.
    content:
      application/json:
        schema:
          $ref: './schemas/api.response.all-findings.yaml'
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 279cb1e and 1935cd4.

📒 Files selected for processing (7)
  • cmd/api/src/api/v2/model.go (1 hunks)
  • cmd/api/src/model/filter.go (2 hunks)
  • cmd/api/src/model/filter_test.go (1 hunks)
  • packages/go/cypher/models/pgsql/model.go (1 hunks)
  • packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml (1 hunks)
  • packages/go/openapi/src/schemas/api.response.all-findings.yaml (1 hunks)
  • packages/go/openapi/src/schemas/model.unified-finding.yaml (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • cmd/api/src/api/v2/model.go
  • packages/go/cypher/models/pgsql/model.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • cmd/api/src/model/filter_test.go
🧰 Additional context used
🪛 YAMLlint (1.37.1)
packages/go/openapi/src/schemas/model.unified-finding.yaml

[error] 1-1: wrong new line character: expected \n

(new-lines)

packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml

[error] 1-1: wrong new line character: expected \n

(new-lines)

packages/go/openapi/src/schemas/api.response.all-findings.yaml

[error] 1-1: wrong new line character: expected \n

(new-lines)

⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Build BloodHound Container Image / Build and Package Container
  • GitHub Check: run-tests
  • GitHub Check: run-analysis
  • GitHub Check: build-ui
🔇 Additional comments (5)
cmd/api/src/model/filter.go (5)

28-30: Well-structured imports for PostgreSQL AST support.

The addition of PostgreSQL AST and formatting packages supports the transition to type-safe SQL generation, which is a significant security and maintainability improvement.


150-170: Clean conversion between filter models.

The ToFiltersModel method properly initializes the map and converts between the old and new filter models. The implementation correctly handles the conversion without data loss.


172-194: Robust type inference for PostgreSQL literals.

The filterValueAsPGLiteral function implements a sensible type inference hierarchy (null → int64 → float64 → bool → string) for converting string filter values to typed PostgreSQL literals. The fallback to pgsql.AsLiteral ensures compatibility with the PostgreSQL package's type system.


196-269: Excellent refactoring to AST-based SQL generation.

This refactor represents a significant security and maintainability improvement:

  • Security: Using AST generation prevents SQL injection vulnerabilities
  • Correctness: The format.SyntaxNode ensures syntactically correct SQL
  • Null handling: Proper use of IS/IS NOT operators for null comparisons
  • Type safety: Leverages the PostgreSQL AST type system

The logic correctly maps filter operators to PostgreSQL operators and handles the special case of ApproximatelyEquals with LIKE and wildcard wrapping. The use of pgsql.OptionalAnd to combine expressions is clean and readable.


271-273: Clean delegation preserves backward compatibility.

The updated method properly delegates to the new BuildSQLFilter function while maintaining the existing interface, ensuring backward compatibility for existing callers.

@zinic zinic force-pushed the BP-1611 branch 4 times, most recently from 8ccddc8 to 341a431 Compare June 5, 2025 22:42
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (6)
packages/go/openapi/src/schemas/api.response.all-findings.yaml (2)

28-29: ⚠️ Potential issue

Constrain finding_assets values to Base64 strings.

Using type: object with no format prevents validation and codegen. Replace it with Base64-encoded strings:

-additionalProperties:
-  type: object
+additionalProperties:
+  type: string
+  format: byte

22-23: ⚠️ Potential issue

Incorrect $ref path breaks schema resolution.

The items reference should point to the sibling model.unified-finding.yaml directly.
Apply this diff to fix:

-items:
-  $ref: './../schemas/model.unified-finding.yaml'
+items:
+  $ref: './model.unified-finding.yaml'
packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml (1)

27-28: ⚠️ Potential issue

Fix response object to use description and content.

OpenAPI requires a full response object, not a direct schema reference. Update the 200 response:

-  200:
-    $ref: './../schemas/api.response.all-findings.yaml'
+  200:
+    description: Successful retrieval of all attack path findings.
+    content:
+      application/json:
+        schema:
+          $ref: './../schemas/api.response.all-findings.yaml'
packages/go/openapi/src/schemas/model.unified-finding.yaml (3)

61-62: ⚠️ Potential issue

Correct type for attack_path_edge_id.

OpenAPI requires integer with format: int64 for 64-bit IDs:

-attack_path_edge_id:
-  type: int64
+attack_path_edge_id:
+  type: integer
+  format: int64

49-52: ⚠️ Potential issue

Fix target_properties type in the second variant.

additionalProperties only applies to objects. Change the type accordingly:

-target_properties:
-  type: string
-  additionalProperties:
-    type: object
+target_properties:
+  type: object
+  additionalProperties:
+    type: object

75-77: ⚠️ Potential issue

Use numeric type for exposure_percentage.

Exposure percentages should be numbers, not strings:

-exposure_percentage:
-  type: string
-  format: int64
+exposure_percentage:
+  type: number
+  format: double
🧹 Nitpick comments (4)
cmd/api/src/database/sso_providers_test.go (1)

241-243: Consider maintaining parameterized query pattern for consistency.

The change from parameterized queries ("name = ?" with params) to direct string embedding reduces type safety and makes tests more brittle. While acceptable in test code, consider whether this aligns with the broader SQL filter handling strategy across the codebase.

cmd/api/src/database/assetgrouptags_test.go (1)

444-444: Inconsistent approach compared to other changes in this file.

This hardcoded "type = 2" approach is inconsistent with lines 255 and 273 which use strconv.Itoa(int(model.AssetGroupTagType...)). Consider using the same pattern for consistency.

-			SQLString: "type = 2"
+			SQLString: "type = " + strconv.Itoa(int(model.SelectorTypeCypher))

Note: Verify the correct constant based on the test context.

cmd/api/src/api/v2/auth/auth_test.go (1)

2828-2828: Consider potential fragility in UUID string concatenation.

While UUID.String() output is predictable and safe, the string concatenation approach creates tight coupling between tests and SQL string formatting. Consider if this approach could be made more maintainable.

-model.SQLFilter{SQLString: "user_id = '" + user.ID.String() + "'"}
+// Consider using a helper function or constants for filter patterns

Also applies to: 3065-3065

cmd/api/src/api/v2/assetgrouptags_test.go (1)

131-131: Consider simplifying the enum-to-string conversion.

The current approach strconv.Itoa(int(model.AssetGroupTagTypeLabel)) works correctly but could potentially be simplified if the enum types support direct string conversion. However, given this is part of a broader refactoring effort, the current approach is acceptable.

Consider if this could be simplified to:

-SQLString: "type = " + strconv.Itoa(int(model.AssetGroupTagTypeLabel)),
+SQLString: fmt.Sprintf("type = %d", model.AssetGroupTagTypeLabel),

Though both approaches are functionally equivalent, fmt.Sprintf might be slightly more readable.

Also applies to: 156-156

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1935cd4 and 341a431.

📒 Files selected for processing (18)
  • cmd/api/src/api/v2/agi_test.go (2 hunks)
  • cmd/api/src/api/v2/assetgrouptags_test.go (2 hunks)
  • cmd/api/src/api/v2/audit_test.go (1 hunks)
  • cmd/api/src/api/v2/auth/auth_test.go (7 hunks)
  • cmd/api/src/api/v2/auth/sso_test.go (1 hunks)
  • cmd/api/src/api/v2/fileingest_test.go (1 hunks)
  • cmd/api/src/api/v2/model.go (1 hunks)
  • cmd/api/src/database/assetgrouptags_test.go (4 hunks)
  • cmd/api/src/database/sso_providers_test.go (2 hunks)
  • cmd/api/src/model/audit.go (1 hunks)
  • cmd/api/src/model/filter.go (2 hunks)
  • cmd/api/src/model/filter_test.go (1 hunks)
  • packages/go/cypher/models/pgsql/model.go (1 hunks)
  • packages/go/openapi/doc/openapi.json (2 hunks)
  • packages/go/openapi/src/openapi.yaml (1 hunks)
  • packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml (1 hunks)
  • packages/go/openapi/src/schemas/api.response.all-findings.yaml (1 hunks)
  • packages/go/openapi/src/schemas/model.unified-finding.yaml (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • cmd/api/src/api/v2/model.go
  • packages/go/openapi/src/openapi.yaml
🚧 Files skipped from review as they are similar to previous changes (5)
  • packages/go/cypher/models/pgsql/model.go
  • cmd/api/src/model/audit.go
  • packages/go/openapi/doc/openapi.json
  • cmd/api/src/model/filter_test.go
  • cmd/api/src/model/filter.go
🧰 Additional context used
🧬 Code Graph Analysis (5)
cmd/api/src/api/v2/audit_test.go (1)
cmd/api/src/model/filter.go (1)
  • SQLFilter (96-99)
cmd/api/src/api/v2/fileingest_test.go (3)
cmd/api/src/services/job/management.go (1)
  • GetAllIngestJobs (34-36)
cmd/api/src/model/filter.go (1)
  • SQLFilter (96-99)
cmd/api/src/model/jobs.go (1)
  • IngestJob (28-40)
cmd/api/src/api/v2/agi_test.go (1)
cmd/api/src/model/filter.go (1)
  • SQLFilter (96-99)
cmd/api/src/database/assetgrouptags_test.go (2)
cmd/api/src/model/filter.go (1)
  • SQLFilter (96-99)
cmd/api/src/model/assetgrouptags.go (2)
  • AssetGroupTagTypeLabel (43-43)
  • AssetGroupTagTypeTier (42-42)
cmd/api/src/api/v2/assetgrouptags_test.go (1)
cmd/api/src/model/assetgrouptags.go (2)
  • AssetGroupTagTypeLabel (43-43)
  • AssetGroupTagTypeTier (42-42)
🪛 YAMLlint (1.37.1)
packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml

[error] 1-1: wrong new line character: expected \n

(new-lines)

packages/go/openapi/src/schemas/api.response.all-findings.yaml

[error] 1-1: wrong new line character: expected \n

(new-lines)

packages/go/openapi/src/schemas/model.unified-finding.yaml

[error] 1-1: wrong new line character: expected \n

(new-lines)

⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Build BloodHound Container Image / Build and Package Container
  • GitHub Check: build-ui
  • GitHub Check: run-analysis
  • GitHub Check: run-tests
🔇 Additional comments (15)
cmd/api/src/api/v2/audit_test.go (1)

224-224: SQL filter format updated consistently with broader refactoring.

The change from parameterized query format to inline SQL is consistent with the architectural changes mentioned in the AI summary. The string value is properly quoted.

cmd/api/src/api/v2/fileingest_test.go (1)

103-103: SQL filter format consistently updated.

The numeric value is correctly formatted without quotes, maintaining proper SQL syntax in the inline filter string.

cmd/api/src/api/v2/auth/sso_test.go (1)

188-188: String value with spaces properly quoted in SQL filter.

The inline SQL format correctly handles the string value containing spaces with proper single-quote escaping.

cmd/api/src/api/v2/agi_test.go (2)

151-151: SQL filter format consistently updated.

The string value is properly quoted, following the same pattern established across all modified test files in this refactoring.


1093-1093: Numeric value correctly formatted in inline SQL filter.

The numeric ID value is properly formatted without quotes, maintaining correct SQL syntax in the updated filter format.

cmd/api/src/database/sso_providers_test.go (1)

296-298: Consistent with previous change but same maintainability concerns.

This change follows the same pattern as line 242, maintaining consistency within the file while sharing the same trade-offs regarding maintainability and type safety.

cmd/api/src/database/assetgrouptags_test.go (3)

23-23: Import addition supports the SQL filter changes.

The strconv import is appropriately added to support the string conversion approach used in the modified SQL filters.


255-255: String conversion approach maintains constant reference.

Using strconv.Itoa(int(model.AssetGroupTagTypeLabel)) is preferable to hardcoding the value as it maintains the relationship to the type constant, though it's more verbose than the original parameterized approach.


273-273: Consistent pattern with line 255.

This change follows the same string conversion pattern as line 255, maintaining consistency within the file and preserving the reference to the type constant.

cmd/api/src/api/v2/auth/auth_test.go (4)

425-425: LGTM - Simple literal filter.

The hardcoded filter string is appropriate for this test scenario.


476-476: LGTM - Consistent with test data.

The filter correctly matches the test data being used.


818-818: LGTM - Simple equality filter.

The filter string correctly represents the expected query condition.


1265-1265: LGTM - Appropriate for test context.

The filter matches the test scenario for user filtering.

cmd/api/src/api/v2/assetgrouptags_test.go (2)

131-131: LGTM: Test expectation correctly updated for new SQL filter format.

The change from parameterized queries to direct string concatenation in the mock expectation aligns with the broader refactoring to PostgreSQL AST builder mentioned in the PR summary.


156-156: LGTM: Consistent with the SQL filter format change.

This follows the same pattern as line 131, correctly converting the enum value to a string for direct SQL concatenation.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (2)
packages/go/openapi/src/schemas/api.response.all-findings.yaml (1)

23-31: 🛠️ Refactor suggestion

Correct $ref path and asset typing
Refine findings.items.$ref to reference the sibling schema (./model.unified-finding.yaml) and constrain finding_assets to Base64‐encoded strings by changing its additionalProperties to type: string with format: byte.

Proposed diff:

-    items:
-      $ref: './../schemas/model.unified-finding.yaml'
+    items:
+      $ref: './model.unified-finding.yaml'

-  finding_assets:
-    type: object
-    description: Directory structure of Base64 encoded assets related to each finding organized by finding name.
-    additionalProperties:
-      type: object
+  finding_assets:
+    type: object
+    description: Directory structure of Base64 encoded assets related to each finding organized by finding name.
+    additionalProperties:
+      type: string
+      format: byte
packages/go/openapi/src/schemas/model.unified-finding.yaml (1)

73-76: ⚠️ Potential issue

Fix invalid target_properties type
The second variant declares target_properties as type: string with additionalProperties, which is invalid. It should mirror the first variant as an object.

Proposed diff:

-      target_properties:
-        type: string
-        additionalProperties:
-          type: object
+      target_properties:
+        type: object
+        additionalProperties:
+          type: object
🧹 Nitpick comments (3)
cmd/api/src/model/filter_test.go (2)

26-31: Prefer typed operator constants over raw string literals

The tests embed operator strings ("eq", "gt", …).
Importing and using the model.* operator constants (e.g. model.Equals) gives compile-time safety, auto-completion, and flags accidental typos at build time.
This also keeps the test in sync with any future refactors that might rename the literals.


165-170: Fix minor typo in sub-test name

"aprox equals""approx equals" – keeps the test descriptions professional and searchable.

packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml (1)

35-35: Normalize $ref format for schema reference
Drop the redundant ./ prefix in the $ref path for consistency. Use:

$ref: '../schemas/api.response.all-findings.yaml'
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 341a431 and 1f3749e.

📒 Files selected for processing (18)
  • cmd/api/src/api/v2/agi_test.go (2 hunks)
  • cmd/api/src/api/v2/assetgrouptags_test.go (2 hunks)
  • cmd/api/src/api/v2/audit_test.go (1 hunks)
  • cmd/api/src/api/v2/auth/auth_test.go (7 hunks)
  • cmd/api/src/api/v2/auth/sso_test.go (1 hunks)
  • cmd/api/src/api/v2/fileingest_test.go (1 hunks)
  • cmd/api/src/api/v2/model.go (1 hunks)
  • cmd/api/src/database/assetgrouptags_test.go (4 hunks)
  • cmd/api/src/database/sso_providers_test.go (2 hunks)
  • cmd/api/src/model/filter.go (2 hunks)
  • cmd/api/src/model/filter_test.go (1 hunks)
  • packages/go/cypher/models/pgsql/model.go (1 hunks)
  • packages/go/openapi/doc/openapi.json (5 hunks)
  • packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml (1 hunks)
  • packages/go/openapi/src/paths/custom-nodes.custom-nodes.name.yaml (1 hunks)
  • packages/go/openapi/src/paths/custom-nodes.custom-nodes.yaml (1 hunks)
  • packages/go/openapi/src/schemas/api.response.all-findings.yaml (1 hunks)
  • packages/go/openapi/src/schemas/model.unified-finding.yaml (1 hunks)
✅ Files skipped from review due to trivial changes (6)
  • packages/go/openapi/src/paths/custom-nodes.custom-nodes.name.yaml
  • cmd/api/src/api/v2/model.go
  • cmd/api/src/api/v2/fileingest_test.go
  • cmd/api/src/api/v2/auth/sso_test.go
  • packages/go/cypher/models/pgsql/model.go
  • packages/go/openapi/src/paths/custom-nodes.custom-nodes.yaml
🚧 Files skipped from review as they are similar to previous changes (7)
  • cmd/api/src/api/v2/audit_test.go
  • cmd/api/src/api/v2/agi_test.go
  • cmd/api/src/database/sso_providers_test.go
  • cmd/api/src/api/v2/assetgrouptags_test.go
  • cmd/api/src/database/assetgrouptags_test.go
  • cmd/api/src/api/v2/auth/auth_test.go
  • cmd/api/src/model/filter.go
🧰 Additional context used
🧬 Code Graph Analysis (1)
cmd/api/src/model/filter_test.go (1)
cmd/api/src/model/filter.go (4)
  • Filters (446-446)
  • SQLFilter (96-99)
  • Filter (441-444)
  • BuildSQLFilter (198-269)
🪛 Checkov (3.2.334)
packages/go/openapi/doc/openapi.json

[HIGH] 1-19167: Ensure that security operations is not empty.

(CKV_OPENAPI_5)

🪛 YAMLlint (1.37.1)
packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml

[error] 1-1: wrong new line character: expected \n

(new-lines)

packages/go/openapi/src/schemas/api.response.all-findings.yaml

[error] 1-1: wrong new line character: expected \n

(new-lines)

packages/go/openapi/src/schemas/model.unified-finding.yaml

[error] 1-1: wrong new line character: expected \n

(new-lines)

⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Build BloodHound Container Image / Build and Package Container
  • GitHub Check: build-ui
  • GitHub Check: run-tests
  • GitHub Check: run-analysis
🔇 Additional comments (5)
packages/go/openapi/src/paths/attack-paths.attack-paths-details.yaml (1)

31-35:

✅ Verification successful

Verify response envelope follows project conventions
Your 200 response wraps the api.response.all-findings schema under a data property. Confirm that other endpoints use the same envelope pattern; if they reference schemas directly at the top level, adjust accordingly.

You can search for existing patterns with:


🏁 Script executed:

rg "properties:\n  data:" -n packages/go/openapi/src/paths

Length of output: 252


To get accurate results on where the data envelope is used across all path specs, let’s enable multiline matching and re-run the search:


🏁 Script executed:

#!/bin/bash
# Search for any schema wrapped under a `data` property in path definitions
rg -U "properties:\s*data:" -n packages/go/openapi/src/paths

Length of output: 20010


Enveloped response confirmed—no changes needed
The 200 response in attack-paths.attack-paths-details.yaml wraps its payload under a data property, matching the pattern used across all other path specs in packages/go/openapi/src/paths.

packages/go/openapi/src/schemas/model.unified-finding.yaml (1)

39-42: Verify environment_id data type
environment_id is defined as an object with arbitrary properties, but IDs are usually strings. Confirm the intended schema or update to:

environment_id:
  type: string
packages/go/openapi/doc/openapi.json (3)

2894-2919: Wrap example nodes under data
The example now correctly encapsulates the node list in the data property, aligning with the updated schema that expects a data array.


3064-3068: Consistent icon nesting in example
The icon details are now properly nested under config.icon, matching the updated schema structure for custom nodes.


14478-14526: Add /api/v2/attack-paths/details endpoint with comprehensive responses
The new PUT operation defines all standard response codes (200, 400, 401, 403, 429, 500) and references the api.response.all-findings schema for the 200 response.

Comment on lines +188 to +208
// Run each test case and compare the output with the expected result
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
actualOutput, err := model.BuildSQLFilter(tc.input)

_, err := queryParameterFilterMap.BuildSQLFilter()
require.Contains(t, err.Error(), "invalid filter predicate")
}
if tc.wantErr {
if err == nil {
t.Errorf("expected error, got nil")
}

func TestModel_BuildSQLFilter_Success(t *testing.T) {
numericMin := model.QueryParameterFilter{
Name: "filtercolumn1",
Operator: model.GreaterThan,
Value: "0",
IsStringData: false,
}

numericMax := model.QueryParameterFilter{
Name: "filtercolumn2",
Operator: model.LessThan,
Value: "10",
IsStringData: false,
}

stringValue := model.QueryParameterFilter{
Name: "filtercolumn3",
Operator: model.Equals,
Value: "stringValue",
IsStringData: true,
}

boolEquals := model.QueryParameterFilter{
Name: "filtercolumn4",
Operator: model.Equals,
Value: "true",
IsStringData: false,
}

boolNotEquals := model.QueryParameterFilter{
Name: "filtercolumn5",
Operator: model.NotEquals,
Value: "false",
IsStringData: false,
}

approximatelyEquals := model.QueryParameterFilter{
Name: "filtercolumn6",
Operator: model.ApproximatelyEquals,
Value: "testing value",
IsStringData: true,
}

expectedResults := map[string]model.SQLFilter{
"numericMin": {SQLString: fmt.Sprintf("%s > ?", numericMin.Name), Params: []any{numericMin.Value}},
"numericMax": {SQLString: fmt.Sprintf("%s < ?", numericMax.Name), Params: []any{numericMax.Value}},
"stringValue": {SQLString: fmt.Sprintf("%s = ?", stringValue.Name), Params: []any{stringValue.Value}},
"boolEquals": {SQLString: fmt.Sprintf("%s = ?", boolEquals.Name), Params: []any{boolEquals.Value}},
"boolNotEquals": {SQLString: fmt.Sprintf("%s <> ?", boolNotEquals.Name), Params: []any{boolNotEquals.Value}},
"stringApproximatelyEquals": {SQLString: fmt.Sprintf("%s ILIKE ?", approximatelyEquals.Name), Params: []any{approximatelyEquals.Value}},
}

queryParameterFilterMap := model.QueryParameterFilterMap{
numericMax.Name: model.QueryParameterFilters{numericMin, numericMax},
stringValue.Name: model.QueryParameterFilters{stringValue},
boolEquals.Name: model.QueryParameterFilters{boolEquals},
boolNotEquals.Name: model.QueryParameterFilters{boolNotEquals},
approximatelyEquals.Name: model.QueryParameterFilters{approximatelyEquals},
}
return
}

result, err := queryParameterFilterMap.BuildSQLFilter()
require.Nil(t, err)
if err != nil {
t.Errorf("unexpected error: %v", err)
return
}

for _, val := range expectedResults {
require.Contains(t, result.SQLString, val.SQLString)
require.EqualValues(t, result.Params, result.Params)
if actualOutput.SQLString != tc.output.SQLString {
t.Errorf("incorrect SQL string: got %q, want %q", actualOutput.SQLString, tc.output.SQLString)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Make assertions case-insensitive & verify Params slice

BuildSQLFilter relies on the formatter used by the pgsql AST builder, which may emit SQL keywords in upper-case (LIKE, IS, IS NOT, …).
A strict, case-sensitive comparison risks brittle false negatives.
Additionally, asserting that Params is empty guards against accidental regression to parameterised queries.

@@
-           if actualOutput.SQLString != tc.output.SQLString {
-               t.Errorf("incorrect SQL string: got %q, want %q", actualOutput.SQLString, tc.output.SQLString)
-           }
+           if !strings.EqualFold(actualOutput.SQLString, tc.output.SQLString) {
+               t.Errorf("incorrect SQL string (case-insensitive compare): got %q, want %q",
+                   actualOutput.SQLString, tc.output.SQLString)
+           }
+
+           if len(actualOutput.Params) != 0 {
+               t.Errorf("expected no query parameters, got %d", len(actualOutput.Params))
+           }

Remember to extend the import block:

-import (
-    "testing"
-    "github.com/specterops/bloodhound/src/model"
-)
+import (
+    "testing"
+    "strings"
+
+    "github.com/specterops/bloodhound/src/model"
+)
🤖 Prompt for AI Agents
In cmd/api/src/model/filter_test.go lines 188 to 208, the test compares SQL
strings case-sensitively, which can cause false negatives due to uppercase
keywords from the pgsql AST builder. Modify the assertion to compare SQL strings
case-insensitively. Also, add an assertion to verify that the Params slice in
actualOutput is empty to prevent regressions involving parameterized queries.
Update the import block as needed to support case-insensitive comparison.

@zinic zinic merged commit 4893cf4 into main Jul 10, 2025
9 checks passed
@zinic zinic deleted the BP-1611 branch July 10, 2025 16:59
@github-actions github-actions bot locked and limited conversation to collaborators Jul 10, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants