exceptionfactory commented on code in PR #9998:
URL: https://github.com/apache/nifi/pull/9998#discussion_r2157429650


##########
nifi-extension-bundles/nifi-mongodb-bundle/nifi-mongodb-services/src/main/java/org/apache/nifi/mongodb/MongoDBControllerService.java:
##########
@@ -96,25 +101,52 @@ protected MongoClient createClient(ConfigurationContext 
context, MongoClient exi
         }
 
         try {
-            final String uri = 
context.getProperty(URI).evaluateAttributeExpressions().getValue();
+            String uri = 
context.getProperty(URI).evaluateAttributeExpressions().getValue();
             final String user = 
context.getProperty(DB_USER).evaluateAttributeExpressions().getValue();
             final String passw = 
context.getProperty(DB_PASSWORD).evaluateAttributeExpressions().getValue();
 
             final MongoClientSettings.Builder builder = 
MongoClientSettings.builder();
-            final ConnectionString cs = new ConnectionString(uri);
 
-            if (user != null && passw != null) {
+            if (StringUtils.containsIgnoreCase(uri, "authmechanism") && user 
!= null && passw != null) {
+                // we extract all specified parameters in the URI
+                final Map<String, String> result = new LinkedHashMap<>();
+                for (String param : uri.split("&")) {
+                    String[] pair = param.split("=", 2);
+                    String key = URLDecoder.decode(pair[0], 
StandardCharsets.UTF_8).toLowerCase();
+                    String value = pair.length > 1 ? 
URLDecoder.decode(pair[1], StandardCharsets.UTF_8) : "";
+                    result.put(key, value);
+                }
+
+                uri = uri.replaceAll("(?i)authmechanism=[^&]*&?", "");
+                final ConnectionString cs = new ConnectionString(uri);
                 final String database = cs.getDatabase() == null ? "admin" : 
cs.getDatabase();
-                final MongoCredential credential = 
MongoCredential.createCredential(user, database, passw.toCharArray());
-                builder.credential(credential);
+                final AuthenticationMechanism mechanism = 
AuthenticationMechanism.fromMechanismName(result.get("authmechanism").toUpperCase());
+
+                switch (mechanism) {
+                    case SCRAM_SHA_1 -> 
builder.credential(MongoCredential.createScramSha1Credential(user, database, 
passw.toCharArray()));
+                    case SCRAM_SHA_256 -> 
builder.credential(MongoCredential.createScramSha256Credential(user, database, 
passw.toCharArray()));
+                    case MONGODB_AWS -> 
builder.credential(MongoCredential.createAwsCredential(user, 
passw.toCharArray()));
+                    case PLAIN -> 
builder.credential(MongoCredential.createPlainCredential(user, database, 
passw.toCharArray()));
+                    default -> throw new IllegalArgumentException("Unsupported 
authentication mechanism with username and password: " + mechanism);
+                }
+
+                builder.applyConnectionString(cs);
+            } else {
+                final ConnectionString cs = new ConnectionString(uri);
+
+                if (user != null && passw != null) {
+                    final String database = cs.getDatabase() == null ? "admin" 
: cs.getDatabase();

Review Comment:
   Given the special nature of this `admin` database case, it would be best to 
put it in a single place, outside of the conditional, as opposed to using the 
same line in both conditional cases.



##########
nifi-extension-bundles/nifi-mongodb-bundle/nifi-mongodb-services/src/main/java/org/apache/nifi/mongodb/MongoDBControllerService.java:
##########
@@ -96,25 +101,52 @@ protected MongoClient createClient(ConfigurationContext 
context, MongoClient exi
         }
 
         try {
-            final String uri = 
context.getProperty(URI).evaluateAttributeExpressions().getValue();
+            String uri = 
context.getProperty(URI).evaluateAttributeExpressions().getValue();
             final String user = 
context.getProperty(DB_USER).evaluateAttributeExpressions().getValue();
             final String passw = 
context.getProperty(DB_PASSWORD).evaluateAttributeExpressions().getValue();
 
             final MongoClientSettings.Builder builder = 
MongoClientSettings.builder();
-            final ConnectionString cs = new ConnectionString(uri);
 
-            if (user != null && passw != null) {
+            if (StringUtils.containsIgnoreCase(uri, "authmechanism") && user 
!= null && passw != null) {
+                // we extract all specified parameters in the URI
+                final Map<String, String> result = new LinkedHashMap<>();
+                for (String param : uri.split("&")) {
+                    String[] pair = param.split("=", 2);
+                    String key = URLDecoder.decode(pair[0], 
StandardCharsets.UTF_8).toLowerCase();
+                    String value = pair.length > 1 ? 
URLDecoder.decode(pair[1], StandardCharsets.UTF_8) : "";
+                    result.put(key, value);
+                }
+
+                uri = uri.replaceAll("(?i)authmechanism=[^&]*&?", "");
+                final ConnectionString cs = new ConnectionString(uri);
                 final String database = cs.getDatabase() == null ? "admin" : 
cs.getDatabase();
-                final MongoCredential credential = 
MongoCredential.createCredential(user, database, passw.toCharArray());
-                builder.credential(credential);
+                final AuthenticationMechanism mechanism = 
AuthenticationMechanism.fromMechanismName(result.get("authmechanism").toUpperCase());
+
+                switch (mechanism) {
+                    case SCRAM_SHA_1 -> 
builder.credential(MongoCredential.createScramSha1Credential(user, database, 
passw.toCharArray()));
+                    case SCRAM_SHA_256 -> 
builder.credential(MongoCredential.createScramSha256Credential(user, database, 
passw.toCharArray()));
+                    case MONGODB_AWS -> 
builder.credential(MongoCredential.createAwsCredential(user, 
passw.toCharArray()));
+                    case PLAIN -> 
builder.credential(MongoCredential.createPlainCredential(user, database, 
passw.toCharArray()));
+                    default -> throw new IllegalArgumentException("Unsupported 
authentication mechanism with username and password: " + mechanism);
+                }
+
+                builder.applyConnectionString(cs);
+            } else {
+                final ConnectionString cs = new ConnectionString(uri);
+
+                if (user != null && passw != null) {
+                    final String database = cs.getDatabase() == null ? "admin" 
: cs.getDatabase();
+                    final MongoCredential credential = 
MongoCredential.createCredential(user, database, passw.toCharArray());
+                    builder.credential(credential);
+                }
+
+                builder.applyConnectionString(cs);

Review Comment:
   This call can be moved outside the conditional, using the `final` value of 
the `ConnectionString` object from either branch.



##########
nifi-extension-bundles/nifi-mongodb-bundle/nifi-mongodb-services/src/main/java/org/apache/nifi/mongodb/MongoDBControllerService.java:
##########
@@ -96,25 +101,52 @@ protected MongoClient createClient(ConfigurationContext 
context, MongoClient exi
         }
 
         try {
-            final String uri = 
context.getProperty(URI).evaluateAttributeExpressions().getValue();
+            String uri = 
context.getProperty(URI).evaluateAttributeExpressions().getValue();
             final String user = 
context.getProperty(DB_USER).evaluateAttributeExpressions().getValue();
             final String passw = 
context.getProperty(DB_PASSWORD).evaluateAttributeExpressions().getValue();
 
             final MongoClientSettings.Builder builder = 
MongoClientSettings.builder();
-            final ConnectionString cs = new ConnectionString(uri);
 
-            if (user != null && passw != null) {
+            if (StringUtils.containsIgnoreCase(uri, "authmechanism") && user 
!= null && passw != null) {
+                // we extract all specified parameters in the URI
+                final Map<String, String> result = new LinkedHashMap<>();
+                for (String param : uri.split("&")) {
+                    String[] pair = param.split("=", 2);
+                    String key = URLDecoder.decode(pair[0], 
StandardCharsets.UTF_8).toLowerCase();
+                    String value = pair.length > 1 ? 
URLDecoder.decode(pair[1], StandardCharsets.UTF_8) : "";
+                    result.put(key, value);
+                }
+
+                uri = uri.replaceAll("(?i)authmechanism=[^&]*&?", "");

Review Comment:
   Instead of parsing the entire query string into a Map, it seems like it 
would be cleaner to define the regular expression pattern that can be used to 
both remove the value from the URI and find to the value of `authMechanism`. 
This could also be used in the conditional itself, instead of the 
`containsIgnoreCase()` method.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to