diff options
| author | Robert Newson <rnewson@apache.org> | 2011-05-28 16:50:32 +0000 |
|---|---|---|
| committer | Robert Newson <rnewson@apache.org> | 2011-05-28 16:50:32 +0000 |
| commit | 697dfceee48e6dad03c2f023b5ebe0e75f5ba5cf (patch) | |
| tree | 2bc170c12a0575fe9ca0f2da1d418e2e72e0f1bb /share/www/script/test/replicator_db.js | |
| parent | cc9965f8a703f2140e1e4ad2ddf2117653195946 (diff) | |
| parent | 31e900ee642e672cec0b7b561c4bb596e1acf9a5 (diff) | |
tagging 1.1.0
git-svn-id: https://svn.apache.org/repos/asf/couchdb/tags/1.1.0@1128705 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'share/www/script/test/replicator_db.js')
| -rw-r--r-- | share/www/script/test/replicator_db.js | 261 |
1 files changed, 243 insertions, 18 deletions
diff --git a/share/www/script/test/replicator_db.js b/share/www/script/test/replicator_db.js index 2810352c..4434124e 100644 --- a/share/www/script/test/replicator_db.js +++ b/share/www/script/test/replicator_db.js @@ -121,7 +121,7 @@ couchTests.replicator_db = function(debug) { T(repDoc1.source === repDoc.source); T(repDoc1.target === repDoc.target); T(repDoc1._replication_state === "completed", "simple"); - T(typeof repDoc1._replication_state_time === "number"); + T(typeof repDoc1._replication_state_time === "string"); T(typeof repDoc1._replication_id === "string"); } @@ -173,7 +173,7 @@ couchTests.replicator_db = function(debug) { T(repDoc1.source === repDoc.source); T(repDoc1.target === repDoc.target); T(repDoc1._replication_state === "completed", "filtered"); - T(typeof repDoc1._replication_state_time === "number"); + T(typeof repDoc1._replication_state_time === "string"); T(typeof repDoc1._replication_id === "string"); } @@ -186,7 +186,10 @@ couchTests.replicator_db = function(debug) { _id: "foo_cont_rep_doc", source: "http://" + host + "/" + dbA.name, target: dbB.name, - continuous: true + continuous: true, + user_ctx: { + roles: ["_admin"] + } }; T(repDb.save(repDoc).ok); @@ -217,13 +220,11 @@ couchTests.replicator_db = function(debug) { T(repDoc1.source === repDoc.source); T(repDoc1.target === repDoc.target); T(repDoc1._replication_state === "triggered"); - T(typeof repDoc1._replication_state_time === "number"); + T(typeof repDoc1._replication_state_time === "string"); T(typeof repDoc1._replication_id === "string"); - // add a design doc to source, it will be replicated to target - // when the "user_ctx" property is not defined in the replication doc, - // the replication will be done under an _admin context, therefore - // design docs will be replicated + // Design documents are only replicated to local targets if the respective + // replication document has a user_ctx filed with the "_admin" role in it. var ddoc = { _id: "_design/foobar", language: "javascript" @@ -303,8 +304,7 @@ couchTests.replicator_db = function(debug) { T(copy === null); copy = dbB.open("_design/mydesign"); - T(copy !== null); - T(copy.language === "javascript"); + T(copy === null); } @@ -332,7 +332,7 @@ couchTests.replicator_db = function(debug) { T(repDoc1_copy.source === repDoc1.source); T(repDoc1_copy.target === repDoc1.target); T(repDoc1_copy._replication_state === "completed"); - T(typeof repDoc1_copy._replication_state_time === "number"); + T(typeof repDoc1_copy._replication_state_time === "string"); T(typeof repDoc1_copy._replication_id === "string"); var newDoc = { @@ -363,7 +363,7 @@ couchTests.replicator_db = function(debug) { T(repDoc2_copy.source === repDoc1.source); T(repDoc2_copy.target === repDoc1.target); T(repDoc2_copy._replication_state === "completed"); - T(typeof repDoc2_copy._replication_state_time === "number"); + T(typeof repDoc2_copy._replication_state_time === "string"); T(typeof repDoc2_copy._replication_id === "string"); T(repDoc2_copy._replication_id === repDoc1_copy._replication_id); } @@ -400,7 +400,7 @@ couchTests.replicator_db = function(debug) { repDoc1 = repDb.open("foo_dup_rep_doc_1"); T(repDoc1 !== null); T(repDoc1._replication_state === "completed", "identical"); - T(typeof repDoc1._replication_state_time === "number"); + T(typeof repDoc1._replication_state_time === "string"); T(typeof repDoc1._replication_id === "string"); repDoc2 = repDb.open("foo_dup_rep_doc_2"); @@ -444,7 +444,7 @@ couchTests.replicator_db = function(debug) { repDoc1 = repDb.open("foo_dup_cont_rep_doc_1"); T(repDoc1 !== null); T(repDoc1._replication_state === "triggered"); - T(typeof repDoc1._replication_state_time === "number"); + T(typeof repDoc1._replication_state_time === "string"); T(typeof repDoc1._replication_id === "string"); repDoc2 = repDb.open("foo_dup_cont_rep_doc_2"); @@ -470,7 +470,7 @@ couchTests.replicator_db = function(debug) { repDoc1 = repDb.open("foo_dup_cont_rep_doc_1"); T(repDoc1 !== null); T(repDoc1._replication_state === "triggered"); - T(typeof repDoc1._replication_state_time === "number"); + T(typeof repDoc1._replication_state_time === "string"); var newDoc2 = { _id: "foo5000", @@ -676,7 +676,8 @@ couchTests.replicator_db = function(debug) { var repDoc = { _id: "foo_rep_doc", source: dbA.name, - target: dbB.name + target: dbB.name, + continuous: true }; T(CouchDB.login("fdmanana", "qwerty").ok); @@ -712,6 +713,225 @@ couchTests.replicator_db = function(debug) { } + function test_user_ctx_validation() { + populate_db(dbA, docs1); + populate_db(dbB, []); + populate_db(usersDb, []); + + var joeUserDoc = CouchDB.prepareUserDoc({ + name: "joe", + roles: ["erlanger", "bar"] + }, "erly"); + var fdmananaUserDoc = CouchDB.prepareUserDoc({ + name: "fdmanana", + roles: ["a", "b", "c"] + }, "qwerty"); + + TEquals(true, usersDb.save(joeUserDoc).ok); + TEquals(true, usersDb.save(fdmananaUserDoc).ok); + + T(dbB.setSecObj({ + admins: { + names: [], + roles: ["god"] + }, + readers: { + names: [], + roles: ["foo"] + } + }).ok); + + TEquals(true, CouchDB.login("joe", "erly").ok); + TEquals("joe", CouchDB.session().userCtx.name); + TEquals(-1, CouchDB.session().userCtx.roles.indexOf("_admin")); + + var repDoc = { + _id: "foo_rep", + source: CouchDB.protocol + host + "/" + dbA.name, + target: dbB.name + }; + + try { + repDb.save(repDoc); + T(false, "Should have failed, user_ctx missing."); + } catch (x) { + TEquals("forbidden", x.error); + } + + repDoc.user_ctx = { + name: "john", + roles: ["erlanger"] + }; + + try { + repDb.save(repDoc); + T(false, "Should have failed, wrong user_ctx.name."); + } catch (x) { + TEquals("forbidden", x.error); + } + + repDoc.user_ctx = { + name: "joe", + roles: ["bar", "god", "erlanger"] + }; + + try { + repDb.save(repDoc); + T(false, "Should have failed, a bad role in user_ctx.roles."); + } catch (x) { + TEquals("forbidden", x.error); + } + + // user_ctx.roles might contain only a subset of the user's roles + repDoc.user_ctx = { + name: "joe", + roles: ["erlanger"] + }; + + TEquals(true, repDb.save(repDoc).ok); + CouchDB.logout(); + + waitForRep(repDb, repDoc, "error"); + var repDoc1 = repDb.open(repDoc._id); + T(repDoc1 !== null); + TEquals(repDoc.source, repDoc1.source); + TEquals(repDoc.target, repDoc1.target); + TEquals("error", repDoc1._replication_state); + TEquals("string", typeof repDoc1._replication_id); + TEquals("string", typeof repDoc1._replication_state_time); + + TEquals(true, CouchDB.login("fdmanana", "qwerty").ok); + TEquals("fdmanana", CouchDB.session().userCtx.name); + TEquals(-1, CouchDB.session().userCtx.roles.indexOf("_admin")); + + try { + T(repDb.deleteDoc(repDoc1).ok); + T(false, "Shouldn't be able to delete replication document."); + } catch (x) { + TEquals("forbidden", x.error); + } + + CouchDB.logout(); + TEquals(true, CouchDB.login("joe", "erly").ok); + TEquals("joe", CouchDB.session().userCtx.name); + TEquals(-1, CouchDB.session().userCtx.roles.indexOf("_admin")); + + T(repDb.deleteDoc(repDoc1).ok); + CouchDB.logout(); + + for (var i = 0; i < docs1.length; i++) { + var doc = docs1[i]; + var copy = dbB.open(doc._id); + + TEquals(null, copy); + } + + T(dbB.setSecObj({ + admins: { + names: [], + roles: ["god", "erlanger"] + }, + readers: { + names: [], + roles: ["foo"] + } + }).ok); + + TEquals(true, CouchDB.login("joe", "erly").ok); + TEquals("joe", CouchDB.session().userCtx.name); + TEquals(-1, CouchDB.session().userCtx.roles.indexOf("_admin")); + + repDoc = { + _id: "foo_rep_2", + source: CouchDB.protocol + host + "/" + dbA.name, + target: dbB.name, + user_ctx: { + name: "joe", + roles: ["erlanger"] + } + }; + + TEquals(true, repDb.save(repDoc).ok); + CouchDB.logout(); + + waitForRep(repDb, repDoc, "complete"); + repDoc1 = repDb.open(repDoc._id); + T(repDoc1 !== null); + TEquals(repDoc.source, repDoc1.source); + TEquals(repDoc.target, repDoc1.target); + TEquals("completed", repDoc1._replication_state); + TEquals("string", typeof repDoc1._replication_id); + TEquals("string", typeof repDoc1._replication_state_time); + + for (var i = 0; i < docs1.length; i++) { + var doc = docs1[i]; + var copy = dbB.open(doc._id); + + T(copy !== null); + TEquals(doc.value, copy.value); + } + + // Admins don't need to supply a user_ctx property in replication docs. + // If they do not, the implicit user_ctx "user_ctx": {name: null, roles: []} + // is used, meaning that design documents will not be replicated into + // local targets + T(dbB.setSecObj({ + admins: { + names: [], + roles: [] + }, + readers: { + names: [], + roles: [] + } + }).ok); + + var ddoc = { _id: "_design/foo" }; + TEquals(true, dbA.save(ddoc).ok); + + repDoc = { + _id: "foo_rep_3", + source: CouchDB.protocol + host + "/" + dbA.name, + target: dbB.name + }; + + TEquals(true, repDb.save(repDoc).ok); + waitForRep(repDb, repDoc, "complete"); + repDoc1 = repDb.open(repDoc._id); + T(repDoc1 !== null); + TEquals(repDoc.source, repDoc1.source); + TEquals(repDoc.target, repDoc1.target); + TEquals("completed", repDoc1._replication_state); + TEquals("string", typeof repDoc1._replication_id); + TEquals("string", typeof repDoc1._replication_state_time); + + var ddoc_copy = dbB.open(ddoc._id); + T(ddoc_copy === null); + + repDoc = { + _id: "foo_rep_4", + source: CouchDB.protocol + host + "/" + dbA.name, + target: dbB.name, + user_ctx: { + roles: ["_admin"] + } + }; + + TEquals(true, repDb.save(repDoc).ok); + waitForRep(repDb, repDoc, "complete"); + repDoc1 = repDb.open(repDoc._id); + T(repDoc1 !== null); + TEquals(repDoc.source, repDoc1.source); + TEquals(repDoc.target, repDoc1.target); + TEquals("completed", repDoc1._replication_state); + TEquals("string", typeof repDoc1._replication_id); + TEquals("string", typeof repDoc1._replication_state_time); + + ddoc_copy = dbB.open(ddoc._id); + T(ddoc_copy !== null); + } + + function rep_doc_with_bad_rep_id() { populate_db(dbA, docs1); populate_db(dbB, []); @@ -738,7 +958,7 @@ couchTests.replicator_db = function(debug) { T(repDoc1.target === repDoc.target); T(repDoc1._replication_state === "completed", "replication document with bad replication id failed"); - T(typeof repDoc1._replication_state_time === "number"); + T(typeof repDoc1._replication_state_time === "string"); T(typeof repDoc1._replication_id === "string"); T(repDoc1._replication_id !== "1234abc"); } @@ -929,7 +1149,7 @@ couchTests.replicator_db = function(debug) { var repDoc1 = repDb.open(repDoc._id); T(repDoc1 !== null); T(repDoc1._replication_state === "error"); - T(typeof repDoc1._replication_state_time === "number"); + T(typeof repDoc1._replication_state_time === "string"); T(typeof repDoc1._replication_id === "string"); } @@ -1110,6 +1330,11 @@ couchTests.replicator_db = function(debug) { value: usersDb.name } ]); + + repDb.deleteDb(); + restartServer(); + run_on_modified_server(server_config_2, test_user_ctx_validation); + repDb.deleteDb(); restartServer(); run_on_modified_server(server_config_2, test_replication_credentials_delegation); |
