예제 #1
0
        private IAsyncCursor <BsonDocument> CreateCursor(IChannelSourceHandle channelSource, BsonDocument result, BsonDocument command)
        {
            var cursorDocument = result["cursor"].AsBsonDocument;
            var cursor         = new AsyncCursor <BsonDocument>(
                channelSource.Fork(),
                CollectionNamespace.FromFullName(cursorDocument["ns"].AsString),
                command,
                cursorDocument["firstBatch"].AsBsonArray.OfType <BsonDocument>().ToList(),
                cursorDocument["id"].ToInt64(),
                0,
                0,
                BsonDocumentSerializer.Instance,
                _messageEncoderSettings);

            return(cursor);
        }
예제 #2
0
        internal QueryMessage ReadMessage <TDocument>(IBsonSerializer <TDocument> serializer)
            where TDocument : BsonDocument
        {
            var binaryReader  = CreateBinaryReader();
            var stream        = binaryReader.BsonStream;
            var startPosition = stream.Position;

            var messageSize = stream.ReadInt32();
            var requestId   = stream.ReadInt32();

            stream.ReadInt32(); // responseTo
            stream.ReadInt32(); // opcode
            var          flags = (QueryFlags)stream.ReadInt32();
            var          fullCollectionName = stream.ReadCString(Encoding);
            var          skip      = stream.ReadInt32();
            var          batchSize = stream.ReadInt32();
            var          context   = BsonDeserializationContext.CreateRoot(binaryReader);
            var          query     = serializer.Deserialize(context);
            BsonDocument fields    = null;

            if (stream.Position < startPosition + messageSize)
            {
                fields = serializer.Deserialize(context);
            }

            var awaitData       = (flags & QueryFlags.AwaitData) == QueryFlags.AwaitData;
            var slaveOk         = (flags & QueryFlags.SlaveOk) == QueryFlags.SlaveOk;
            var partialOk       = (flags & QueryFlags.Partial) == QueryFlags.Partial;
            var noCursorTimeout = (flags & QueryFlags.NoCursorTimeout) == QueryFlags.NoCursorTimeout;
            var oplogReplay     = (flags & QueryFlags.OplogReplay) == QueryFlags.OplogReplay;
            var tailableCursor  = (flags & QueryFlags.TailableCursor) == QueryFlags.TailableCursor;

            return(new QueryMessage(
                       requestId,
                       CollectionNamespace.FromFullName(fullCollectionName),
                       query,
                       fields,
                       NoOpElementNameValidator.Instance,
                       skip,
                       batchSize,
                       slaveOk,
                       partialOk,
                       noCursorTimeout,
                       oplogReplay,
                       tailableCursor,
                       awaitData));
        }
예제 #3
0
        public QueryMessage ReadMessage()
        {
            var binaryReader  = CreateBinaryReader();
            var streamReader  = binaryReader.StreamReader;
            var startPosition = streamReader.Position;

            var          messageSize        = streamReader.ReadInt32();
            var          requestId          = streamReader.ReadInt32();
            var          responseTo         = streamReader.ReadInt32();
            var          opcode             = (Opcode)streamReader.ReadInt32();
            var          flags              = (QueryFlags)streamReader.ReadInt32();
            var          fullCollectionName = streamReader.ReadCString();
            var          skip      = streamReader.ReadInt32();
            var          batchSize = streamReader.ReadInt32();
            var          context   = BsonDeserializationContext.CreateRoot <BsonDocument>(binaryReader);
            var          query     = BsonDocumentSerializer.Instance.Deserialize(context);
            BsonDocument fields    = null;

            if (streamReader.Position < startPosition + messageSize)
            {
                fields = BsonDocumentSerializer.Instance.Deserialize(context);
            }

            var awaitData       = flags.HasFlag(QueryFlags.AwaitData);
            var slaveOk         = flags.HasFlag(QueryFlags.SlaveOk);
            var partialOk       = flags.HasFlag(QueryFlags.Partial);
            var noCursorTimeout = flags.HasFlag(QueryFlags.NoCursorTimeout);
            var tailableCursor  = flags.HasFlag(QueryFlags.TailableCursor);

            return(new QueryMessage(
                       requestId,
                       CollectionNamespace.FromFullName(fullCollectionName),
                       query,
                       fields,
                       NoOpElementNameValidator.Instance,
                       skip,
                       batchSize,
                       slaveOk,
                       partialOk,
                       noCursorTimeout,
                       tailableCursor,
                       awaitData));
        }
        // methods
        public GetMoreMessage ReadMessage()
        {
            var binaryReader = CreateBinaryReader();
            var streamReader = binaryReader.StreamReader;

            var messageSize        = streamReader.ReadInt32();
            var requestId          = streamReader.ReadInt32();
            var responseTo         = streamReader.ReadInt32();
            var opcode             = (Opcode)streamReader.ReadInt32();
            var reserved           = streamReader.ReadInt32();
            var fullCollectionName = streamReader.ReadCString();
            var batchSize          = streamReader.ReadInt32();
            var cursorId           = streamReader.ReadInt64();

            return(new GetMoreMessage(
                       requestId,
                       CollectionNamespace.FromFullName(fullCollectionName),
                       cursorId,
                       batchSize));
        }
