Merge branch 'master' of github.com:mongodb/mongo-python-driver
This commit is contained in:
commit
ce9dc9f0d7
@ -1940,7 +1940,7 @@ tasks:
|
||||
git commit -m "add files"
|
||||
export AZUREOIDC_DRIVERS_TAR_FILE=/tmp/mongo-python-driver.tgz
|
||||
git archive -o $AZUREOIDC_DRIVERS_TAR_FILE HEAD
|
||||
export AZUREOIDC_TEST_CMD="source ./env.sh && export OIDC_PROVIDER_NAME=azure && ./.evergreen/run-mongodb-oidc-test.sh"
|
||||
export AZUREOIDC_TEST_CMD="source ./env.sh && export OIDC_ENV=azure && ./.evergreen/run-mongodb-oidc-test.sh"
|
||||
bash $DRIVERS_TOOLS/.evergreen/auth_oidc/azure/run-driver-test.sh
|
||||
|
||||
- name: "test-fips-standalone"
|
||||
|
||||
@ -5,9 +5,9 @@ set -o errexit # Exit the script with error if any of the commands fail
|
||||
|
||||
echo "Running MONGODB-OIDC authentication tests"
|
||||
|
||||
OIDC_PROVIDER_NAME=${OIDC_PROVIDER_NAME:-"aws"}
|
||||
OIDC_ENV=${OIDC_ENV:-"test"}
|
||||
|
||||
if [ $OIDC_PROVIDER_NAME == "aws" ]; then
|
||||
if [ $OIDC_ENV == "test" ]; then
|
||||
# Make sure DRIVERS_TOOLS is set.
|
||||
if [ -z "$DRIVERS_TOOLS" ]; then
|
||||
echo "Must specify DRIVERS_TOOLS"
|
||||
@ -39,13 +39,15 @@ if [ $OIDC_PROVIDER_NAME == "aws" ]; then
|
||||
export MONGODB_URI_MULTI="$OIDC_ATLAS_URI_MULTI/?authMechanism=MONGODB-OIDC"
|
||||
set -x
|
||||
fi
|
||||
export AWS_WEB_IDENTITY_TOKEN_FILE="$OIDC_TOKEN_DIR/test_user1"
|
||||
export OIDC_ADMIN_USER=$OIDC_ALTAS_USER
|
||||
export OIDC_TOKEN_FILE="$OIDC_TOKEN_DIR/test_user1"
|
||||
set +x # turn off xtrace for this portion
|
||||
export OIDC_ADMIN_USER=$OIDC_ATLAS_USER
|
||||
export OIDC_ADMIN_PWD=$OIDC_ATLAS_PASSWORD
|
||||
set -x
|
||||
|
||||
elif [ $OIDC_PROVIDER_NAME == "azure" ]; then
|
||||
if [ -z "${AZUREOIDC_AUDIENCE:-}" ]; then
|
||||
echo "Must specify an AZUREOIDC_AUDIENCE"
|
||||
elif [ $OIDC_ENV == "azure" ]; then
|
||||
if [ -z "${AZUREOIDC_RESOURCE:-}" ]; then
|
||||
echo "Must specify an AZUREOIDC_RESOURCE"
|
||||
exit 1
|
||||
fi
|
||||
set +x # turn off xtrace for this portion
|
||||
@ -54,11 +56,11 @@ elif [ $OIDC_PROVIDER_NAME == "azure" ]; then
|
||||
set -x
|
||||
export MONGODB_URI=${MONGODB_URI:-"mongodb://localhost"}
|
||||
MONGODB_URI_SINGLE="${MONGODB_URI}/?authMechanism=MONGODB-OIDC"
|
||||
MONGODB_URI_SINGLE="${MONGODB_URI_SINGLE}&authMechanismProperties=PROVIDER_NAME:azure"
|
||||
export MONGODB_URI_SINGLE="${MONGODB_URI_SINGLE},TOKEN_AUDIENCE:${AZUREOIDC_AUDIENCE}"
|
||||
MONGODB_URI_SINGLE="${MONGODB_URI_SINGLE}&authMechanismProperties=ENVIRONMENT:azure"
|
||||
export MONGODB_URI_SINGLE="${MONGODB_URI_SINGLE},TOKEN_RESOURCE:${AZUREOIDC_RESOURCE}"
|
||||
export MONGODB_URI_MULTI=$MONGODB_URI_SINGLE
|
||||
else
|
||||
echo "Unrecognized OIDC_PROVIDER_NAME $OIDC_PROVIDER_NAME"
|
||||
echo "Unrecognized OIDC_ENV $OIDC_ENV"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@ -2293,6 +2293,7 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer,
|
||||
uint32_t c_w_s_size;
|
||||
uint32_t code_size;
|
||||
uint32_t scope_size;
|
||||
uint32_t len;
|
||||
PyObject* code;
|
||||
PyObject* scope;
|
||||
|
||||
@ -2311,7 +2312,8 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer,
|
||||
memcpy(&code_size, buffer + *position, 4);
|
||||
code_size = BSON_UINT32_FROM_LE(code_size);
|
||||
/* code_w_scope length + code length + code + scope length */
|
||||
if (!code_size || max < code_size || max < 4 + 4 + code_size + 4) {
|
||||
len = 4 + 4 + code_size + 4;
|
||||
if (!code_size || max < code_size || max < len || len < code_size) {
|
||||
goto invalid;
|
||||
}
|
||||
*position += 4;
|
||||
@ -2329,12 +2331,9 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer,
|
||||
|
||||
memcpy(&scope_size, buffer + *position, 4);
|
||||
scope_size = BSON_UINT32_FROM_LE(scope_size);
|
||||
if (scope_size < BSON_MIN_SIZE) {
|
||||
Py_DECREF(code);
|
||||
goto invalid;
|
||||
}
|
||||
/* code length + code + scope length + scope */
|
||||
if ((4 + code_size + 4 + scope_size) != c_w_s_size) {
|
||||
len = 4 + 4 + code_size + scope_size;
|
||||
if (scope_size < BSON_MIN_SIZE || len != c_w_s_size || len < scope_size) {
|
||||
Py_DECREF(code);
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
@ -40,9 +40,9 @@ from pymongo.auth_aws import _authenticate_aws
|
||||
from pymongo.auth_oidc import (
|
||||
_authenticate_oidc,
|
||||
_get_authenticator,
|
||||
_OIDCAWSCallback,
|
||||
_OIDCAzureCallback,
|
||||
_OIDCProperties,
|
||||
_OIDCTestCallback,
|
||||
)
|
||||
from pymongo.errors import ConfigurationError, OperationFailure
|
||||
from pymongo.saslprep import saslprep
|
||||
@ -170,8 +170,8 @@ def _build_credentials_tuple(
|
||||
properties = extra.get("authmechanismproperties", {})
|
||||
callback = properties.get("OIDC_CALLBACK")
|
||||
human_callback = properties.get("OIDC_HUMAN_CALLBACK")
|
||||
provider_name = properties.get("PROVIDER_NAME")
|
||||
token_audience = properties.get("TOKEN_AUDIENCE", "")
|
||||
environ = properties.get("ENVIRONMENT")
|
||||
token_resource = properties.get("TOKEN_RESOURCE", "")
|
||||
default_allowed = [
|
||||
"*.mongodb.net",
|
||||
"*.mongodb-dev.net",
|
||||
@ -182,41 +182,42 @@ def _build_credentials_tuple(
|
||||
"::1",
|
||||
]
|
||||
allowed_hosts = properties.get("ALLOWED_HOSTS", default_allowed)
|
||||
msg = "authentication with MONGODB-OIDC requires providing either a callback or a provider_name"
|
||||
msg = (
|
||||
"authentication with MONGODB-OIDC requires providing either a callback or a environment"
|
||||
)
|
||||
if passwd is not None:
|
||||
msg = "password is not supported by MONGODB-OIDC"
|
||||
raise ConfigurationError(msg)
|
||||
if callback or human_callback:
|
||||
if provider_name is not None:
|
||||
if environ is not None:
|
||||
raise ConfigurationError(msg)
|
||||
if callback and human_callback:
|
||||
msg = "cannot set both OIDC_CALLBACK and OIDC_HUMAN_CALLBACK"
|
||||
raise ConfigurationError(msg)
|
||||
elif provider_name is not None:
|
||||
if provider_name == "aws":
|
||||
elif environ is not None:
|
||||
if environ == "test":
|
||||
if user is not None:
|
||||
msg = "AWS provider for MONGODB-OIDC does not support username"
|
||||
msg = "test environment for MONGODB-OIDC does not support username"
|
||||
raise ConfigurationError(msg)
|
||||
callback = _OIDCAWSCallback()
|
||||
elif provider_name == "azure":
|
||||
callback = _OIDCTestCallback()
|
||||
elif environ == "azure":
|
||||
passwd = None
|
||||
if not token_audience:
|
||||
if not token_resource:
|
||||
raise ConfigurationError(
|
||||
"Azure provider for MONGODB-OIDC requires a TOKEN_AUDIENCE auth mechanism property"
|
||||
"Azure environment for MONGODB-OIDC requires a TOKEN_RESOURCE auth mechanism property"
|
||||
)
|
||||
callback = _OIDCAzureCallback(token_audience, user)
|
||||
callback = _OIDCAzureCallback(token_resource)
|
||||
else:
|
||||
raise ConfigurationError(
|
||||
f"unrecognized provider_name for MONGODB-OIDC: {provider_name}"
|
||||
)
|
||||
raise ConfigurationError(f"unrecognized ENVIRONMENT for MONGODB-OIDC: {environ}")
|
||||
else:
|
||||
raise ConfigurationError(msg)
|
||||
|
||||
oidc_props = _OIDCProperties(
|
||||
callback=callback,
|
||||
human_callback=human_callback,
|
||||
provider_name=provider_name,
|
||||
environment=environ,
|
||||
allowed_hosts=allowed_hosts,
|
||||
username=user,
|
||||
)
|
||||
return MongoCredential(mech, "$external", user, passwd, oidc_props, _Cache())
|
||||
|
||||
|
||||
@ -44,6 +44,14 @@ def _authenticate_aws(credentials: MongoCredential, conn: Connection) -> None:
|
||||
"install with: python -m pip install 'pymongo[aws]'"
|
||||
)
|
||||
|
||||
# Delayed import.
|
||||
from pymongo_auth_aws.auth import ( # type:ignore[import]
|
||||
set_cached_credentials,
|
||||
set_use_cached_credentials,
|
||||
)
|
||||
|
||||
set_use_cached_credentials(True)
|
||||
|
||||
if conn.max_wire_version < 9:
|
||||
raise ConfigurationError("MONGODB-AWS authentication requires MongoDB version 4.4 or later")
|
||||
|
||||
@ -87,12 +95,12 @@ def _authenticate_aws(credentials: MongoCredential, conn: Connection) -> None:
|
||||
break
|
||||
except pymongo_auth_aws.PyMongoAuthAwsError as exc:
|
||||
# Clear the cached credentials if we hit a failure in auth.
|
||||
pymongo_auth_aws.set_cached_credentials(None)
|
||||
set_cached_credentials(None)
|
||||
# Convert to OperationFailure and include pymongo-auth-aws version.
|
||||
raise OperationFailure(
|
||||
f"{exc} (pymongo-auth-aws version {pymongo_auth_aws.__version__})"
|
||||
) from None
|
||||
except Exception:
|
||||
# Clear the cached credentials if we hit a failure in auth.
|
||||
pymongo_auth_aws.set_cached_credentials(None)
|
||||
set_cached_credentials(None)
|
||||
raise
|
||||
|
||||
@ -43,6 +43,7 @@ class OIDCIdPInfo:
|
||||
@dataclass
|
||||
class OIDCCallbackContext:
|
||||
timeout_seconds: float
|
||||
username: str
|
||||
version: int
|
||||
refresh_token: Optional[str] = field(default=None)
|
||||
idp_info: Optional[OIDCIdPInfo] = field(default=None)
|
||||
@ -67,8 +68,9 @@ class OIDCCallback(abc.ABC):
|
||||
class _OIDCProperties:
|
||||
callback: Optional[OIDCCallback] = field(default=None)
|
||||
human_callback: Optional[OIDCCallback] = field(default=None)
|
||||
provider_name: Optional[str] = field(default=None)
|
||||
environment: Optional[str] = field(default=None)
|
||||
allowed_hosts: list[str] = field(default_factory=list)
|
||||
username: str = ""
|
||||
|
||||
|
||||
"""Mechanism properties for MONGODB-OIDC authentication."""
|
||||
@ -91,7 +93,7 @@ def _get_authenticator(
|
||||
properties = credentials.mechanism_properties
|
||||
|
||||
# Validate that the address is allowed.
|
||||
if not properties.provider_name:
|
||||
if not properties.environment:
|
||||
found = False
|
||||
allowed_hosts = properties.allowed_hosts
|
||||
for patt in allowed_hosts:
|
||||
@ -109,24 +111,23 @@ def _get_authenticator(
|
||||
return credentials.cache.data
|
||||
|
||||
|
||||
class _OIDCAWSCallback(OIDCCallback):
|
||||
class _OIDCTestCallback(OIDCCallback):
|
||||
def fetch(self, context: OIDCCallbackContext) -> OIDCCallbackResult:
|
||||
token_file = os.environ.get("AWS_WEB_IDENTITY_TOKEN_FILE")
|
||||
token_file = os.environ.get("OIDC_TOKEN_FILE")
|
||||
if not token_file:
|
||||
raise RuntimeError(
|
||||
'MONGODB-OIDC with an "aws" provider requires "AWS_WEB_IDENTITY_TOKEN_FILE" to be set'
|
||||
'MONGODB-OIDC with an "test" provider requires "OIDC_TOKEN_FILE" to be set'
|
||||
)
|
||||
with open(token_file) as fid:
|
||||
return OIDCCallbackResult(access_token=fid.read().strip())
|
||||
|
||||
|
||||
class _OIDCAzureCallback(OIDCCallback):
|
||||
def __init__(self, token_audience: str, username: Optional[str]) -> None:
|
||||
self.token_audience = token_audience
|
||||
self.username = username
|
||||
def __init__(self, token_resource: str) -> None:
|
||||
self.token_resource = token_resource
|
||||
|
||||
def fetch(self, context: OIDCCallbackContext) -> OIDCCallbackResult:
|
||||
resp = _get_azure_response(self.token_audience, self.username, context.timeout_seconds)
|
||||
resp = _get_azure_response(self.token_resource, context.username, context.timeout_seconds)
|
||||
return OIDCCallbackResult(
|
||||
access_token=resp["access_token"], expires_in_seconds=resp["expires_in"]
|
||||
)
|
||||
@ -255,6 +256,7 @@ class _OIDCAuthenticator:
|
||||
version=CALLBACK_VERSION,
|
||||
refresh_token=self.refresh_token,
|
||||
idp_info=self.idp_info,
|
||||
username=self.properties.username,
|
||||
)
|
||||
resp = cb.fetch(context)
|
||||
if not isinstance(resp, OIDCCallbackResult):
|
||||
|
||||
@ -424,8 +424,8 @@ _MECHANISM_PROPS = frozenset(
|
||||
"CANONICALIZE_HOST_NAME",
|
||||
"SERVICE_REALM",
|
||||
"AWS_SESSION_TOKEN",
|
||||
"PROVIDER_NAME",
|
||||
"TOKEN_AUDIENCE",
|
||||
"ENVIRONMENT",
|
||||
"TOKEN_RESOURCE",
|
||||
"ALLOWED_HOSTS",
|
||||
]
|
||||
)
|
||||
|
||||
@ -446,8 +446,8 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should recognise the mechanism with aws provider (MONGODB-OIDC)",
|
||||
"uri": "mongodb://localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=PROVIDER_NAME:aws",
|
||||
"description": "should recognise the mechanism with test environment (MONGODB-OIDC)",
|
||||
"uri": "mongodb://localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:test",
|
||||
"valid": true,
|
||||
"credential": {
|
||||
"username": null,
|
||||
@ -455,13 +455,13 @@
|
||||
"source": "$external",
|
||||
"mechanism": "MONGODB-OIDC",
|
||||
"mechanism_properties": {
|
||||
"PROVIDER_NAME": "aws"
|
||||
"ENVIRONMENT": "test"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should recognise the mechanism when auth source is explicitly specified and with provider (MONGODB-OIDC)",
|
||||
"uri": "mongodb://localhost/?authMechanism=MONGODB-OIDC&authSource=$external&authMechanismProperties=PROVIDER_NAME:aws",
|
||||
"description": "should recognise the mechanism when auth source is explicitly specified and with environment (MONGODB-OIDC)",
|
||||
"uri": "mongodb://localhost/?authMechanism=MONGODB-OIDC&authSource=$external&authMechanismProperties=ENVIRONMENT:test",
|
||||
"valid": true,
|
||||
"credential": {
|
||||
"username": null,
|
||||
@ -469,31 +469,31 @@
|
||||
"source": "$external",
|
||||
"mechanism": "MONGODB-OIDC",
|
||||
"mechanism_properties": {
|
||||
"PROVIDER_NAME": "aws"
|
||||
"ENVIRONMENT": "test"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should throw an exception if username and password is specified for aws provider (MONGODB-OIDC)",
|
||||
"uri": "mongodb://user:pass@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=PROVIDER_NAME:aws",
|
||||
"description": "should throw an exception if username and password is specified for test environment (MONGODB-OIDC)",
|
||||
"uri": "mongodb://user:pass@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:test",
|
||||
"valid": false,
|
||||
"credential": null
|
||||
},
|
||||
{
|
||||
"description": "should throw an exception if username is specified for aws provider (MONGODB-OIDC)",
|
||||
"uri": "mongodb://principalName@localhost/?authMechanism=MONGODB-OIDC&PROVIDER_NAME:aws",
|
||||
"description": "should throw an exception if username is specified for test environment (MONGODB-OIDC)",
|
||||
"uri": "mongodb://principalName@localhost/?authMechanism=MONGODB-OIDC&ENVIRONMENT:test",
|
||||
"valid": false,
|
||||
"credential": null
|
||||
},
|
||||
{
|
||||
"description": "should throw an exception if specified provider is not supported (MONGODB-OIDC)",
|
||||
"uri": "mongodb://localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=PROVIDER_NAME:invalid",
|
||||
"uri": "mongodb://localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:invalid",
|
||||
"valid": false,
|
||||
"credential": null
|
||||
},
|
||||
{
|
||||
"description": "should throw an exception custom callback is chosen but no callback is provided (MONGODB-OIDC)",
|
||||
"uri": "mongodb://localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=PROVIDER_NAME:custom",
|
||||
"uri": "mongodb://localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:custom",
|
||||
"valid": false,
|
||||
"credential": null
|
||||
},
|
||||
@ -505,7 +505,7 @@
|
||||
},
|
||||
{
|
||||
"description": "should recognise the mechanism with azure provider (MONGODB-OIDC)",
|
||||
"uri": "mongodb://localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=PROVIDER_NAME:azure,TOKEN_AUDIENCE:foo",
|
||||
"uri": "mongodb://localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:azure,TOKEN_RESOURCE:foo",
|
||||
"valid": true,
|
||||
"credential": {
|
||||
"username": null,
|
||||
@ -513,14 +513,14 @@
|
||||
"source": "$external",
|
||||
"mechanism": "MONGODB-OIDC",
|
||||
"mechanism_properties": {
|
||||
"PROVIDER_NAME": "azure",
|
||||
"TOKEN_AUDIENCE": "foo"
|
||||
"ENVIRONMENT": "azure",
|
||||
"TOKEN_RESOURCE": "foo"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should accept a username with azure provider (MONGODB-OIDC)",
|
||||
"uri": "mongodb://user@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=PROVIDER_NAME:azure,TOKEN_AUDIENCE:foo",
|
||||
"uri": "mongodb://user@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:azure,TOKEN_RESOURCE:foo",
|
||||
"valid": true,
|
||||
"credential": {
|
||||
"username": "user",
|
||||
@ -528,20 +528,20 @@
|
||||
"source": "$external",
|
||||
"mechanism": "MONGODB-OIDC",
|
||||
"mechanism_properties": {
|
||||
"PROVIDER_NAME": "azure",
|
||||
"TOKEN_AUDIENCE": "foo"
|
||||
"ENVIRONMENT": "azure",
|
||||
"TOKEN_RESOURCE": "foo"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should accept a username and throw an error for a password with azure provider (MONGODB-OIDC)",
|
||||
"uri": "mongodb://user:pass@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=PROVIDER_NAME:azure,TOKEN_AUDIENCE:foo",
|
||||
"uri": "mongodb://user:pass@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:azure,TOKEN_RESOURCE:foo",
|
||||
"valid": false,
|
||||
"credential": null
|
||||
},
|
||||
{
|
||||
"description": "should throw and exception if no token audience is given for azure provider (MONGODB-OIDC)",
|
||||
"uri": "mongodb://username@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=PROVIDER_NAME:azure",
|
||||
"uri": "mongodb://username@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:azure",
|
||||
"valid": false,
|
||||
"credential": null
|
||||
}
|
||||
|
||||
@ -60,8 +60,13 @@ class TestAuthAWS(unittest.TestCase):
|
||||
def setup_cache(self):
|
||||
if os.environ.get("AWS_ACCESS_KEY_ID", None) or "@" in self.uri:
|
||||
self.skipTest("Not testing cached credentials")
|
||||
if not hasattr(auth, "set_cached_credentials"):
|
||||
self.skipTest("Cached credentials not available")
|
||||
|
||||
# Make a connection to ensure that we enable caching.
|
||||
client = MongoClient(self.uri)
|
||||
client.get_database().test.find_one()
|
||||
client.close()
|
||||
|
||||
self.assertTrue(auth.get_use_cached_credentials())
|
||||
|
||||
# Ensure cleared credentials.
|
||||
auth.set_cached_credentials(None)
|
||||
|
||||
@ -45,7 +45,7 @@ from pymongo.uri_parser import parse_uri
|
||||
|
||||
ROOT = Path(__file__).parent.parent.resolve()
|
||||
TEST_PATH = ROOT / "auth" / "unified"
|
||||
PROVIDER_NAME = os.environ.get("OIDC_PROVIDER_NAME", "aws")
|
||||
ENVIRON = os.environ.get("OIDC_ENV", "test")
|
||||
|
||||
|
||||
# Generate unified tests.
|
||||
@ -64,15 +64,17 @@ class OIDCTestBase(unittest.TestCase):
|
||||
|
||||
def get_token(self, username=None):
|
||||
"""Get a token for the current provider."""
|
||||
if PROVIDER_NAME == "aws":
|
||||
if ENVIRON == "test":
|
||||
token_dir = os.environ["OIDC_TOKEN_DIR"]
|
||||
token_file = os.path.join(token_dir, username).replace(os.sep, "/")
|
||||
with open(token_file) as fid:
|
||||
return fid.read()
|
||||
elif PROVIDER_NAME == "azure":
|
||||
elif ENVIRON == "azure":
|
||||
opts = parse_uri(self.uri_single)["options"]
|
||||
token_aud = opts["authmechanismproperties"]["TOKEN_AUDIENCE"]
|
||||
return _get_azure_response(token_aud, username)["access_token"]
|
||||
resource = opts["authmechanismproperties"]["TOKEN_RESOURCE"]
|
||||
return _get_azure_response(resource, username)["access_token"]
|
||||
else:
|
||||
raise RuntimeError(f"Invalid ENVIRONMENT {ENVIRON}")
|
||||
|
||||
@contextmanager
|
||||
def fail_point(self, command_args):
|
||||
@ -91,8 +93,8 @@ class TestAuthOIDCHuman(OIDCTestBase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
if PROVIDER_NAME != "aws":
|
||||
raise unittest.SkipTest("Human workflows are only tested with the aws provider")
|
||||
if ENVIRON != "test":
|
||||
raise unittest.SkipTest("Human workflows are only tested with the test environment")
|
||||
super().setUpClass()
|
||||
|
||||
def create_request_cb(self, username="test_user1", sleep=0):
|
||||
@ -630,7 +632,7 @@ class TestAuthOIDCMachine(OIDCTestBase):
|
||||
|
||||
def setUp(self):
|
||||
self.request_called = 0
|
||||
if PROVIDER_NAME == "aws":
|
||||
if ENVIRON == "test":
|
||||
self.default_username = "test_user1"
|
||||
else:
|
||||
self.default_username = None
|
||||
@ -752,9 +754,9 @@ class TestAuthOIDCMachine(OIDCTestBase):
|
||||
client.close()
|
||||
|
||||
def test_2_5_invalid_client_configuration_with_callback(self):
|
||||
# Create a MongoClient configured with an OIDC callback and auth mechanism property PROVIDER_NAME:aws.
|
||||
# Create a MongoClient configured with an OIDC callback and auth mechanism property ENVIRONMENT:test.
|
||||
request_cb = self.create_request_cb()
|
||||
props: Dict = {"OIDC_CALLBACK": request_cb, "PROVIDER_NAME": "aws"}
|
||||
props: Dict = {"OIDC_CALLBACK": request_cb, "ENVIRONMENT": "test"}
|
||||
# Assert it returns a client configuration error.
|
||||
with self.assertRaises(ConfigurationError):
|
||||
self.create_client(authmechanismproperties=props)
|
||||
@ -826,6 +828,30 @@ class TestAuthOIDCMachine(OIDCTestBase):
|
||||
# Close the client.
|
||||
client.close()
|
||||
|
||||
def test_5_1_azure_with_no_username(self):
|
||||
if ENVIRON != "azure":
|
||||
raise unittest.SkipTest("Test is only supported on Azure")
|
||||
opts = parse_uri(self.uri_single)["options"]
|
||||
resource = opts["authmechanismproperties"]["TOKEN_RESOURCE"]
|
||||
|
||||
props = dict(TOKEN_RESOURCE=resource, ENVIRONMENT="azure")
|
||||
client = self.create_client(authMechanismProperties=props)
|
||||
client.test.test.find_one()
|
||||
client.close()
|
||||
|
||||
def test_5_2_azure_with_bad_username(self):
|
||||
if ENVIRON != "azure":
|
||||
raise unittest.SkipTest("Test is only supported on Azure")
|
||||
|
||||
opts = parse_uri(self.uri_single)["options"]
|
||||
token_aud = opts["authmechanismproperties"]["TOKEN_RESOURCE"]
|
||||
|
||||
props = dict(TOKEN_RESOURCE=token_aud, ENVIRONMENT="azure")
|
||||
client = self.create_client(username="bad", authmechanismproperties=props)
|
||||
with self.assertRaises(ValueError):
|
||||
client.test.test.find_one()
|
||||
client.close()
|
||||
|
||||
def test_speculative_auth_success(self):
|
||||
client1 = self.create_client()
|
||||
client1.test.test.find_one()
|
||||
@ -892,30 +918,6 @@ class TestAuthOIDCMachine(OIDCTestBase):
|
||||
client1.close()
|
||||
client2.close()
|
||||
|
||||
def test_azure_no_username(self):
|
||||
if PROVIDER_NAME != "azure":
|
||||
raise unittest.SkipTest("Test is only supported on Azure")
|
||||
opts = parse_uri(self.uri_single)["options"]
|
||||
token_aud = opts["authmechanismproperties"]["TOKEN_AUDIENCE"]
|
||||
|
||||
props = dict(TOKEN_AUDIENCE=token_aud, PROVIDER_NAME="azure")
|
||||
client = self.create_client(authMechanismProperties=props)
|
||||
client.test.test.find_one()
|
||||
client.close()
|
||||
|
||||
def test_azure_bad_username(self):
|
||||
if PROVIDER_NAME != "azure":
|
||||
raise unittest.SkipTest("Test is only supported on Azure")
|
||||
|
||||
opts = parse_uri(self.uri_single)["options"]
|
||||
token_aud = opts["authmechanismproperties"]["TOKEN_AUDIENCE"]
|
||||
|
||||
props = dict(TOKEN_AUDIENCE=token_aud, PROVIDER_NAME="azure")
|
||||
client = self.create_client(username="bad", authmechanismproperties=props)
|
||||
with self.assertRaises(ValueError):
|
||||
client.test.test.find_one()
|
||||
client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@ -86,8 +86,8 @@ def create_test(test_case):
|
||||
self.assertEqual(
|
||||
actual.aws_session_token, expected["AWS_SESSION_TOKEN"]
|
||||
)
|
||||
elif "PROVIDER_NAME" in expected:
|
||||
self.assertEqual(actual.provider_name, expected["PROVIDER_NAME"])
|
||||
elif "ENVIRONMENT" in expected:
|
||||
self.assertEqual(actual.environment, expected["ENVIRONMENT"])
|
||||
elif "callback" in expected:
|
||||
self.assertEqual(actual.callback, expected["callback"])
|
||||
else:
|
||||
|
||||
@ -164,13 +164,13 @@ for provider_name, provider_data in [
|
||||
placeholder = f"/clientEncryptionOpts/kmsProviders/{provider_name}/{key}"
|
||||
PLACEHOLDER_MAP[placeholder] = value
|
||||
|
||||
PROVIDER_NAME = os.environ.get("OIDC_PROVIDER_NAME", "aws")
|
||||
if PROVIDER_NAME == "aws":
|
||||
PLACEHOLDER_MAP["/uriOptions/authMechanismProperties"] = {"PROVIDER_NAME": "aws"}
|
||||
elif PROVIDER_NAME == "azure":
|
||||
OIDC_ENV = os.environ.get("OIDC_ENV", "test")
|
||||
if OIDC_ENV == "test":
|
||||
PLACEHOLDER_MAP["/uriOptions/authMechanismProperties"] = {"ENVIRONMENT": "test"}
|
||||
elif OIDC_ENV == "azure":
|
||||
PLACEHOLDER_MAP["/uriOptions/authMechanismProperties"] = {
|
||||
"PROVIDER_NAME": "azure",
|
||||
"TOKEN_AUDIENCE": os.environ["AZUREOIDC_AUDIENCE"],
|
||||
"ENVIRONMENT": "azure",
|
||||
"TOKEN_RESOURCE": os.environ["AZUREOIDC_RESOURCE"],
|
||||
}
|
||||
|
||||
|
||||
@ -971,6 +971,7 @@ class UnifiedSpecTestMixinV1(IntegrationTest):
|
||||
RUN_ON_LOAD_BALANCER = True
|
||||
RUN_ON_SERVERLESS = True
|
||||
TEST_SPEC: Any
|
||||
mongos_clients: list[MongoClient] = []
|
||||
|
||||
@staticmethod
|
||||
def should_run_on(run_on_spec):
|
||||
|
||||
Loading…
Reference in New Issue
Block a user