Skip to content

Commit

Permalink
CBG-4046 add ctx to GetDocument calls
Browse files Browse the repository at this point in the history
GetDocument may audit information for reads.

- change rt.GetSingleDatabaseCollection to return user. One place that
  it was commonly used to was to construct a user. When the user
  construction was trivial, use rt.CreateUser, otherwise leave as is.
  Switch the GetUserPayload to use DataStore so it can we accessed with
  a single API call.
  • Loading branch information
torcolvin committed Jul 17, 2024
1 parent 1570f17 commit 0a2937b
Show file tree
Hide file tree
Showing 37 changed files with 456 additions and 503 deletions.
28 changes: 14 additions & 14 deletions db/revision_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,38 +263,38 @@ func TestBypassRevisionCache(t *testing.T) {
rc := NewBypassRevisionCache(backingStoreMap, &bypassStat)

// Peek always returns false for BypassRevisionCache
_, ok := rc.Peek(base.TestCtx(t), key, rev1, 0)
_, ok := rc.Peek(ctx, key, rev1, 0)
assert.False(t, ok)
_, ok = rc.Peek(base.TestCtx(t), key, rev2, 0)
_, ok = rc.Peek(ctx, key, rev2, 0)
assert.False(t, ok)

// Get non-existing doc
_, err = rc.Get(base.TestCtx(t), "invalid", rev1, testCollectionID, RevCacheOmitBody, RevCacheOmitDelta)
_, err = rc.Get(ctx, "invalid", rev1, testCollectionID, RevCacheOmitBody, RevCacheOmitDelta)
assert.True(t, base.IsDocNotFoundError(err))

// Get non-existing revision
_, err = rc.Get(base.TestCtx(t), key, "3-abc", testCollectionID, RevCacheOmitBody, RevCacheOmitDelta)
_, err = rc.Get(ctx, key, "3-abc", testCollectionID, RevCacheOmitBody, RevCacheOmitDelta)
assertHTTPError(t, err, 404)

// Get specific revision
doc, err := rc.Get(base.TestCtx(t), key, rev1, testCollectionID, RevCacheOmitBody, RevCacheOmitDelta)
doc, err := rc.Get(ctx, key, rev1, testCollectionID, RevCacheOmitBody, RevCacheOmitDelta)
assert.NoError(t, err)
require.NotNil(t, doc)
assert.Equal(t, `{"value":1234}`, string(doc.BodyBytes))

// Check peek is still returning false for "Get"
_, ok = rc.Peek(base.TestCtx(t), key, rev1, testCollectionID)
_, ok = rc.Peek(ctx, key, rev1, testCollectionID)
assert.False(t, ok)

// Put no-ops
rc.Put(base.TestCtx(t), doc, testCollectionID)
rc.Put(ctx, doc, testCollectionID)

// Check peek is still returning false for "Put"
_, ok = rc.Peek(base.TestCtx(t), key, rev1, testCollectionID)
_, ok = rc.Peek(ctx, key, rev1, testCollectionID)
assert.False(t, ok)

// Get active revision
doc, err = rc.GetActive(base.TestCtx(t), key, testCollectionID, false)
doc, err = rc.GetActive(ctx, key, testCollectionID, false)
assert.NoError(t, err)
assert.Equal(t, `{"value":5678}`, string(doc.BodyBytes))

Expand Down Expand Up @@ -325,7 +325,7 @@ func TestPutRevisionCacheAttachmentProperty(t *testing.T) {
assert.False(t, ok, "_attachments property still present in document body retrieved from bucket: %#v", bucketBody)

// Get the raw document directly from the revcache, validate _attachments property isn't found
docRevision, ok := collection.revisionCache.Peek(base.TestCtx(t), rev1key, rev1id)
docRevision, ok := collection.revisionCache.Peek(ctx, rev1key, rev1id)
assert.True(t, ok)
assert.NotContains(t, docRevision.BodyBytes, BodyAttachments, "_attachments property still present in document body retrieved from rev cache: %#v", bucketBody)
_, ok = docRevision.Attachments["myatt"]
Expand Down Expand Up @@ -375,7 +375,7 @@ func TestPutExistingRevRevisionCacheAttachmentProperty(t *testing.T) {
assert.False(t, ok, "_attachments property still present in document body retrieved from bucket: %#v", bucketBody)

// Get the raw document directly from the revcache, validate _attachments property isn't found
docRevision, err := collection.revisionCache.Get(base.TestCtx(t), docKey, rev2id, RevCacheOmitBody, RevCacheOmitDelta)
docRevision, err := collection.revisionCache.Get(ctx, docKey, rev2id, RevCacheOmitBody, RevCacheOmitDelta)
assert.NoError(t, err, "Unexpected error calling collection.revisionCache.Get")
assert.NotContains(t, docRevision.BodyBytes, BodyAttachments, "_attachments property still present in document body retrieved from rev cache: %#v", bucketBody)
_, ok = docRevision.Attachments["myatt"]
Expand Down Expand Up @@ -471,19 +471,19 @@ func TestRevisionCacheRemove(t *testing.T) {
rev1id, _, err := collection.Put(ctx, "doc", Body{"val": 123})
assert.NoError(t, err)

docRev, err := collection.revisionCache.Get(base.TestCtx(t), "doc", rev1id, true, true)
docRev, err := collection.revisionCache.Get(ctx, "doc", rev1id, true, true)
assert.NoError(t, err)
assert.Equal(t, rev1id, docRev.RevID)
assert.Equal(t, int64(0), db.DbStats.Cache().RevisionCacheMisses.Value())

collection.revisionCache.Remove("doc", rev1id)

docRev, err = collection.revisionCache.Get(base.TestCtx(t), "doc", rev1id, true, true)
docRev, err = collection.revisionCache.Get(ctx, "doc", rev1id, true, true)
assert.NoError(t, err)
assert.Equal(t, rev1id, docRev.RevID)
assert.Equal(t, int64(1), db.DbStats.Cache().RevisionCacheMisses.Value())

docRev, err = collection.revisionCache.GetActive(base.TestCtx(t), "doc", true)
docRev, err = collection.revisionCache.GetActive(ctx, "doc", true)
assert.NoError(t, err)
assert.Equal(t, rev1id, docRev.RevID)
assert.Equal(t, int64(1), db.DbStats.Cache().RevisionCacheMisses.Value())
Expand Down
33 changes: 16 additions & 17 deletions rest/access_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,8 @@ func TestPublicChanGuestAccess(t *testing.T) {
}},
})
defer rt.Close()
collection := rt.GetSingleTestDatabaseCollection()
c := collection.Name
s := collection.ScopeName
c := rt.GetSingleDataStore().CollectionName()
s := rt.GetSingleDataStore().ScopeName()

// Create a document on the public channel
resp := rt.SendAdminRequest(http.MethodPut, "/{{.keyspace}}/doc", `{"channels": ["!"], "foo": "bar"}`)
Expand Down Expand Up @@ -323,12 +322,11 @@ func TestUserHasDocAccessDocNotFound(t *testing.T) {
}},
})
defer rt.Close()
ctx := rt.Context()