예제 #5
0
        // methods
        /// <summary>
        /// Reads the message.
        /// </summary>
        /// <returns>A message.</returns>
        public GetMoreMessage ReadMessage()
        {
            var binaryReader = CreateBinaryReader();
            var stream       = binaryReader.BsonStream;

            stream.ReadInt32(); // messageSize
            var requestId = stream.ReadInt32();

            stream.ReadInt32(); // responseTo
            stream.ReadInt32(); // opcode
            stream.ReadInt32(); // reserved
            var fullCollectionName = stream.ReadCString(Encoding);
            var batchSize          = stream.ReadInt32();
            var cursorId           = stream.ReadInt64();

            return(new GetMoreMessage(
                       requestId,
                       CollectionNamespace.FromFullName(fullCollectionName),
                       cursorId,
                       batchSize));
        }
        public void KillCursors_should_return_expected_result()
        {
            RequireEnvironment.Check().EnvironmentVariable("ATLAS_DATA_LAKE_TESTS_ENABLED");
            RequireServer.Check();

            var databaseName   = "test";
            var collectionName = "driverdata";

            var eventCapturer = new EventCapturer()
                                .Capture <CommandStartedEvent>(x => "killCursors" == x.CommandName)
                                .Capture <CommandSucceededEvent>(x => new[] { "killCursors", "find" }.Contains(x.CommandName));

            using (var client = DriverTestConfiguration.CreateDisposableClient(eventCapturer))
            {
                var cursor = client
                             .GetDatabase(databaseName)
                             .GetCollection <BsonDocument>(collectionName)
                             .Find(new BsonDocument(), new FindOptions {
                    BatchSize = 2
                })
                             .ToCursor();

                var findCommandSucceededEvent = eventCapturer.Events.OfType <CommandSucceededEvent>().First(x => x.CommandName == "find");
                var findCommandResult         = findCommandSucceededEvent.Reply;
                var cursorId        = findCommandResult["cursor"]["id"].AsInt64;
                var cursorNamespace = CollectionNamespace.FromFullName(findCommandResult["cursor"]["ns"].AsString);

                cursor.Dispose();

                var killCursorsCommandStartedEvent   = eventCapturer.Events.OfType <CommandStartedEvent>().First(x => x.CommandName == "killCursors");
                var killCursorsCommandSucceededEvent = eventCapturer.Events.OfType <CommandSucceededEvent>().First(x => x.CommandName == "killCursors");
                var killCursorsStartedCommand        = killCursorsCommandStartedEvent.Command;

                cursorNamespace.DatabaseNamespace.DatabaseName.Should().Be(killCursorsCommandStartedEvent.DatabaseNamespace.DatabaseName);
                cursorNamespace.CollectionName.Should().Be(killCursorsStartedCommand["killCursors"].AsString);
                cursorId.Should().Be(killCursorsStartedCommand["cursors"][0].AsInt64);
                cursorId.Should().Be(killCursorsCommandSucceededEvent.Reply["cursorsKilled"][0].AsInt64);
            }
        }
예제 #7
0
        public void ToString_should_return_expected_result()
        {
            var guid      = new Guid("00112233445566778899aabbccddeeff");
            var guidBytes = GuidConverter.ToBytes(guid, GuidRepresentation.Standard);
            var binary    = new BsonBinaryData(guidBytes, BsonBinarySubType.UuidStandard);

            var extraOptions = new Dictionary <string, object>()
            {
                { "mongocryptdURI", "testURI" },
            };
            var kmsProviders = new Dictionary <string, IReadOnlyDictionary <string, object> >()
            {
                { "provider1", new Dictionary <string, object>()
                  {
                      { "string", "test" }
                  } },
                { "provider2", new Dictionary <string, object>()
                  {
                      { "binary", binary.Bytes }
                  } }
            };
            var schemaMap = new Dictionary <string, BsonDocument>()
            {
                { "coll1", new BsonDocument("string", "test") },
                { "coll2", new BsonDocument("binary", binary) },
            };

            var subject = new AutoEncryptionOptions(
                keyVaultNamespace: CollectionNamespace.FromFullName("db.coll"),
                kmsProviders: kmsProviders,
                bypassAutoEncryption: true,
                extraOptions: extraOptions,
                schemaMap: schemaMap);

            var result = subject.ToString();

            result.Should().Be("{ BypassAutoEncryption : True, KmsProviders : { \"provider1\" : { \"string\" : \"test\" }, \"provider2\" : { \"binary\" : { \"_t\" : \"System.Byte[]\", \"_v\" : new BinData(0, \"ABEiM0RVZneImaq7zN3u/w==\") } } }, KeyVaultNamespace : \"db.coll\", ExtraOptions : { \"mongocryptdURI\" : \"testURI\" }, SchemaMap : { \"coll1\" : { \"string\" : \"test\" }, \"coll2\" : { \"binary\" : UUID(\"00112233-4455-6677-8899-aabbccddeeff\") } } }");
        }
        public DeleteMessage ReadMessage()
        {
            var binaryReader = CreateBinaryReader();
            var streamReader = binaryReader.StreamReader;

            var messageSize        = streamReader.ReadInt32();
            var requestId          = streamReader.ReadInt32();
            var responseTo         = streamReader.ReadInt32();
            var opcode             = (Opcode)streamReader.ReadInt32();
            var reserved           = streamReader.ReadInt32();
            var fullCollectionName = streamReader.ReadCString();
            var flags   = (DeleteFlags)streamReader.ReadInt32();
            var context = BsonDeserializationContext.CreateRoot <BsonDocument>(binaryReader);
            var query   = BsonDocumentSerializer.Instance.Deserialize(context);

            var isMulti = !flags.HasFlag(DeleteFlags.Single);

            return(new DeleteMessage(
                       requestId,
                       CollectionNamespace.FromFullName(fullCollectionName),
                       query,
                       isMulti));
        }
            public override AggregateResult Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
            {
                var reader = context.Reader;
                var result = new AggregateResult();

                reader.ReadStartDocument();
                while (reader.ReadBsonType() != 0)
                {
                    var elementName = reader.ReadName();
                    switch (elementName)
                    {
                    case "id":
                        result.CursorId = new Int64Serializer().Deserialize(context);
                        break;

                    case "ns":
                        var ns = reader.ReadString();
                        result.CollectionNamespace = CollectionNamespace.FromFullName(ns);
                        break;

                    case "firstBatch":
                        var arraySerializer = new ArraySerializer <TResult>(_resultSerializer);
                        result.Results = arraySerializer.Deserialize(context);
                        break;

                    case "postBatchResumeToken":
                        result.PostBatchResumeToken = BsonDocumentSerializer.Instance.Deserialize(context);
                        break;

                    default:
                        reader.SkipValue();
                        break;
                    }
                }
                reader.ReadEndDocument();
                return(result);
            }
