mongodb-labs / mongo-rust-driver-prototype

This is superseded by the official MongoDB Rust Driver
https://github.com/mongodb/mongo-rust-driver
Apache License 2.0
379 stars 72 forks source link

Some connection URIs are not supported #291

Closed cubetastic33 closed 5 years ago

cubetastic33 commented 5 years ago

Connection URIs to MongoDB Atlas that start with mongodb+srv:// don't work, and even with mongodb://, supplying connection options there in the URI doesn't to work. My connection URI looks like this: mongodb://<USERNAME>:<PASSWORD>@<SECONDARY SERVER>,<PRIMARY SERVER>,<SECONDARY SERVER>/test?ssl=true&replicaSet=<SOME STUFF>&authSource=admin&retryWrites=true. This doesn't work, and I was told that I'm supposed to specify the connection options using ClientOptions, but I don't know how.

saghm commented 5 years ago

Hello! You're correct that there is currently a lot missing from the connection string implementation right now. Additionally, retryable writes are not implemented in the driver, so there isn't any way to specific that.

For authentication, currently the only way to authentication is through lazy authentication, namely the Database::auth method. SSL can be used by creating the options with ClientOptions::with_ssl (which currently doesn't show up in the API docs for some reason, as described in https://github.com/mongodb-labs/mongo-rust-driver-prototype/issues/227). It was pointed out to me recently that all of the official drivers allow users to connect without specifying a CA and instead fall back to the system CA. This is definitely something we need to implement so that users can connect to Atlas.

cubetastic33 commented 5 years ago

Okay, but what is the ca_file? Where do I get that? Why do I need that?

cubetastic33 commented 5 years ago

Also, what connection string should I use if it shouldn't have the username and password? Both the connection URIs provided in the Atlas interface have usernames and passwords in them...

saghm commented 5 years ago

Apologies if I was unclear about the CA file; the Rust driver currently requires one, but Atlas expects the driver to just use the system CA. I've opened this pull request to fix that bug in the API, and I'll follow-up here when it lands.

As for the authentication info, I believe that (once the aforementioned PR is merged), it should work if you remove the <username>@<password> substring from the (non-srv) URI and then manually pass them in as arguments to Database::auth (as described above) before doing anything with the client.

cubetastic33 commented 5 years ago

So, atm, what's the workaround to these issues? Also, what is the verify_peer?

cubetastic33 commented 5 years ago

I tried using a CA file and authenticating later - here is my code, but it still doesn't work (same error)

saghm commented 5 years ago

The CA file should be the path to the CA file, not the contents of it.

cubetastic33 commented 5 years ago

@saghm I still get the same error... thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: OperationError("No servers available for the provided ReadPreference.")'

saghm commented 5 years ago

I just published version 0.3.12, which has support for using the system CA instead of specifying your own. Can you try that out and see if it works?

cubetastic33 commented 5 years ago

In this code, if I just change the options line to let options = ClientOptions::with_unauthenticated_ssl(None, false);, then I get this error:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: OperationError("Authentication failed.")', libcore/result.rs:1009:5

And if I replace it with let options = ClientOptions::with_unauthenticated_ssl(None, true);, I get this error:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: OperationError("No servers available for the provided ReadPreference.")', libcore/result.rs:1009:5

What exactly is verify_peer?

cubetastic33 commented 5 years ago

@saghm Also, what all does the new version fix? Does it allow authentication from the connection URI?

cubetastic33 commented 5 years ago

Yaaaaay! I managed to get it working now, but I had to authenticate on client.db("auth"), not client.db("<my database name>"). I got the idea when connecting using MongoDB Compass Community... Thanks a lot for your help!

saghm commented 5 years ago

Awesome! For future reference, "\" is just supposed to be the name of the database the user is stored in.

tony-cox commented 5 years ago

Without this discussion, I doubt I would have worked out how to connect to Atlas. I've added the following summary. Is there any way we can either get this up on the docs for the crate or better yet have Atlas themselves give a connection string and example for Rust? I gather the latter is unlikely while this is an unsupported driver, but it would be nice. At the very least, updating the title of the issue to include 'Atlas' would be greatly helpful for finding it in a web search, as there are a number of other solutions out there that aren't as good as this (including one that suggests using a completely different crate as the driver).