resp := rt.SendAdminRequest("PUT", "/{{.keyspace}}/doc", `{"channels": ["A"]}`)
RequireStatus(t, resp, http.StatusCreated)

collection, ctx := rt.GetSingleTestDatabaseCollectionWithUser(ctx)
collection, ctx := rt.GetSingleTestDatabaseCollectionWithUser()
userHasDocAccess, err := db.UserHasDocAccess(ctx, collection, "doc")
assert.NoError(t, err)
assert.True(t, userHasDocAccess)
Expand Down Expand Up @@ -395,11 +393,12 @@ func TestForceAPIForbiddenErrors(t *testing.T) {
}},
})
defer rt.Close()
collection := rt.GetSingleTestDatabaseCollection()
c := collection.Name
s := collection.ScopeName
dataStore := rt.GetSingleDataStore()
c := dataStore.CollectionName()
s := dataStore.ScopeName()

resp := rt.SendAdminRequest(http.MethodPut, "/{{.db}}/_user/Perms", GetUserPayload(t, "Perms", "password", "", collection, []string{"chan"}, nil))
// update the user to add chan
resp := rt.SendAdminRequest(http.MethodPut, "/{{.db}}/_user/Perms", GetUserPayload(t, "Perms", "password", "", dataStore, []string{"chan"}, nil))
RequireStatus(t, resp, http.StatusOK)