예제 #10
0
        static void Main(string[] args)
        {
            var connectionString  = "mongodb://localhost:27017";
            var keyVaultNamespace = CollectionNamespace.FromFullName("encryption.__keyVault");

            var kmsKeyHelper = new KmsKeyHelper(
                connectionString: connectionString,
                keyVaultNamespace: keyVaultNamespace);
            var autoEncryptionHelper = new AutoEncryptionHelper(
                connectionString: connectionString,
                keyVaultNamespace: keyVaultNamespace);

            string kmsKeyIdBase64;

            //Only run GenerateLocalMasterKey() once
            //kmsKeyHelper.GenerateLocalMasterKey();

            //Local
            kmsKeyIdBase64 = kmsKeyHelper.CreateKeyWithLocalKmsProvider();
            autoEncryptionHelper.EncryptedWriteAndRead(kmsKeyIdBase64, KmsKeyLocation.Local);

            // AWS
            //kmsKeyIdBase64 = kmsKeyHelper.CreateKeyWithAwsKmsProvider();
            //autoEncryptionHelper.EncryptedWriteAndRead(kmsKeyIdBase64, KmsKeyLocation.AWS);

            // Azure
            //kmsKeyIdBase64 = kmsKeyHelper.CreateKeyWithAzureKmsProvider();
            //autoEncryptionHelper.EncryptedWriteAndRead(kmsKeyIdBase64, KmsKeyLocation.Azure);

            // GCP
            //kmsKeyIdBase64 = kmsKeyHelper.CreateKeyWithGcpKmsProvider();
            //autoEncryptionHelper.EncryptedWriteAndRead(kmsKeyIdBase64, KmsKeyLocation.GCP);

            autoEncryptionHelper.QueryWithNonEncryptedClient();

            Console.ReadKey();
        }
예제 #11
0
        private async Task <IAsyncCursor <BsonDocument> > ExecuteUsingCommandAsync(IChannelSourceHandle channelSource, ReadPreference readPreference, CancellationToken cancellationToken)
        {
            var command = new BsonDocument
            {
                { "listCollections", 1 },
                { "filter", _filter, _filter != null }
            };
            var operation = new ReadCommandOperation <BsonDocument>(_databaseNamespace, command, BsonDocumentSerializer.Instance, _messageEncoderSettings);
            var response  = await operation.ExecuteAsync(channelSource, readPreference, cancellationToken).ConfigureAwait(false);

            var cursorDocument = response["cursor"].AsBsonDocument;
            var cursor         = new AsyncCursor <BsonDocument>(
                channelSource.Fork(),
                CollectionNamespace.FromFullName(cursorDocument["ns"].AsString),
                command,
                cursorDocument["firstBatch"].AsBsonArray.OfType <BsonDocument>().ToList(),
                cursorDocument["id"].ToInt64(),
                0,
                0,
                BsonDocumentSerializer.Instance,
                _messageEncoderSettings);

            return(cursor);
        }
