> http://github.com/jchris/couchdb/tree/readeracl
I have tried out the readeracl branch, and I have the following
observations.
Firstly, the practical problems.
(1) There is no Futon interface to _readers, at least I couldn't find one.
But fortunately curl with HTTP basic auth works (you don't have to mess with
cookies). So I was able to access the _readers resource using server admin
credentials.
(2) Databases you cannot read are still listed in _all_dbs. As a result, the
Overview page in Futon pops up an error dialog saying "Database information
could not be retrieved: You are not authorized to access this db."
(3) More seriously, I was able to break it like this:
$ curl -d '{"users":["brian"]}' -X PUT
http://admin:[email protected]:5984/testdb/_readers
{"ok":true}
$ curl http://127.0.0.1:5984/testdb/_readers
{"error":"json_encode","reason":"{bad_term,{<<\"names\">>,[]}}"}
[error] [<0.1471.0>] Uncaught error in HTTP request: {exit,
{json_encode,
{bad_term,{<<"names">>,[<<"brian">>]}}}}
[info] [<0.1471.0>] Stacktrace: [{couch_util,'-json_encode/1-fun-0-',1},
{mochijson2,json_encode,2},
{mochijson2,'-json_encode_array/2-fun-0-',3},
{lists,foldl,3},
{mochijson2,json_encode_array,2},
{couch_httpd,send_json,4},
{couch_httpd_db,do_db_req,2},
{couch_httpd,handle_request,5}]
Obviously I put "users" instead of "names" here, which was my bad.
So I tried deleting and recreating the database, with I think the correct
format of _readers, but to no avail:
$ curl -X DELETE http://admin:[email protected]:5984/testdb
{"ok":true}
$ curl -X PUT http://admin:[email protected]:5984/testdb
{"ok":true}
$ curl -X PUT -d '{"hello":"world"}'
http://admin:[email protected]:5984/testdb/doc1
{"ok":true,"id":"doc1","rev":"1-15f65339921e497348be384867bb940f"}
$ curl -X PUT -d '{"names":["brian"],"roles":[]}'
http://admin:[email protected]:5984/testdb/_readers
{"ok":true}
$ curl http://admin:[email protected]:5984/testdb/_readers
{"error":"json_encode","reason":"{bad_term,{<<\"names\">>,[<<\"brian\">>]}}"}
Even creating a brand new database with a different name was the same.
Restarting the database didn't make a difference either.
Apache CouchDB 0.11.0bd9c04422-git (LogLevel=info) is starting.
Apache CouchDB has started. Time to relax.
[info] [<0.32.0>] Apache CouchDB has started on http://127.0.0.1:5984/
[error] [<0.112.0>] ReadersPtr 4183
[error] [<0.112.0>] Readers [{<<"names">>,[<<"brian">>]},{<<"roles">>,[]}]
[error] [<0.96.0>] Uncaught error in HTTP request: {exit,
{json_encode,
{bad_term,{<<"names">>,[<<"brian">>]}}}}
[info] [<0.96.0>] Stacktrace: [{couch_util,'-json_encode/1-fun-0-',1},
{mochijson2,json_encode,2},
{mochijson2,'-json_encode_array/2-fun-0-',3},
{lists,foldl,3},
{mochijson2,json_encode_array,2},
{couch_httpd,send_json,4},
{couch_httpd_db,do_db_req,2},
{couch_httpd,handle_request,5}]
[info] [<0.96.0>] 127.0.0.1 - - 'GET' /test2/_readers 500
Notice the [error] on startup about the Readers.
I even deleted var/lib/couchdb/*.couch (apart from _users) and restarted
couchdb, same problem:
[info] [<0.160.0>] 127.0.0.1 - - 'PUT' /test3 201
[info] [<0.188.0>] 127.0.0.1 - - 'PUT' /test3/doc1 201
[info] [<0.208.0>] 127.0.0.1 - - 'GET' /test3/_readers 200
[info] [<0.222.0>] 127.0.0.1 - - 'PUT' /test3/_readers 200
[error] [<0.242.0>] Uncaught error in HTTP request: {exit,
{json_encode,{bad_term,{<<"names">>,[]}}}}
[info] [<0.242.0>] Stacktrace: [{couch_util,'-json_encode/1-fun-0-',1},
{mochijson2,json_encode,2},
{mochijson2,'-json_encode_array/2-fun-0-',3},
{lists,foldl,3},
{mochijson2,json_encode_array,2},
{couch_httpd,send_json,4},
{couch_httpd_db,do_db_req,2},
{couch_httpd,handle_request,5}]
[info] [<0.242.0>] 127.0.0.1 - - 'GET' /test3/_readers 500
Also tried --data-binary argument to curl.
So I'm well and truly stuck and unable to do any further testing - although
I *did* get it to work initially!!
FYI, this is couchdb git d9c04422 which includes the names/roles separation.
I build with ./configure --prefix=/var/tmp/couch, and I've checked there
is only one set of each library:
$ ls /var/tmp/couch/lib/couchdb/erlang/lib/
couch-0.11.0bd9c04422-git erlang-oauth etap ibrowse-1.5.2 mochiweb-r113
I'm pretty sure my main couchdb installation isn't interfering; I did
sudo mv /usr/local/lib/couchdb{,x}
to double-check, and everything's the same.
Now for the philosophical issues.
(4) Because _readers is a single resource, you have to GET it then PUT it to
add a new reader. This won't scale when you have a million users and want to
add your million-and-first.
(5) Because _readers is not a real document, there is no concurrency
control, which aggrevates (4).
(6) Because _readers is not a real document, it can't replicate.
(7) All the above apply to the _admins resource too (although I didn't get
around to testing it before I broke my install; I was doing the changes as
server admin rather than database admin)
(8) I didn't get as far as checking whether _readers is visible to all
readers, or only to _admins. If it is visible to readers, it would be a
privacy concern.
(9) I think that _readers behaves differently to _admins: if _admins is
empty then presumably nobody gets admin, but if _readers is empty then
everybody gets access.
For example, if you replicate a db then the copy will default to being open
to the world, unless you've remembered to add at least one entry to _readers
first.
(10) It's unclear how controlling write access will interact with this
mechanism, but it looks like you'll need to add every user into two distinct
places (i.e. both _readers and the security context doc). That just feels
wrong to me. I've asked before: why can't db admin and reader control just
be a role picked up from the security context doc(s)?
Regards,
Brian.