summaryrefslogtreecommitdiff
path: root/share/www/script/test/security_validation.js
diff options
context:
space:
mode:
Diffstat (limited to 'share/www/script/test/security_validation.js')
-rw-r--r--share/www/script/test/security_validation.js97
1 files changed, 75 insertions, 22 deletions
diff --git a/share/www/script/test/security_validation.js b/share/www/script/test/security_validation.js
index d07195e1..42aa11c9 100644
--- a/share/www/script/test/security_validation.js
+++ b/share/www/script/test/security_validation.js
@@ -13,7 +13,7 @@
couchTests.security_validation = function(debug) {
// This tests couchdb's security and validation features. This does
// not test authentication, except to use test authentication code made
- // specifically for this testing. It is a WWWW-Authenticate scheme named
+ // specifically for this testing. It is a WWW-Authenticate scheme named
// X-Couch-Test-Auth, and the user names and passwords are hard coded
// on the server-side.
//
@@ -21,7 +21,7 @@ couchTests.security_validation = function(debug) {
// implementation for Firefox and Safari, and probably other browsers are
// broken (Firefox always prompts the user on 401 failures, Safari gives
// odd security errors when using different name/passwords, perhaps due
- // to cross site scripting prevention). These problems essentially make Basic
+ // to cross site scripting prevention). These problems essentially make Basic
// authentication testing in the browser impossible. But while hard to
// test automated in the browser, Basic auth may still useful for real
// world use where these bugs/behaviors don't matter.
@@ -69,7 +69,13 @@ couchTests.security_validation = function(debug) {
var designDoc = {
_id:"_design/test",
language: "javascript",
- validate_doc_update: "(" + (function (newDoc, oldDoc, userCtx) {
+ validate_doc_update: "(" + (function (newDoc, oldDoc, userCtx, secObj) {
+ if (secObj.admin_override) {
+ if (userCtx.roles.indexOf('_admin') != -1) {
+ // user is admin, they can do anything
+ return true;
+ }
+ }
// docs should have an author field.
if (!newDoc._deleted && !newDoc.author) {
throw {forbidden:
@@ -99,13 +105,27 @@ couchTests.security_validation = function(debug) {
}
// set user as the admin
- T(db.setDbProperty("_admins", ["Damien Katz"]).ok);
+ T(db.setSecObj({
+ admins : {names : ["Damien Katz"]}
+ }).ok);
T(userDb.save(designDoc).ok);
- // test the _whoami endpoint
+ var user2Db = new CouchDB("test_suite_db",
+ {"WWW-Authenticate": "X-Couch-Test-Auth Jan Lehnardt:apple"}
+ );
+ // Attempt to save the design as a non-admin (in replication scenario)
+ try {
+ user2Db.save(designDoc, {new_edits : false});
+ T(false && "Can't get here. Should have thrown an error on design doc");
+ } catch (e) {
+ T(e.error == "unauthorized");
+ T(user2Db.last_req.status == 401);
+ }
+
+ // test the _session API
var resp = userDb.request("GET", "/_session");
- var user = JSON.parse(resp.responseText)
+ var user = JSON.parse(resp.responseText).userCtx;
T(user.name == "Damien Katz");
// test that the roles are listed properly
TEquals(user.roles, []);
@@ -116,20 +136,23 @@ couchTests.security_validation = function(debug) {
doc.foo=2;
T(userDb.save(doc).ok);
- // Save a document that's missing an author field.
- try {
- userDb.save({foo:1});
- T(false && "Can't get here. Should have thrown an error 2");
- } catch (e) {
- T(e.error == "forbidden");
- T(userDb.last_req.status == 403);
+ // Save a document that's missing an author field (before and after compaction)
+ for (var i=0; i<2; i++) {
+ try {
+ userDb.save({foo:1});
+ T(false && "Can't get here. Should have thrown an error 2");
+ } catch (e) {
+ T(e.error == "forbidden");
+ T(userDb.last_req.status == 403);
+ }
+ // compact.
+ T(db.compact().ok);
+ T(db.last_req.status == 202);
+ // compaction isn't instantaneous, loop until done
+ while (db.info().compact_running) {};
}
// Now attempt to update the document as a different user, Jan
- var user2Db = new CouchDB("test_suite_db",
- {"WWW-Authenticate": "X-Couch-Test-Auth Jan Lehnardt:apple"}
- );
-
var doc = user2Db.open("testdoc");
doc.foo=3;
try {
@@ -158,6 +181,37 @@ couchTests.security_validation = function(debug) {
T(e.error == "unauthorized");
T(userDb.last_req.status == 401);
}
+
+ // admin must save with author field unless admin override
+ var resp = db.request("GET", "/_session");
+ var user = JSON.parse(resp.responseText).userCtx;
+ T(user.name == null);
+ // test that we are admin
+ TEquals(user.roles, ["_admin"]);
+
+ // can't save the doc even though we are admin
+ var doc = db.open("testdoc");
+ doc.foo=3;
+ try {
+ db.save(doc);
+ T(false && "Can't get here. Should have thrown an error 3");
+ } catch (e) {
+ T(e.error == "unauthorized");
+ T(db.last_req.status == 401);
+ }
+
+ // now turn on admin override
+ T(db.setDbProperty("_security", {admin_override : true}).ok);
+ T(db.save(doc).ok);
+
+ // try to do something lame
+ try {
+ db.setDbProperty("_security", ["foo"]);
+ T(false && "can't do this");
+ } catch(e) {}
+
+ // go back to normal
+ T(db.setDbProperty("_security", {admin_override : false}).ok);
// Now delete document
T(user2Db.deleteDoc(doc).ok);
@@ -188,7 +242,6 @@ couchTests.security_validation = function(debug) {
T(db.open("booboo") == null);
T(db.open("foofoo") == null);
-
// Now test replication
var AuthHeaders = {"WWW-Authenticate": "X-Couch-Test-Auth Christopher Lenz:dog food"};
var host = CouchDB.host;
@@ -197,16 +250,16 @@ couchTests.security_validation = function(debug) {
target:"test_suite_db_b"},
{source:"test_suite_db_a",
- target:{url: "http://" + host + "/test_suite_db_b",
+ target:{url: CouchDB.protocol + host + "/test_suite_db_b",
headers: AuthHeaders}},
- {source:{url:"http://" + host + "/test_suite_db_a",
+ {source:{url:CouchDB.protocol + host + "/test_suite_db_a",
headers: AuthHeaders},
target:"test_suite_db_b"},
- {source:{url:"http://" + host + "/test_suite_db_a",
+ {source:{url:CouchDB.protocol + host + "/test_suite_db_a",
headers: AuthHeaders},
- target:{url:"http://" + host + "/test_suite_db_b",
+ target:{url:CouchDB.protocol + host + "/test_suite_db_b",
headers: AuthHeaders}},
]
var adminDbA = new CouchDB("test_suite_db_a", {"X-Couch-Full-Commit":"false"});