예제 #12
0
        /// <summary>
        /// Reads the message.
        /// </summary>
        /// <returns>A message.</returns>
        public InsertMessage <TDocument> ReadMessage()
        {
            var binaryReader  = CreateBinaryReader();
            var stream        = binaryReader.BsonStream;
            var startPosition = stream.Position;

            var messageSize = stream.ReadInt32();
            var requestId   = stream.ReadInt32();

            stream.ReadInt32(); // responseTo
            stream.ReadInt32(); // opcode
            var flags = (InsertFlags)stream.ReadInt32();
            var fullCollectionName = stream.ReadCString(Encoding);
            var documents          = new List <TDocument>();

            while (stream.Position < startPosition + messageSize)
            {
                var context  = BsonDeserializationContext.CreateRoot(binaryReader);
                var document = _serializer.Deserialize(context);
                documents.Add(document);
            }

            var documentSource  = new BatchableSource <TDocument>(documents);
            var maxBatchCount   = int.MaxValue;
            var maxMessageSize  = int.MaxValue;
            var continueOnError = (flags & InsertFlags.ContinueOnError) == InsertFlags.ContinueOnError;

            return(new InsertMessage <TDocument>(
                       requestId,
                       CollectionNamespace.FromFullName(fullCollectionName),
                       _serializer,
                       documentSource,
                       maxBatchCount,
                       maxMessageSize,
                       continueOnError));
        }
예제 #13
0
        /// <summary>
        /// Reads the message.
        /// </summary>
        /// <returns>A message.</returns>
        public DeleteMessage ReadMessage()
        {
            var binaryReader = CreateBinaryReader();
            var stream       = binaryReader.BsonStream;

            stream.ReadInt32(); // messageSize
            var requestId = stream.ReadInt32();

            stream.ReadInt32(); // responseTo
            stream.ReadInt32(); // opcode
            stream.ReadInt32(); // reserved
            var fullCollectionName = stream.ReadCString(Encoding);
            var flags   = (DeleteFlags)stream.ReadInt32();
            var context = BsonDeserializationContext.CreateRoot(binaryReader);
            var query   = BsonDocumentSerializer.Instance.Deserialize(context);

            var isMulti = (flags & DeleteFlags.Single) != DeleteFlags.Single;

            return(new DeleteMessage(
                       requestId,
                       CollectionNamespace.FromFullName(fullCollectionName),
                       query,
                       isMulti));
        }
        // private methods
        private AutoEncryptionOptions ConfigureAutoEncryptionOptions(BsonDocument autoEncryptOpts)
        {
            var extraOptions = new Dictionary <string, object>()
            {
                { "mongocryptdSpawnPath", GetEnvironmentVariableOrDefaultOrThrowIfNothing("MONGODB_BINARIES", string.Empty) }
            };

            var kmsProviders          = new ReadOnlyDictionary <string, IReadOnlyDictionary <string, object> >(new Dictionary <string, IReadOnlyDictionary <string, object> >());
            var autoEncryptionOptions = new AutoEncryptionOptions(
                keyVaultNamespace: __keyVaultCollectionNamespace,
                kmsProviders: kmsProviders,
                extraOptions: extraOptions);

            foreach (var option in autoEncryptOpts.Elements)
            {
                switch (option.Name)
                {
                case "kmsProviders":
                    kmsProviders          = ParseKmsProviders(option.Value.AsBsonDocument);
                    autoEncryptionOptions = autoEncryptionOptions
                                            .With(kmsProviders: kmsProviders);
                    break;

                case "schemaMap":
                    var schemaMaps         = new Dictionary <string, BsonDocument>();
                    var schemaMapsDocument = option.Value.AsBsonDocument;
                    foreach (var schemaMapElement in schemaMapsDocument.Elements)
                    {
                        schemaMaps.Add(schemaMapElement.Name, schemaMapElement.Value.AsBsonDocument);
                    }
                    autoEncryptionOptions = autoEncryptionOptions.With(schemaMap: schemaMaps);
                    break;

                case "bypassAutoEncryption":
                    autoEncryptionOptions = autoEncryptionOptions.With(bypassAutoEncryption: option.Value.ToBoolean());
                    break;

                case "keyVaultNamespace":
                    autoEncryptionOptions = autoEncryptionOptions.With(keyVaultNamespace: CollectionNamespace.FromFullName(option.Value.AsString));
                    break;

                default:
                    throw new Exception($"Unexpected auto encryption option {option.Name}.");
                }
            }

            return(autoEncryptionOptions);
        }
