2

I have created the _users database as well as the _security document and set the security appropriately according to https://cloudant.com/for-developers/faq/auth/.

I have then created a user "test" with role "_reader" however when I try to log in to Cloudant it does not recognize the user.

_users database contains one document:

{
  "_id": "test",
  "_rev": "1-96973497bc9c89989c4beed02e3f0b96",
  "name": "test",
  "roles": [
    "_reader"
  ],
  "type": "user",
  "password": "password"
}

I was then trying to view a design document using username "test" and password "password", as created above, however it did not work.

Within the security document of the database where the design document is located I have:

{ "couchdb_auth_only": true, "members": { "names": [ "test" ], "roles": [ "_reader" ] } }

Any suggestions?

Thanks!

Julie
  • 65
  • 1
  • 11
  • have you seen this post: http://stackoverflow.com/questions/18039704/cloudant-auth-lacks-users-database? – Chris Snow Oct 15 '15 at 22:07
  • Yes, I saw that post. I have searched the internet for hours and don't understand how to set this up. That post is from a few years ago and was not helpful to me at all. The github link is way too complex for me to understand. – Julie Oct 16 '15 at 02:16
  • I don't know node.js. Is there some java code that could hash the password similarly or something? Or just simplified javascript... idk. – Julie Oct 16 '15 at 02:22

2 Answers2

6

I haven't tested this with Cloudant, and I haven't verified the security of this approach with a cryptography expert (please do this), but hopefully it may point you in the right direction:

First you need to generate a salt and a password_sha:

    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    import java.util.Random;

    public class CouchPassword {

        public static void main(String[] args) throws NoSuchAlgorithmException {

            String password = "123456"; // your password        
            String salt = genSalt();
            password = password + salt;

            MessageDigest md = MessageDigest.getInstance("SHA1");
            md.update(password.getBytes());
            byte byteData[] = md.digest();

            System.out.println("Password SHA:   " + byteToHexString(byteData) );
            System.out.println("Generated Salt: " + salt);
        }
        public static String genSalt() {
            Random ranGen = new SecureRandom();
            byte[] salt = new byte[16];
            ranGen.nextBytes(salt);
            return byteToHexString(salt);
        }
        public static String byteToHexString(byte[] b) {    
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < b.length; i++) {
             sb.append(Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1));
            }
            return sb.toString();
        }
    }
    // There are libraries to help with generating SHAs and Hex Strings
    // but I have choosen not to use those here so the answer is more standalone.

Set the above password string to the required value, and execute. E.g.

    Password SHA:   316ccb0df3c8bbd8f568347827803682d2c93849
    Generated Salt: bba45713ef54016c8ef4b56b6b147936

Create the _user and _security document (option 1):

   // _user
    {
           "_id"          : "org.couchdb.user:joe",
           "type"         : "user",
           "name"         : "joe",
           "roles"        : ["standarduser"],
           "password_sha" : "316ccb0df3c8bbd8f568347827803682d2c93849",
          "salt"         : "bba45713ef54016c8ef4b56b6b147936"
    }

The roles from the _users document map to roles defined in the _security document.

// _security
{
   "couchdb_auth_only": true,
   "members": {
     "names": [],
     "roles": ["standarduser"]
   },
   "admins": {}
 }

From the CouchDB documentation

  • database members - Defined per database. They can read all types of documents from the DB, and they can write (and edit) documents to the DB except for design documents.

  • database admins - Defined per database. They have all the privileges members have plus the privileges: write (and edit) design documents, add/remove database admins and members, set the database revisions limit (/somedb/_revs_limit API) and execute temporary views against the database (/somedb/_temp_view API). They can not create a database and neither delete a database.

In my example, my user joe has been given the role standarduser which maps to a database member for the database.

Create the _user and _security document (option 2):

Note that instead of using roles, I could have specified member.names:

// _user document
{
  "_id"          : "org.couchdb.user:joe",
  "type"         : "user",
  "name"         : "joe",
  "password_sha" : "316ccb0df3c8bbd8f568347827803682d2c93849",
  "salt"         : "bba45713ef54016c8ef4b56b6b147936"
}

// _security document
{
  "couchdb_auth_only": true,
  "members": {
    "names": ["joe"],
    "roles": []
  },
  "admins": {}
}

Warning

Ensure both member.names and member.roles parameters are not empty as this will grant read and write access to everyone:

{
  "couchdb_auth_only": true,
  "members": {
    "names": [],
    "roles": []
  },
  "admins": {}
}

Having no members, any user can write regular documents (any non-design document) and read documents from the database.

Source: http://wiki.apache.org/couchdb/Security_Features_Overview

Chris Snow
  • 23,813
  • 35
  • 144
  • 309
1

Julie-- In Apache CouchDB, you currently have to use a validation function to enable read-only access. (There isn't a "turn-key" user role that will give you what I think you're asking for.)

In particular, I found this thread helpful: https://stackoverflow.com/a/10713843/1459475

It links to the official CouchDB book section on Validation Functions: http://guide.couchdb.org/draft/validation.html as well as a JavaScript example and an explanation: https://github.com/iriscouch/manage_couchdb/blob/master/js/validate_doc_update.js https://github.com/iriscouch/manage_couchdb#an-easy-validation-function

In Cloudant, read-only access is a little more straightforward with API keys, but you can still implement read-only access with out-of-the-box CouchDB. It's just not as turnkey as you might expect. Good luck!

Community
  • 1
  • 1
brobes
  • 706
  • 3
  • 7