Search code examples
pythoncouchdbcouchdb-python

Managing users in _users with couchdb-python


I'm trying to store and retrieve user from the database _users using couchdb-python. I'm a beginner here with couchdb.

I mapped the python class User with couchdb Document couchdb.mapping.Document like this:

import couchdb.mapping as cmap


class User(cmap.Document):
    name = cmap.TextField()
    password = cmap.TextField()
    type = 'user'
    roles = {}

but this is not working. I got doc.type must be user ServerError so probably the way I'm declaring the type is not correct.

How should I construct my class to be used with the _users database?


Solution

  • After some hints from the #couchdb channel on IRC I came out with this class (that's probably more than I was asking...)

    import couchdb.mapping as cmap
    
    class User(cmap.Document):
        """  Class used to map a user document inside the '_users' database to a
        Python object.
    
        For better understanding check https://wiki.apache.org
            /couchdb/Security_Features_Overview
    
        Args:
            name: Name of the user
            password: password of the user in plain text
            type: (Must be) 'user'
            roles: Roles for the users
    
        """
    
        def __init__(self, **values):
            # For user in the _users database id must be org.couchdb.user:<name>
            # Here we're auto-generating it.
            if 'name' in values:
                _id = 'org.couchdb.user:{}'.format(values['name'])
                cmap.Document.__init__(self, id=_id, **values)
    
        type = cmap.TextField(default='user')
        name = cmap.TextField()
        password = cmap.TextField()
        roles = cmap.ListField(cmap.TextField())
    
        @cmap.ViewField.define('users')
        def default(doc):
            if doc['name']:
                yield doc['name'], doc
    

    This should work:

    db = couchdb.server()['_users']
    alice = User(name="Alice", password="strongpassword")
    alice.store(db)