예제 #15
0
        public void Equals_should_work_correctly()
        {
            var options1 = CreateAutoEncryptionOptions();
            var options2 = CreateAutoEncryptionOptions();

            options1.Equals(options2).Should().BeTrue();

            options1 = CreateAutoEncryptionOptions(tlsOptions: new SslSettings());
            options2 = CreateAutoEncryptionOptions(tlsOptions: new SslSettings());
            options1.Equals(options2).Should().BeTrue();

            options1 = CreateAutoEncryptionOptions(tlsOptions: new SslSettings());
            options2 = CreateAutoEncryptionOptions(tlsOptions: new SslSettings(), collectionNamespace: CollectionNamespace.FromFullName("d.c"));
            options1.Equals(options2).Should().BeFalse();

            options1 = CreateAutoEncryptionOptions(tlsOptions: new SslSettings(), tlsKey: "test1");
            options2 = CreateAutoEncryptionOptions(tlsOptions: new SslSettings());
            options1.Equals(options2).Should().BeFalse();

            options1 = CreateAutoEncryptionOptions(tlsOptions: new SslSettings()
            {
                EnabledSslProtocols = System.Security.Authentication.SslProtocols.None
            });
            options2 = CreateAutoEncryptionOptions(tlsOptions: new SslSettings());
            options1.Equals(options2).Should().BeFalse();

            AutoEncryptionOptions CreateAutoEncryptionOptions(SslSettings tlsOptions = null, string tlsKey = "test", CollectionNamespace collectionNamespace = null)
            {
                var autoEncryptionOptions = new AutoEncryptionOptions(
                    keyVaultNamespace: collectionNamespace ?? __keyVaultNamespace,
                    kmsProviders: GetKmsProviders());

                if (tlsOptions != null)
                {
                    autoEncryptionOptions = autoEncryptionOptions.With(tlsOptions: new Dictionary <string, SslSettings> {
                        { tlsKey, tlsOptions }
                    });
                }
                return(autoEncryptionOptions);
            }
        }
        // private methods
        private AutoEncryptionOptions ConfigureAutoEncryptionOptions(BsonDocument autoEncryptOpts)
        {
            var extraOptions = new Dictionary <string, object>();

            EncryptionTestHelper.ConfigureDefaultExtraOptions(extraOptions);

            var kmsProviders          = new ReadOnlyDictionary <string, IReadOnlyDictionary <string, object> >(new Dictionary <string, IReadOnlyDictionary <string, object> >());
            var autoEncryptionOptions = new AutoEncryptionOptions(
                keyVaultNamespace: __keyVaultCollectionNamespace,
                kmsProviders: kmsProviders,
                extraOptions: extraOptions);

            foreach (var option in autoEncryptOpts.Elements)
            {
                switch (option.Name)
                {
                case "kmsProviders":
                    kmsProviders          = ParseKmsProviders(option.Value.AsBsonDocument);
                    autoEncryptionOptions = autoEncryptionOptions.With(kmsProviders: kmsProviders);
                    var tlsSettings = EncryptionTestHelper.CreateTlsOptionsIfAllowed(kmsProviders, allowClientCertificateFunc: (kms) => kms == "kmip");
                    if (tlsSettings != null)
                    {
                        autoEncryptionOptions = autoEncryptionOptions.With(tlsOptions: tlsSettings);
                    }
                    break;

                case "schemaMap":
                    var schemaMapsDocument = option.Value.AsBsonDocument;
                    var schemaMaps         = schemaMapsDocument.Elements.ToDictionary(e => e.Name, e => e.Value.AsBsonDocument);
                    autoEncryptionOptions = autoEncryptionOptions.With(schemaMap: schemaMaps);
                    break;

                case "bypassAutoEncryption":
                    autoEncryptionOptions = autoEncryptionOptions.With(bypassAutoEncryption: option.Value.ToBoolean());
                    break;

                case "keyVaultNamespace":
                    autoEncryptionOptions = autoEncryptionOptions.With(keyVaultNamespace: CollectionNamespace.FromFullName(option.Value.AsString));
                    break;

                case "encryptedFieldsMap":
                    var encryptedFieldsMapDocument = option.Value.AsBsonDocument;
                    var encryptedFieldsMap         = encryptedFieldsMapDocument.Elements.ToDictionary(e => e.Name, e => e.Value.AsBsonDocument);
                    autoEncryptionOptions = autoEncryptionOptions.With(encryptedFieldsMap: encryptedFieldsMap);
                    break;

                default:
                    throw new Exception($"Unexpected auto encryption option {option.Name}.");
                }
            }

            return(autoEncryptionOptions);
        }
예제 #17
0
 public LoadBalancingIntergationTests()
 {
     _collectionNamespace = CollectionNamespace.FromFullName("db.coll");
 }
