Connecting to access controlled MongoDB replicaSet from Python Eve - mongodb

I have an Eve application that I want to connect to a mongodb replicaset. I was able to do thisby setting the MONGO_URI parameter in settings.py to mongodb://host/dbName?replicaSet=replicaSetname
however, now that I have enabled access control on the replica set, I can't seem to pass the user credentials in.
I am using a uri of the form:
mongodb://user:password#host/dbName?replicaSet=replicaSetName&authSource=admin
Most infuriatingly of all, when I serve this URI directly to the database, it connects and logs in without issue. But if I try to access something through eve I get the following error:
pymongo.errors.OperationFailure: Authentication failed.
I have tried several variations, including settings the MONGO_USERNAME and MONGO_PASSWORD parameters in eve. The only possible issue I can think of is that the user I created for eve has limited permissions (readWrite on one database).

After much effort I managed to figure out how to do it on eve, it involved a few settings that were not mentioned in the eve documentation:
MONGO_HOST = 'mypod-1.mongo,mypod-2.mongo,mypod-3.mongo;
MONGO_USERNAME = 'user'
MONGO_PASSWORD = 'pass'
MONGO_DBNAME = 'mydb'
MONGO_AUTH_SOURCE = 'admin'
MONGO_REPLICA_SET = 'mySet'
And also, because this tripped me up, don't have MONGO_URI set to anything in your settings, not even None, as eve will attempt to use the URI over any other setting if it finds that variable declared.

Related

How do I get the full uri including username and password with the mongodbatlas provider in terraform

When I try to output the mongodb uri with Terraform and the mongodb atlas provider, I can't get the full uri with username and password. For example, when I do something like:
terraform {
required_version = "~> 0.14.7"
required_providers {
mongodbatlas = {
source = "mongodb/mongodbatlas"
version = "0.8.2"
}
}
}
provider "mongodbatlas" {
public_key = var.mongodbatlas_public_key
private_key = var.mongodbatlas_private_key
}
data "mongodbatlas_cluster" "db" {
project_id = var.mongodbatlas_project_id
name = format("some-db-name-%s", var.env)
}
output "db_url" {
value = data.mongodbatlas_cluster.db.connection_strings[0].address_srv
}
I always get a uri of the form: mongodb+srv://some-db-name-staging.xjcol.mongodb.net
Adding that as an environment variable to my web app in order to connect to db does not work as it needs to authenticate with a username and password. Manually adding the username and password to that string as in mongodb+srv://[username]:[password]#some-db-name-staging.xjcol.mongodb.net works and the app can connect to the db fine.
While I get what you're trying to achieve, I suspect you're mixing things here. Let me explain:
MongoDB allows you to create database users that are able to authenticate using password. Those can be created using mongodbatlas_database_user resource.
You can create your cluster (or source cluster information) using both the resource or data source the way you're trying to achieve it.
However, cluster creation is independent of database and database user creation, meaning that what you're getting from Terraform is just a generic connection string from Mongo where not even Mongo knows which user/database you want to connect to.
I suggest you to compose your own connection string and pass it along to your application using a post-provisioning script, either using your Terraform outputs of cluster and database user, or simply composing it by yourself if you already know the info upfront.
In case you're using AWS, MongoDB Atlas supports connection strings using IAM Users and IAM Roles. This is a much better, safer approach than dealing with passwords and all the extra burden managing passwords implies. If this sounds like something you'd like to explore, do let me know.
My solution was to use the string replace function with mongodbatlas_database_user resource:
replace(mongodbatlas_advanced_cluster.mongodb_cluster.connection_strings[0].standard_srv, "mongodb+srv://", "mongodb+srv://${mongodbatlas_database_user.userspace_db_user.username}:${coalesce(nonsensitive(mongodbatlas_database_user.userspace_db_user.password), "null")}#")

Firebird connection string not working post Firebird 3 migration

