diff --git a/relay-event-schema/src/protocol/user.rs b/relay-event-schema/src/protocol/user.rs index 88263fa9c0..b43fb3830e 100644 --- a/relay-event-schema/src/protocol/user.rs +++ b/relay-event-schema/src/protocol/user.rs @@ -68,6 +68,14 @@ pub struct User { #[metastructure(pii = "true", max_chars = 128, skip_serialization = "empty")] pub name: Annotated, + /// The user string representation as handled in Sentry. + /// + /// This field is computed by concatenating the name of specific fields of the `User` + /// struct with their value. For example, if `id` is set, `sentry_user` will be equal to + /// `"id:id-of-the-user". + #[metastructure(pii = "true", skip_serialization = "empty")] + pub sentry_user: Annotated, + /// Approximate geographical location of the end user or device. #[metastructure(skip_serialization = "empty")] pub geo: Annotated, @@ -76,14 +84,6 @@ pub struct User { #[metastructure(skip_serialization = "empty")] pub segment: Annotated, - /// The user string representation as handled in Sentry. - /// - /// This field is computed by concatenating the name of specific fields of the `User` - /// struct with their value. For example, if `id` is set, `sentry_user` will be equal to - /// `"id:id-of-the-user". - #[metastructure(skip_serialization = "empty")] - pub sentry_user: Annotated, - /// Additional arbitrary fields, as stored in the database (and sometimes as sent by clients). /// All data from `self.other` should end up here after store normalization. #[metastructure(pii = "true", skip_serialization = "empty")] diff --git a/relay-pii/src/processor.rs b/relay-pii/src/processor.rs index c1f6a1ffb1..197b085455 100644 --- a/relay-pii/src/processor.rs +++ b/relay-pii/src/processor.rs @@ -622,6 +622,33 @@ mod tests { assert_debug_snapshot!(&data); } + #[test] + fn test_sentry_user() { + let mut data = Event::from_value( + json!({ + "user": { + "ip_address": "73.133.27.120", + "sentry_user": "ip:73.133.27.120", + }, + }) + .into(), + ); + + let scrubbing_config = DataScrubbingConfig { + scrub_data: true, + scrub_ip_addresses: true, + scrub_defaults: true, + ..Default::default() + }; + + let pii_config = to_pii_config(&scrubbing_config).unwrap(); + let mut pii_processor = PiiProcessor::new(pii_config.compiled()); + + process_value(&mut data, &mut pii_processor, ProcessingState::root()).unwrap(); + + assert_debug_snapshot!(&data); + } + #[test] fn test_basic_stripping() { let config = serde_json::from_str::( diff --git a/relay-pii/src/snapshots/relay_pii__processor__tests__scrub_original_value.snap b/relay-pii/src/snapshots/relay_pii__processor__tests__scrub_original_value.snap index 8848e3da47..680f80e883 100644 --- a/relay-pii/src/snapshots/relay_pii__processor__tests__scrub_original_value.snap +++ b/relay-pii/src/snapshots/relay_pii__processor__tests__scrub_original_value.snap @@ -71,9 +71,9 @@ Event { }, ), name: ~, + sentry_user: ~, geo: ~, segment: ~, - sentry_user: ~, data: ~, other: {}, }, diff --git a/relay-pii/src/snapshots/relay_pii__processor__tests__sentry_user.snap b/relay-pii/src/snapshots/relay_pii__processor__tests__sentry_user.snap new file mode 100644 index 0000000000..f30b6409b2 --- /dev/null +++ b/relay-pii/src/snapshots/relay_pii__processor__tests__sentry_user.snap @@ -0,0 +1,112 @@ +--- +source: relay-pii/src/processor.rs +expression: "&data" +--- +Event { + id: ~, + level: ~, + version: ~, + ty: ~, + fingerprint: ~, + culprit: ~, + transaction: ~, + transaction_info: ~, + time_spent: ~, + logentry: ~, + logger: ~, + modules: ~, + platform: ~, + timestamp: ~, + start_timestamp: ~, + received: ~, + server_name: ~, + release: ~, + dist: ~, + environment: ~, + site: ~, + user: User { + id: ~, + email: ~, + ip_address: Meta { + remarks: [ + Remark { + ty: Substituted, + rule_id: "@ip:replace", + range: Some( + ( + 0, + 4, + ), + ), + }, + Remark { + ty: Removed, + rule_id: "@anything:remove", + range: None, + }, + ], + errors: [], + original_length: Some( + 13, + ), + original_value: None, + }, + username: ~, + name: ~, + sentry_user: Annotated( + "ip:[ip]", + Meta { + remarks: [ + Remark { + ty: Substituted, + rule_id: "@ip:replace", + range: Some( + ( + 3, + 7, + ), + ), + }, + ], + errors: [], + original_length: Some( + 16, + ), + original_value: None, + }, + ), + geo: ~, + segment: ~, + data: ~, + other: {}, + }, + request: ~, + contexts: ~, + breadcrumbs: ~, + exceptions: ~, + stacktrace: ~, + template: ~, + threads: ~, + tags: ~, + extra: ~, + debug_meta: ~, + client_sdk: ~, + ingest_path: ~, + errors: ~, + key_id: ~, + project: ~, + grouping_config: ~, + checksum: ~, + csp: ~, + hpkp: ~, + expectct: ~, + expectstaple: ~, + spans: ~, + measurements: ~, + breakdowns: ~, + scraping_attempts: ~, + _metrics: ~, + _metrics_summary: ~, + _dsc: ~, + other: {}, +}