Skip to content

Commit

Permalink
Move common GetRev/GetCV work into documentRevisionForRequest function
Browse files Browse the repository at this point in the history
  • Loading branch information
bbrks committed Jan 17, 2024
1 parent 1411d91 commit f2510b6
Showing 1 changed file with 25 additions and 42 deletions.
67 changes: 25 additions & 42 deletions db/crud.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,14 +322,29 @@ func (db *DatabaseCollectionWithUser) getRev(ctx context.Context, docid, revid s
// No rev ID given, so load active revision
revision, err = db.revisionCache.GetActive(ctx, docid, includeBody)
}

if err != nil {
return DocumentRevision{}, err
}

return db.documentRevisionForRequest(ctx, docid, revision, &revid, nil, maxHistory, historyFrom)
}

// documentRevisionForRequest processes the given DocumentRevision and returns a version of it for a given client request, depending on access, deleted, etc.
func (db *DatabaseCollectionWithUser) documentRevisionForRequest(ctx context.Context, docID string, revision DocumentRevision, revID *string, cv *Version, maxHistory int, historyFrom []string) (DocumentRevision, error) {
// ensure only one of cv or revID is specified
if (cv != nil && revID != nil) || (cv == nil && revID == nil) {
return DocumentRevision{}, fmt.Errorf("must have exactly one of cv or revID in documentRevisionForRequest (had %v %v)", cv, revID)
}
var requestedVersion string
if revID != nil {
requestedVersion = *revID
} else if cv != nil {
requestedVersion = cv.String()
}

if revision.BodyBytes == nil {
if db.ForceAPIForbiddenErrors() {
base.InfofCtx(ctx, base.KeyCRUD, "Doc: %s %s is missing", base.UD(docid), base.MD(revid))
base.InfofCtx(ctx, base.KeyCRUD, "Doc: %s %s is missing", base.UD(docID), base.MD(requestedVersion))
return DocumentRevision{}, ErrForbidden
}
return DocumentRevision{}, ErrMissing
Expand All @@ -348,16 +363,18 @@ func (db *DatabaseCollectionWithUser) getRev(ctx context.Context, docid, revid s
_, requestedHistory = trimEncodedRevisionsToAncestor(ctx, requestedHistory, historyFrom, maxHistory)
}

isAuthorized, redactedRev := db.authorizeUserForChannels(docid, revision.RevID, nil, revision.Channels, revision.Deleted, requestedHistory)
revIDStr := base.StringDefault(revID, "")
isAuthorized, redactedRevision := db.authorizeUserForChannels(docID, revIDStr, cv, revision.Channels, revision.Deleted, requestedHistory)
if !isAuthorized {
if revid == "" {
// client just wanted active revision, not a specific one
if requestedVersion == "" {
return DocumentRevision{}, ErrForbidden
}
if db.ForceAPIForbiddenErrors() {
base.InfofCtx(ctx, base.KeyCRUD, "Not authorized to view doc: %s %s", base.UD(docid), base.MD(revid))
base.InfofCtx(ctx, base.KeyCRUD, "Not authorized to view doc: %s %s", base.UD(docID), base.MD(requestedVersion))
return DocumentRevision{}, ErrForbidden
}
return redactedRev, nil
return redactedRevision, nil
}

// If the revision is a removal cache entry (no body), but the user has access to that removal, then just
Expand All @@ -366,7 +383,7 @@ func (db *DatabaseCollectionWithUser) getRev(ctx context.Context, docid, revid s
return DocumentRevision{}, ErrMissing
}

if revision.Deleted && revid == "" {
if revision.Deleted && requestedVersion == "" {
return DocumentRevision{}, ErrDeleted
}

Expand All @@ -379,45 +396,11 @@ func (db *DatabaseCollectionWithUser) GetCV(ctx context.Context, docid string, c
} else {
revision, err = db.revisionCache.GetActive(ctx, docid, includeBody)
}

if err != nil {
return DocumentRevision{}, err
}

if revision.BodyBytes == nil {
if db.ForceAPIForbiddenErrors() {
base.InfofCtx(ctx, base.KeyCRUD, "Doc: %s %s:%s is missing", base.UD(docid), base.MD(cv.SourceID), base.MD(cv.Value))
return DocumentRevision{}, ErrForbidden
}
return DocumentRevision{}, ErrMissing
}

db.collectionStats.NumDocReads.Add(1)
db.collectionStats.DocReadsBytes.Add(int64(len(revision.BodyBytes)))

isAuthorized, redactedRevision := db.authorizeUserForChannels(docid, revision.RevID, cv, revision.Channels, revision.Deleted, nil)
if !isAuthorized {
if cv == nil {
return DocumentRevision{}, ErrForbidden
}
if db.ForceAPIForbiddenErrors() {
base.InfofCtx(ctx, base.KeyCRUD, "Not authorized to view doc: %s %s:%s", base.UD(docid), base.MD(cv.SourceID), base.MD(cv.Value))
return DocumentRevision{}, ErrForbidden
}
return redactedRevision, nil
}

// If the revision is a removal cache entry (no body), but the user has access to that removal, then just
// return 404 missing to indicate that the body of the revision is no longer available.
if revision.Removed {
return DocumentRevision{}, ErrMissing
}

if revision.Deleted && cv == nil {
return DocumentRevision{}, ErrDeleted
}

return revision, nil
return db.documentRevisionForRequest(ctx, docid, revision, nil, cv, 0, nil)
}

// GetDelta attempts to return the delta between fromRevId and toRevId. If the delta can't be generated,
Expand Down

0 comments on commit f2510b6

Please sign in to comment.