|
33 | 33 | #include <mongoc/mongoc-error-private.h> |
34 | 34 | #include <mongoc/mongoc-http-private.h> |
35 | 35 |
|
| 36 | +/* _mongoc_crypt_get_libmongocrypt_version */ |
| 37 | +#include <mongoc/mongoc-crypt-private.h> |
| 38 | + |
36 | 39 | #include <mongoc/mongoc-uri.h> |
37 | 40 |
|
38 | 41 | #include <mlib/cmp.h> |
@@ -6522,6 +6525,16 @@ drop_coll(mongoc_database_t *db, const char *collname) |
6522 | 6525 | mongoc_collection_destroy(coll); |
6523 | 6526 | } |
6524 | 6527 |
|
| 6528 | +server_version_t |
| 6529 | +get_libmongocrypt_version(void) |
| 6530 | +{ |
| 6531 | +#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION |
| 6532 | + return test_framework_str_to_version(_mongoc_crypt_get_libmongocrypt_version()); |
| 6533 | +#else |
| 6534 | + return 0; |
| 6535 | +#endif |
| 6536 | +} |
| 6537 | + |
6525 | 6538 | static void |
6526 | 6539 | test_lookup_setup(void) |
6527 | 6540 | { |
@@ -6619,6 +6632,19 @@ test_lookup_setup(void) |
6619 | 6632 | mongoc_collection_destroy(coll); |
6620 | 6633 | } |
6621 | 6634 |
|
| 6635 | + // Create db.non_csfle_schema: |
| 6636 | + { |
| 6637 | + drop_coll(db, "non_csfle_schema"); |
| 6638 | + bson_t *const schema = get_bson_from_json_file(TESTDIR "schema-non-csfle.json"); |
| 6639 | + bson_t *const create_opts = BCON_NEW("validator", "{", "$jsonSchema", BCON_DOCUMENT(schema), "}"); |
| 6640 | + mongoc_collection_t *const coll = |
| 6641 | + mongoc_database_create_collection(db, "non_csfle_schema", create_opts, &error); |
| 6642 | + ASSERT_OR_PRINT(coll, error); |
| 6643 | + mongoc_collection_destroy(coll); |
| 6644 | + bson_destroy(create_opts); |
| 6645 | + bson_destroy(schema); |
| 6646 | + } |
| 6647 | + |
6622 | 6648 | mongoc_database_destroy(db); |
6623 | 6649 | } |
6624 | 6650 | #undef TESTDIR |
@@ -6699,6 +6725,20 @@ test_lookup_setup(void) |
6699 | 6725 | mongoc_collection_destroy(coll_unencrypted); |
6700 | 6726 | } |
6701 | 6727 |
|
| 6728 | + // Insert to db.non_csfle_schema |
| 6729 | + { |
| 6730 | + mongoc_collection_t *const coll = mongoc_client_get_collection(client, "db", "non_csfle_schema"); |
| 6731 | + ok = mongoc_collection_insert_one( |
| 6732 | + coll, MAKE_BSON({"non_csfle_schema" : "non_csfle_schema"}), NULL, NULL, &error); |
| 6733 | + ASSERT_OR_PRINT(ok, error); |
| 6734 | + mongoc_collection_destroy(coll); |
| 6735 | + // Find document with unencrypted client to check it is not encrypted. |
| 6736 | + mongoc_collection_t *const coll_unencrypted = |
| 6737 | + mongoc_client_get_collection(setup_client, "db", "non_csfle_schema"); |
| 6738 | + ASSERT_COLL_MATCHES_ONE(coll_unencrypted, MAKE_BSON({"non_csfle_schema" : "non_csfle_schema"})); |
| 6739 | + mongoc_collection_destroy(coll_unencrypted); |
| 6740 | + } |
| 6741 | + |
6702 | 6742 | mongoc_client_destroy(client); |
6703 | 6743 | } |
6704 | 6744 |
|
@@ -6909,7 +6949,67 @@ test_lookup(void *unused) |
6909 | 6949 | ] |
6910 | 6950 | }); |
6911 | 6951 |
|
6912 | | - ASSERT_AGG_ERROR(coll, pipeline, "not supported"); |
| 6952 | + if (test_framework_get_server_version() < test_framework_str_to_version("8.2.0") || |
| 6953 | + get_libmongocrypt_version() < test_framework_str_to_version("1.17.0")) { |
| 6954 | + ASSERT_AGG_ERROR(coll, pipeline, "not supported"); |
| 6955 | + } else { |
| 6956 | + // The error domain differs depending on the query analysis component: |
| 6957 | + // * `crypt_shared`: `MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION` |
| 6958 | + // * `mongocryptd`: `MONGOC_ERROR_QUERY` |
| 6959 | + |
| 6960 | + static const char *const expected_error_substring = |
| 6961 | + "Cannot specify both encryptionInformation and csfleEncryptionSchemas unless csfleEncryptionSchemas only " |
| 6962 | + "contains non-encryption JSON schema validators"; |
| 6963 | + |
| 6964 | + if (mongoc_client_get_crypt_shared_version(client)) { |
| 6965 | + ASSERT_AGG_ERROR(coll, pipeline, expected_error_substring); |
| 6966 | + } else { |
| 6967 | + mongoc_cursor_t *const cursor = mongoc_collection_aggregate(coll, 0, pipeline, NULL, NULL); |
| 6968 | + const bson_t *got; |
| 6969 | + ASSERT(!mongoc_cursor_next(cursor, &got)); |
| 6970 | + ASSERT(mongoc_cursor_error(cursor, &error)); |
| 6971 | + static const uint32_t expected_error_code = 10026002u; |
| 6972 | + ASSERT_ERROR_CONTAINS(error, MONGOC_ERROR_QUERY, expected_error_code, expected_error_substring); |
| 6973 | + mongoc_cursor_destroy(cursor); |
| 6974 | + } |
| 6975 | + } |
| 6976 | + |
| 6977 | + mongoc_collection_destroy(coll); |
| 6978 | + mongoc_client_destroy(client); |
| 6979 | + } |
| 6980 | +} |
| 6981 | + |
| 6982 | +static void |
| 6983 | +test_lookup_post82(void *unused) |
| 6984 | +{ |
| 6985 | + BSON_UNUSED(unused); |
| 6986 | + test_lookup_setup(); |
| 6987 | + bson_error_t error; |
| 6988 | + |
| 6989 | + // Case 10: db.qe joins db.non_csfle_schema: |
| 6990 | + { |
| 6991 | + mongoc_client_t *const client = create_encrypted_client(); |
| 6992 | + mongoc_collection_t *const coll = mongoc_client_get_collection(client, "db", "qe"); |
| 6993 | + |
| 6994 | + bson_t *const pipeline = MAKE_BSON({ |
| 6995 | + "pipeline" : [ |
| 6996 | + {"$match" : {"qe" : "qe"}}, |
| 6997 | + { |
| 6998 | + "$lookup" : { |
| 6999 | + "from" : "non_csfle_schema", |
| 7000 | + "as" : "matched", |
| 7001 | + "pipeline" : [ |
| 7002 | + {"$match" : {"non_csfle_schema" : "non_csfle_schema"}}, |
| 7003 | + {"$project" : {"_id" : 0, "__safeContent__" : 0}} |
| 7004 | + ] |
| 7005 | + } |
| 7006 | + }, |
| 7007 | + {"$project" : {"_id" : 0, "__safeContent__" : 0}} |
| 7008 | + ] |
| 7009 | + }); |
| 7010 | + |
| 7011 | + bson_t *const expect = MAKE_BSON({"qe" : "qe", "matched" : [ {"non_csfle_schema" : "non_csfle_schema"} ]}); |
| 7012 | + ASSERT_AGG_RETURNS_ONE(coll, pipeline, expect); |
6913 | 7013 | mongoc_collection_destroy(coll); |
6914 | 7014 | mongoc_client_destroy(client); |
6915 | 7015 | } |
@@ -6947,6 +7047,12 @@ test_lookup_pre81(void *unused) |
6947 | 7047 | } |
6948 | 7048 | } |
6949 | 7049 |
|
| 7050 | +int |
| 7051 | +skip_if_libmongocrypt_less_than_1_17_0(void) |
| 7052 | +{ |
| 7053 | + return get_libmongocrypt_version() >= test_framework_str_to_version("1.17.0"); |
| 7054 | +} |
| 7055 | + |
6950 | 7056 | void |
6951 | 7057 | test_client_side_encryption_install(TestSuite *suite) |
6952 | 7058 | { |
@@ -7388,6 +7494,15 @@ test_client_side_encryption_install(TestSuite *suite) |
7388 | 7494 | test_framework_skip_if_max_wire_version_less_than_26 /* require server 8.1+ */, |
7389 | 7495 | test_framework_skip_if_single, /* QE not supported on standalone */ |
7390 | 7496 | test_framework_skip_if_no_client_side_encryption); |
| 7497 | + TestSuite_AddFull(suite, |
| 7498 | + "/client_side_encryption/test_lookup/post-8.2", |
| 7499 | + test_lookup_post82, |
| 7500 | + NULL, |
| 7501 | + NULL, |
| 7502 | + test_framework_skip_if_max_wire_version_less_than_27, /* require server 8.2+ */ |
| 7503 | + skip_if_libmongocrypt_less_than_1_17_0, /* require libmongocrypt 1.17.0+ */ |
| 7504 | + test_framework_skip_if_single, /* QE not supported on standalone */ |
| 7505 | + test_framework_skip_if_no_client_side_encryption); |
7391 | 7506 | TestSuite_AddFull(suite, |
7392 | 7507 | "/client_side_encryption/test_lookup/pre-8.1", |
7393 | 7508 | test_lookup_pre81, |
|
0 commit comments