I have a regression with a TCP\IP connection string post a firebird 3 migration from v2.5. The FirebirdClient version is 4.6.1 but I've tested with the latest stable version and it also doesn't work (v7.10.1).
The error message is "Your user name and password are not defined. Ask your database administrator to set up a Firebird login".
The stacktrace:
at FirebirdSql.Data.FirebirdClient.FbConnectionInternal.Connect()
at FirebirdSql.Data.FirebirdClient.FbConnectionPoolManager.Pool.GetConnection(FbConnection owner)
at FirebirdSql.Data.FirebirdClient.FbConnectionPoolManager.Get(ConnectionString connectionString, FbConnection owner)
at FirebirdSql.Data.FirebirdClient.FbConnection.Open()
The user was created via the IBExpert UI.
Here's how the connection string looks (not real life connection data obviously):
#"Database=inet://10.000.0.000:3050/C:\Database.FDB;User=MY_USER;Password=secret";
The same user works if using a standard same network connection string as below:
#dialect=3;initial catalog=C:\Database.FDB;data source=localhost;user id=MY_USER;password=secret;character set=ISO8859_1;pooling=True;connection lifetime=30;server type=Default;port number=3050
My firebird.conf is set like so:
ServerMode = Super
DefaultDbCachePages = 100K
FileSystemCacheThreshold = 100M
TempBlockSize = 2M
TempCacheLimit = 4000M
AuthServer = Legacy_Auth, Srp, Win_Sspi
AuthClient = Legacy_Auth, Srp, Win_Sspi
UserManager = Legacy_UserManager, Srp
WireCrypt = Enabled
RemoteServicePort = 3050
LockMemSize = 30M
LockHashSlots = 30011
RemoteAccess = true
Not sure what I'm missing here. The connection string above works with SYSDBA. According to the firebird documentation I've read it looks fine. I've read all other stackoverflow tickets with the same issue but don't see any answers that work for me. Any ideas?
Recent versions of FirebirdSql.Data.FirebirdClient support the version 13-15 wire protocol of Firebird 3, and then only support Srp authentication. Your old version supported only up to the v12 protocol (Firebird 2.5) and then would use the legacy authentication. If you created the user using the Legacy_UserManager (the default in your configuration), then you cannot authenticate with version 7.10.1 (where you could with 4.6.1), because as far as the Srp authentication plugin is concerned, the user does not exist.
It looks like you created the user either using gsec, which always applies the default user manager (FYI, gsec is deprecated since Firebird 3), or you used CREATE USER without USING PLUGIN Srp (or with USING PLUGIN Legacy_UserManager). You can verify this by checking the output of select sec$user_name, sec$plugin from sec$users. The solution would be to drop the user and then create it again with the right user manager (USING PLUGIN Srp).
Note that in theory you could have the user both for Srp and Legacy_UserManager (e.g. if the same user needs to be used by an application that cannot authenticate with Srp), but it is far more secure to have the user only exist for one plugin.
On a related note, the configuration you have applied is insecure. It is far more secure to leave out Legacy_Auth of the AuthServer setting or - if you still have applications that cannot apply Srp - to put it last (for both AuthServer and AuthClient). Similarly, it is recommended to put Legacy_UserManager last in UserManager (or leave it out entirely), so by default - if you use gsec, or don't include USING PLUGIN xxx in CREATE USER - it will create more secure Srp-type users.

Netlify returning 404 when connecting to Atlas MongoDB

