From 984140fe84658a88b1370c7ec76fbc8d72357843 Mon Sep 17 00:00:00 2001 From: Frol Date: Sun, 13 Jun 2010 21:32:26 +0300 Subject: [PATCH] SUCKS-FIX: Need for Pylons and Beaker sessions. Auto force authenticate for each request of connection --- pymongo/connection.py | 4 ++++ pymongo/database.py | 34 +++++++++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/pymongo/connection.py b/pymongo/connection.py index ab3938bbef..53ac4de358 100644 --- a/pymongo/connection.py +++ b/pymongo/connection.py @@ -167,6 +167,7 @@ def __init__(self, host=None, port=None, pool_size=None, self.__host = None self.__port = None + self.connected = False self.__nodes = [(host, port)] self.__slave_okay = slave_okay @@ -468,8 +469,10 @@ def __connect(self): sock.settimeout(_CONNECT_TIMEOUT) sock.connect((self.__host, self.__port)) sock.settimeout(self.__network_timeout) + self.connected = True return sock except socket.error: + self.connected = False raise AutoReconnect("could not connect to %r" % self.__nodes) def disconnect(self): @@ -485,6 +488,7 @@ def disconnect(self): .. seealso:: :meth:`end_request` .. versionadded:: 1.3 """ + self.connected = False self.__pool = Pool(self.__connect) def _reset(self): diff --git a/pymongo/database.py b/pymongo/database.py index ef10d666bd..a5f9b92fe6 100644 --- a/pymongo/database.py +++ b/pymongo/database.py @@ -65,6 +65,9 @@ def __init__(self, connection, name): self.__name = unicode(name) self.__connection = connection + self.__authenticating = False + self.__username = None + self.__password = None self.__incoming_manipulators = [] self.__incoming_copying_manipulators = [] @@ -111,9 +114,14 @@ def connection(self): """The :class:`~pymongo.connection.Connection` instance for this :class:`Database`. + .. versionchanged:: 1.6+ + when requested connetion use auto authentication + .. versionchanged:: 1.3 ``connection`` is now a property rather than a method. """ + if self.__connection.connected: + self.authenticate() return self.__connection @property @@ -459,7 +467,7 @@ def remove_user(self, name): """ self.system.users.remove({"user": name}, safe=True) - def authenticate(self, name, password): + def authenticate(self, name=None, password=None): """Authenticate to use this database. Once authenticated, the user has full read and write access to @@ -484,10 +492,6 @@ def authenticate(self, name, password): :meth:`~pymongo.connection.Connection.disconnect` or :meth:`~pymongo.connection.Connection.end_request`. - - When sharing a :class:`~pymongo.connection.Connection` - between multiple threads, each thread will need to - authenticate separately. - .. warning:: Currently, calls to :meth:`~pymongo.connection.Connection.end_request` will lead to unpredictable behavior in combination with @@ -502,6 +506,24 @@ def authenticate(self, name, password): .. mongodoc:: authenticate """ + # lock for prevent the recursion + if self.__authenticating: + return + self.__authenticating = True + + # if name is None then use previous saved username and password + # else save current name and password + if name is None and self.__username is None: + # authentication not need + self.__authenticating = False + return + elif name is None: + name = self.__username + password = self.__password + else: + self.__username = name + self.__password = password + if not isinstance(name, basestring): raise TypeError("name must be an instance of basestring") if not isinstance(password, basestring): @@ -512,8 +534,10 @@ def authenticate(self, name, password): try: self.command("authenticate", user=unicode(name), nonce=nonce, key=key) + self.__authenticating = False return True except OperationFailure: + self.__authenticating = False return False def logout(self):