예제 #18
0
        public void Equals_should_work_correctly()
        {
            // collectionNamespace
            Assert(
                CreateSubject(collectionNamespace: __keyVaultNamespace),
                CreateSubject(collectionNamespace: __keyVaultNamespace),
                expectedResult: true);

            Assert(
                CreateSubject(collectionNamespace: __keyVaultNamespace),
                CreateSubject(collectionNamespace: CollectionNamespace.FromFullName("db.temp")),
                expectedResult: false);

            // extraOptions
            Assert(
                CreateSubject(extraOptions: GetDictionary <object>(("mongocryptdURI", "key"))),
                CreateSubject(extraOptions: GetDictionary <object>(("mongocryptdSpawnPath", "key"))),
                expectedResult: false);

            Assert(
                CreateSubject(extraOptions: GetDictionary <object>(("mongocryptdURI", "key"))),
                CreateSubject(extraOptions: GetDictionary <object>(("mongocryptdURI", "key1"))),
                expectedResult: false);

            Assert(
                CreateSubject(extraOptions: GetDictionary <object>(("mongocryptdSpawnArgs", "key1"))),
                CreateSubject(extraOptions: GetDictionary <object>(("mongocryptdSpawnArgs", "key1"), ("mongocryptdSpawnPath", "key12"))),
                expectedResult: false);

            Assert(
                CreateSubject(extraOptions: GetDictionary <object>(("mongocryptdSpawnArgs", "key1"), ("mongocryptdSpawnPath", "key12"))),
                CreateSubject(extraOptions: GetDictionary <object>(("mongocryptdSpawnArgs", "key1"), ("mongocryptdSpawnPath", "key12"))),
                expectedResult: true);

            // schemaMap
            Assert(
                CreateSubject(schemaMap: GetDictionary(("coll1", new BsonDocument()))),
                CreateSubject(schemaMap: GetDictionary(("coll2", new BsonDocument()))),
                expectedResult: false);

            Assert(
                CreateSubject(schemaMap: GetDictionary(("coll1", new BsonDocument()))),
                CreateSubject(schemaMap: GetDictionary(("coll1", new BsonDocument("key", "value")))),
                expectedResult: false);

            Assert(
                CreateSubject(schemaMap: GetDictionary(("coll1", new BsonDocument()))),
                CreateSubject(schemaMap: GetDictionary(("coll1", new BsonDocument()), ("coll2", new BsonDocument("key", "value")))),
                expectedResult: false);

            Assert(
                CreateSubject(schemaMap: GetDictionary(("coll1", new BsonDocument()), ("coll2", new BsonDocument("key", "value")))),
                CreateSubject(schemaMap: GetDictionary(("coll1", new BsonDocument()), ("coll2", new BsonDocument("key", "value")))),
                expectedResult: true);

            // encryptedFieldsMap
            Assert(
                CreateSubject(encryptedFieldsMap: GetDictionary(("coll1", new BsonDocument()))),
                CreateSubject(encryptedFieldsMap: GetDictionary(("coll2", new BsonDocument()))),
                expectedResult: false);

            Assert(
                CreateSubject(encryptedFieldsMap: GetDictionary(("coll1", new BsonDocument()))),
                CreateSubject(encryptedFieldsMap: GetDictionary(("coll1", new BsonDocument("key", "value")))),
                expectedResult: false);

            Assert(
                CreateSubject(encryptedFieldsMap: GetDictionary(("coll1", new BsonDocument()))),
                CreateSubject(encryptedFieldsMap: GetDictionary(("coll1", new BsonDocument()), ("coll2", new BsonDocument("key", "value")))),
                expectedResult: false);

            Assert(
                CreateSubject(encryptedFieldsMap: GetDictionary(("coll1", new BsonDocument()), ("coll2", new BsonDocument("key", "value")))),
                CreateSubject(encryptedFieldsMap: GetDictionary(("coll1", new BsonDocument()), ("coll2", new BsonDocument("key", "value")))),
                expectedResult: true);

            void Assert(AutoEncryptionOptions subject1, AutoEncryptionOptions subject2, bool expectedResult) => subject1.Equals(subject2).Should().Be(expectedResult);
        }
        public void ClientSideExplicitEncryptionAndAutoDecryptionTour()
        {
            RequireServer.Check().Supports(Feature.ClientSideEncryption);

            var localMasterKey = Convert.FromBase64String(LocalMasterKey);

            var kmsProviders = new Dictionary <string, IReadOnlyDictionary <string, object> >();
            var localKey     = new Dictionary <string, object>
            {
                { "key", localMasterKey }
            };

            kmsProviders.Add("local", localKey);

            var keyVaultNamespace     = CollectionNamespace.FromFullName("encryption.__keyVault");
            var collectionNamespace   = CollectionNamespace.FromFullName("test.coll");
            var autoEncryptionOptions = new AutoEncryptionOptions(
                keyVaultNamespace,
                kmsProviders,
                bypassAutoEncryption: true);
            var clientSettings = MongoClientSettings.FromConnectionString("mongodb://localhost");

            clientSettings.AutoEncryptionOptions = autoEncryptionOptions;
            var mongoClient = new MongoClient(clientSettings);
            var database    = mongoClient.GetDatabase(collectionNamespace.DatabaseNamespace.DatabaseName);

            database.DropCollection(collectionNamespace.CollectionName);
            var collection = database.GetCollection <BsonDocument>(collectionNamespace.CollectionName);

            var keyVaultClient   = new MongoClient("mongodb://localhost");
            var keyVaultDatabase = keyVaultClient.GetDatabase(keyVaultNamespace.DatabaseNamespace.DatabaseName);

            keyVaultDatabase.DropCollection(keyVaultNamespace.CollectionName);

            // Create the ClientEncryption instance
            var clientEncryptionSettings = new ClientEncryptionOptions(
                keyVaultClient,
                keyVaultNamespace,
                kmsProviders);

            using (var clientEncryption = new ClientEncryption(clientEncryptionSettings))
            {
                var dataKeyId = clientEncryption.CreateDataKey(
                    "local",
                    new DataKeyOptions(),
                    CancellationToken.None);

                var originalString = "123456789";
                _output.WriteLine($"Original string {originalString}.");

                // Explicitly encrypt a field
                var encryptOptions = new EncryptOptions(
                    EncryptionAlgorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic.ToString(),
                    keyId: dataKeyId);
                var encryptedFieldValue = clientEncryption.Encrypt(
                    originalString,
                    encryptOptions,
                    CancellationToken.None);
                _output.WriteLine($"Encrypted value {encryptedFieldValue}.");

                collection.InsertOne(new BsonDocument("encryptedField", encryptedFieldValue));

                // Automatically decrypts the encrypted field.
                var decryptedValue = collection.Find(FilterDefinition <BsonDocument> .Empty).First();
                _output.WriteLine($"Decrypted document {decryptedValue.ToJson()}.");
            }
        }