// Create the initial document
Expand Down Expand Up @@ -796,9 +795,9 @@ func TestChannelAccessChanges(t *testing.T) {
rtConfig := RestTesterConfig{SyncFn: `function(doc) {access(doc.owner, doc._id);channel(doc.channel)}`}
rt := NewRestTester(t, &rtConfig)
defer rt.Close()
collection := rt.GetSingleTestDatabaseCollection()
c := collection.Name
s := collection.ScopeName
dataStore := rt.GetSingleDataStore()
c := dataStore.CollectionName()
s := dataStore.ScopeName()

ctx := rt.Context()
a := rt.ServerContext().Database(ctx, "db").Authenticator(ctx)
Expand Down Expand Up @@ -950,9 +949,9 @@ func TestChannelAccessChanges(t *testing.T) {
// Finally, throw a wrench in the works by changing the sync fn. Note that normally this wouldn't
// be changed while the database is in use (only when it's re-opened) but for testing purposes
// we do it now because we can't close and re-open an ephemeral Walrus database.
collectionWithUser, ctx := rt.GetSingleTestDatabaseCollectionWithUser(rt.Context())
collectionWithUser, ctx := rt.GetSingleTestDatabaseCollectionWithUser()

changed, err := collection.UpdateSyncFun(ctx, `function(doc) {access("alice", "beta");channel("beta");}`)
changed, err := collectionWithUser.UpdateSyncFun(ctx, `function(doc) {access("alice", "beta");channel("beta");}`)
assert.NoError(t, err)
assert.True(t, changed)
changeCount, err := collectionWithUser.UpdateAllDocChannels(ctx, false, func(docsProcessed, docsChanged *int) {}, base.NewSafeTerminator())
Expand Down Expand Up @@ -1115,9 +1114,9 @@ func TestRoleChannelGrantInheritance(t *testing.T) {
ctx := rt.Context()
a := rt.ServerContext().Database(ctx, "db").Authenticator(ctx)

collection := rt.GetSingleTestDatabaseCollection()
scopeName := collection.ScopeName
collectionName := collection.Name
dataStore := rt.GetSingleDataStore()
scopeName := dataStore.ScopeName()
collectionName := dataStore.CollectionName()

user, err := a.GetUser("")
assert.NoError(t, err)
Expand Down
3 changes: 1 addition & 2 deletions rest/adminapitest/admin_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,7 @@ func TestServerlessChangesEndpointLimit(t *testing.T) {

resp := rt.SendAdminRequest(http.MethodPut, "/_config", `{"max_concurrent_replications" : 2}`)
rest.RequireStatus(t, resp, http.StatusOK)
resp = rt.SendAdminRequest("PUT", "/db/_user/alice", rest.GetUserPayload(t, "alice", "letmein", "", rt.GetSingleTestDatabaseCollection(), []string{"ABC"}, nil))
rest.RequireStatus(t, resp, 201)
rt.CreateUser("alice", []string{"ABC"})

// Put several documents in channel PBS
response := rt.SendAdminRequest("PUT", "/{{.keyspace}}/pbs1", `{"value":1, "channel":["PBS"]}`)
Expand Down
7 changes: 4 additions & 3 deletions rest/adminapitest/resync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ func TestResyncRegenerateSequencesPrincipals(t *testing.T) {
require.NotEqual(t, 0, originalUserSeq)

rt.CreateTestDoc(standardDoc)
doc, err := rt.GetSingleTestDatabaseCollection().GetDocument(ctx, standardDoc, db.DocUnmarshalSync)
collection, ctx := rt.GetSingleTestDatabaseCollection()
doc, err := collection.GetDocument(ctx, standardDoc, db.DocUnmarshalSync)
require.NoError(t, err)
oldDocSeq := doc.Sequence
require.NotEqual(t, 0, oldDocSeq)
Expand Down Expand Up @@ -157,7 +158,7 @@ func TestResyncRegenerateSequencesPrincipals(t *testing.T) {
}

// regular doc will always change sequence
doc, err = rt.GetSingleTestDatabaseCollection().GetDocument(ctx, standardDoc, db.DocUnmarshalSync)
doc, err = collection.GetDocument(ctx, standardDoc, db.DocUnmarshalSync)
require.NoError(t, err)
require.NotEqual(t, 0, doc.Sequence)
require.NotEqual(t, oldDocSeq, doc.Sequence)
Expand Down Expand Up @@ -207,7 +208,7 @@ func TestResyncInvalidatePrincipals(t *testing.T) {
}`
rt.CreateUser(username, nil)

response := rt.SendAdminRequest(http.MethodPut, "/{{.db}}/_role/"+rolename, rest.GetRolePayload(t, rolename, rt.GetSingleTestDatabaseCollection(), nil))
response := rt.SendAdminRequest(http.MethodPut, "/{{.db}}/_role/"+rolename, rest.GetRolePayload(t, rolename, rt.GetSingleDataStore(), nil))
rest.RequireStatus(t, response, http.StatusCreated)

// Write doc to perform dynamic grants
Expand Down
3 changes: 1 addition & 2 deletions rest/api_collections_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ func TestCollectionsBasicIndexQuery(t *testing.T) {

const docID = "doc1"

collection := rt.GetSingleTestDatabaseCollection()
collection, ctx := rt.GetSingleTestDatabaseCollection()

resp := rt.SendAdminRequest(http.MethodPut, "/{{.keyspace}}/"+docID, `{"test":true}`)
RequireStatus(t, resp, http.StatusCreated)
Expand All @@ -494,7 +494,6 @@ func TestCollectionsBasicIndexQuery(t *testing.T) {
require.True(t, ok)

idxName := t.Name() + "_primary"
ctx := base.TestCtx(t)
require.NoError(t, n1qlStore.CreatePrimaryIndex(ctx, idxName, nil))
require.NoError(t, n1qlStore.WaitForIndexesOnline(ctx, []string{idxName}, base.WaitForIndexesDefault))

Expand Down
15 changes: 9 additions & 6 deletions rest/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2532,7 +2532,8 @@ func TestDocumentChannelHistory(t *testing.T) {
RequireStatus(t, resp, http.StatusCreated)
err := json.Unmarshal(resp.BodyBytes(), &body)
assert.NoError(t, err)
syncData, err := rt.GetSingleTestDatabaseCollection().GetDocSyncData(base.TestCtx(t), "doc")
collection, ctx := rt.GetSingleTestDatabaseCollection()
syncData, err := collection.GetDocSyncData(ctx, "doc")
assert.NoError(t, err)

require.Len(t, syncData.ChannelSet, 1)
Expand All @@ -2545,7 +2546,7 @@ func TestDocumentChannelHistory(t *testing.T) {
RequireStatus(t, resp, http.StatusCreated)
err = json.Unmarshal(resp.BodyBytes(), &body)
assert.NoError(t, err)
syncData, err = rt.GetSingleTestDatabaseCollection().GetDocSyncData(base.TestCtx(t), "doc")
syncData, err = collection.GetDocSyncData(ctx, "doc")
assert.NoError(t, err)

require.Len(t, syncData.ChannelSet, 1)
Expand All @@ -2558,7 +2559,7 @@ func TestDocumentChannelHistory(t *testing.T) {
RequireStatus(t, resp, http.StatusCreated)
err = json.Unmarshal(resp.BodyBytes(), &body)
assert.NoError(t, err)
syncData, err = rt.GetSingleTestDatabaseCollection().GetDocSyncData(base.TestCtx(t), "doc")
syncData, err = collection.GetDocSyncData(ctx, "doc")
assert.NoError(t, err)

require.Len(t, syncData.ChannelSet, 2)
Expand Down Expand Up @@ -2623,7 +2624,8 @@ func TestChannelHistoryLegacyDoc(t *testing.T) {
RequireStatus(t, resp, http.StatusCreated)
err = json.Unmarshal(resp.BodyBytes(), &body)
assert.NoError(t, err)
syncData, err := rt.GetSingleTestDatabaseCollection().GetDocSyncData(base.TestCtx(t), "doc1")
collection, ctx := rt.GetSingleTestDatabaseCollection()
syncData, err := collection.GetDocSyncData(ctx, "doc1")
assert.NoError(t, err)
require.Len(t, syncData.ChannelSet, 1)
assert.Contains(t, syncData.ChannelSet, db.ChannelSetEntry{
Expand Down Expand Up @@ -2734,7 +2736,8 @@ func TestDocChannelSetPruning(t *testing.T) {
version = rt.UpdateDoc(docID, version, `{"channels": ["a"]}`)
}

syncData, err := rt.GetSingleTestDatabaseCollection().GetDocSyncData(base.TestCtx(t), "doc")
collection, ctx := rt.GetSingleTestDatabaseCollection()
syncData, err := collection.GetDocSyncData(ctx, "doc")
assert.NoError(t, err)

require.Len(t, syncData.ChannelSetHistory, db.DocumentHistoryMaxEntriesPerChannel)
Expand All @@ -2746,7 +2749,7 @@ func TestDocChannelSetPruning(t *testing.T) {
func TestNullDocHandlingForMutable1xBody(t *testing.T) {
rt := NewRestTester(t, nil)
defer rt.Close()
collection, ctx := rt.GetSingleTestDatabaseCollectionWithUser(rt.Context())
collection, ctx := rt.GetSingleTestDatabaseCollectionWithUser()

documentRev := db.DocumentRevision{DocID: "doc1", BodyBytes: []byte("null")}

Expand Down
8 changes: 2 additions & 6 deletions rest/api_test_no_race_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,11 @@ func TestChangesNotifyChannelFilter(t *testing.T) {
})
defer rt.Close()

collection := rt.GetSingleTestDatabaseCollection()

// Create user:
userResponse := rt.SendAdminRequest("PUT", "/db/_user/bernard", GetUserPayload(t, "bernard", "letmein", "", collection, []string{"ABC"}, nil))
RequireStatus(t, userResponse, 201)
rt.CreateUser("bernard", []string{"ABC"})

// Get user, to trigger all_channels calculation and bump the user change count BEFORE we write the PBS docs - otherwise the user key count
// will still be higher than the latest change count.
userResponse = rt.SendAdminRequest("GET", "/db/_user/bernard", "")
userResponse := rt.SendAdminRequest("GET", "/db/_user/bernard", "")
RequireStatus(t, userResponse, 200)

/*
Expand Down
12 changes: 7 additions & 5 deletions rest/attachment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2299,17 +2299,18 @@ func TestUpdateExistingAttachment(t *testing.T) {
assert.NoError(t, rt.WaitForVersion(doc1ID, doc1Version))
assert.NoError(t, rt.WaitForVersion(doc2ID, doc2Version))

_, err = rt.GetSingleTestDatabaseCollection().GetDocument(base.TestCtx(t), "doc1", db.DocUnmarshalAll)
collection, ctx := rt.GetSingleTestDatabaseCollection()
_, err = collection.GetDocument(ctx, "doc1", db.DocUnmarshalAll)
require.NoError(t, err)
_, err = rt.GetSingleTestDatabaseCollection().GetDocument(base.TestCtx(t), "doc2", db.DocUnmarshalAll)
_, err = collection.GetDocument(ctx, "doc2", db.DocUnmarshalAll)
require.NoError(t, err)

doc1Version, err = btcRunner.PushRev(btc.id, doc1ID, doc1Version, []byte(`{"key": "val", "_attachments":{"attachment":{"digest":"sha1-SKk0IV40XSHW37d3H0xpv2+z9Ck=","length":11,"content_type":"","stub":true,"revpos":3}}}`))
require.NoError(t, err)

assert.NoError(t, rt.WaitForVersion(doc1ID, doc1Version))

doc1, err := rt.GetSingleTestDatabaseCollection().GetDocument(base.TestCtx(t), "doc1", db.DocUnmarshalAll)
doc1, err := collection.GetDocument(ctx, "doc1", db.DocUnmarshalAll)
assert.NoError(t, err)

assert.Equal(t, "sha1-SKk0IV40XSHW37d3H0xpv2+z9Ck=", doc1.Attachments["attachment"].(map[string]interface{})["digest"])
Expand Down Expand Up @@ -2631,9 +2632,10 @@ func TestCBLRevposHandling(t *testing.T) {
assert.NoError(t, btc.rt.WaitForVersion(doc1ID, doc1Version))
assert.NoError(t, btc.rt.WaitForVersion(doc2ID, doc2Version))

_, err = btc.rt.GetSingleTestDatabaseCollection().GetDocument(base.TestCtx(t), "doc1", db.DocUnmarshalAll)
collection, ctx := btc.rt.GetSingleTestDatabaseCollection()
_, err = collection.GetDocument(ctx, "doc1", db.DocUnmarshalAll)
require.NoError(t, err)
_, err = btc.rt.GetSingleTestDatabaseCollection().GetDocument(base.TestCtx(t), "doc2", db.DocUnmarshalAll)
_, err = collection.GetDocument(ctx, "doc2", db.DocUnmarshalAll)
require.NoError(t, err)

// Update doc1, don't change attachment, use correct revpos
Expand Down
Loading

0 comments on commit 0a2937b

Please sign in to comment.