def authenticate(self, name, password): """Authenticate to use this database. Once authenticated, the user has full read and write access to this database. Raises :class:`TypeError` if either `name` or `password` is not an instance of ``(str, unicode)``. Authentication lasts for the life of the underlying :class:`~pymongo.connection.Connection`, or until :meth:`logout` is called. The "admin" database is special. Authenticating on "admin" gives access to *all* databases. Effectively, "admin" access means root access to the database. .. note:: This method authenticates the current connection, and will also cause all new :class:`~socket.socket` connections in the underlying :class:`~pymongo.connection.Connection` to be authenticated automatically. - When sharing a :class:`~pymongo.connection.Connection` between multiple threads, all threads will share the authentication. If you need different authentication profiles for different purposes (e.g. admin users) you must use distinct instances of :class:`~pymongo.connection.Connection`. - To get authentication to apply immediately to all existing sockets you may need to reset this Connection's sockets using :meth:`~pymongo.connection.Connection.disconnect`. .. warning:: Currently, calls to :meth:`~pymongo.connection.Connection.end_request` will lead to unpredictable behavior in combination with auth. The :class:`~socket.socket` owned by the calling thread will be returned to the pool, so whichever thread uses that :class:`~socket.socket` next will have whatever permissions were granted to the calling thread. :Parameters: - `name`: the name of the user to authenticate - `password`: the password of the user to authenticate .. mongodoc:: authenticate """ if not isinstance(name, basestring): raise TypeError("name must be an instance of basestring") if not isinstance(password, basestring): raise TypeError("password must be an instance of basestring") nonce = self.command("getnonce")["nonce"] key = helpers._auth_key(nonce, name, password) try: self.command("authenticate", user=unicode(name), nonce=nonce, key=key) self.connection._cache_credentials(self.name, unicode(name), unicode(password)) return True except OperationFailure: return False
def copy_database(self, from_name, to_name, from_host=None, username=None, password=None): """Copy a database, potentially from another host. Raises :class:`TypeError` if `from_name` or `to_name` is not an instance of :class:`basestring` (:class:`str` in python 3). Raises :class:`~pymongo.errors.InvalidName` if `to_name` is not a valid database name. If `from_host` is ``None`` the current host is used as the source. Otherwise the database is copied from `from_host`. If the source database requires authentication, `username` and `password` must be specified. :Parameters: - `from_name`: the name of the source database - `to_name`: the name of the target database - `from_host` (optional): host name to copy from - `username` (optional): username for source database - `password` (optional): password for source database .. note:: Specifying `username` and `password` requires server version **>= 1.3.3+**. """ if not isinstance(from_name, basestring): raise TypeError("from_name must be an instance " "of %s" % (basestring.__name__, )) if not isinstance(to_name, basestring): raise TypeError("to_name must be an instance " "of %s" % (basestring.__name__, )) database._check_name(to_name) command = {"fromdb": from_name, "todb": to_name} if from_host is not None: command["fromhost"] = from_host in_request = self.in_request() try: if not in_request: self.start_request() if username is not None: nonce = self.admin.command("copydbgetnonce", fromhost=from_host)["nonce"] command["username"] = username command["nonce"] = nonce command["key"] = helpers._auth_key(nonce, username, password) return self.admin.command("copydb", **command) finally: if not in_request: self.end_request()
def authenticate(self, name, password): """Authenticate to use this database. Once authenticated, the user has full read and write access to this database. Raises :class:`TypeError` if either `name` or `password` is not an instance of ``(str, unicode)``. Authentication lasts for the life of the database connection, or until :meth:`logout` is called. The "admin" database is special. Authenticating on "admin" gives access to *all* databases. Effectively, "admin" access means root access to the database. .. note:: Currently, authentication is per :class:`~socket.socket`. This means that there are a couple of situations in which re-authentication is necessary: - On failover (when an :class:`~pymongo.errors.AutoReconnect` exception is raised). - After a call to :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 auth. The :class:`~socket.socket` owned by the calling thread will be returned to the pool, so whichever thread uses that :class:`~socket.socket` next will have whatever permissions were granted to the calling thread. :Parameters: - `name`: the name of the user to authenticate - `password`: the password of the user to authenticate .. mongodoc:: authenticate """ if not isinstance(name, basestring): raise TypeError("name must be an instance of basestring") if not isinstance(password, basestring): raise TypeError("password must be an instance of basestring") nonce = self.command("getnonce")["nonce"] key = helpers._auth_key(nonce, name, password) try: self.command("authenticate", user=unicode(name), nonce=nonce, key=key) return True except OperationFailure: return False
def copy_database(self, from_name, to_name, from_host=None, username=None, password=None): """Copy a database, potentially from another host. Raises :class:`TypeError` if `from_name` or `to_name` is not an instance of :class:`basestring` (:class:`str` in python 3). Raises :class:`~pymongo.errors.InvalidName` if `to_name` is not a valid database name. If `from_host` is ``None`` the current host is used as the source. Otherwise the database is copied from `from_host`. If the source database requires authentication, `username` and `password` must be specified. :Parameters: - `from_name`: the name of the source database - `to_name`: the name of the target database - `from_host` (optional): host name to copy from - `username` (optional): username for source database - `password` (optional): password for source database .. note:: Specifying `username` and `password` requires server version **>= 1.3.3+**. .. versionadded:: 1.5 """ if not isinstance(from_name, basestring): raise TypeError("from_name must be an instance " "of %s" % (basestring.__name__,)) if not isinstance(to_name, basestring): raise TypeError("to_name must be an instance " "of %s" % (basestring.__name__,)) database._check_name(to_name) command = {"fromdb": from_name, "todb": to_name} if from_host is not None: command["fromhost"] = from_host in_request = self.in_request() try: if not in_request: self.start_request() if username is not None: nonce = self.admin.command("copydbgetnonce", fromhost=from_host)["nonce"] command["username"] = username command["nonce"] = nonce command["key"] = helpers._auth_key(nonce, username, password) return self.admin.command("copydb", **command) finally: if not in_request: self.end_request()
def __auth(self, sock, dbname, user, passwd): """Authenticate socket `sock` against database `dbname`. """ # Get a nonce response = self.__simple_command(sock, dbname, {"getnonce": 1}) nonce = response["nonce"] key = helpers._auth_key(nonce, user, passwd) # Actually authenticate query = SON([("authenticate", 1), ("user", user), ("nonce", nonce), ("key", key)]) self.__simple_command(sock, dbname, query)
def __auth(self, sock_info, dbname, user, passwd): """Authenticate socket against database `dbname`. """ # Get a nonce response = self.__simple_command(sock_info, dbname, {'getnonce': 1}) nonce = response['nonce'] key = helpers._auth_key(nonce, user, passwd) # Actually authenticate query = SON([('authenticate', 1), ('user', user), ('nonce', nonce), ('key', key)]) self.__simple_command(sock_info, dbname, query)
def __auth(self, sock, dbname, user, passwd): """Authenticate socket `sock` against database `dbname`. """ # Get a nonce response = self.__simple_command(sock, dbname, {'getnonce': 1}) nonce = response['nonce'] key = helpers._auth_key(nonce, user, passwd) # Actually authenticate query = SON([('authenticate', 1), ('user', user), ('nonce', nonce), ('key', key)]) self.__simple_command(sock, dbname, query)
def authenticate_with_nonce(self, result, name, password, d): nonce = result['nonce'] key = helpers._auth_key(nonce, name, password) # hacky because order matters auth_command = SON(authenticate=1) auth_command['user'] = unicode(name) auth_command['nonce'] = nonce auth_command['key'] = key # Now actually authenticate df = self["$cmd"].find_one(auth_command) df.addCallback(self.authenticated, d) df.addErrback(d.errback) return df
def __auth(self, sock, dbase, user, passwd): """Athenticate `sock` against `dbase` """ # TODO: Error handling... # Get a nonce request_id, msg, _ = message.query(0, dbase + '.$cmd', 0, -1, {'getnonce': 1}) sock.sendall(msg) raw = self.__recv_msg(1, request_id, sock) nonce = helpers._unpack_response(raw)['data'][0]['nonce'] key = helpers._auth_key(nonce, user, passwd) # Actually authenticate query = {'authenticate': 1, 'user': user, 'nonce': nonce, 'key': key} request_id, msg, _ = message.query(0, dbase + '.$cmd', 0, -1, query) sock.sendall(msg) raw = self.__recv_msg(1, request_id, sock) print helpers._unpack_response(raw)['data'][0]