예제 #20
0
        public void ClientSideEncryptionAutoEncryptionSettingsTour()
        {
            RequireServer.Check().Supports(Feature.ClientSideEncryption);

            var localMasterKey = Convert.FromBase64String(LocalMasterKey);

            var kmsProviders = new Dictionary <string, IReadOnlyDictionary <string, object> >();
            var localKey     = new Dictionary <string, object>
            {
                { "key", localMasterKey }
            };

            kmsProviders.Add("local", localKey);

            var keyVaultNamespace        = CollectionNamespace.FromFullName("admin.datakeys");
            var keyVaultMongoClient      = new MongoClient();
            var clientEncryptionSettings = new ClientEncryptionOptions(
                keyVaultMongoClient,
                keyVaultNamespace,
                kmsProviders);

            var clientEncryption = new ClientEncryption(clientEncryptionSettings);
            var dataKeyId        = clientEncryption.CreateDataKey("local", new DataKeyOptions(), CancellationToken.None);
            var base64DataKeyId  = Convert.ToBase64String(GuidConverter.ToBytes(dataKeyId, GuidRepresentation.Standard));

            clientEncryption.Dispose();

            var collectionNamespace = CollectionNamespace.FromFullName("test.coll");

            var schemaMap = $@"{{
                properties: {{
                    encryptedField: {{
                        encrypt: {{
                            keyId: [{{
                                '$binary' : {{
                                    'base64' : '{base64DataKeyId}',
                                    'subType' : '04'
                                }}
                            }}],
                        bsonType: 'string',
                        algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'
                        }}
                    }}
                }},
                'bsonType': 'object'
            }}";
            var autoEncryptionSettings = new AutoEncryptionOptions(
                keyVaultNamespace,
                kmsProviders,
                schemaMap: new Dictionary <string, BsonDocument>()
            {
                { collectionNamespace.ToString(), BsonDocument.Parse(schemaMap) }
            });
            var clientSettings = new MongoClientSettings
            {
                AutoEncryptionOptions = autoEncryptionSettings
            };
            var client   = new MongoClient(clientSettings);
            var database = client.GetDatabase("test");

            database.DropCollection("coll");
            var collection = database.GetCollection <BsonDocument>("coll");

            collection.InsertOne(new BsonDocument("encryptedField", "123456789"));

            var result = collection.Find(FilterDefinition <BsonDocument> .Empty).First();

            _output.WriteLine(result.ToJson());
        }
        // public void ClientSideEncryptionAutoEncryptionSettingsTour()
        public static void Main(string[] args)
        {
            var localMasterKey = Convert.FromBase64String(LocalMasterKey);

            var kmsProviders = new Dictionary <string, IReadOnlyDictionary <string, object> >();
            var localKey     = new Dictionary <string, object>
            {
                { "key", localMasterKey }
            };

            kmsProviders.Add("local", localKey);

            var keyVaultDB        = "keyVault";
            var keystore          = "__keystore";
            var keyVaultNamespace = CollectionNamespace.FromFullName($"{keyVaultDB}.{keystore}");

            var keyVaultMongoClient      = new MongoClient();
            var clientEncryptionSettings = new ClientEncryptionOptions(
                keyVaultMongoClient,
                keyVaultNamespace,
                kmsProviders);
            var clientEncryption = new ClientEncryption(clientEncryptionSettings);

            keyVaultMongoClient.GetDatabase(keyVaultDB).DropCollection(keystore);

            var altKeyName      = new[] { "csharpDataKey01" };
            var dataKeyOptions  = new DataKeyOptions(alternateKeyNames: altKeyName);
            var dataKeyId       = clientEncryption.CreateDataKey("local", dataKeyOptions, CancellationToken.None);
            var base64DataKeyId = Convert.ToBase64String(GuidConverter.ToBytes(dataKeyId, GuidRepresentation.Standard));

            clientEncryption.Dispose();

            var collectionNamespace = CollectionNamespace.FromFullName("test.coll");

            var schemaMap = $@"{{
                properties: {{
                    SSN: {{
                        encrypt: {{
                            keyId: [{{
                                '$binary' : {{
                                    'base64' : '{base64DataKeyId}',
                                    'subType' : '04'
                                }}
                            }}],
                        bsonType: 'string',
                        algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'
                        }}
                    }}
                }},
                'bsonType': 'object'
            }}";
            var autoEncryptionSettings = new AutoEncryptionOptions(
                keyVaultNamespace,
                kmsProviders,
                schemaMap: new Dictionary <string, BsonDocument>()
            {
                { collectionNamespace.ToString(), BsonDocument.Parse(schemaMap) }
            });
            var clientSettings = new MongoClientSettings
            {
                AutoEncryptionOptions = autoEncryptionSettings
            };
            var client   = new MongoClient(clientSettings);
            var database = client.GetDatabase("test");

            database.DropCollection("coll");

            var collection = database.GetCollection <BsonDocument>("coll");

            collection.InsertOne(new BsonDocument("SSN", "123456789"));

            var result = collection.Find(FilterDefinition <BsonDocument> .Empty).First();

            Console.WriteLine(result.ToJson());
        }
