// 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.auth_cache = function(debug) { if (debug) debugger; // Simple secret key generator function generateSecret(length) { var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789+/"; var secret = ''; for (var i = 0; i < length; i++) { secret += tab.charAt(Math.floor(Math.random() * 64)); } return secret; } var authDb = new CouchDB("test_suite_users", {"X-Couch-Full-Commit":"false"}); var server_config = [ { section: "couch_httpd_auth", key: "authentication_db", value: authDb.name }, { section: "couch_httpd_auth", key: "auth_cache_size", value: "3" }, { section: "httpd", key: "authentication_handlers", value: "{couch_httpd_auth, default_authentication_handler}" }, { section: "couch_httpd_auth", key: "secret", value: generateSecret(64) } ]; function hits() { var hits = CouchDB.requestStats("couchdb", "auth_cache_hits", true); return hits.current || 0; } function misses() { var misses = CouchDB.requestStats("couchdb", "auth_cache_misses", true); return misses.current || 0; } function testFun() { var hits_before, misses_before, hits_after, misses_after; var fdmanana = CouchDB.prepareUserDoc({ name: "fdmanana", roles: ["dev"] }, "qwerty"); T(authDb.save(fdmanana).ok); var chris = CouchDB.prepareUserDoc({ name: "chris", roles: ["dev", "mafia", "white_costume"] }, "the_god_father"); T(authDb.save(chris).ok); var joe = CouchDB.prepareUserDoc({ name: "joe", roles: ["erlnager"] }, "functional"); T(authDb.save(joe).ok); var johndoe = CouchDB.prepareUserDoc({ name: "johndoe", roles: ["user"] }, "123456"); T(authDb.save(johndoe).ok); hits_before = hits(); misses_before = misses(); T(CouchDB.login("fdmanana", "qwerty").ok); hits_after = hits(); misses_after = misses(); T(misses_after === (misses_before + 1)); T(hits_after === hits_before); hits_before = hits_after; misses_before = misses_after; T(CouchDB.logout().ok); T(CouchDB.login("fdmanana", "qwerty").ok); hits_after = hits(); misses_after = misses(); T(misses_after === misses_before); T(hits_after === (hits_before + 1)); hits_before = hits_after; misses_before = misses_after; T(CouchDB.logout().ok); T(CouchDB.login("chris", "the_god_father").ok); hits_after = hits(); misses_after = misses(); T(misses_after === (misses_before + 1)); T(hits_after === hits_before); hits_before = hits_after; misses_before = misses_after; T(CouchDB.logout().ok); T(CouchDB.login("joe", "functional").ok); hits_after = hits(); misses_after = misses(); T(misses_after === (misses_before + 1)); T(hits_after === hits_before); hits_before = hits_after; misses_before = misses_after; T(CouchDB.logout().ok); T(CouchDB.login("johndoe", "123456").ok); hits_after = hits(); misses_after = misses(); T(misses_after === (misses_before + 1)); T(hits_after === hits_before); hits_before = hits_after; misses_before = misses_after; T(CouchDB.logout().ok); T(CouchDB.login("joe", "functional").ok); hits_after = hits(); misses_after = misses(); // it's an MRU cache, joe was removed from cache to add johndoe T(misses_after === (misses_before + 1)); T(hits_after === hits_before); hits_before = hits_after; misses_before = misses_after; T(CouchDB.logout().ok); T(CouchDB.login("fdmanana", "qwerty").ok); hits_after = hits(); misses_after = misses(); T(misses_after === misses_before); T(hits_after === (hits_before + 1)); hits_before = hits_after; misses_before = misses_after; var new_salt = CouchDB.newUuids(1)[0]; var new_passwd = hex_sha1("foobar" + new_salt); fdmanana.salt = new_salt; fdmanana.password_sha = new_passwd; T(authDb.save(fdmanana).ok); T(CouchDB.logout().ok); // cache was refreshed T(CouchDB.login("fdmanana", "qwerty").error === "unauthorized"); T(CouchDB.login("fdmanana", "foobar").ok); hits_after = hits(); misses_after = misses(); T(misses_after === misses_before); T(hits_after === (hits_before + 2)); T(CouchDB.logout().ok); hits_before = hits_after; misses_before = misses_after; // and yet another update new_salt = CouchDB.newUuids(1)[0]; new_passwd = hex_sha1("javascript" + new_salt); fdmanana.salt = new_salt; fdmanana.password_sha = new_passwd; T(authDb.save(fdmanana).ok); T(CouchDB.logout().ok); // cache was refreshed T(CouchDB.login("fdmanana", "foobar").error === "unauthorized"); T(CouchDB.login("fdmanana", "javascript").ok); hits_after = hits(); misses_after = misses(); T(misses_after === misses_before); T(hits_after === (hits_before + 2)); T(authDb.deleteDoc(fdmanana).ok); T(CouchDB.logout().ok); hits_before = hits_after; misses_before = misses_after; T(CouchDB.login("fdmanana", "javascript").error === "unauthorized"); hits_after = hits(); misses_after = misses(); T(misses_after === misses_before); T(hits_after === (hits_before + 1)); // login, compact authentication DB, login again and verify that // there was a cache hit hits_before = hits_after; misses_before = misses_after; T(CouchDB.login("johndoe", "123456").ok); hits_after = hits(); misses_after = misses(); T(misses_after === (misses_before + 1)); T(hits_after === hits_before); T(CouchDB.logout().ok); T(authDb.compact().ok); while (authDb.info().compact_running); hits_before = hits_after; misses_before = misses_after; T(CouchDB.login("johndoe", "123456").ok); hits_after = hits(); misses_after = misses(); T(misses_after === misses_before); T(hits_after === (hits_before + 1)); T(CouchDB.logout().ok); } authDb.deleteDb(); run_on_modified_server(server_config, testFun); // cleanup authDb.deleteDb(); }