Export to GitHub

couchdb-python - issue #238

_security object is an exception to the document model


Posted on Jun 14, 2014 by Massive Elephant

What steps will reproduce the problem? 1. Instantiate server: server = couchdb.client.Server("http://admin:password@localhost:5984") 2. Try to set the _security object for a database you have admin privileges for: server['test']['_security']={'members':{'names':[],'roles':['meow']},'admins':{'names':[],'roles':[]}}

What is the expected output? What do you see instead? The expected outcome is that the method should return successfully, what happens is that an error is thrown:

>>> server['test']['_security']={'members':{'names':[],'roles':['meow']},'admins':{'names':[],'roles':[]}} Traceback (most recent call last): File "<stdin>", line 1, in <module> File "couchdb/client.py", line 351, in setitem content.update({'_id': data['id'], '_rev': data['rev']}) KeyError: 'id'

This is likely due to the fact that the returned document does not have a _id or _rev attribute. This is because the security document is not a real document and does not follow the same rules as other documents in the database.

What version of the product are you using? On what operating system?

CouchDB 1.6 on Mac OS X using the latest version of couchdb-python in the repo.

Comment #1

Posted on Jun 15, 2014 by Massive Elephant

This issue could be resolved pretty easily by adding a check right before the affected line of code (351 of client.py):

if 'id' in data and 'rev' in data: content.update({'_id': data['id'], '_rev': data['rev']})

Comment #2

Posted on Jun 29, 2014 by Quick Rhino

That solves one use case, but I think we have other problems with security objects as well (i.e. just with receiving them?). We should try to solve all of them, but I'm not sure what API would make sense. Maybe there should be dedicated API.

Comment #3

Posted on Jul 1, 2014 by Massive Elephant

Yes, it does fail on retrieval as well. Maybe an API like this:

db = server['meow'] db.readers.users = ['kitty'] db.admins.roles = ['poopsykins']

OR, this would be faster to execute in a single request:

db.security = { 'readers':{'users':['kitty']}, 'admins':{'roles':['poopsykins']} }

Comment #4

Posted on Jul 1, 2014 by Quick Rhino

Yeah, I think a db.security attribute could work pretty well.

Comment #5

Posted on Jul 6, 2014 by Quick Rhino

Okay, a very basic implementation is in r7cd158aa7c1b. Please check whether this fulfills your use cases.

Status: Fixed

Labels:
Type-Defect Priority-Medium