Posts Tagged ‘couchdb’

Invalid JSON in CouchDB

03 Dec

I recently upgraded from Ubuntu 12.04 to 12.10 and Ubuntu automatically upgraded my CouchDB installation from 1.0.1 to 1.2.0. After the upgrade I started getting the error message “Bad request… Invalid JSON” anytime I try to add or query an existing design document.

A lot my code depends on CouchDB so this was a big deal, after hours of googling, still no solution until I found the JSONlint test. I realized that the old JSON parser in CouchDB 1.0.1 would parse invalid JSON with no problems but the parser in CouchDB 1.2.0 would throw an error.

This code below is invalid JSON but works fine on CouchDB 1.0.1. It will throw the ‘Invalid JSON’ error on CouchDB 1.2.0

 "language" : "javascript",
 "views" :{
   "age" : {
     "map" : "function(doc){

To work on CouchDB 1.2.0 it has to be valid JSON like the code below

    "language": "javascript",
    "views": {
        "age": {
            "map": "function(doc){ if(doc.age) emit(doc.age,doc); }"

This small change fixes the problem. You can always test your JSON for validity here:


CouchDB Security in Ruby

30 Oct

To get some background on couchDB security read here.

All the code samples below, require the Restclient rubygem. You can install it with the command:

gem install rest-client

And Require it in your code with:

require 'rest_client'

Let’s say your couchDB is in Admin Party mode. To end the admin party and add an admin user:

RestClient.put '', '"ssstepin"',{:content_type => :json}

james is the name of the new admin, and his password is ssstepin. The password needs to be enclosed in double quote,to denote a string in the couchDB configuration.

To authenticate the admin user:

response = '', 'name=james&password=ssstepin',{:content_type => 'application/x-www-form-urlencoded'}
puts response.cookies
# => {"AuthSession"=>"b2tlOjRFQUJCNzE0OkXtpl9cxR_zbIxvlvW2J60txIwT", "Version"=>"1", "Path"=>"%2F"}

This returns the authentication token for making future requests, on behalf of the authenticated user.

To add a new admin user:

RestClient.put '', '"wuzz234"',{:cookies => {"AuthSession" => "b2tlOjRFQUJCNzE0OkXtpl9cxR_zbIxvlvW2J60txIwT"}}

We added a new admin david with password wuzz234, we made the request on behalf of james (see the AuthSession token, we are using the same token generated for james).

To delete the new admin user:

RestClient.delete '',{:cookies => {"AuthSession" => "b2tlOjRFQUJCNzE0OkXtpl9cxR_zbIxvlvW2J60txIwT"}}

We deleted the admin david, we made the request on behalf of james (see the AuthSession token). If you delete all admins CouchDB will switch back to Admin Party.

To create a non-admin user:

salt = "somerandomstring123"
password = "seenow109"
password_sha = Digest::SHA1.hexdigest(password + salt)
user_hash = { :type => "user",
                   :name => "nancy",
                   :password_sha => password_sha,
                   :salt => salt,
                   :roles => []
 str = Yajl::Encoder.encode(user_hash)
RestClient.put "", str, {:content_type => :json, :accept => :json}

We created the non-admin user nancy with password seenow109. The above code implements in ruby code the security features explained here. Note that non-admins are authenticated with the same API call as admins.

To create a new database with the authenticated admin user:

RestClient.put '', {:content_type => :json},{:cookies => {"AuthSession" => "b2tlOjRFQUJCNzE0OkXtpl9cxR_zbIxvlvW2J60txIwT"}}

We created a new database called contacts. This request was made by the user james, notice the AuthSession token in the request.

To add a security object to the contacts database:

security_hash = { :admins => {"names" => ["nancy"], "roles" => ["admin"]},
                   :readers => {"names" => ["nancy"],"roles"  => ["admin"]}
security = Yajl::Encoder.encode(security_hash)
response = RestClient.put '',security,{:cookies => {"AuthSession" => "b2tlOjRFQUJCNzE0OkXtpl9cxR_zbIxvlvW2J60txIwT"}}

The above example uses the yajl-ruby gem to encode the ruby hash to JSON.

To add a new document to the contacts database with the authenticated user session

data = { :name => 'sunny',
         :email => ''
 str = Yajl::Encoder.encode(data)
 RestClient.put "", str, {:cookies => {"AuthSession" => "b2tlOjRFQUJCNzE0OkXtpl9cxR_zbIxvlvW2J60txIwT"}}

We added a document with _id sunny to the contacts database. The above example also uses the yajl-ruby gem for json encoding.

I hope this was helpful. If you find any errors or have suggestions please let me know in the comments.

Premium Wordpress Plugin