Skip to content

Commit 2355b2d

Browse files
feat(uptime): Auto-convert AUTO_DETECTED monitors to MANUAL when edited (#103240)
When a non-superuser edits an uptime monitor that was originally auto-detected by the system, automatically convert the mode from AUTO_DETECTED_* to MANUAL to reflect user ownership. Auto-detected monitors are created by the system based on observed traffic patterns. Once a user actively modifies them, they're taking ownership and the monitor should reflect that it's now manually managed. Fixes NEW-628
1 parent 8eaaf26 commit 2355b2d

File tree

2 files changed

+54
-2
lines changed

2 files changed

+54
-2
lines changed

src/sentry/uptime/endpoints/validators.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -469,16 +469,27 @@ class UptimeDomainCheckFailureValidator(BaseDetectorTypeValidator):
469469
def validate_config(self, config: dict[str, Any]) -> dict[str, Any]:
470470
"""
471471
Validate that only superusers can change mode to non-MANUAL values.
472+
473+
When a non-superuser updates a monitor that is not in MANUAL mode,
474+
automatically switch to MANUAL.
472475
"""
473476
if "mode" not in config:
474477
return config
475478

476479
mode = config["mode"]
477480

478-
# For updates, only validate if mode is being changed
481+
# For updates, if current mode is not MANUAL and user is not a superuser,
482+
# automatically switch to MANUAL mode
479483
if self.instance:
480484
current_mode = self.instance.config.get("mode")
481-
# If mode hasn't changed, no validation needed
485+
486+
if current_mode != UptimeMonitorMode.MANUAL:
487+
request = self.context["request"]
488+
if not is_active_superuser(request):
489+
config["mode"] = UptimeMonitorMode.MANUAL
490+
return config
491+
492+
# If mode hasn't changed, no further validation needed
482493
if current_mode == mode:
483494
return config
484495

tests/sentry/uptime/endpoints/test_detector.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,47 @@ def test_update(self) -> None:
157157
)
158158
assert updated_sub.timeout_ms == 15000
159159

160+
def test_update_auto_detected_switches_to_manual(self) -> None:
161+
"""Test that when a user modifies an AUTO_DETECTED detector, it automatically switches to MANUAL mode."""
162+
# Create an AUTO_DETECTED detector
163+
auto_detector = self.create_uptime_detector(
164+
project=self.project,
165+
env=self.environment,
166+
uptime_subscription=self.uptime_subscription,
167+
name="Auto Detected Monitor",
168+
mode=UptimeMonitorMode.AUTO_DETECTED_ACTIVE,
169+
)
170+
171+
assert auto_detector.workflow_condition_group is not None
172+
# User modifies the detector (e.g., changes name)
173+
# They pass the current config including the AUTO_DETECTED mode
174+
valid_data = {
175+
"id": auto_detector.id,
176+
"projectId": self.project.id,
177+
"name": "User Modified Monitor",
178+
"type": UptimeDomainCheckFailure.slug,
179+
"dateCreated": auto_detector.date_added,
180+
"dateUpdated": timezone.now(),
181+
"conditionGroup": {
182+
"id": auto_detector.workflow_condition_group.id,
183+
"organizationId": self.organization.id,
184+
},
185+
"config": auto_detector.config, # Passing existing config with AUTO_DETECTED mode
186+
}
187+
188+
self.get_success_response(
189+
self.organization.slug,
190+
auto_detector.id,
191+
**valid_data,
192+
status_code=status.HTTP_200_OK,
193+
method="PUT",
194+
)
195+
196+
# Verify that mode was automatically switched to MANUAL
197+
auto_detector.refresh_from_db()
198+
assert auto_detector.name == "User Modified Monitor"
199+
assert auto_detector.config["mode"] == UptimeMonitorMode.MANUAL.value
200+
160201
def test_update_invalid(self) -> None:
161202
assert self.detector.workflow_condition_group is not None
162203
valid_data = {

0 commit comments

Comments
 (0)