summaryrefslogtreecommitdiff
path: root/test/javascript/tests/users_db_security.js
diff options
context:
space:
mode:
Diffstat (limited to 'test/javascript/tests/users_db_security.js')
-rw-r--r--test/javascript/tests/users_db_security.js144
1 files changed, 131 insertions, 13 deletions
diff --git a/test/javascript/tests/users_db_security.js b/test/javascript/tests/users_db_security.js
index ad516a0c4..536585acf 100644
--- a/test/javascript/tests/users_db_security.js
+++ b/test/javascript/tests/users_db_security.js
@@ -15,6 +15,8 @@ couchTests.users_db_security = function(debug) {
var usersDb = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
try { usersDb.createDb(); } catch (e) { /* ignore if exists*/ }
+ var passwordSchemes = ['pbkdf2', 'bcrypt'];
+
if (debug) debugger;
var loginUser = function(username) {
@@ -86,7 +88,7 @@ couchTests.users_db_security = function(debug) {
}
};
- var testFun = function()
+ var testFun = function(scheme, derivedKeyTest, saltTest)
{
// _users db
@@ -105,11 +107,13 @@ couchTests.users_db_security = function(debug) {
// jan's gonna be admin as he's the first user
TEquals(true, usersDb.save(userDoc).ok, "should save document");
- wait(5000)
+ wait(5000);
userDoc = open_as(usersDb, "org.couchdb.user:jchris", "jchris");
TEquals(undefined, userDoc.password, "password field should be null 1");
- TEquals(40, userDoc.derived_key.length, "derived_key should exist");
- TEquals(32, userDoc.salt.length, "salt should exist");
+ TEquals(scheme, userDoc.password_scheme, "password_scheme should be " + scheme);
+ derivedKeyTest(userDoc.derived_key);
+ saltTest(userDoc.salt);
+
// create server admin
@@ -141,10 +145,13 @@ couchTests.users_db_security = function(debug) {
var jchrisDoc = open_as(usersDb, "org.couchdb.user:jchris", "jan");
TEquals(undefined, jchrisDoc.password, "password field should be null 2");
- TEquals(40, jchrisDoc.derived_key.length, "derived_key should exist");
- TEquals(32, jchrisDoc.salt.length, "salt should exist");
+ TEquals(scheme, jchrisDoc.password_scheme, "password_scheme should be " + scheme);
+ derivedKeyTest(jchrisDoc.derived_key);
+ saltTest(jchrisDoc.salt);
- TEquals(true, userDoc.salt != jchrisDoc.salt, "should have new salt");
+ if(userDoc.salt || jchrisDoc.salt) {
+ TEquals(true, userDoc.salt != jchrisDoc.salt, "should have new salt");
+ }
TEquals(true, userDoc.derived_key != jchrisDoc.derived_key,
"should have new derived_key");
@@ -227,7 +234,7 @@ couchTests.users_db_security = function(debug) {
TEquals("forbidden", e.error, "non-admins can't read design docs");
}
- // admin shold be able to read _list
+ // admin should be able to read _list
var listPath = ddoc["_id"] + "/_list/names/test";
var result = request_as(usersDb, listPath, "jan");
var lines = result.responseText.split("\n");
@@ -373,14 +380,124 @@ couchTests.users_db_security = function(debug) {
});
};
+ var derivedKeyTests = {
+ pbkdf2: function(derived_key) {
+ TEquals(40, derived_key.length, "derived_key should exist");
+ },
+ bcrypt: function(derived_key) {
+ TEquals(60, derived_key.length, "derived_key should exist");
+ }
+ };
+ var saltTests = {
+ pbkdf2: function(salt) {
+ TEquals(32, salt.length, "salt should exist");
+ },
+ bcrypt: function(salt) {
+ TEquals(undefined, salt, "salt should not exist");
+ }
+ };
+ passwordSchemes.forEach(function(scheme){
+ run_on_modified_server(
+ [{
+ section: "couch_httpd_auth",
+ key: "iterations", value: "1"
+ }, {
+ section: "couch_httpd_auth",
+ key: "password_scheme", value: scheme
+ }, {
+ section: "admins",
+ key: "jan", value: "apple"
+ }],
+ function() {
+ try {
+ testFun(scheme, derivedKeyTests[scheme], saltTests[scheme]);
+ } finally {
+ CouchDB.login("jan", "apple");
+ usersDb.deleteDb(); // cleanup
+ sleep(5000);
+ usersDb.createDb();
+ }
+ }
+ );
+ });
+
+ var testFunUpdatePasswordScheme = function() {
+ var userDocs = {
+ jchris: {
+ _id: "org.couchdb.user:jchris",
+ type: "user",
+ name: "jchris",
+ password: "mp3",
+ roles: []
+ },
+ fdmanana: {
+ _id: "org.couchdb.user:fdmanana",
+ type: "user",
+ name: "fdmanana",
+ password: "foobar",
+ roles: []
+ }
+ };
+
+ // create new user (has pbkdf2 hash)
+ TEquals(true, usersDb.save(userDocs.jchris).ok, "should save document");
+ wait(5000);
+ var userDoc = open_as(usersDb, "org.couchdb.user:jchris", "jchris");
+ TEquals(undefined, userDoc.password, "password field should be null 1");
+ TEquals("pbkdf2", userDoc.password_scheme, "password_scheme should be pbkdf2");
+ derivedKeyTests.pbkdf2(userDoc.derived_key);
+ saltTests.pbkdf2(userDoc.salt);
+
+ // change scheme to bcrypt
+ CouchDB.login("jan", "apple");
+ var xhr = CouchDB.request("PUT", "/_node/node1@127.0.0.1/_config/couch_httpd_auth/password_scheme", {
+ body : JSON.stringify("bcrypt"),
+ headers: {"X-Couch-Persist": "false"}
+ });
+ TEquals(200, xhr.status);
+ xhr = CouchDB.request("GET", "/_node/node1@127.0.0.1/_config/couch_httpd_auth/password_scheme");
+ var scheme = JSON.parse(xhr.responseText);
+ TEquals("bcrypt", scheme);
+
+ // create new user (has bcrypt hash)
+ TEquals(true, usersDb.save(userDocs.fdmanana).ok, "should save document");
+ wait(5000);
+ userDoc = open_as(usersDb, "org.couchdb.user:fdmanana", "fdmanana");
+ TEquals(undefined, userDoc.password, "password field should be null 1");
+ TEquals("bcrypt", userDoc.password_scheme, "password_scheme should be bcrypt");
+ derivedKeyTests.bcrypt(userDoc.derived_key);
+ saltTests.bcrypt(userDoc.salt);
+
+ // test that both users can still log in
+ TEquals(true, CouchDB.login(userDocs.jchris.name, userDocs.jchris.password).ok);
+ TEquals(true, CouchDB.login(userDocs.fdmanana.name, userDocs.fdmanana.password).ok);
+
+ // change scheme back to pbkdf2
+ CouchDB.login("jan", "apple");
+ var xhr = CouchDB.request("PUT", "/_node/node1@127.0.0.1/_config/couch_httpd_auth/password_scheme", {
+ body : JSON.stringify("pbkdf2"),
+ headers: {"X-Couch-Persist": "false"}
+ });
+ TEquals(200, xhr.status);
+ xhr = CouchDB.request("GET", "/_node/node1@127.0.0.1/_config/couch_httpd_auth/password_scheme");
+ var scheme = JSON.parse(xhr.responseText);
+ TEquals("pbkdf2", scheme);
+
+ // test that both users can still log in
+ TEquals(true, CouchDB.login(userDocs.jchris.name, userDocs.jchris.password).ok);
+ TEquals(true, CouchDB.login(userDocs.fdmanana.name, userDocs.fdmanana.password).ok);
+ };
run_on_modified_server(
- [{section: "couch_httpd_auth",
- key: "iterations", value: "1"},
- {section: "admins",
- key: "jan", value: "apple"}],
+ [{
+ section: "couch_httpd_auth",
+ key: "iterations", value: "1"
+ }, {
+ section: "admins",
+ key: "jan", value: "apple"
+ }],
function() {
try {
- testFun();
+ testFunUpdatePasswordScheme();
} finally {
CouchDB.login("jan", "apple");
usersDb.deleteDb(); // cleanup
@@ -389,5 +506,6 @@ couchTests.users_db_security = function(debug) {
}
}
);
+
CouchDB.logout();
};