txmongo
txmongo copied to clipboard
txmongo.collection.Collection#rename() without admin DB
Hi there,
I was trying to use txmongo.collection.Collection#rename()
with a user without admin permissions. This can be done in Mongo just fine without admin permissions, as you can do db.collection.renameCollection()
within a db you have rw permissions from in the mongo repl. Looking at the source for txmongo.collection.Collection#rename()
, it does an admin command by default. Can this be switched to use the non-admin one by default and perhaps a flag for the admin version or a different method?
Hi,
I've just checked if txmongo's rename
works for a user with single role "roles" : [ { "role" : "readWrite", "db" : "mydb" } ]
and it does well.
According to the docs, renameCollection
command should always be issued against admin
database. Nevertheless it should work as long as you have readWrite
role for a given DB (and if you are renaming collection inside this db, not moving it to another one).
If you look into the source code of REPL's renameCollection
you can see that it issues the command against admin
DB too:
> db.coll.renameCollection
function (newName, dropTarget) {
if (arguments.length === 1 && typeof newName === 'object') {
if (newName.hasOwnProperty('dropTarget')) {
dropTarget = newName['dropTarget'];
}
newName = newName['to'];
}
if (typeof dropTarget === 'undefined') {
dropTarget = false;
}
if (typeof newName !== 'string' || typeof dropTarget !== 'boolean') {
throw Error(
'renameCollection must either take a string and an optional boolean or an object.');
}
return this._db._adminCommand({
renameCollection: this._fullName,
to: this._db._name + "." + newName,
dropTarget: dropTarget
});
}
> db.adminCommand
function (obj, extra) {
if (this._name == "admin")
return this.runCommand(obj, extra);
return this.getSiblingDB("admin").runCommand(obj, extra);
}
Please check what roles does your DB user have and correct me if I'm wrong.
So I am using a user with dbOwner
permissions on a specific DB, but no role for the admin and I am geting a permissions issue. mongo has two renameCollection's the one you linked and this one. In the latter, it is exec'd on the selected DB, not requiring rw to admin.
Sorry, but I can't reproduce the issue.
I tried as follows:
- Started fresh clean MongoDB 3.4 instance (
docker run --rm -it -p 27017:27017 mongo --auth
) - Ran
mongo admin
and did:db.createUser({user: 'userAdmin', pwd: 'qwe', roles:[{role: 'userAdminAnyDatabase', db: 'admin'}]})
- Ran
mongo -u userAdmin -p qwe admin
and did:db.createUser({user: 'test', pwd: 'test', roles:[{role: 'dbOwner', db: 'test'}]})
- Ran this python code:
from twisted.internet.task import react
from twisted.internet import defer
from txmongo.connection import ConnectionPool
@defer.inlineCallbacks
def main(reactor):
conn = ConnectionPool('mongodb://test:test@localhost/test')
yield conn.test.qwe.insert({'x': 42})
yield conn.test.qwe.rename('rty')
result = yield conn.test.rty.find()
print result
yield conn.disconnect()
react(main)
It printed [{u'x': 42}]
as expected and rty
collection remains in the database
mongo has two renameCollection's
They are actually the same: first one is the low-level DB command, second one is Mongo Shell's wrapper written in JavaScript. I've cited its source code above and you can see that it simply runs underlying renameCollection
DB command.
Could you please try to reproduce the issue on a clean database and publish DB's user accounts setup and testing code?