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.js165
1 files changed, 141 insertions, 24 deletions
diff --git a/share/www/script/test/security_validation.js b/share/www/script/test/security_validation.js
index 61f56b39..a41d8d70 100644
--- a/share/www/script/test/security_validation.js
+++ b/share/www/script/test/security_validation.js
@@ -31,28 +31,27 @@ couchTests.security_validation = function(debug) {
// the "username:password" string, it's sent completely plain text.
// Firefox and Safari both deal with this correctly (which is to say
// they correctly do nothing special).
-
-
+
+
var db = new CouchDB("test_suite_db");
db.deleteDb();
db.createDb();
if (debug) debugger;
-
+
run_on_modified_server(
[{section: "httpd",
key: "authentication_handler",
value: "{couch_httpd, special_test_authentication_handler}"},
- {section:"httpd",
+ {section:"httpd",
key: "WWW-Authenticate",
value: "X-Couch-Test-Auth"}],
-
- function () {
+ function () {
// try saving document usin the wrong credentials
var wrongPasswordDb = new CouchDB("test_suite_db",
{"WWW-Authenticate": "X-Couch-Test-Auth Damien Katz:foo"}
);
-
+
try {
wrongPasswordDb.save({foo:1,author:"Damien Katz"});
T(false && "Can't get here. Should have thrown an error 1");
@@ -60,8 +59,8 @@ couchTests.security_validation = function(debug) {
T(e.error == "unauthorized");
T(wrongPasswordDb.last_req.status == 401);
}
-
-
+
+
// Create the design doc that will run custom validation code
var designDoc = {
_id:"_design/test",
@@ -83,9 +82,9 @@ couchTests.security_validation = function(debug) {
var userDb = new CouchDB("test_suite_db",
{"WWW-Authenticate": "X-Couch-Test-Auth Damien Katz:pecan pie"}
);
-
+
T(userDb.save({_id:"testdoc", foo:1, author:"Damien Katz"}).ok);
-
+
// Attempt to save the design as a non-admin
try {
userDb.save(designDoc);
@@ -94,17 +93,17 @@ couchTests.security_validation = function(debug) {
T(e.error == "unauthorized");
T(userDb.last_req.status == 401);
}
-
- // add user as admin
- db.setAdmins(["Damien Katz"]);
-
+
+ // set user as the admin
+ T(db.setDbProperty("_admins", ["Damien Katz"]).ok);
+
T(userDb.save(designDoc).ok);
-
+
// update the document
var doc = userDb.open("testdoc");
doc.foo=2;
T(userDb.save(doc).ok);
-
+
// Save a document that's missing an author field.
try {
userDb.save({foo:1});
@@ -113,12 +112,12 @@ couchTests.security_validation = function(debug) {
T(e.error == "forbidden");
T(userDb.last_req.status == 403);
}
-
+
// 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 {
@@ -128,17 +127,17 @@ couchTests.security_validation = function(debug) {
T(e.error == "unauthorized");
T(user2Db.last_req.status == 401);
}
-
+
// Now have Damien change the author to Jan
doc = userDb.open("testdoc");
doc.author="Jan Lehnardt";
T(userDb.save(doc).ok);
-
+
// Now update the document as Jan
doc = user2Db.open("testdoc");
doc.foo = 3;
T(user2Db.save(doc).ok);
-
+
// Damien can't delete it
try {
userDb.deleteDoc(doc);
@@ -147,8 +146,126 @@ couchTests.security_validation = function(debug) {
T(e.error == "unauthorized");
T(userDb.last_req.status == 401);
}
-
+
// Now delete document
- T(user2Db.deleteDoc(doc).ok);
+ T(user2Db.deleteDoc(doc).ok);
+
+ // now test bulk docs
+ var docs = [{_id:"bahbah",author:"Damien Katz",foo:"bar"},{_id:"fahfah",foo:"baz"}];
+
+ // Create the docs
+ var results = db.bulkSave(docs);
+
+ T(results[0].rev)
+ T(results[0].error == undefined)
+ T(results[1].rev === undefined)
+ T(results[1].error == "forbidden")
+
+ T(db.open("bahbah"));
+ T(db.open("fahfah") == null);
+
+
+ // now all or nothing with a failure
+ var docs = [{_id:"booboo",author:"Damien Katz",foo:"bar"},{_id:"foofoo",foo:"baz"}];
+
+ // Create the docs
+ var results = db.bulkSave(docs, {all_or_nothing:true});
+
+ T(results.errors.length == 1);
+ T(results.errors[0].error == "forbidden");
+ 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;
+ var dbPairs = [
+ {source:"test_suite_db_a",
+ target:"test_suite_db_b"},
+
+ {source:"test_suite_db_a",
+ target:{url: "http://" + host + "/test_suite_db_b",
+ headers: AuthHeaders}},
+
+ {source:{url:"http://" + host + "/test_suite_db_a",
+ headers: AuthHeaders},
+ target:"test_suite_db_b"},
+
+ {source:{url:"http://" + host + "/test_suite_db_a",
+ headers: AuthHeaders},
+ target:{url:"http://" + host + "/test_suite_db_b",
+ headers: AuthHeaders}},
+ ]
+ var adminDbA = new CouchDB("test_suite_db_a");
+ var adminDbB = new CouchDB("test_suite_db_b");
+ var dbA = new CouchDB("test_suite_db_a",
+ {"WWW-Authenticate": "X-Couch-Test-Auth Christopher Lenz:dog food"});
+ var dbB = new CouchDB("test_suite_db_b",
+ {"WWW-Authenticate": "X-Couch-Test-Auth Christopher Lenz:dog food"});
+ var xhr;
+ for (var testPair = 0; testPair < dbPairs.length; testPair++) {
+ var A = dbPairs[testPair].source
+ var B = dbPairs[testPair].target
+
+ adminDbA.deleteDb();
+ adminDbA.createDb();
+ adminDbB.deleteDb();
+ adminDbB.createDb();
+
+ // save and replicate a documents that will and will not pass our design
+ // doc validation function.
+ dbA.save({_id:"foo1",value:"a",author:"Noah Slater"});
+ dbA.save({_id:"foo2",value:"a",author:"Christopher Lenz"});
+ dbA.save({_id:"bad1",value:"a"});
+
+ T(CouchDB.replicate(A, B, {headers:AuthHeaders}).ok);
+ T(CouchDB.replicate(B, A, {headers:AuthHeaders}).ok);
+
+ T(dbA.open("foo1"));
+ T(dbB.open("foo1"));
+ T(dbA.open("foo2"));
+ T(dbB.open("foo2"));
+
+ // save the design doc to dbA
+ delete designDoc._rev; // clear rev from previous saves
+ adminDbA.save(designDoc);
+
+ // no affect on already saved docs
+ T(dbA.open("bad1"));
+
+ // Update some docs on dbB. Since the design hasn't replicated, anything
+ // is allowed.
+
+ // this edit will fail validation on replication to dbA (no author)
+ T(dbB.save({_id:"bad2",value:"a"}).ok);
+
+ // this edit will fail security on replication to dbA (wrong author
+ // replicating the change)
+ var foo1 = dbB.open("foo1");
+ foo1.value = "b";
+ dbB.save(foo1);
+
+ // this is a legal edit
+ var foo2 = dbB.open("foo2");
+ foo2.value = "b";
+ dbB.save(foo2);
+
+ var results = CouchDB.replicate(B, A, {headers:AuthHeaders});
+
+ T(results.ok);
+
+ T(results.history[0].docs_written == 1);
+ T(results.history[0].doc_write_failures == 2);
+
+ // bad2 should not be on dbA
+ T(dbA.open("bad2") == null);
+
+ // The edit to foo1 should not have replicated.
+ T(dbA.open("foo1").value == "a");
+
+ // The edit to foo2 should have replicated.
+ T(dbA.open("foo2").value == "b");
+ }
});
};