Exemple #1
0
    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

        try:
            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"] = auth._auth_key(nonce, username, password)

            return self.admin.command("copydb", **command)
        finally:
            self.end_request()
Exemple #2
0
    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

        try:
            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"] = auth._auth_key(nonce, username, password)

            return self.admin.command("copydb", **command)
        finally:
            self.end_request()
Exemple #3
0
def test_pymongo():
    response = b"%s%s%s%s%s" % (struct.pack("<i", 4), struct.pack(
        "<q", 1), struct.pack("<i", 1), struct.pack(
            "<i", 1), bson.BSON.encode({"hello": "world"}))
    assert asynmongo._unpack_response(response, 1) == {
        'starting_from': 1,
        'number_returned': 1,
        'cursor_id': 1,
        'data': [{
            'hello': 'world'
        }]
    }

    payload = bson.BSON.encode({"hello": "world"})
    response = b"%s%s%s" % (struct.pack(
        "<B", 0), struct.pack("<i", len(payload)), payload)
    assert asynmongo._unpack_response(response, 2013) == {
        'first_payload_type': 0,
        'data': [{
            'hello': 'world'
        }],
        'first_payload_size': 22
    }

    opts = CodecOptions(SON)
    assert auth._auth_key(1, "a", "b") == "90b38d5dbfabd0b883e17ae67847220a"
    assert message.query(0, "%s.$cmd" % "mydb", 0, 1, SON({
        'getnonce': 1
    }), SON({}), opts) == (
        1804289383,
        b'>\x00\x00\x00gE\x8bk\x00\x00\x00\x00\xd4\x07\x00\x00\x00\x00\x00\x00mydb.$cmd\x00\x00\x00\x00\x00\x01\x00\x00\x00\x13\x00\x00\x00\x10getnonce\x00\x01\x00\x00\x00\x00\x05\x00\x00\x00\x00',
        19)
    assert message.query(0, "col.a", 0, 1, {"_id": 1}, None, opts) == (
        846930886,
        b'0\x00\x00\x00\xc6#{2\x00\x00\x00\x00\xd4\x07\x00\x00\x00\x00\x00\x00col.a\x00\x00\x00\x00\x00\x01\x00\x00\x00\x0e\x00\x00\x00\x10_id\x00\x01\x00\x00\x00\x00',
        14)
    assert message.update("col.a", 0, 0, {"_id": 1}, {
        "a": 1
    }, 1, (), False, opts) == (
        1681692777,
        b'8\x00\x00\x00i\x98<d\x00\x00\x00\x00\xd1\x07\x00\x00\x00\x00\x00\x00col.a\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x10_id\x00\x01\x00\x00\x00\x00\x0c\x00\x00\x00\x10a\x00\x01\x00\x00\x00\x00<\x00\x00\x00i\x98<d\x00\x00\x00\x00\xd4\x07\x00\x00\x00\x00\x00\x00col.$cmd\x00\x00\x00\x00\x00\xff\xff\xff\xff\x17\x00\x00\x00\x10getlasterror\x00\x01\x00\x00\x00\x00',
        14)

    msg = message.delete("col.a", {"_id": 1}, 1, (), opts, 0)
    assert len(msg) == 3 and msg[0] == 1714636915 and msg[-1] == 14

    msg = message.insert("col.a", [{"a": 1}], False, 1, (), 0, opts)
    assert len(msg) == 3 and msg[0] == 1957747793 and msg[-1] == 12
Exemple #4
0
    def authenticate_with_nonce(self, result, name, password, d):
        nonce = result['nonce']
        key = auth._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
Exemple #5
0
    def authenticate_mongo_cr(self, database_name, username, password):
        result = yield self.__run_command(database_name, {"getnonce": 1})

        if not result["ok"]:
            raise MongoAuthenticationError(result["errmsg"])

        nonce = result["nonce"]

        auth_cmd = SON(authenticate=1)
        auth_cmd["user"] = unicode(username)
        auth_cmd["nonce"] = nonce
        auth_cmd["key"] = auth._auth_key(nonce, username, password)

        result = yield self.__run_command(database_name, auth_cmd)

        if not result["ok"]:
            raise MongoAuthenticationError(result["errmsg"])

        defer.returnValue(result)
