Skip to content

Commit

Permalink
feat(replays): Add killswitch for mobile replays (#3402)
Browse files Browse the repository at this point in the history
Organizations are not allowed unless the
`organizations:session-replay-video` flag evaluates to `true`.

Related: getsentry/sentry#63255

Related PRs:
https://github.com/getsentry/getsentry/pull/13596/files
https://github.com/getsentry/sentry/pull/68567/files
  • Loading branch information
cmanallen committed Apr 15, 2024
1 parent 55c1d97 commit be342fb
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
- Add `cardinality_limited` outcome with id `6`. ([#3389](https://github.com/getsentry/relay/pull/3389))
- Extract `cache.item_size` and `cache.hit` metrics. ([#3371]https://github.com/getsentry/relay/pull/3371)
- Optionally convert segment spans to transactions for compatibility. ([#3375](https://github.com/getsentry/relay/pull/3375))
- Add feature flag for replay video event types. ([#3402](https://github.com/getsentry/relay/pull/3402))

**Internal**:

Expand Down
5 changes: 5 additions & 0 deletions relay-dynamic-config/src/feature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ pub enum Feature {
/// Serialized as `organizations:session-replay`.
#[serde(rename = "organizations:session-replay")]
SessionReplay,
/// Enables ingestion of video-based Session Replays.
///
/// Serialized as `organizations:session-replay-video`.
#[serde(rename = "organizations:session-replay-video")]
SessionReplayVideo,
/// Enables data scrubbing of replay recording payloads.
///
/// Serialized as `organizations:session-replay-recording-scrubbing`.
Expand Down
6 changes: 6 additions & 0 deletions relay-server/src/services/processor/replay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub fn process(
let project_state = &state.project_state;
let replays_enabled = project_state.has_feature(Feature::SessionReplay);
let scrubbing_enabled = project_state.has_feature(Feature::SessionReplayRecordingScrubbing);
let video_replay_enabled = project_state.has_feature(Feature::SessionReplayVideo);

let meta = state.envelope().meta().clone();
let client_addr = meta.client_addr();
Expand Down Expand Up @@ -88,6 +89,11 @@ pub fn process(
item.set_payload(ContentType::OctetStream, replay_recording);
}
ItemType::ReplayVideo => {
if !video_replay_enabled {
state.managed_envelope.drop_items_silently();
return Ok(());
}

let replay_video = handle_replay_video_item(
item.payload(),
&event_id,
Expand Down
50 changes: 49 additions & 1 deletion tests/integration/test_replay_videos.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,15 @@ def test_replay_recording_with_video(
replay_id = "515539018c9b4260a6f999572f1661ee"
relay = relay_with_processing()
mini_sentry.add_basic_project_config(
project_id, extra={"config": {"features": ["organizations:session-replay"]}}
project_id,
extra={
"config": {
"features": [
"organizations:session-replay",
"organizations:session-replay-video",
]
}
},
)
replay = generate_replay_sdk_event(replay_id)
replay_events_consumer = replay_events_consumer(timeout=10)
Expand Down Expand Up @@ -76,3 +84,43 @@ def test_replay_recording_with_video(
replay_recordings_consumer.assert_empty()
outcomes_consumer.assert_empty()
replay_events_consumer.assert_empty()


def test_replay_recording_with_video_flag_disabled(
mini_sentry,
relay_with_processing,
replay_recordings_consumer,
outcomes_consumer,
replay_events_consumer,
):
project_id = 42
replay_id = "515539018c9b4260a6f999572f1661ee"
relay = relay_with_processing()
mini_sentry.add_basic_project_config(
project_id,
extra={"config": {"features": ["organizations:session-replay"]}},
)
replay = generate_replay_sdk_event(replay_id)
replay_events_consumer = replay_events_consumer(timeout=10)
replay_recordings_consumer = replay_recordings_consumer()
outcomes_consumer = outcomes_consumer()

_recording_payload = recording_payload(b"[]")
payload = msgpack.packb(
{
"replay_event": json.dumps(replay).encode(),
"replay_recording": _recording_payload,
"replay_video": b"hello, world!",
}
)

envelope = Envelope(
headers=[["event_id", replay_id], ["attachment_type", "replay_video"]]
)
envelope.add_item(Item(payload=PayloadRef(bytes=payload), type="replay_video"))

relay.send_envelope(project_id, envelope)

replay_recordings_consumer.assert_empty()
outcomes_consumer.assert_empty()
replay_events_consumer.assert_empty()

0 comments on commit be342fb

Please sign in to comment.