diff options
-rw-r--r-- | jstests/core/doc_validation_encrypt_keywords.js | 39 | ||||
-rw-r--r-- | src/mongo/db/catalog/collection_impl.cpp | 10 |
2 files changed, 42 insertions, 7 deletions
diff --git a/jstests/core/doc_validation_encrypt_keywords.js b/jstests/core/doc_validation_encrypt_keywords.js index de8303fe59d..21d84768def 100644 --- a/jstests/core/doc_validation_encrypt_keywords.js +++ b/jstests/core/doc_validation_encrypt_keywords.js @@ -7,8 +7,8 @@ (function() { "use strict"; -var collName = "doc_validation_encrypt_keywords"; -var coll = db[collName]; +const collName = "doc_validation_encrypt_keywords"; +const coll = db[collName]; coll.drop(); const encryptSchema = { @@ -21,6 +21,29 @@ const encryptMetadataSchema = { $jsonSchema: {encryptMetadata: {algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"}} }; +/** + * Verify that the validator's in-memory state matches its on-disk state. + */ +function validateCollectionOptions() { + function verifyValidateSuccess(output) { + assert(output.hasOwnProperty("errors"), output); + assert.eq(0, output["errors"].length, output); + assert(output.hasOwnProperty("valid"), output); + assert.eq(true, output["valid"], output); + } + + const validateResult = assert.commandWorked(coll.validate({full: true})); + + if (validateResult.hasOwnProperty("raw")) { + const rawOutput = validateResult["raw"]; + for (const key of Object.keys(rawOutput)) { + verifyValidateSuccess(rawOutput[key]); + } + } else { + verifyValidateSuccess(validateResult); + } +} + assert.commandFailedWithCode( db.createCollection(collName, {validator: encryptSchema, validationAction: "warn"}), ErrorCodes.QueryFeatureNotAllowed); @@ -48,10 +71,13 @@ assert.commandWorked(db.createCollection( // Verify that we can't collMod the validator to include an encryption-related keyword. assert.commandFailedWithCode(db.runCommand({collMod: collName, validator: encryptSchema}), ErrorCodes.QueryFeatureNotAllowed); +validateCollectionOptions(); assert.commandFailedWithCode(db.runCommand({collMod: collName, validator: nestedEncryptSchema}), ErrorCodes.QueryFeatureNotAllowed); +validateCollectionOptions(); assert.commandFailedWithCode(db.runCommand({collMod: collName, validator: encryptMetadataSchema}), ErrorCodes.QueryFeatureNotAllowed); +validateCollectionOptions(); coll.drop(); // Create the collection with an encrypted validator and action 'error'. @@ -62,11 +88,13 @@ assert.commandWorked( // encryption-related keyword. assert.commandFailedWithCode(db.runCommand({collMod: collName, validationAction: "warn"}), ErrorCodes.QueryFeatureNotAllowed); +validateCollectionOptions(); // Verify that we can't collMod the validation level to 'moderate' since the schema contains an // encryption-related keyword. assert.commandFailedWithCode(db.runCommand({collMod: collName, validationLevel: "moderate"}), ErrorCodes.QueryFeatureNotAllowed); +validateCollectionOptions(); coll.drop(); // Create the collection without a document validator. @@ -77,22 +105,27 @@ assert.commandWorked(db.createCollection(collName)); assert.commandFailedWithCode( db.runCommand({collMod: collName, validator: encryptSchema, validationAction: "warn"}), ErrorCodes.QueryFeatureNotAllowed); +validateCollectionOptions(); assert.commandFailedWithCode( db.runCommand({collMod: collName, validator: nestedEncryptSchema, validationAction: "warn"}), ErrorCodes.QueryFeatureNotAllowed); +validateCollectionOptions(); assert.commandFailedWithCode( db.runCommand({collMod: collName, validator: encryptMetadataSchema, validationAction: "warn"}), ErrorCodes.QueryFeatureNotAllowed); +validateCollectionOptions(); assert.commandFailedWithCode( db.runCommand({collMod: collName, validator: encryptSchema, validationLevel: "moderate"}), ErrorCodes.QueryFeatureNotAllowed); +validateCollectionOptions(); assert.commandFailedWithCode( db.runCommand({collMod: collName, validator: nestedEncryptSchema, validationLevel: "moderate"}), ErrorCodes.QueryFeatureNotAllowed); +validateCollectionOptions(); assert.commandFailedWithCode( db.runCommand( {collMod: collName, validator: encryptMetadataSchema, validationLevel: "moderate"}), ErrorCodes.QueryFeatureNotAllowed); -coll.drop(); +validateCollectionOptions(); })(); diff --git a/src/mongo/db/catalog/collection_impl.cpp b/src/mongo/db/catalog/collection_impl.cpp index 9b1a80d2bb7..c6498fc3afb 100644 --- a/src/mongo/db/catalog/collection_impl.cpp +++ b/src/mongo/db/catalog/collection_impl.cpp @@ -953,6 +953,9 @@ Status CollectionImpl::setValidationLevel(OperationContext* opCtx, StringData ne auto oldValidationLevel = _validationLevel; _validationLevel = levelSW.getValue(); + opCtx->recoveryUnit()->onRollback( + [this, oldValidationLevel]() { this->_validationLevel = oldValidationLevel; }); + // Reparse the validator as there are some features which are only supported with certain // validation levels. auto allowedFeatures = MatchExpressionParser::kAllowAllSpecialFeatures; @@ -966,8 +969,6 @@ Status CollectionImpl::setValidationLevel(OperationContext* opCtx, StringData ne DurableCatalog::get(opCtx)->updateValidator( opCtx, ns(), _validatorDoc, getValidationLevel(), getValidationAction()); - opCtx->recoveryUnit()->onRollback( - [this, oldValidationLevel]() { this->_validationLevel = oldValidationLevel; }); return Status::OK(); } @@ -983,6 +984,9 @@ Status CollectionImpl::setValidationAction(OperationContext* opCtx, StringData n auto oldValidationAction = _validationAction; _validationAction = actionSW.getValue(); + opCtx->recoveryUnit()->onRollback( + [this, oldValidationAction]() { this->_validationAction = oldValidationAction; }); + // Reparse the validator as there are some features which are only supported with certain // validation actions. auto allowedFeatures = MatchExpressionParser::kAllowAllSpecialFeatures; @@ -996,8 +1000,6 @@ Status CollectionImpl::setValidationAction(OperationContext* opCtx, StringData n DurableCatalog::get(opCtx)->updateValidator( opCtx, ns(), _validatorDoc, getValidationLevel(), getValidationAction()); - opCtx->recoveryUnit()->onRollback( - [this, oldValidationAction]() { this->_validationAction = oldValidationAction; }); return Status::OK(); } |