Skip to content

fix: correctly serialize RFC3339 datetimes in EI API types - #2565

Merged
Strum355 merged 1 commit into
guacsec:mainfrom
Strum355:TC-5538
Aug 12, 2026
Merged

fix: correctly serialize RFC3339 datetimes in EI API types#2565
Strum355 merged 1 commit into
guacsec:mainfrom
Strum355:TC-5538

Conversation

@Strum355

@Strum355 Strum355 commented Aug 10, 2026

Copy link
Copy Markdown
Member

OpenAPI spec currently states that these date fields should be strings, but the implementation didnt match. Not currently used anywhere so the issue wasn't caught.

Fixes TC-5538

Summary by Sourcery

Ensure exploit intelligence API timestamps are serialized as RFC3339 strings and update tests accordingly.

Bug Fixes:

  • Correct RFC3339 serialization of created and updated timestamp fields in exploit intelligence job and component responses.

Tests:

  • Adjust exploit intelligence job completion test to assert string-based RFC3339 timestamps and other serialized fields via generic JSON inspection.

@Strum355
Strum355 requested a review from a team August 10, 2026 14:25
@sourcery-ai

sourcery-ai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

This PR updates Exploit Intelligence API models and tests so OffsetDateTime fields are serialized as RFC3339 strings, aligning the implementation with the OpenAPI spec and adding coverage to ensure the returned JSON uses the expected string format.

Sequence diagram for RFC3339 serialization in Exploit Intelligence API responses

sequenceDiagram
    actor Client
    participant ExploitIntelligenceEndpoint as ExploitIntelligenceEndpoint
    participant ExploitIntelligenceJobSummary as ExploitIntelligenceJobSummary
    participant ExploitIntelligenceJobDetails as ExploitIntelligenceJobDetails
    participant ComponentResult as ComponentResult
    participant time_serde_rfc3339 as time::serde::rfc3339
    participant JsonResponse as JsonResponse

    Client->>ExploitIntelligenceEndpoint: GET /exploit-intelligence/jobs
    ExploitIntelligenceEndpoint->>ExploitIntelligenceJobSummary: build job summaries
    ExploitIntelligenceEndpoint->>ExploitIntelligenceJobDetails: build job details
    ExploitIntelligenceEndpoint->>ComponentResult: build component results

    ExploitIntelligenceJobSummary->>time_serde_rfc3339: serialize created OffsetDateTime
    ExploitIntelligenceJobSummary->>time_serde_rfc3339: serialize updated OffsetDateTime

    ExploitIntelligenceJobDetails->>time_serde_rfc3339: serialize created OffsetDateTime
    ExploitIntelligenceJobDetails->>time_serde_rfc3339: serialize updated OffsetDateTime

    ComponentResult->>time_serde_rfc3339: serialize created OffsetDateTime
    ComponentResult->>time_serde_rfc3339: serialize updated OffsetDateTime

    time_serde_rfc3339-->>JsonResponse: RFC3339 datetime strings
    JsonResponse-->>Client: JSON with RFC3339 created and updated fields
Loading

File-Level Changes

Change Details Files
Ensure all Exploit Intelligence timestamps are serialized as RFC3339 strings in API responses.
  • Added serde RFC3339 serialization attribute to created and updated fields on job summary model.
  • Added serde RFC3339 serialization attribute to created and updated fields on job details model.
  • Added serde RFC3339 serialization attribute to created and updated fields on component result model.
modules/exploit-intelligence/src/model/mod.rs
Adjust endpoint test to validate JSON payload and RFC3339 datetime formatting instead of relying on direct Rust type deserialization.
  • Switched test response body type from ExploitIntelligenceJobDetails to serde_json::Value for flexible JSON inspection.
  • Updated assertions to compare primitive JSON fields (id, status, vulnerability_id, finding) to expected string values.
  • Added parsing checks using time::format_description::well_known::Rfc3339 to verify created and updated fields are valid RFC3339 datetimes.
modules/exploit-intelligence/src/endpoints/test.rs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • In the updated test, body["created"].as_str().unwrap() and body["updated"].as_str().unwrap() can panic if the fields are missing or not strings; consider using expect with a clear message or checking is_string() before parsing to make failures easier to diagnose.
  • Instead of comparing OffsetDateTime::parse(...).err() == None, using OffsetDateTime::parse(..., &Rfc3339).is_ok() would be more idiomatic and directly express the intent of validating RFC3339 formatting.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In the updated test, `body["created"].as_str().unwrap()` and `body["updated"].as_str().unwrap()` can panic if the fields are missing or not strings; consider using `expect` with a clear message or checking `is_string()` before parsing to make failures easier to diagnose.
- Instead of comparing `OffsetDateTime::parse(...).err() == None`, using `OffsetDateTime::parse(..., &Rfc3339).is_ok()` would be more idiomatic and directly express the intent of validating RFC3339 formatting.

## Individual Comments

### Comment 1
<location path="modules/exploit-intelligence/src/endpoints/test.rs" line_range="156-161" />
<code_context>
+    assert_eq!(body["status"], "completed");
+    assert_eq!(body["vulnerability_id"], "CVE-2024-1234");
+    assert_eq!(body["finding"], "not_vulnerable");
+    assert_eq!(
+        OffsetDateTime::parse(body["created"].as_str().unwrap(), &Rfc3339).err(),
+        None
+    );
     assert_eq!(
-        body.finding,
-        Some(ExploitIntelligenceFinding::NotVulnerable)
+        OffsetDateTime::parse(body["updated"].as_str().unwrap(), &Rfc3339).err(),
+        None
     );
</code_context>
<issue_to_address>
**nitpick:** Use `is_ok()` (or similar) instead of checking `err() == None` for clearer intent in datetime parsing assertions.

The `created` and `updated` assertions currently use `OffsetDateTime::parse(...).err() == None`, which hides the intent and produces less clear failure output (an `Option` instead of a parse `Result`). Please switch to `assert!(OffsetDateTime::parse(..., &Rfc3339).is_ok())` (optionally with a custom message) so the tests clearly assert successful parsing and produce more readable failures.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread modules/exploit-intelligence/src/endpoints/test.rs Outdated
@ptomanRH
ptomanRH requested a review from a-oren August 12, 2026 08:22
Comment thread modules/exploit-intelligence/src/endpoints/test.rs Outdated

@rh-jfuller rh-jfuller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

you might have to run >cargo xtask precommit to refresh openapi defs ... otherwise LGTM

@Strum355

Copy link
Copy Markdown
Member Author

you might have to run >cargo xtask precommit to refresh openapi defs ... otherwise LGTM

This was bringing the implementation in-line with what openapi was declaring. CI would catch precommit yielding a diff though, so we're all good there

@Strum355
Strum355 enabled auto-merge August 12, 2026 09:52
@Strum355
Strum355 added this pull request to the merge queue Aug 12, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Aug 12, 2026
@Strum355
Strum355 enabled auto-merge August 12, 2026 12:06
@Strum355
Strum355 added this pull request to the merge queue Aug 12, 2026
Merged via the queue into guacsec:main with commit 443b775 Aug 12, 2026
9 checks passed
@Strum355
Strum355 deleted the TC-5538 branch August 12, 2026 15:53
@github-project-automation github-project-automation Bot moved this to Done in Trustify Aug 12, 2026
@trustify-ci-bot

Copy link
Copy Markdown

Successfully created backport PR for release/0.6.z:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants