You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Below is a summary of compliance checks for this PR:
Security Compliance
⚪
Mutable default timestamp
Description: The dataclass field 'queued' uses timezone.now() directly as a default which is evaluated at import time, causing all instances without an explicit 'queued' to share the same timestamp; use default_factory=timezone.now instead. assignment_source.py [14-35]
Follow the guide to enable codebase context checks.
Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code
Objective: Ensure all identifiers clearly express their purpose and intent, making code self-documenting
Status: Passed
Generic: Secure Error Handling
Objective: To prevent the leakage of sensitive system information through error messages while providing sufficient detail for internal debugging.
Status: Passed
Generic: Secure Logging Practices
Objective: To ensure logs are useful for debugging and auditing without exposing sensitive information like PII, PHI, or cardholder data.
Status: Passed
⚪
Generic: Comprehensive Audit Trails
Objective: To create a detailed and reliable record of critical system actions for security analysis and compliance.
Status: Missing auditing: New assignment propagation and cycle-prevention logic executes without adding or verifying audit log entries capturing user/integration source, timestamp, and outcome.
Generic: Robust Error Handling and Edge Case Management
Objective: Ensure comprehensive error handling that provides meaningful context and graceful degradation
Status: Edge case handling: The dataclass sets a timezone-aware default at class definition time and from_dict silently returns None on invalid input without logging, which may obscure issues when assignment_source is malformed.
Generic: Security-First Input Validation and Data Handling
Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent vulnerabilities
Status: Input validation: The task accepts assignment_source_dict from external queues and uses it after minimal validation, relying on dataclass coercion without explicit schema checks or logging when input is invalid.
Explicitly add the assignment_source: AssignmentSource | None = None parameter to the sync_assignee_outbound abstract method signature for improved clarity and consistency.
Why: The suggestion correctly points out that assignment_source is passed to sync_assignee_outbound but is not an explicit parameter in its abstract definition. Adding it improves code clarity, consistency with other methods in the file, and type safety for implementers.
Medium
Improve deserialization to handle extra keys
Improve the from_dict method in AssignmentSource to be more robust by explicitly checking for required parameters and filtering out extraneous keys, rather than broadly catching TypeError.
@classmethod
def from_dict(cls, input_dict: dict[str, Any]) -> AssignmentSource | None:
- try:- return cls(**input_dict)- except (ValueError, TypeError):+ import inspect++ if not isinstance(input_dict, dict):
return None
+ required_params = {+ p.name+ for p in inspect.signature(cls).parameters.values()+ if p.default is inspect.Parameter.empty+ }+ if not required_params.issubset(input_dict.keys()):+ return None++ # Filter out unexpected keys to avoid TypeError on `__init__`+ known_params = {p.name for p in inspect.signature(cls).parameters.values()}+ filtered_dict = {k: v for k, v in input_dict.items() if k in known_params}++ try:+ return cls(**filtered_dict)+ except TypeError:+ # This could still fail if types are wrong, e.g. integration_id="abc"+ return None+
Apply / Chat
Suggestion importance[1-10]: 6
__
Why: The suggestion correctly identifies that the broad exception handling in the new from_dict method can hide bugs by silently returning None. The proposed change improves robustness by explicitly handling required and extraneous parameters.
Low
More
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
User description
PR #7
PR Type
Bug fix, Enhancement
Description
Implement
AssignmentSourcetracking to prevent sync cyclesAdd assignment source parameter to sync methods
Prevent outbound sync when source matches target integration
Update group assignee operations to pass assignment source
Diagram Walkthrough
flowchart LR A["Assignment Action"] --> B["AssignmentSource Created"] B --> C["Sync Methods Check Source"] C --> D{"Source == Target Integration?"} D -->|Yes| E["Skip Sync - Prevent Cycle"] D -->|No| F["Proceed with Sync"]File Walkthrough
assignment_source.py
New assignment source tracking dataclasssrc/sentry/integrations/services/assignment_source.py
AssignmentSourceto track sync operation originsource_name,integration_id, andqueuedtimestampfrom_integration()factory method for creating instancesto_dict()andfrom_dict()for serializationsync_assignee_outbound.py
Thread assignment source through outbound sync tasksrc/sentry/integrations/tasks/sync_assignee_outbound.py
assignment_source_dictparameter tosync_assignee_outbound()taskAssignmentSource.from_dict()should_sync()andsync_assignee_outbound()callssync.py
Add assignment source propagation to sync utilitiessrc/sentry/integrations/utils/sync.py
AssignmentSourceclasssync_group_assignee_inbound()to pass assignment source whenassigning/deassigning
sync_group_assignee_outbound()to accept and forward assignmentsource parameter
groupassignee.py
Add assignment source to group assignee operationssrc/sentry/models/groupassignee.py
AssignmentSourceclassassignment_sourceparameter toassign()methodassignment_sourceparameter todeassign()methodsync_group_assignee_outbound()callsissues.py
Add sync cycle prevention to integration mixinssrc/sentry/integrations/mixins/issues.py
AssignmentSourceimportshould_sync()method signature to accept optionalsync_sourceparameter
IssueSyncIntegration.should_sync()tocheck if source integration matches target
sync_status_outbound()abstract method signature to includeassignment_sourceparametertest_assignment_source.py
New tests for assignment source serializationtests/sentry/integrations/services/test_assignment_source.py
from_dict()with empty dictionary returns Nonefrom_dict()with invalid data returns Nonefrom_dict()with valid data creates proper instanceto_dict()serialization includes all fieldstest_groupassignee.py
Add tests for sync cycle preventiontests/sentry/models/test_groupassignee.py
AssignmentSourceclassassignment_source=Noneparametertest_assignee_sync_outbound_assign_with_matching_source_integration()to verify sync is skipped when source matches target