blob: 353e2ed9e7baba7fb334a581329f8e3ca59e7d60 [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.replicator_db_user_ctx = function(debug) {
return console.log('TODO');
if (debug) debugger;
var populate_db = replicator_db.populate_db;
var docs1 = replicator_db.docs1;
var dbA = replicator_db.dbA;
var dbB = replicator_db.dbB;
var repDb = replicator_db.repDb;
var usersDb = replicator_db.usersDb;
var wait = replicator_db.wait;
var waitForRep = replicator_db.waitForRep;
var waitForSeq = replicator_db.waitForSeq;
var wait_rep_doc = replicator_db.wait_rep_doc;
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 + CouchDB.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 + CouchDB.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 + CouchDB.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 + CouchDB.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);
}
var server_config = [
{
section: "couch_httpd_auth",
key: "iterations",
value: "1"
},
{
section: "replicator",
key: "db",
value: repDb.name
},
{
section: "couch_httpd_auth",
key: "authentication_db",
value: usersDb.name
}
];
repDb.deleteDb();
run_on_modified_server(server_config, test_user_ctx_validation);
// cleanup
repDb.deleteDb();
dbA.deleteDb();
dbB.deleteDb();
usersDb.deleteDb();
}