Skip to content

Commit 1ed7718

Browse files
committed
Don't mask authentication failure details.
These changes should make it easier to debug kerberos configuration issues on the client and server.
1 parent 1e5f334 commit 1ed7718

File tree

7 files changed

+34
-21
lines changed

7 files changed

+34
-21
lines changed

doc/changelog.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ Important new features:
1313
- Support for delegated and role based authentication.
1414
- New GEOSPHERE (2dsphere) and HASHED index constants.
1515

16+
.. note:: :meth:`~pymongo.database.Database.authenticate` now raises a
17+
subclass of :class:`~pymongo.errors.PyMongoError` if authentication
18+
fails due to invalid credentials or configuration issues.
19+
1620
Issues Resolved
1721
...............
1822

pymongo/auth.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
HAVE_KERBEROS = False
2929

3030
from bson.son import SON
31-
from pymongo.errors import OperationFailure
31+
from pymongo.errors import ConfigurationError, OperationFailure
3232

3333

3434
MECHANISMS = ('MONGODB-CR', 'GSSAPI')
@@ -164,8 +164,8 @@ def authenticate(credentials, sock_info, cmd_func):
164164
# Use a dict for this when we support more mechanisms.
165165
if mechanism == 'GSSAPI':
166166
if not HAVE_KERBEROS:
167-
raise OperationFailure('The "kerberos" module must be '
168-
'installed to use GSSAPI authentication.')
167+
raise ConfigurationError('The "kerberos" module must be '
168+
'installed to use GSSAPI authentication.')
169169
_authenticate_gssapi(username, sock_info, cmd_func)
170170
else:
171171
_authenticate_mongo_cr(username, password, source, sock_info, cmd_func)

pymongo/database.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,12 @@ def authenticate(self, name, password=None,
704704
:data:`~pymongo.auth.MECHANISMS` for options.
705705
Defaults to MONGODB-CR (MongoDB Challenge Response protocol)
706706
707+
.. versionchanged:: 2.5
708+
Added the `source` and `mechanism` parameters. :meth:`authenticate`
709+
now raises a subclass of :class:`~pymongo.errors.PyMongoError` if
710+
authentication fails due to invalid credentials or configuration
711+
issues.
712+
707713
.. mongodoc:: authenticate
708714
"""
709715
if not isinstance(name, basestring):
@@ -717,13 +723,10 @@ def authenticate(self, name, password=None,
717723
"of %s" % (basestring.__name__,))
718724
common.validate_auth_mechanism('mechanism', mechanism)
719725

720-
try:
721-
credentials = (source or self.name, unicode(name),
722-
password and unicode(password) or None, mechanism)
723-
self.connection._cache_credentials(self.name, credentials)
724-
return True
725-
except OperationFailure:
726-
return False
726+
credentials = (source or self.name, unicode(name),
727+
password and unicode(password) or None, mechanism)
728+
self.connection._cache_credentials(self.name, credentials)
729+
return True
727730

728731
def logout(self):
729732
"""Deauthorize use of this database for this client instance.

pymongo/mongo_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,8 +350,8 @@ def __init__(self, host=None, port=None, max_pool_size=10,
350350
unicode(password), mechanism)
351351
try:
352352
self._cache_credentials(source, credentials)
353-
except OperationFailure:
354-
raise ConfigurationError("authentication failed")
353+
except OperationFailure, exc:
354+
raise ConfigurationError(str(exc))
355355

356356
def _cached(self, dbname, coll, index):
357357
"""Test if `index` is cached.

pymongo/mongo_replica_set_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -530,8 +530,8 @@ def __init__(self, hosts_or_uri=None, max_pool_size=10,
530530
unicode(password), mechanism)
531531
try:
532532
self._cache_credentials(source, credentials)
533-
except OperationFailure:
534-
raise ConfigurationError("authentication failed")
533+
except OperationFailure, exc:
534+
raise ConfigurationError(str(exc))
535535

536536
# Start the monitor after we know the configuration is correct.
537537
if monitor_class:

test/test_auth.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,9 @@ def test_delegated_auth(self):
240240
self.assertRaises(OperationFailure,
241241
self.client.pymongo_test2.foo.find_one)
242242
# Auth must occur on the db where the user is defined.
243-
self.assertFalse(self.client.pymongo_test2.authenticate('user',
244-
'pass'))
243+
self.assertRaises(OperationFailure,
244+
self.client.pymongo_test2.authenticate,
245+
'user', 'pass')
245246
# Auth directly
246247
self.assertTrue(self.client.pymongo_test.authenticate('user', 'pass'))
247248
self.assertTrue(self.client.pymongo_test2.foo.find_one())

test/test_database.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -319,22 +319,27 @@ def test_authenticate_add_remove_user(self):
319319
self.assertRaises(TypeError, db.authenticate, 5, "password")
320320
self.assertRaises(TypeError, db.authenticate, "mike", 5)
321321

322-
self.assertFalse(db.authenticate("mike", "not a real password"))
323-
self.assertFalse(db.authenticate("faker", "password"))
322+
self.assertRaises(OperationFailure,
323+
db.authenticate, "mike", "not a real password")
324+
self.assertRaises(OperationFailure,
325+
db.authenticate, "faker", "password")
324326
self.assertTrue(db.authenticate("mike", "password"))
325327
self.assertTrue(db.authenticate(u"mike", u"password"))
326328
db.logout()
327329

328330
db.remove_user("mike")
329-
self.assertFalse(db.authenticate("mike", "password"))
331+
self.assertRaises(OperationFailure,
332+
db.authenticate, "mike", "password")
330333

331-
self.assertFalse(db.authenticate("Gustave", u"Dor\xe9"))
334+
self.assertRaises(OperationFailure,
335+
db.authenticate, "Gustave", u"Dor\xe9")
332336
db.add_user("Gustave", u"Dor\xe9")
333337
self.assertTrue(db.authenticate("Gustave", u"Dor\xe9"))
334338
db.logout()
335339

336340
db.add_user("Gustave", "password")
337-
self.assertFalse(db.authenticate("Gustave", u"Dor\xe9"))
341+
self.assertRaises(OperationFailure,
342+
db.authenticate, "Gustave", u"Dor\xe9")
338343
self.assertTrue(db.authenticate("Gustave", u"password"))
339344
db.logout()
340345

0 commit comments

Comments
 (0)