blob: ff770c7284e910ccfa93eee908c9c0b075c8f537 [file] [log] [blame]
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
couchTests.reader_acl = function(debug) {
// this tests read access control
var usersDb = new CouchDB("test_suite_users", {"X-Couch-Full-Commit":"false"});
var secretDb = new CouchDB("test_suite_db", {"X-Couch-Full-Commit":"false"});
function testFun() {
try {
usersDb.deleteDb();
try {
usersDb.createDb();
} catch(e) {
if(usersDb.last_req.status != 412) {
throw e;
}
}
secretDb.deleteDb();
secretDb.createDb();
// create a user with top-secret-clearance
var jchrisUserDoc = CouchDB.prepareUserDoc({
name: "jchris@apache.org",
roles : ["top-secret"]
}, "funnybone");
T(usersDb.save(jchrisUserDoc).ok);
usersDb.ensureFullCommit();
T(CouchDB.session().userCtx.name == null);
// set secret db to be read controlled
T(secretDb.save({_id:"baz",foo:"bar"}).ok);
T(secretDb.open("baz").foo == "bar");
T(secretDb.setSecObj({
"members" : {
roles : ["super-secret-club"],
names : ["joe","barb"]
}
}).ok);
} finally {
CouchDB.logout();
}
}
// split into 2 funs so we can test restart behavior
function testFun2() {
try {
// can't read it as jchris b/c he's missing the needed role
T(CouchDB.login("jchris@apache.org", "funnybone").ok);
T(CouchDB.session().userCtx.name == "jchris@apache.org");
try {
secretDb.open("baz");
T(false && "can't open a doc from a secret db") ;
} catch(e) {
T(true)
}
CouchDB.logout();
// make anyone with the top-secret role an admin
// db admins are automatically members
T(secretDb.setSecObj({
"admins" : {
roles : ["top-secret"],
names : []
},
"members" : {
roles : ["super-secret-club"],
names : ["joe","barb"]
}
}).ok);
T(CouchDB.login("jchris@apache.org", "funnybone").ok);
// db admin can read
T(secretDb.open("baz").foo == "bar");
// and run temp views
TEquals(secretDb.query(function(doc) {
emit(null, null)
}).total_rows, 1);
CouchDB.logout();
T(CouchDB.session().userCtx.roles.indexOf("_admin") != -1);
// admin now adds the top-secret role to the db's members
// and removes db-admins
T(secretDb.setSecObj({
"admins" : {
roles : [],
names : []
},
"members" : {
roles : ["super-secret-club", "top-secret"],
names : ["joe","barb"]
}
}).ok);
// server _admin can always read
T(secretDb.open("baz").foo == "bar");
// and run temp views
TEquals(secretDb.query(function(doc) {
emit(null, null)
}).total_rows, 1);
T(secretDb.save({
"_id" : "_design/foo",
views : {
bar : {
map : "function(doc){emit(null, null)}"
}
}
}).ok)
// now top-secret users can read too
T(CouchDB.login("jchris@apache.org", "funnybone").ok);
T(CouchDB.session().userCtx.roles.indexOf("_admin") == -1);
T(secretDb.open("baz").foo == "bar");
// members can query stored views
T(secretDb.view("foo/bar").total_rows == 1);
// members can't do temp views
try {
var results = secretDb.query(function(doc) {
emit(null, null);
});
T(false && "temp view should be admin only");
} catch (e) {
T(true && "temp view is admin only");
}
CouchDB.logout();
// works with readers (backwards compat with 1.0)
T(secretDb.setSecObj({
"admins" : {
roles : [],
names : []
},
"readers" : {
roles : ["super-secret-club", "top-secret"],
names : ["joe","barb"]
}
}).ok);
T(CouchDB.login("jchris@apache.org", "funnybone").ok);
T(CouchDB.session().userCtx.roles.indexOf("_admin") == -1);
T(secretDb.open("baz").foo == "bar");
// can't set non string reader names or roles
try {
secretDb.setSecObj({
"members" : {
roles : ["super-secret-club", {"top-secret":"awesome"}],
names : ["joe","barb"]
}
})
T(false && "only string roles");
} catch (e) {}
try {
secretDb.setSecObj({
"members" : {
roles : ["super-secret-club", {"top-secret":"awesome"}],
names : ["joe",22]
}
});
T(false && "only string names");
} catch (e) {}
try {
secretDb.setSecObj({
"members" : {
roles : ["super-secret-club", {"top-secret":"awesome"}],
names : "joe"
}
});
T(false && "only lists of names");
} catch (e) {}
} finally {
CouchDB.logout();
}
};
run_on_modified_server(
[{section: "httpd",
key: "authentication_handlers",
value: "{couch_httpd_auth, cookie_authentication_handler}, {couch_httpd_auth, default_authentication_handler}"},
{section: "couch_httpd_auth",
key: "authentication_db", value: "test_suite_users"}],
testFun
);
// security changes will always commit synchronously
restartServer();
run_on_modified_server(
[{section: "httpd",
key: "authentication_handlers",
value: "{couch_httpd_auth, cookie_authentication_handler}, {couch_httpd_auth, default_authentication_handler}"},
{section: "couch_httpd_auth",
key: "authentication_db", value: "test_suite_users"}],
testFun2
);
}