Scan all protobuf string values for a sensitive word and replace it with a suitable alternative.
()
| 230 | // Scan all protobuf string values for a sensitive word and replace it with |
| 231 | // a suitable alternative. |
| 232 | func Example_sanitizeStrings() { |
| 233 | m := &newspb.Article{ |
| 234 | Author: "Hermione Granger", |
| 235 | Date: timestamppb.New(time.Date(1998, time.May, 2, 0, 0, 0, 0, time.UTC)), |
| 236 | Title: "Harry Potter vanquishes Voldemort once and for all!", |
| 237 | Content: "In a final duel between Harry Potter and Lord Voldemort earlier this evening...", |
| 238 | Tags: []string{"HarryPotter", "LordVoldemort"}, |
| 239 | Attachments: []*anypb.Any{{ |
| 240 | TypeUrl: "google.golang.org.KeyValueAttachment", |
| 241 | Value: mustMarshal(&newspb.KeyValueAttachment{ |
| 242 | Name: "aliases.txt", |
| 243 | Data: map[string]string{ |
| 244 | "Harry Potter": "The Boy Who Lived", |
| 245 | "Tom Riddle": "Lord Voldemort", |
| 246 | }, |
| 247 | }), |
| 248 | }}, |
| 249 | } |
| 250 | |
| 251 | protorange.Range(m.ProtoReflect(), func(p protopath.Values) error { |
| 252 | const ( |
| 253 | sensitive = "Voldemort" |
| 254 | alternative = "[He-Who-Must-Not-Be-Named]" |
| 255 | ) |
| 256 | |
| 257 | // Check if there is a sensitive word to redact. |
| 258 | last := p.Index(-1) |
| 259 | s, ok := last.Value.Interface().(string) |
| 260 | if !ok || !strings.Contains(s, sensitive) { |
| 261 | return nil |
| 262 | } |
| 263 | s = strings.Replace(s, sensitive, alternative, -1) |
| 264 | |
| 265 | // Store the redacted string back into the message. |
| 266 | beforeLast := p.Index(-2) |
| 267 | switch last.Step.Kind() { |
| 268 | case protopath.FieldAccessStep: |
| 269 | m := beforeLast.Value.Message() |
| 270 | fd := last.Step.FieldDescriptor() |
| 271 | m.Set(fd, protoreflect.ValueOfString(s)) |
| 272 | case protopath.ListIndexStep: |
| 273 | ls := beforeLast.Value.List() |
| 274 | i := last.Step.ListIndex() |
| 275 | ls.Set(i, protoreflect.ValueOfString(s)) |
| 276 | case protopath.MapIndexStep: |
| 277 | ms := beforeLast.Value.Map() |
| 278 | k := last.Step.MapIndex() |
| 279 | ms.Set(k, protoreflect.ValueOfString(s)) |
| 280 | } |
| 281 | return nil |
| 282 | }) |
| 283 | |
| 284 | fmt.Println(protojson.Format(m)) |
| 285 | |
| 286 | // Output: |
| 287 | // { |
| 288 | // "author": "Hermione Granger", |
| 289 | // "date": "1998-05-02T00:00:00Z", |
nothing calls this directly
no test coverage detected