Exemple #6
0
    def authenticate_mongo_cr(self, database_name, username, password):
        result = yield self.__run_command(database_name, {"getnonce": 1})

        if not result["ok"]:
            raise MongoAuthenticationError(result["errmsg"])

        nonce = result["nonce"]

        auth_cmd = SON(authenticate=1)
        auth_cmd["user"] = unicode(username)
        auth_cmd["nonce"] = nonce
        auth_cmd["key"] = auth._auth_key(nonce, username, password)

        result = yield self.__run_command(database_name, auth_cmd)

        if not result["ok"]:
            raise MongoAuthenticationError(result["errmsg"])

        defer.returnValue(result)
    def authenticate_with_nonce (self,database,name,password) :

        database_name = str(database)
        self.cred_cache[database_name] = (name,password)
        current_connection = self.__pool[self.__index]
        proto = yield self.getprotocol()

        collection_name = database_name+'.$cmd'
        query = Query(collection=collection_name, query={'getnonce': 1})
        result = yield proto.send_QUERY(query)
           
        result = result.documents[0].decode()
        
        if result["ok"] :
            nonce = result["nonce"]
        else :
            defer.returnValue(result["errmsg"])
        
        key = auth._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

        query = Query(collection=str(collection_name), query=auth_command)
        result = yield proto.send_QUERY(query)
                
        result = result.documents[0].decode()
                
        if result["ok"]:
            database._authenticated = True
            current_connection.auth_set.add(database_name)
            defer.returnValue(result["ok"])
        else:
            del self.cred_cache[database_name]
            defer.returnValue(result["errmsg"])
    def authenticate_with_nonce(self, database, name, password):

        database_name = str(database)
        self.cred_cache[database_name] = (name, password)
        current_connection = self.__pool[self.__index]
        proto = yield self.getprotocol()

        collection_name = database_name + '.$cmd'
        query = Query(collection=collection_name, query={'getnonce': 1})
        result = yield proto.send_QUERY(query)

        result = result.documents[0].decode()

        if result["ok"]:
            nonce = result["nonce"]
        else:
            defer.returnValue(result["errmsg"])

        key = auth._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

        query = Query(collection=str(collection_name), query=auth_command)
        result = yield proto.send_QUERY(query)

        result = result.documents[0].decode()

        if result["ok"]:
            database._authenticated = True
            current_connection.auth_set.add(database_name)
            defer.returnValue(result["ok"])
        else:
            del self.cred_cache[database_name]
            defer.returnValue(result["errmsg"])
Exemple #9
0
def _copy_database(fromdb, todb, fromhost, mechanism, username, password,
                   sock_info, cmd_func):
    """Copy a database, perhaps from a remote host.

    :Parameters:
      - `fromdb`: Source database.
      - `todb`: Target database.
      - `fromhost`: Source host like 'foo.com', 'foo.com:27017', or None.
      - `mechanism`: An authentication mechanism.
      - `username`: A str or unicode, or None.
      - `password`: A str or unicode, or None.
      - `sock_info`: A SocketInfo instance.
      - `cmd_func`: A callback taking args sock_info, database, command doc.
    """
    if not isinstance(fromdb, str):
        raise TypeError('from_name must be an instance '
                        'of %s' % (str.__name__, ))
    if not isinstance(todb, str):
        raise TypeError('to_name must be an instance '
                        'of %s' % (str.__name__, ))

    _check_database_name(todb)

    warnings.warn(
        "copy_database is deprecated. Use the raw 'copydb' command"
        " or db.copyDatabase() in the mongo shell. See"
        " doc/examples/copydb.",
        DeprecationWarning,
        stacklevel=2)

    # It would be better if the user told us what mechanism to use, but for
    # backwards compatibility with earlier PyMongos we don't require the
    # mechanism. Hope 'fromhost' runs the same version as the target.
    if mechanism == 'DEFAULT':
        if sock_info.max_wire_version >= 3:
            mechanism = 'SCRAM-SHA-1'
        else:
            mechanism = 'MONGODB-CR'

    if username is not None:
        if mechanism == 'SCRAM-SHA-1':
            credentials = auth._build_credentials_tuple(mech=mechanism,
                                                        source='admin',
                                                        user=username,
                                                        passwd=password,
                                                        extra=None)

            try:
                auth._copydb_scram_sha1(credentials=credentials,
                                        sock_info=sock_info,
                                        cmd_func=cmd_func,
                                        fromdb=fromdb,
                                        todb=todb,
                                        fromhost=fromhost)
            except OperationFailure as exc:
                errmsg = exc.details and exc.details.get('errmsg') or ''
                if 'no such cmd: saslStart' in errmsg:
                    explanation = ("%s doesn't support SCRAM-SHA-1, pass"
                                   " mechanism='MONGODB-CR' to copy_database" %
                                   fromhost)

                    raise OperationFailure(explanation, exc.code, exc.details)
                else:
                    raise

        elif mechanism == 'MONGODB-CR':
            get_nonce_cmd = SON([('copydbgetnonce', 1),
                                 ('fromhost', fromhost)])

            get_nonce_response, _ = cmd_func(sock_info, 'admin', get_nonce_cmd)
            nonce = get_nonce_response['nonce']
            copydb_cmd = SON([('copydb', 1), ('fromdb', fromdb),
                              ('todb', todb)])

            copydb_cmd['username'] = username
            copydb_cmd['nonce'] = nonce
            copydb_cmd['key'] = auth._auth_key(nonce, username, password)
            if fromhost is not None:
                copydb_cmd['fromhost'] = fromhost

            cmd_func(sock_info, 'admin', copydb_cmd)
        else:
            raise InvalidOperation('Authentication mechanism %r not supported'
                                   ' for copy_database' % mechanism)
    else:
        # No username.
        copydb_cmd = SON([('copydb', 1), ('fromdb', fromdb), ('todb', todb)])

        if fromhost:
            copydb_cmd['fromhost'] = fromhost

        cmd_func(sock_info, 'admin', copydb_cmd)
