-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
OIDC Add remaining environments (azure, gcp), evergreen testing, API naming updates #1371
Merged
Merged
Changes from 23 commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
240af4c
Add remaining environments (azure, gcp), evergreen testing, API namin…
katcharov b84ca99
Add remaining tests, refactor, increase GCP test machine
katcharov df3ef8d
Cleanup, update since annotations, updates to match spec API
katcharov 581ae2e
Test fixes
katcharov 00e4c15
PR fixes
katcharov 6898b4f
Remove admin credentials
katcharov 2621ae8
PR fixes
katcharov c842d22
PR fixes
katcharov 3cea409
Apply suggestions from code review
katcharov e883279
Update driver-core/src/main/com/mongodb/MongoCredential.java
katcharov bc30a2f
Update driver-core/src/main/com/mongodb/internal/authentication/Crede…
katcharov d856d84
Implement OIDC map value splitting
katcharov 479fcdd
PR fixes, doc updates
katcharov 4a844b1
PR fixes for OIDC feature branch
katcharov cc1c7ec
Update connection-string latest specifications/pull/1569
katcharov 678d7b7
PR fixes
katcharov fcb65dc
PR fixes
katcharov 71b3846
PR fixes
katcharov f6cb3da
PR Fixes
katcharov be63643
PR fixes
katcharov 0532a87
PR fixes
katcharov 761918e
PR fixes: mustDecodeNonOidcAsWhole
katcharov 7428fd1
PR fixes
katcharov fcdab29
Update driver-sync/src/test/functional/com/mongodb/internal/connectio…
katcharov 8971a79
Doc fix
katcharov File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#!/bin/bash | ||
|
||
set +x # Disable debug trace | ||
set -eu | ||
|
||
echo "Running MONGODB-OIDC authentication tests" | ||
echo "OIDC_ENV $OIDC_ENV" | ||
|
||
if [ $OIDC_ENV == "test" ]; then | ||
if [ -z "$DRIVERS_TOOLS" ]; then | ||
echo "Must specify DRIVERS_TOOLS" | ||
exit 1 | ||
fi | ||
source ${DRIVERS_TOOLS}/.evergreen/auth_oidc/secrets-export.sh | ||
# java will not need to be installed, but we need to config | ||
RELATIVE_DIR_PATH="$(dirname "${BASH_SOURCE:-$0}")" | ||
source "${RELATIVE_DIR_PATH}/javaConfig.bash" | ||
elif [ $OIDC_ENV == "azure" ]; then | ||
source ./env.sh | ||
elif [ $OIDC_ENV == "gcp" ]; then | ||
source ./secrets-export.sh | ||
else | ||
echo "Unrecognized OIDC_ENV $OIDC_ENV" | ||
exit 1 | ||
fi | ||
|
||
|
||
if ! which java ; then | ||
echo "Installing java..." | ||
sudo apt install openjdk-17-jdk -y | ||
echo "Installed java." | ||
fi | ||
|
||
which java | ||
export OIDC_TESTS_ENABLED=true | ||
|
||
./gradlew -Dorg.mongodb.test.uri="$MONGODB_URI" \ | ||
--stacktrace --debug --info --no-build-cache driver-core:cleanTest \ | ||
driver-sync:test --tests OidcAuthenticationProseTests --tests UnifiedAuthTest \ | ||
driver-reactive-streams:test --tests OidcAuthenticationAsyncProseTests \ |
stIncMale marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,6 +38,7 @@ | |
import java.net.URLDecoder; | ||
import java.nio.charset.StandardCharsets; | ||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.HashSet; | ||
|
@@ -229,17 +230,18 @@ | |
* </ul> | ||
* <p>Authentication configuration:</p> | ||
* <ul> | ||
* <li>{@code authMechanism=MONGO-CR|GSSAPI|PLAIN|MONGODB-X509}: The authentication mechanism to use if a credential was supplied. | ||
* <li>{@code authMechanism=MONGO-CR|GSSAPI|PLAIN|MONGODB-X509|MONGODB-OIDC}: The authentication mechanism to use if a credential was supplied. | ||
* The default is unspecified, in which case the client will pick the most secure mechanism available based on the sever version. For the | ||
* GSSAPI and MONGODB-X509 mechanisms, no password is accepted, only the username. | ||
* GSSAPI, MONGODB-X509, and MONGODB-OIDC mechanisms, no password is accepted, only the username. | ||
* </li> | ||
* <li>{@code authSource=string}: The source of the authentication credentials. This is typically the database that | ||
* the credentials have been created. The value defaults to the database specified in the path portion of the connection string. | ||
* If the database is specified in neither place, the default value is "admin". This option is only respected when using the MONGO-CR | ||
* mechanism (the default). | ||
* </li> | ||
* <li>{@code authMechanismProperties=PROPERTY_NAME:PROPERTY_VALUE,PROPERTY_NAME2:PROPERTY_VALUE2}: This option allows authentication | ||
* mechanism properties to be set on the connection string. | ||
* mechanism properties to be set on the connection string. Property values must be percent-encoded individually, as needed. The | ||
* entire substring following the {@code =} should not itself be encoded. | ||
* </li> | ||
* <li>{@code gssapiServiceName=string}: This option only applies to the GSSAPI mechanism and is used to alter the service name. | ||
* Deprecated, please use {@code authMechanismProperties=SERVICE_NAME:string} instead. | ||
|
@@ -916,13 +918,16 @@ private MongoCredential createCredentials(final Map<String, List<String>> option | |
|
||
if (credential != null && authMechanismProperties != null) { | ||
for (String part : authMechanismProperties.split(",")) { | ||
String[] mechanismPropertyKeyValue = part.split(":"); | ||
String[] mechanismPropertyKeyValue = part.split(":", 2); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This ignores the second |
||
if (mechanismPropertyKeyValue.length != 2) { | ||
throw new IllegalArgumentException(format("The connection string contains invalid authentication properties. " | ||
+ "'%s' is not a key value pair", part)); | ||
} | ||
String key = mechanismPropertyKeyValue[0].trim().toLowerCase(); | ||
String value = mechanismPropertyKeyValue[1].trim(); | ||
if (decodeValueOfKeyValuePair(credential.getMechanism())) { | ||
value = urldecode(value); | ||
} | ||
if (MECHANISM_KEYS_DISALLOWED_IN_CONNECTION_STRING.contains(key)) { | ||
throw new IllegalArgumentException(format("The connection string contains disallowed mechanism properties. " | ||
+ "'%s' must be set on the credential programmatically.", key)); | ||
|
@@ -938,6 +943,27 @@ private MongoCredential createCredentials(final Map<String, List<String>> option | |
return credential; | ||
} | ||
|
||
private static boolean decodeWholeOptionValue(final boolean isOidc, final String key) { | ||
// The "whole option value" is the entire string following = in an option, | ||
// including separators when the value is a list or list of key-values. | ||
// This is the original parsing behaviour, but implies that users can | ||
// encode separators (much like they might with URL parameters). This | ||
// behaviour implies that users cannot encode "key-value" values that | ||
// contain a comma, because this will (after this "whole value decoding) | ||
// be parsed as a key-value separator, rather than part of a value. | ||
return !(isOidc && key.equals("authmechanismproperties")); | ||
} | ||
|
||
private static boolean decodeValueOfKeyValuePair(@Nullable final String mechanismName) { | ||
// Only authMechanismProperties should be individually decoded, and only | ||
// when the mechanism is OIDC. These will not have been decoded. | ||
return AuthenticationMechanism.MONGODB_OIDC.getMechanismName().equals(mechanismName); | ||
} | ||
|
||
private static boolean isOidc(final List<String> options) { | ||
return options.contains("authMechanism=" + AuthenticationMechanism.MONGODB_OIDC.getMechanismName()); | ||
} | ||
|
||
private MongoCredential createMongoCredentialWithMechanism(final AuthenticationMechanism mechanism, final String userName, | ||
@Nullable final char[] password, | ||
@Nullable final String authSource, | ||
|
@@ -1018,12 +1044,14 @@ private String getLastValue(final Map<String, List<String>> optionsMap, final St | |
|
||
private Map<String, List<String>> parseOptions(final String optionsPart) { | ||
Map<String, List<String>> optionsMap = new HashMap<>(); | ||
if (optionsPart.length() == 0) { | ||
if (optionsPart.isEmpty()) { | ||
return optionsMap; | ||
} | ||
|
||
for (final String part : optionsPart.split("&|;")) { | ||
if (part.length() == 0) { | ||
List<String> options = Arrays.asList(optionsPart.split("&|;")); | ||
boolean isOidc = isOidc(options); | ||
for (final String part : options) { | ||
if (part.isEmpty()) { | ||
continue; | ||
} | ||
int idx = part.indexOf("="); | ||
|
@@ -1034,7 +1062,10 @@ private Map<String, List<String>> parseOptions(final String optionsPart) { | |
if (valueList == null) { | ||
valueList = new ArrayList<>(1); | ||
} | ||
valueList.add(urldecode(value)); | ||
if (decodeWholeOptionValue(isOidc, key)) { | ||
value = urldecode(value); | ||
stIncMale marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
valueList.add(value); | ||
optionsMap.put(key, valueList); | ||
} else { | ||
throw new IllegalArgumentException(format("The connection string contains an invalid option '%s'. " | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
We explicitly test on Windows and MacOS in PyMongo, but I'd consider that optional.
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.
All of our tests use linux/ubuntu as the
os
, so I took those out.