PYTHON-1425 - Implement the auth spec and tests
This commit is contained in:
parent
94c680c7da
commit
984977ba9e
@ -10,6 +10,8 @@ Version 3.7 adds support for MongoDB 4.0. Highlights include:
|
||||
- Support for the SCRAM-SHA-256 authentication mechanism.
|
||||
- Support for Python 3.7.
|
||||
- MD5 is now optional in GridFS.
|
||||
- If not specified, the authSource for the PLAIN authentication mechanism
|
||||
defaults to $external.
|
||||
- wtimeoutMS is once again supported as a URI option.
|
||||
- Deprecate the snapshot option of :meth:`~pymongo.collection.Collection.find`
|
||||
and :meth:`~pymongo.collection.Collection.find_one`. The option was
|
||||
|
||||
@ -71,10 +71,15 @@ GSSAPIProperties = namedtuple('GSSAPIProperties',
|
||||
"""Mechanism properties for GSSAPI authentication."""
|
||||
|
||||
|
||||
def _build_credentials_tuple(mech, source, user, passwd, extra):
|
||||
def _build_credentials_tuple(mech, source, user, passwd, extra, database):
|
||||
"""Build and return a mechanism specific credentials tuple.
|
||||
"""
|
||||
if mech != 'MONGODB-X509' and user is None:
|
||||
raise ConfigurationError("%s requires a username." % (mech,))
|
||||
if mech == 'GSSAPI':
|
||||
if source is not None and source != '$external':
|
||||
raise ValueError(
|
||||
"authentication source must be $external or None for GSSAPI")
|
||||
properties = extra.get('authmechanismproperties', {})
|
||||
service_name = properties.get('SERVICE_NAME', 'mongodb')
|
||||
canonicalize = properties.get('CANONICALIZE_HOST_NAME', False)
|
||||
@ -85,12 +90,23 @@ def _build_credentials_tuple(mech, source, user, passwd, extra):
|
||||
# Source is always $external.
|
||||
return MongoCredential(mech, '$external', user, passwd, props)
|
||||
elif mech == 'MONGODB-X509':
|
||||
if passwd is not None:
|
||||
raise ConfigurationError(
|
||||
"Passwords are not supported by MONGODB-X509")
|
||||
if source is not None and source != '$external':
|
||||
raise ValueError(
|
||||
"authentication source must be "
|
||||
"$external or None for MONGODB-X509")
|
||||
# user can be None.
|
||||
return MongoCredential(mech, '$external', user, None, None)
|
||||
elif mech == 'PLAIN':
|
||||
source_database = source or database or '$external'
|
||||
return MongoCredential(mech, source_database, user, passwd, None)
|
||||
else:
|
||||
source_database = source or database or 'admin'
|
||||
if passwd is None:
|
||||
raise ConfigurationError("A password is required.")
|
||||
return MongoCredential(mech, source, user, passwd, None)
|
||||
return MongoCredential(mech, source_database, user, passwd, None)
|
||||
|
||||
|
||||
if PY3:
|
||||
|
||||
@ -30,12 +30,12 @@ from pymongo.write_concern import WriteConcern
|
||||
|
||||
def _parse_credentials(username, password, database, options):
|
||||
"""Parse authentication credentials."""
|
||||
mechanism = options.get('authmechanism', 'DEFAULT')
|
||||
if username is None and mechanism != 'MONGODB-X509':
|
||||
return None
|
||||
source = options.get('authsource', database or 'admin')
|
||||
return _build_credentials_tuple(
|
||||
mechanism, source, username, password, options)
|
||||
mechanism = options.get('authmechanism', 'DEFAULT' if username else None)
|
||||
source = options.get('authsource')
|
||||
if username or mechanism:
|
||||
return _build_credentials_tuple(
|
||||
mechanism, source, username, password, options, database)
|
||||
return None
|
||||
|
||||
|
||||
def _parse_read_preference(options):
|
||||
|
||||
@ -1166,10 +1166,11 @@ class Database(common.BaseObject):
|
||||
|
||||
credentials = auth._build_credentials_tuple(
|
||||
mechanism,
|
||||
source or self.name,
|
||||
source,
|
||||
name,
|
||||
password,
|
||||
validated_options)
|
||||
validated_options,
|
||||
self.name)
|
||||
|
||||
self.client._cache_credentials(
|
||||
self.name,
|
||||
|
||||
453
test/auth/connection-string.json
Normal file
453
test/auth/connection-string.json
Normal file
@ -0,0 +1,453 @@
|
||||
{
|
||||
"tests": [
|
||||
{
|
||||
"description": "should use the default source and mechanism",
|
||||
"uri": "mongodb://user:password@localhost",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"auth": {
|
||||
"username": "user",
|
||||
"password": "password",
|
||||
"db": "admin"
|
||||
},
|
||||
"options": null
|
||||
},
|
||||
{
|
||||
"description": "should use the database when no authSource is specified",
|
||||
"uri": "mongodb://user:password@localhost/foo",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"auth": {
|
||||
"username": "user",
|
||||
"password": "password",
|
||||
"db": "foo"
|
||||
},
|
||||
"options": null
|
||||
},
|
||||
{
|
||||
"description": "should use the authSource when specified",
|
||||
"uri": "mongodb://user:password@localhost/foo?authSource=bar",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"auth": {
|
||||
"username": "user",
|
||||
"password": "password",
|
||||
"db": "bar"
|
||||
},
|
||||
"options": null
|
||||
},
|
||||
{
|
||||
"description": "should recognise the mechanism (GSSAPI)",
|
||||
"uri": "mongodb://user%40DOMAIN.COM@localhost/?authMechanism=GSSAPI",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"auth": {
|
||||
"username": "user@DOMAIN.COM",
|
||||
"password": null,
|
||||
"db": "$external"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "GSSAPI"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should ignore the database (GSSAPI)",
|
||||
"uri": "mongodb://user%40DOMAIN.COM@localhost/foo?authMechanism=GSSAPI",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"auth": {
|
||||
"username": "user@DOMAIN.COM",
|
||||
"password": null,
|
||||
"db": "$external"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "GSSAPI"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should accept valid authSource (GSSAPI)",
|
||||
"uri": "mongodb://user%40DOMAIN.COM@localhost/?authMechanism=GSSAPI&authSource=$external",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"auth": {
|
||||
"username": "user@DOMAIN.COM",
|
||||
"password": null,
|
||||
"db": "$external"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "GSSAPI"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should accept generic mechanism property (GSSAPI)",
|
||||
"uri": "mongodb://user%40DOMAIN.COM@localhost/?authMechanism=GSSAPI&authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"auth": {
|
||||
"username": "user@DOMAIN.COM",
|
||||
"password": null,
|
||||
"db": "$external"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "GSSAPI",
|
||||
"authmechanismproperties": {
|
||||
"SERVICE_NAME": "other",
|
||||
"CANONICALIZE_HOST_NAME": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should accept the password (GSSAPI)",
|
||||
"uri": "mongodb://user%40DOMAIN.COM:password@localhost/?authMechanism=GSSAPI&authSource=$external",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"auth": {
|
||||
"username": "user@DOMAIN.COM",
|
||||
"password": "password",
|
||||
"db": "$external"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "GSSAPI"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "may support deprecated gssapiServiceName option (GSSAPI)",
|
||||
"uri": "mongodb://user%40DOMAIN.COM@localhost/?authMechanism=GSSAPI&gssapiServiceName=other",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"optional": true,
|
||||
"auth": {
|
||||
"username": "user@DOMAIN.COM",
|
||||
"password": null,
|
||||
"db": "$external"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "GSSAPI",
|
||||
"authmechanismproperties": {
|
||||
"SERVICE_NAME": "other"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should throw an exception if authSource is invalid (GSSAPI)",
|
||||
"uri": "mongodb://user%40DOMAIN.COM@localhost/?authMechanism=GSSAPI&authSource=foo",
|
||||
"hosts": null,
|
||||
"valid": false,
|
||||
"warning": false,
|
||||
"auth": null,
|
||||
"options": null
|
||||
},
|
||||
{
|
||||
"description": "should throw an exception if no username (GSSAPI)",
|
||||
"uri": "mongodb://localhost/?authMechanism=GSSAPI",
|
||||
"hosts": null,
|
||||
"valid": false,
|
||||
"warning": false,
|
||||
"auth": null,
|
||||
"options": null
|
||||
},
|
||||
{
|
||||
"description": "should recognize the mechanism (MONGODB-CR)",
|
||||
"uri": "mongodb://user:password@localhost/?authMechanism=MONGODB-CR",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"auth": {
|
||||
"username": "user",
|
||||
"password": "password",
|
||||
"db": "admin"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "MONGODB-CR"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should use the database when no authSource is specified (MONGODB-CR)",
|
||||
"uri": "mongodb://user:password@localhost/foo?authMechanism=MONGODB-CR",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"auth": {
|
||||
"username": "user",
|
||||
"password": "password",
|
||||
"db": "foo"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "MONGODB-CR"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should use the authSource when specified (MONGODB-CR)",
|
||||
"uri": "mongodb://user:password@localhost/foo?authMechanism=MONGODB-CR&authSource=bar",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"auth": {
|
||||
"username": "user",
|
||||
"password": "password",
|
||||
"db": "bar"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "MONGODB-CR"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should throw an exception if no username is supplied (MONGODB-CR)",
|
||||
"uri": "mongodb://localhost/?authMechanism=MONGODB-CR",
|
||||
"hosts": null,
|
||||
"valid": false,
|
||||
"warning": false,
|
||||
"auth": null,
|
||||
"options": null
|
||||
},
|
||||
{
|
||||
"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",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"auth": {
|
||||
"username": "CN=myName,OU=myOrgUnit,O=myOrg,L=myLocality,ST=myState,C=myCountry",
|
||||
"password": null,
|
||||
"db": "$external"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "MONGODB-X509"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should ignore the database (MONGODB-X509)",
|
||||
"uri": "mongodb://CN%3DmyName%2COU%3DmyOrgUnit%2CO%3DmyOrg%2CL%3DmyLocality%2CST%3DmyState%2CC%3DmyCountry@localhost/foo?authMechanism=MONGODB-X509",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"auth": {
|
||||
"username": "CN=myName,OU=myOrgUnit,O=myOrg,L=myLocality,ST=myState,C=myCountry",
|
||||
"password": null,
|
||||
"db": "$external"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "MONGODB-X509"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should accept valid authSource (MONGODB-X509)",
|
||||
"uri": "mongodb://CN%3DmyName%2COU%3DmyOrgUnit%2CO%3DmyOrg%2CL%3DmyLocality%2CST%3DmyState%2CC%3DmyCountry@localhost/?authMechanism=MONGODB-X509&authSource=$external",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"auth": {
|
||||
"username": "CN=myName,OU=myOrgUnit,O=myOrg,L=myLocality,ST=myState,C=myCountry",
|
||||
"password": null,
|
||||
"db": "$external"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "MONGODB-X509"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should recognize the mechanism with no username (MONGODB-X509)",
|
||||
"uri": "mongodb://localhost/?authMechanism=MONGODB-X509",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"auth": {
|
||||
"username": null,
|
||||
"password": null,
|
||||
"db": "$external"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "MONGODB-X509"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should throw an exception if supplied a password (MONGODB-X509)",
|
||||
"uri": "mongodb://user:password@localhost/?authMechanism=MONGODB-X509",
|
||||
"hosts": null,
|
||||
"valid": false,
|
||||
"warning": false,
|
||||
"auth": null,
|
||||
"options": null
|
||||
},
|
||||
{
|
||||
"description": "should throw an exception if authSource is invalid (MONGODB-X509)",
|
||||
"uri": "mongodb://CN%3DmyName%2COU%3DmyOrgUnit%2CO%3DmyOrg%2CL%3DmyLocality%2CST%3DmyState%2CC%3DmyCountry@localhost/foo?authMechanism=MONGODB-X509&authSource=bar",
|
||||
"hosts": null,
|
||||
"valid": false,
|
||||
"warning": false,
|
||||
"auth": null,
|
||||
"options": null
|
||||
},
|
||||
{
|
||||
"description": "should recognize the mechanism (PLAIN)",
|
||||
"uri": "mongodb://user:password@localhost/?authMechanism=PLAIN",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"auth": {
|
||||
"username": "user",
|
||||
"password": "password",
|
||||
"db": "$external"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "PLAIN"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should use the database when no authSource is specified (PLAIN)",
|
||||
"uri": "mongodb://user:password@localhost/foo?authMechanism=PLAIN",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"auth": {
|
||||
"username": "user",
|
||||
"password": "password",
|
||||
"db": "foo"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "PLAIN"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should use the authSource when specified (PLAIN)",
|
||||
"uri": "mongodb://user:password@localhost/foo?authMechanism=PLAIN&authSource=bar",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"auth": {
|
||||
"username": "user",
|
||||
"password": "password",
|
||||
"db": "bar"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "PLAIN"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should throw an exception if no username (PLAIN)",
|
||||
"uri": "mongodb://localhost/?authMechanism=PLAIN",
|
||||
"hosts": null,
|
||||
"valid": false,
|
||||
"warning": false,
|
||||
"auth": null,
|
||||
"options": null
|
||||
},
|
||||
{
|
||||
"description": "should recognize the mechanism (SCRAM-SHA-1)",
|
||||
"uri": "mongodb://user:password@localhost/?authMechanism=SCRAM-SHA-1",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"auth": {
|
||||
"username": "user",
|
||||
"password": "password",
|
||||
"db": "admin"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "SCRAM-SHA-1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should use the database when no authSource is specified (SCRAM-SHA-1)",
|
||||
"uri": "mongodb://user:password@localhost/foo?authMechanism=SCRAM-SHA-1",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"auth": {
|
||||
"username": "user",
|
||||
"password": "password",
|
||||
"db": "foo"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "SCRAM-SHA-1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should accept valid authSource (SCRAM-SHA-1)",
|
||||
"uri": "mongodb://user:password@localhost/foo?authMechanism=SCRAM-SHA-1&authSource=bar",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"auth": {
|
||||
"username": "user",
|
||||
"password": "password",
|
||||
"db": "bar"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "SCRAM-SHA-1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should throw an exception if no username (SCRAM-SHA-1)",
|
||||
"uri": "mongodb://localhost/?authMechanism=SCRAM-SHA-1",
|
||||
"hosts": null,
|
||||
"valid": false,
|
||||
"warning": false,
|
||||
"auth": null,
|
||||
"options": null
|
||||
},
|
||||
{
|
||||
"description": "should recognize the mechanism (SCRAM-SHA-256)",
|
||||
"uri": "mongodb://user:password@localhost/?authMechanism=SCRAM-SHA-256",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"auth": {
|
||||
"username": "user",
|
||||
"password": "password",
|
||||
"db": "admin"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "SCRAM-SHA-256"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should use the database when no authSource is specified (SCRAM-SHA-256)",
|
||||
"uri": "mongodb://user:password@localhost/foo?authMechanism=SCRAM-SHA-256",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"auth": {
|
||||
"username": "user",
|
||||
"password": "password",
|
||||
"db": "foo"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "SCRAM-SHA-256"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should accept valid authSource (SCRAM-SHA-256)",
|
||||
"uri": "mongodb://user:password@localhost/foo?authMechanism=SCRAM-SHA-256&authSource=bar",
|
||||
"hosts": null,
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"auth": {
|
||||
"username": "user",
|
||||
"password": "password",
|
||||
"db": "bar"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "SCRAM-SHA-256"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should throw an exception if no username (SCRAM-SHA-256)",
|
||||
"uri": "mongodb://localhost/?authMechanism=SCRAM-SHA-256",
|
||||
"hosts": null,
|
||||
"valid": false,
|
||||
"warning": false,
|
||||
"auth": null,
|
||||
"options": null
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -97,19 +97,19 @@ class TestGSSAPI(unittest.TestCase):
|
||||
def test_credentials_hashing(self):
|
||||
# GSSAPI credentials are properly hashed.
|
||||
creds0 = _build_credentials_tuple(
|
||||
'GSSAPI', '', 'user', 'pass', {})
|
||||
'GSSAPI', None, 'user', 'pass', {}, None)
|
||||
|
||||
creds1 = _build_credentials_tuple(
|
||||
'GSSAPI', '', 'user', 'pass',
|
||||
{'authmechanismproperties': {'SERVICE_NAME': 'A'}})
|
||||
'GSSAPI', None, 'user', 'pass',
|
||||
{'authmechanismproperties': {'SERVICE_NAME': 'A'}}, None)
|
||||
|
||||
creds2 = _build_credentials_tuple(
|
||||
'GSSAPI', '', 'user', 'pass',
|
||||
{'authmechanismproperties': {'SERVICE_NAME': 'A'}})
|
||||
'GSSAPI', None, 'user', 'pass',
|
||||
{'authmechanismproperties': {'SERVICE_NAME': 'A'}}, None)
|
||||
|
||||
creds3 = _build_credentials_tuple(
|
||||
'GSSAPI', '', 'user', 'pass',
|
||||
{'authmechanismproperties': {'SERVICE_NAME': 'B'}})
|
||||
'GSSAPI', None, 'user', 'pass',
|
||||
{'authmechanismproperties': {'SERVICE_NAME': 'B'}}, None)
|
||||
|
||||
self.assertEqual(1, len(set([creds1, creds2])))
|
||||
self.assertEqual(3, len(set([creds0, creds1, creds2, creds3])))
|
||||
|
||||
96
test/test_auth_spec.py
Normal file
96
test/test_auth_spec.py
Normal file
@ -0,0 +1,96 @@
|
||||
# Copyright 2018-present MongoDB, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Run the auth spec tests."""
|
||||
|
||||
import glob
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
from pymongo import MongoClient
|
||||
from test import unittest
|
||||
|
||||
|
||||
_TEST_PATH = os.path.join(
|
||||
os.path.dirname(os.path.realpath(__file__)), 'auth')
|
||||
|
||||
|
||||
class TestAuthSpec(unittest.TestCase):
|
||||
pass
|
||||
|
||||
|
||||
def create_test(test_case):
|
||||
|
||||
def run_test(self):
|
||||
uri = test_case['uri']
|
||||
valid = test_case['valid']
|
||||
auth = test_case['auth']
|
||||
options = test_case['options']
|
||||
|
||||
if not valid:
|
||||
self.assertRaises(Exception, MongoClient, uri, connect=False)
|
||||
else:
|
||||
client = MongoClient(uri, connect=False)
|
||||
credentials = client._MongoClient__options.credentials
|
||||
if auth is not None:
|
||||
self.assertEqual(credentials.username, auth['username'])
|
||||
self.assertEqual(credentials.password, auth['password'])
|
||||
self.assertEqual(credentials.source, auth['db'])
|
||||
if options is not None:
|
||||
if 'authmechanism' in options:
|
||||
self.assertEqual(
|
||||
credentials.mechanism, options['authmechanism'])
|
||||
else:
|
||||
self.assertEqual(credentials.mechanism, 'DEFAULT')
|
||||
if 'authmechanismproperties' in options:
|
||||
expected = options['authmechanismproperties']
|
||||
actual = credentials.mechanism_properties
|
||||
if 'SERVICE_NAME' in expected:
|
||||
self.assertEqual(
|
||||
actual.service_name, expected['SERVICE_NAME'])
|
||||
if 'CANONICALIZE_HOST_NAME' in expected:
|
||||
self.assertEqual(
|
||||
actual.canonicalize_host_name,
|
||||
expected['CANONICALIZE_HOST_NAME'])
|
||||
if 'SERVICE_REALM' in expected:
|
||||
self.assertEqual(
|
||||
actual.service_realm, expected['SERVICE_REALM'])
|
||||
|
||||
return run_test
|
||||
|
||||
|
||||
def create_tests():
|
||||
for filename in glob.glob(os.path.join(_TEST_PATH, '*.json')):
|
||||
test_suffix, _ = os.path.splitext(os.path.basename(filename))
|
||||
with open(filename) as auth_tests:
|
||||
test_cases = json.load(auth_tests)['tests']
|
||||
for test_case in test_cases:
|
||||
if test_case.get('optional', False):
|
||||
continue
|
||||
test_method = create_test(test_case)
|
||||
name = str(test_case['description'].lower().replace(' ', '_'))
|
||||
setattr(
|
||||
TestAuthSpec,
|
||||
'test_%s_%s' % (test_suffix, name),
|
||||
test_method)
|
||||
|
||||
|
||||
create_tests()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@ -1095,7 +1095,7 @@ class TestClient(IntegrationTest):
|
||||
|
||||
# Simulate an authenticate() call on a different socket.
|
||||
credentials = auth._build_credentials_tuple(
|
||||
'DEFAULT', 'admin', db_user, db_pwd, {})
|
||||
'DEFAULT', 'admin', db_user, db_pwd, {}, None)
|
||||
|
||||
c._cache_credentials('test', credentials, connect=False)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user