PYTHON-4922 Remove Support for MONGODB-CR Authentication (#1978)

This commit is contained in:
Steven Silvester 2024-10-30 12:57:31 -05:00 committed by GitHub
parent 9a11b78fdf
commit ad3292e39b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 13 additions and 127 deletions

View File

@ -12,6 +12,7 @@ PyMongo 4.11 brings a number of changes including:
- Dropped support for Python 3.8.
- Dropped support for MongoDB 3.6.
- Dropped support for the MONGODB-CR authenticate mechanism, which is no longer supported by MongoDB 4.0+.
- Added support for free-threaded Python with the GIL disabled. For more information see:
`Free-threaded CPython <https://docs.python.org/3.13/whatsnew/3.13.html#whatsnew313-free-threaded-cpython>`_.
- :attr:`~pymongo.asynchronous.mongo_client.AsyncMongoClient.address` and

View File

@ -76,24 +76,6 @@ For best performance on Python versions older than 2.7.8 install `backports.pbkd
.. _backports.pbkdf2: https://pypi.python.org/pypi/backports.pbkdf2/
MONGODB-CR
----------
.. warning:: MONGODB-CR was deprecated with the release of MongoDB 3.6 and
is no longer supported by MongoDB 4.0.
Before MongoDB 3.0 the default authentication mechanism was MONGODB-CR,
the "MongoDB Challenge-Response" protocol::
>>> from pymongo import MongoClient
>>> client = MongoClient('example.com',
... username='user',
... password='password',
... authMechanism='MONGODB-CR')
>>>
>>> uri = "mongodb://user:password@example.com/?authSource=the_database&authMechanism=MONGODB-CR"
>>> client = MongoClient(uri)
Default Authentication Mechanism
--------------------------------
@ -221,8 +203,7 @@ SASL PLAIN (RFC 4616)
MongoDB Enterprise Edition version 2.6 and newer support the SASL PLAIN
authentication mechanism, initially intended for delegating authentication
to an LDAP server. Using the PLAIN mechanism is very similar to MONGODB-CR.
These examples use the $external virtual database for LDAP support::
to an LDAP server. These examples use the $external virtual database for LDAP support::
>>> from pymongo import MongoClient
>>> uri = "mongodb://user:password@example.com/?authMechanism=PLAIN"

View File

@ -329,21 +329,6 @@ async def _authenticate_x509(credentials: MongoCredential, conn: AsyncConnection
await conn.command("$external", cmd)
async def _authenticate_mongo_cr(credentials: MongoCredential, conn: AsyncConnection) -> None:
"""Authenticate using MONGODB-CR."""
source = credentials.source
username = credentials.username
password = credentials.password
# Get a nonce
response = await conn.command(source, {"getnonce": 1})
nonce = response["nonce"]
key = _auth_key(nonce, username, password)
# Actually authenticate
query = {"authenticate": 1, "user": username, "nonce": nonce, "key": key}
await conn.command(source, query)
async def _authenticate_default(credentials: MongoCredential, conn: AsyncConnection) -> None:
if conn.max_wire_version >= 7:
if conn.negotiated_mechs:
@ -365,7 +350,6 @@ async def _authenticate_default(credentials: MongoCredential, conn: AsyncConnect
_AUTH_MAP: Mapping[str, Callable[..., Coroutine[Any, Any, None]]] = {
"GSSAPI": _authenticate_gssapi,
"MONGODB-CR": _authenticate_mongo_cr,
"MONGODB-X509": _authenticate_x509,
"MONGODB-AWS": _authenticate_aws,
"MONGODB-OIDC": _authenticate_oidc, # type:ignore[dict-item]

View File

@ -34,7 +34,6 @@ from pymongo.errors import ConfigurationError
MECHANISMS = frozenset(
[
"GSSAPI",
"MONGODB-CR",
"MONGODB-OIDC",
"MONGODB-X509",
"MONGODB-AWS",

View File

@ -326,21 +326,6 @@ def _authenticate_x509(credentials: MongoCredential, conn: Connection) -> None:
conn.command("$external", cmd)
def _authenticate_mongo_cr(credentials: MongoCredential, conn: Connection) -> None:
"""Authenticate using MONGODB-CR."""
source = credentials.source
username = credentials.username
password = credentials.password
# Get a nonce
response = conn.command(source, {"getnonce": 1})
nonce = response["nonce"]
key = _auth_key(nonce, username, password)
# Actually authenticate
query = {"authenticate": 1, "user": username, "nonce": nonce, "key": key}
conn.command(source, query)
def _authenticate_default(credentials: MongoCredential, conn: Connection) -> None:
if conn.max_wire_version >= 7:
if conn.negotiated_mechs:
@ -360,7 +345,6 @@ def _authenticate_default(credentials: MongoCredential, conn: Connection) -> Non
_AUTH_MAP: Mapping[str, Callable[..., None]] = {
"GSSAPI": _authenticate_gssapi,
"MONGODB-CR": _authenticate_mongo_cr,
"MONGODB-X509": _authenticate_x509,
"MONGODB-AWS": _authenticate_aws,
"MONGODB-OIDC": _authenticate_oidc, # type:ignore[dict-item]

View File

@ -127,47 +127,6 @@
"uri": "mongodb://localhost/?authMechanism=GSSAPI",
"valid": false
},
{
"description": "should recognize the mechanism (MONGODB-CR)",
"uri": "mongodb://user:password@localhost/?authMechanism=MONGODB-CR",
"valid": true,
"credential": {
"username": "user",
"password": "password",
"source": "admin",
"mechanism": "MONGODB-CR",
"mechanism_properties": null
}
},
{
"description": "should use the database when no authSource is specified (MONGODB-CR)",
"uri": "mongodb://user:password@localhost/foo?authMechanism=MONGODB-CR",
"valid": true,
"credential": {
"username": "user",
"password": "password",
"source": "foo",
"mechanism": "MONGODB-CR",
"mechanism_properties": null
}
},
{
"description": "should use the authSource when specified (MONGODB-CR)",
"uri": "mongodb://user:password@localhost/foo?authMechanism=MONGODB-CR&authSource=bar",
"valid": true,
"credential": {
"username": "user",
"password": "password",
"source": "bar",
"mechanism": "MONGODB-CR",
"mechanism_properties": null
}
},
{
"description": "should throw an exception if no username is supplied (MONGODB-CR)",
"uri": "mongodb://localhost/?authMechanism=MONGODB-CR",
"valid": false
},
{
"description": "should recognize the mechanism (MONGODB-X509)",
"uri": "mongodb://CN%3DmyName%2COU%3DmyOrgUnit%2CO%3DmyOrg%2CL%3DmyLocality%2CST%3DmyState%2CC%3DmyCountry@localhost/?authMechanism=MONGODB-X509",

View File

@ -220,29 +220,8 @@
"options": null
},
{
"description": "Escaped user info and database (MONGODB-CR)",
"uri": "mongodb://%24am:f%3Azzb%40z%2Fz%3D@127.0.0.1/admin%3F?authMechanism=MONGODB-CR",
"valid": true,
"warning": false,
"hosts": [
{
"type": "ipv4",
"host": "127.0.0.1",
"port": null
}
],
"auth": {
"username": "$am",
"password": "f:zzb@z/z=",
"db": "admin?"
},
"options": {
"authmechanism": "MONGODB-CR"
}
},
{
"description": "Subdelimiters in user/pass don't need escaping (MONGODB-CR)",
"uri": "mongodb://!$&'()*+,;=:!$&'()*+,;=@127.0.0.1/admin?authMechanism=MONGODB-CR",
"description": "Subdelimiters in user/pass don't need escaping (PLAIN)",
"uri": "mongodb://!$&'()*+,;=:!$&'()*+,;=@127.0.0.1/admin?authMechanism=PLAIN",
"valid": true,
"warning": false,
"hosts": [
@ -258,7 +237,7 @@
"db": "admin"
},
"options": {
"authmechanism": "MONGODB-CR"
"authmechanism": "PLAIN"
}
},
{

View File

@ -2,7 +2,7 @@
"tests": [
{
"description": "Option names are normalized to lowercase",
"uri": "mongodb://alice:secret@example.com/admin?AUTHMechanism=MONGODB-CR",
"uri": "mongodb://alice:secret@example.com/admin?AUTHMechanism=PLAIN",
"valid": true,
"warning": false,
"hosts": [
@ -18,7 +18,7 @@
"db": "admin"
},
"options": {
"authmechanism": "MONGODB-CR"
"authmechanism": "PLAIN"
}
},
{

View File

@ -142,7 +142,6 @@ class TestURI(unittest.TestCase):
self.assertEqual({"fsync": True}, split_options("fsync=true"))
self.assertEqual({"fsync": False}, split_options("fsync=false"))
self.assertEqual({"authmechanism": "GSSAPI"}, split_options("authMechanism=GSSAPI"))
self.assertEqual({"authmechanism": "MONGODB-CR"}, split_options("authMechanism=MONGODB-CR"))
self.assertEqual(
{"authmechanism": "SCRAM-SHA-1"}, split_options("authMechanism=SCRAM-SHA-1")
)
@ -295,30 +294,30 @@ class TestURI(unittest.TestCase):
# Various authentication tests
res = copy.deepcopy(orig)
res["options"] = {"authmechanism": "MONGODB-CR"}
res["options"] = {"authmechanism": "SCRAM-SHA-256"}
res["username"] = "user"
res["password"] = "password"
self.assertEqual(
res, parse_uri("mongodb://user:password@localhost/?authMechanism=MONGODB-CR")
res, parse_uri("mongodb://user:password@localhost/?authMechanism=SCRAM-SHA-256")
)
res = copy.deepcopy(orig)
res["options"] = {"authmechanism": "MONGODB-CR", "authsource": "bar"}
res["options"] = {"authmechanism": "SCRAM-SHA-256", "authsource": "bar"}
res["username"] = "user"
res["password"] = "password"
res["database"] = "foo"
self.assertEqual(
res,
parse_uri(
"mongodb://user:password@localhost/foo?authSource=bar;authMechanism=MONGODB-CR"
"mongodb://user:password@localhost/foo?authSource=bar;authMechanism=SCRAM-SHA-256"
),
)
res = copy.deepcopy(orig)
res["options"] = {"authmechanism": "MONGODB-CR"}
res["options"] = {"authmechanism": "SCRAM-SHA-256"}
res["username"] = "user"
res["password"] = ""
self.assertEqual(res, parse_uri("mongodb://user:@localhost/?authMechanism=MONGODB-CR"))
self.assertEqual(res, parse_uri("mongodb://user:@localhost/?authMechanism=SCRAM-SHA-256"))
res = copy.deepcopy(orig)
res["username"] = "user@domain.com"