Exemple #10
0
def _copy_database(
        fromdb,
        todb,
        fromhost,
        mechanism,
        username,
        password,
        sock_info,
        cmd_func):
    """Copy a database, perhaps from a remote host.

    :Parameters:
      - `fromdb`: Source database.
      - `todb`: Target database.
      - `fromhost`: Source host like 'foo.com', 'foo.com:27017', or None.
      - `mechanism`: An authentication mechanism.
      - `username`: A str or unicode, or None.
      - `password`: A str or unicode, or None.
      - `sock_info`: A SocketInfo instance.
      - `cmd_func`: A callback taking args sock_info, database, command doc.
    """
    if not isinstance(fromdb, basestring):
        raise TypeError('from_name must be an instance '
                        'of %s' % (basestring.__name__,))
    if not isinstance(todb, basestring):
        raise TypeError('to_name must be an instance '
                        'of %s' % (basestring.__name__,))

    _check_database_name(todb)

    warnings.warn("copy_database is deprecated. Use the raw 'copydb' command"
                  " or db.copyDatabase() in the mongo shell. See"
                  " doc/examples/copydb.",
                  DeprecationWarning, stacklevel=2)

    # It would be better if the user told us what mechanism to use, but for
    # backwards compatibility with earlier PyMongos we don't require the
    # mechanism. Hope 'fromhost' runs the same version as the target.
    if mechanism == 'DEFAULT':
        if sock_info.max_wire_version >= 3:
            mechanism = 'SCRAM-SHA-1'
        else:
            mechanism = 'MONGODB-CR'

    if username is not None:
        if mechanism == 'SCRAM-SHA-1':
            credentials = auth._build_credentials_tuple(mech=mechanism,
                                                        source='admin',
                                                        user=username,
                                                        passwd=password,
                                                        extra=None)

            try:
                auth._copydb_scram_sha1(credentials=credentials,
                                        sock_info=sock_info,
                                        cmd_func=cmd_func,
                                        fromdb=fromdb,
                                        todb=todb,
                                        fromhost=fromhost)
            except OperationFailure, exc:
                errmsg = exc.details and exc.details.get('errmsg') or ''
                if 'no such cmd: saslStart' in errmsg:
                    explanation = (
                        "%s doesn't support SCRAM-SHA-1, pass"
                        " mechanism='MONGODB-CR' to copy_database" % fromhost)

                    raise OperationFailure(explanation,
                                           exc.code,
                                           exc.details)
                else:
                    raise

        elif mechanism == 'MONGODB-CR':
            get_nonce_cmd = SON([('copydbgetnonce', 1),
                                 ('fromhost', fromhost)])

            get_nonce_response, _ = cmd_func(sock_info, 'admin', get_nonce_cmd)
            nonce = get_nonce_response['nonce']
            copydb_cmd = SON([('copydb', 1),
                              ('fromdb', fromdb),
                              ('todb', todb)])

            copydb_cmd['username'] = username
            copydb_cmd['nonce'] = nonce
            copydb_cmd['key'] = auth._auth_key(nonce, username, password)
            if fromhost is not None:
                copydb_cmd['fromhost'] = fromhost

            cmd_func(sock_info, 'admin', copydb_cmd)
        else:
            raise InvalidOperation('Authentication mechanism %r not supported'
                                   ' for copy_database' % mechanism)