예제 #22
0
        public void Equals_with_tls_should_work_correctly()
        {
            var options1 = CreateSubject();
            var options2 = CreateSubject();

            options1.Equals(options2).Should().BeTrue();

            options1 = CreateSubject(tlsOptions: new SslSettings());
            options2 = CreateSubject(tlsOptions: new SslSettings());
            options1.Equals(options2).Should().BeTrue();

            options1 = CreateSubject(tlsOptions: new SslSettings());
            options2 = CreateSubject(tlsOptions: new SslSettings(), collectionNamespace: CollectionNamespace.FromFullName("d.c"));
            options1.Equals(options2).Should().BeFalse();

            options1 = CreateSubject(tlsOptions: new SslSettings(), tlsKey: "test1");
            options2 = CreateSubject(tlsOptions: new SslSettings());
            options1.Equals(options2).Should().BeFalse();

            options1 = CreateSubject(tlsOptions: new SslSettings()
            {
                EnabledSslProtocols = System.Security.Authentication.SslProtocols.None
            });
            options2 = CreateSubject(tlsOptions: new SslSettings());
            options1.Equals(options2).Should().BeFalse();
        }
 public AutoEncryptHelper(string connectionString, CollectionNamespace keyVaultNamespace)
 {
     _connectionString        = connectionString;
     _keyVaultNamespace       = keyVaultNamespace;
     _medicalRecordsNamespace = CollectionNamespace.FromFullName("medicalRecords.patients");
 }
예제 #24
0
        public void Example1()
        {
            RequireServer.Check().ClusterTypes(ClusterType.ReplicaSet, ClusterType.Sharded).Supports(Feature.Transactions);

            var connectionString = CoreTestConfiguration.ConnectionString.ToString();

            DropCollections(
                connectionString,
                CollectionNamespace.FromFullName("mydb1.foo"),
                CollectionNamespace.FromFullName("mydb2.bar"));
            string result = null;

            // Start Transactions withTxn API Example 1
            // For a replica set, include the replica set name and a seedlist of the members in the URI string; e.g.
            // string uri = "mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017/?replicaSet=myRepl";
            // For a sharded cluster, connect to the mongos instances; e.g.
            // string uri = "mongodb://mongos0.example.com:27017,mongos1.example.com:27017/";
            var client = new MongoClient(connectionString);

            // Prereq: Create collections. CRUD operations in transactions must be on existing collections.
            var database1   = client.GetDatabase("mydb1");
            var collection1 = database1.GetCollection <BsonDocument>("foo").WithWriteConcern(WriteConcern.WMajority);

            collection1.InsertOne(new BsonDocument("abc", 0));

            var database2   = client.GetDatabase("mydb2");
            var collection2 = database2.GetCollection <BsonDocument>("bar").WithWriteConcern(WriteConcern.WMajority);

            collection2.InsertOne(new BsonDocument("xyz", 0));

            // Step 1: Start a client session.
            using (var session = client.StartSession())
            {
                // Step 2: Optional. Define options to use for the transaction.
                var transactionOptions = new TransactionOptions(
                    readPreference: ReadPreference.Primary,
                    readConcern: ReadConcern.Local,
                    writeConcern: WriteConcern.WMajority);

                // Step 3: Define the sequence of operations to perform inside the transactions
                var cancellationToken = CancellationToken.None; // normally a real token would be used
                result = session.WithTransaction(
                    (s, ct) =>
                {
                    collection1.InsertOne(s, new BsonDocument("abc", 1), cancellationToken: ct);
                    collection2.InsertOne(s, new BsonDocument("xyz", 999), cancellationToken: ct);
                    return("Inserted into collections in different databases");
                },
                    transactionOptions,
                    cancellationToken);
            }
            //End Transactions withTxn API Example 1

            result.Should().Be("Inserted into collections in different databases");

            var collection1Documents = collection1.Find(FilterDefinition <BsonDocument> .Empty).ToList();

            collection1Documents.Count.Should().Be(2);
            collection1Documents[0]["abc"].Should().Be(0);
            collection1Documents[1]["abc"].Should().Be(1);

            var collection2Documents = collection2.Find(FilterDefinition <BsonDocument> .Empty).ToList();

            collection2Documents.Count.Should().Be(2);
            collection2Documents[0]["xyz"].Should().Be(0);
            collection2Documents[1]["xyz"].Should().Be(999);
        }