I'm trying to make a Netlify app that posts data to an Atlas MongoDB, and while I can post to the DB when I run my page from localhost, Netlify is returning a 404 whenever I attempt to post data to the DB. I know it is not an issue with Atlas's whitelisted IP addresses because I have whitelisted all IP addresses for the time being. I suspect that this has something to do with Netlify not properly reading or running the env.process that I'm using to store my Atlas information, although I am not completely certain that is the cause. When I run it locally, I have my config set up to simply use the Atlas information directly rather than relying on a .env file. I'm using mongoose to connect to the DB, and the connection portion of my code is the following in my production build:
mongoose.connect(process.env.MONGODB_URI || "mongodb://localhost/dbname");
This has not been working, but on the working copy that I run from localhost, I use:
const uri = `mongodb://atlasDB:<PASSWORDHERE>#atlasDB-shard-00-00-ot2tv.mongodb.net:27017,atlasDB-shard-00-01-ot2tv.mongodb.net:27017,atlasDB-shard-00-02-ot2tv.mongodb.net:27017/test?ssl=true&replicaSet=atlasDB-shard-0&authSource=admin&retryWrites=true`;
mongoose.connect(uri);
I have configured Netlify to have a MONGODB_URI build environmental variable of mongodb://atlasDB:<PASSWORDHERE>#atlasDB-shard-00-00-ot2tv.mongodb.net:27017,atlasDB-shard-00-01-ot2tv.mongodb.net:27017,atlasDB-shard-00-02-ot2tv.mongodb.net:27017/test?ssl=true&replicaSet=atlasDB-shard-0&authSource=admin&retryWrites=true
I have replaced PASSWORDHERE with the actual password in both instances, but the Netlify build environmental variable does not feature string quotations around the value when viewed in the entry field on the Netlify website. I tried putting them in, but it seemed to make no difference, but I may have simply not waiting long enough for the change to take effect.
Aside from Mongoose, I am not running any other dependencies that should have any effect on this problem. The project deadline is in a couple days, so any help with this would be greatly appreciated.

Authentication DB setting not working using mongoDB URI configuration

I am triyng to connect pyeve with a MongoDB Atlas replica set (https://cloud.mongodb.com/). I've connected successfully DB management tools from the same host, to make sure the deployment is working OK.
One particularity is that using Atlas, all users must authenticate against auth database, I cannot put my users in the application database, so I need to set authSource in MONGO_URI.
Now, when defining the MONGO_URI for the replica set, in settings.py, like this:
MONGO_URI = mongodb://<USER>:<PASS>#my-shard-00-00-tlati.mongodb.net:27017,my-shard-00-01-tlati.mongodb.net:27017,my-shard-00-02-tlati.mongodb.net:27017/<MY_DB>?ssl=true&replicaSet=my-shard-0&authSource=admin
The authSource=admin parameter seems to be ignored, (I've checked debugging pymongo's auth and the authentication source used is None).
MONGO_AUTH_SOURCE could be used to set the authorization database, but it has no effect since MONGO_URI is used in preference of the other configuration variables, according to eve's documentation.
Is this an issue or am I doing it wrong?
Found out that the problem was that I was using version 0.4.1 for flask-pymongo. Updating it to version 0.5.1 fixed the problem.

How to format the connection string for a MongoDB replica set in Sitecore?

I have configured MongoDB for Sitecore using a replica set.
I set up keyfile access control and added a user.
But I'm facing problems while creating connection strings.
Lets assume my replica set name is rsHelloWorld with several mongod instances: localhost:21017,localhost:21018,localhost:21019,localhost:21020,localhost:21021(arbitor)
username: mongo_admin
password: test#123
The default connection string in Sitecore is:
<add name="analytics" connectionString="mongodb://localhost/analytics" />
How to specify the connection string for my MongoDB database with a replica set and authentication?
Sitecore xDB uses the standard MongoDB connection string format.
In the provided example, the connection string will be this:
mongodb://mongo_admin:test%40123#localhost:21017,localhost:21018,localhost:21019,localhost:21020,localhost:21021/?replicaSet=rsHelloWorld
Note that I have replaced the # symbol in your password with %40. This is because # in a connection string is the separator between credentials and host names. See more here.
Also, keep in mind that you don't have to specify all of your servers in the connection string. You need to specify at least one, and upon connecting to it, xDB will receive full information about the replica set, including the addresses of all data-bearing nodes. Nevertheless, it is a best practice to include several servers in order to ensure that if one of them goes down, the application will still find a server to connect to. In your case, including the arbiter doesn't make much sense since xDB (or any other MongoDB client) will never have to communicate with it.