MCPcopy Create free account
hub / github.com/couchbase/sync_gateway / handleGetRawDoc

Method handleGetRawDoc

rest/admin_api.go:1431–1499  ·  view source on GitHub ↗

handleGetRawDoc returns the raw version of the stored document for diagnostic purposes. It can optionally redact UserData in the sync metadata and allows a custom salt for correlating with collected logs.

()

Source from the content-addressed store, hash-verified

1429// handleGetRawDoc returns the raw version of the stored document for diagnostic purposes.
1430// It can optionally redact UserData in the sync metadata and allows a custom salt for correlating with collected logs.
1431func (h *handler) handleGetRawDoc() error {
1432 h.assertAdminOnly()
1433
1434 var (
1435 docID = h.PathVar("docid")
1436 includeDoc, includeDocSet = h.getOptBoolQuery("include_doc", true)
1437 redact = h.getBoolQuery("redact")
1438 redactSalt = h.getQuery("salt")
1439 )
1440
1441 if redact {
1442 // cannot explicitly include doc and redact - it doesn't make sense since the doc body itself is considered UserData and eligible for redaction.
1443 if includeDocSet && includeDoc {
1444 return base.HTTPErrorf(http.StatusBadRequest, "redact and include_doc cannot be true at the same time. "+
1445 "If you want to redact you must specify include_doc=false")
1446 }
1447 // if include_doc was not explicitly set, and we want to redact, then automatically set include_doc to false
1448 includeDoc = false
1449 } else if redactSalt != "" {
1450 return base.HTTPErrorf(http.StatusBadRequest, "redactSalt can only be used when redact=true")
1451 }
1452
1453 opts := db.GetRawDocOpts{
1454 IncludeDoc: includeDoc,
1455 Redact: redact,
1456 RedactSalt: redactSalt,
1457 }
1458 docBody, xattrValues, err := h.collection.GetRawDoc(h.ctx(), docID, &opts)
1459 if err != nil {
1460 return err
1461 }
1462
1463 responseBody := []byte(base.EmptyDocument)
1464 if docBody != nil {
1465 responseBody = docBody
1466 }
1467
1468 responseBody, err = base.InjectJSONProperties(responseBody, base.KVPair{Key: "_xattrs", Val: xattrValues})
1469 if err != nil {
1470 return base.HTTPErrorf(http.StatusInternalServerError, "couldn't inject xattrs into response: %s", err)
1471 }
1472
1473 base.Audit(h.ctx(), base.AuditIDDocumentMetadataRead, base.AuditFields{
1474 base.AuditFieldDocID: docID,
1475 })
1476 if includeDoc && base.AuditEventIsEnabled(h.ctx(), base.AuditIDDocumentRead) {
1477 // best-effort attempt to extract a revision from the raw sync data
1478 docCurrentRev := "unknown"
1479 if syncData, ok := xattrValues[base.SyncXattrName]; ok {
1480 var sdRev struct {
1481 Rev channels.RevAndVersion `json:"rev"`
1482 }
1483 if err := json.Unmarshal(syncData, &sdRev); err != nil {
1484 // syncData is not normally generally redacted, but in this case we know it's malformed in some way and want the raw data in the log message.
1485 // This data may contain channel names, etc. which _are_ classed as UserData, so tag the whole thing.
1486 base.WarnfCtx(h.ctx(), "couldn't unmarshal doc %q SyncData xattr value %q: %s", base.UD(docID), base.UD(syncData), err)
1487 } else {
1488 docCurrentRev = sdRev.Rev.RevTreeID

Callers

nothing calls this directly

Calls 15

assertAdminOnlyMethod · 0.95
PathVarMethod · 0.95
getOptBoolQueryMethod · 0.95
getBoolQueryMethod · 0.95
getQueryMethod · 0.95
ctxMethod · 0.95
writeRawJSONMethod · 0.95
HTTPErrorfFunction · 0.92
InjectJSONPropertiesFunction · 0.92
AuditFunction · 0.92
AuditEventIsEnabledFunction · 0.92
WarnfCtxFunction · 0.92

Tested by

no test coverage detected