-
Notifications
You must be signed in to change notification settings - Fork 104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix persistence error mongo authentication #1851
fix persistence error mongo authentication #1851
Conversation
Thank you for your contribution! Some comments:
|
* @param mongoAuthSource | ||
* @param dataModel | ||
*/ | ||
public MongoBackendImpl(String mongoHosts, String mongoUsername, String mongoPassword, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no need to overload the costructor in this case, since mongoAuthSource has a not null validation on getDatabase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From my point of view it is better to have this new constructor to avoid side effect and maintain the backward compatibility. There is no problem to have 2 constructors in OOP and it is common to do it allowing to initialize and/or construct objects with different parameters depending of the use cases and future needs and maintaining the interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, but the constructor is actually only used in NGSIMongoBaseSink and in tests, so there is no need to have both.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @IvanHdzC . The constructor is only used in one point of the code, so lest's adapt constructor and calling code better than adding a second constructor. In addition, the lesser constructor we have, the easier it would be to have good code coverage in tests.
mongoHosts = context.getString("mongo_hosts", "localhost:27017"); | ||
LOGGER.debug("[" + this.getName() + "] Reading configuration (mongo_hosts=" + mongoHosts + ")"); | ||
mongoUsername = context.getString("mongo_username", ""); | ||
LOGGER.debug("[" + this.getName() + "] Reading configuration (mongo_username=" + mongoUsername + ")"); | ||
// FIXME: mongoPassword should be read as a SHA1 and decoded here | ||
mongoPassword = context.getString("mongo_password", ""); | ||
LOGGER.debug("[" + this.getName() + "] Reading configuration (mongo_password=" + mongoPassword + ")"); | ||
|
||
mongoAuthSource = context.getString("mongo_auth_source", ""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thing it's more usuall that the default authSource is "admin". It would be better if the default value of mongo_auth_source is "admin".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO authSource is necessary to be configured and not fixed as default constant value to admin for security reason. Admin is a sensible and critical database with rights and high privileges. Giving the possibility to configure the authentication database will allow to provide other specific databases with some restrictions and with just the necesary privileges with a set of user depending of the uses and applications needed and it is more secure tha using only the admin database.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, I misunderstood the "defaultauthdb" value, it actually is the db where the connection is created.
NTC
if ((mongoAuthSource != null) && !mongoAuthSource.isEmpty()) { | ||
authSource = mongoAuthSource; | ||
} else { | ||
authSource = dbName; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if the dbName is the right authSource in case it is not specified.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before this modification dbName was the value used in the previous version. If authSource is not configured then the behavior of the code is the same as before maintaining the backward compatibility. From my point of view it is better to keep the code as it is and not setting authSource as a constant to "admin".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I misunderstood the "defaultauthdb" value, it actually is the db where the connection is created.
NTC
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, dbName is one thing and authSource is another. The parameter dbName is the name of the database to create and based on "Fiware-Service" where the collections will be stored. And authSource is used to specify a user DB where the credentials are defined, as documented by Mongo and for the credentials objects. These are 2 different things.
dbName is used in client.getDatabase(dbName) (class MongoClient) and authSource is used by credential object (MongoCredential) if only there is a need of authentication.
Missing tests for this PR. |
/** | ||
* Gets the mongo auth_source | ||
* @return | ||
*/ | ||
public String getAuthSource() { | ||
return mongoAuthSource; | ||
} // getAuthSource | ||
|
||
/** | ||
* Set the mongo auth_source | ||
* @param authSource DB used for mongo authentication | ||
*/ | ||
public void setAuthSource(String authSource) { | ||
if (authSource != null) { | ||
this.mongoAuthSource = authSource; | ||
} else { | ||
this.mongoAuthSource = ""; | ||
} | ||
} // setAuthSource | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this ever used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, if somebody or other piece of code (allowing other new sink in the future to use mongo as a DB with authentication), and want to use the first constructor without authSource in parameter, it will have the opportunity to set the authSource after to build the backend object using the setAuthSource(...) operation when needed and in some place in the code. It is typical and best practices to do it in OOP (overload constructors and get/set operations), and give more possibilities.
Notice that in this case mongoAuthSource shoud not be annotated as "final" in the declaration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get/setAuthSource(...) could be used, if somebody build the object without authSource parameter and if after they want to initialize this parameter.
This is what I tested successfully and put in comment as documentation (see start() operation), and use of the new constructor.
BTW, What does it mean "NTC" and "LGTM"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NTC = Nothing to change
LGTM = Looks good to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More on "the NTC and LGTM protocol" review protocol here: https://github.com/telefonicaid/fiware-orion/blob/master/doc/manuals/contribution_guidelines.md#pull-request-protocol
Yes I will update the documentation in this cygnus repository (but do not know to do it in readthedocs.org). And yes there is new configuration parameters: In MongoSink:
And probably In STHSink:
This PR covers the mongo sink authentication issues. Yes, I will update CHANGES_NEXT_RELEASE |
In order to be aligned to your thoughts concerning the backend constructor I will review the code removing the old backend constructor and removing get/setAuthSource. But impact on the tests, i.e. need to modify "MongoBackendImplTest.java" |
…ameter to built Mongo backend
…auth_source parameter
Please could you check the PR with the new commit related to the code, documentation, docker, agent conf,... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@@ -332,6 +332,7 @@ A configuration example could be: | |||
cygnus-ngsi.sinks.mongo-sink.mongo_hosts = 192.168.80.34:27017 | |||
cygnus-ngsi.sinks.mongo-sink.mongo_username = myuser | |||
cygnus-ngsi.sinks.mongo-sink.mongo_password = mypassword | |||
cygnus-ngsi.sinks.mongo-sink.mongo_auth_source = admin | |||
cygnus-ngsi.sinks.mongo-sink.db_prefix = cygnus_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new parameter mongo_auth_source should be also added to the configuration table included in this file .md file.
@@ -330,6 +330,7 @@ A configuration example could be: | |||
cygnus-ngsi.sinks.sth-sink.mongo_hosts = 192.168.80.34:27017 | |||
cygnus-ngsi.sinks.sth-sink.mongo_username = myuser | |||
cygnus-ngsi.sinks.sth-sink.mongo_password = mypassword | |||
cygnus-ngsi.sinks.sth-sink.mongo_auth_source = admin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new parameter mongo_auth_source should be also added to the configuration table included in this file .md file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new parameter mongo_auth_source have been added to the configuration table for both sinks.
The PR looks good after the modification :) I provided some extra comments (in CHANGEX_NEXT_RELEASE and documentation files). Once they get addressed I think the PR could be merged. With regards to readthedocs.org don't worry about it. RTD is generated automatically from .md files, once the PR is merged. |
Please could you check if now this PR is OK to be merged. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
I think the PR is mostly fine. However, I'm still seeing two suggesiton in the CHANGES_NEXT_RELEASE that hasn't been addressed. Please confirm them (buttom "Commit suggestion") or explain why do you think are not valid, please. |
Co-Authored-By: Fermín Galán Márquez <[email protected]>
I confirmed the commit suggestion. Please check the PR to proceed with the merge. |
Co-Authored-By: Fermín Galán Márquez <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks!
Please check this PR that solve the issue #1849 ([cygnus][bug] Persistence Error Mongo Authentication and side effect #1849)
I made exhaustive tests and it work fine with various configuration and various users created by different way and with several data source (iotagents) send to the Orion Context Broker.
Now the databases (based on "Fiware-Service") and corresponding collections (based on "Fiware-ServicePath") are created automatically on the fly without manual action on mongodb when cygnus receive the data by notification (i.e. by subscription).
With this modification using auth_source option for mongo authentication, there is no side effect when more than one data source is received with different "Fiware-Service" and different "Fiware-ServicePath" at the same time or concurrently.
The "agent_1.conf" must add the following entry as example:
The new entry in the agent configuration file for mongo sink is:
If this new entry is not specified in the agent configuration file and authentication with the credentials is enabled, then the cygnus will work the same as before with the side effect as described in the issue (because it will use the corresponding dbName as before). I mean if we want to access mongodb with authentication mechanism auth_source must be specified and all will work fine.
Usually mongo_auth_source could be "admin" but could be another database where the user created must have the correct rights and correct privileges to access read/write the other DB based on the "Fiware-Service" value (i.e. DB name starting with "sth_").
The pertinent user should be created in the auth source DB:
For example:
use admin
Or to adding more restrictions on the DB, if you know in advance the name of the database based on the "Fiware-Service" value:
Notice that just after creating the user in the DB auth source, it is recommended to restart the mongo database, just in case, to apply the changes correctly (by using "sudo service mongod restart").
The only file modifies are: