Return-Path: X-Original-To: apmail-couchdb-commits-archive@www.apache.org Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 5A8BCC810 for ; Wed, 10 Dec 2014 11:08:11 +0000 (UTC) Received: (qmail 41155 invoked by uid 500); 10 Dec 2014 11:08:10 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 40937 invoked by uid 500); 10 Dec 2014 11:08:10 -0000 Mailing-List: contact commits-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list commits@couchdb.apache.org Received: (qmail 40368 invoked by uid 99); 10 Dec 2014 11:08:09 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 10 Dec 2014 11:08:09 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 5B713A2321E; Wed, 10 Dec 2014 11:08:09 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: kxepal@apache.org To: commits@couchdb.apache.org Date: Wed, 10 Dec 2014 11:08:20 -0000 Message-Id: <9b9ce87fb57a4d46b67a689fe7a60530@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [13/39] couchdb commit: updated refs/heads/master to 9950caa http://git-wip-us.apache.org/repos/asf/couchdb/blob/6a4893aa/share/www/script/test/security_validation.js ---------------------------------------------------------------------- diff --git a/share/www/script/test/security_validation.js b/share/www/script/test/security_validation.js deleted file mode 100644 index 14e5d04..0000000 --- a/share/www/script/test/security_validation.js +++ /dev/null @@ -1,338 +0,0 @@ -// 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.security_validation = function(debug) { - // This tests couchdb's security and validation features. This does - // not test authentication, except to use test authentication code made - // specifically for this testing. It is a WWW-Authenticate scheme named - // X-Couch-Test-Auth, and the user names and passwords are hard coded - // on the server-side. - // - // We could have used Basic authentication, however the XMLHttpRequest - // implementation for Firefox and Safari, and probably other browsers are - // broken (Firefox always prompts the user on 401 failures, Safari gives - // odd security errors when using different name/passwords, perhaps due - // to cross site scripting prevention). These problems essentially make Basic - // authentication testing in the browser impossible. But while hard to - // test automated in the browser, Basic auth may still useful for real - // world use where these bugs/behaviors don't matter. - // - // So for testing purposes we are using this custom X-Couch-Test-Auth. - // It's identical to Basic auth, except it doesn't even base64 encode - // 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", {"X-Couch-Full-Commit":"false"}); - db.deleteDb(); - db.createDb(); - if (debug) debugger; - - run_on_modified_server( - [{section: "httpd", - key: "authentication_handlers", - value: "{couch_httpd_auth, special_test_authentication_handler}"}, - {section:"httpd", - key: "WWW-Authenticate", - value: "X-Couch-Test-Auth"}], - - function () { - // try saving document using 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"); - } catch (e) { - T(e.error == "unauthorized"); - T(wrongPasswordDb.last_req.status == 401); - } - - // test force basic login - var resp = wrongPasswordDb.request("GET", "/_session?basic=true"); - var err = JSON.parse(resp.responseText); - T(err.error == "unauthorized"); - T(resp.status == 401); - - // Create the design doc that will run custom validation code - var designDoc = { - _id:"_design/test", - language: "javascript", - validate_doc_update: stringFun(function (newDoc, oldDoc, userCtx, secObj) { - if (secObj.admin_override) { - if (userCtx.roles.indexOf('_admin') != -1) { - // user is admin, they can do anything - return true; - } - } - // docs should have an author field. - if (!newDoc._deleted && !newDoc.author) { - throw {forbidden: - "Documents must have an author field"}; - } - if (oldDoc && oldDoc.author != userCtx.name) { - throw {unauthorized: - "You are not the author of this document. You jerk."}; - } - }) - } - - // Save a document normally - 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); - T(false && "Can't get here. Should have thrown an error on design doc"); - } catch (e) { - T(e.error == "unauthorized"); - T(userDb.last_req.status == 401); - } - - // set user as the admin - T(db.setSecObj({ - admins : {names : ["Damien Katz"]} - }).ok); - - T(userDb.save(designDoc).ok); - - var user2Db = new CouchDB("test_suite_db", - {"WWW-Authenticate": "X-Couch-Test-Auth Jan Lehnardt:apple"} - ); - // Attempt to save the design as a non-admin (in replication scenario) - designDoc.foo = "bar"; - designDoc._rev = "2-642e20f96624a0aae6025b4dba0c6fb2"; - try { - user2Db.save(designDoc, {new_edits : false}); - T(false && "Can't get here. Should have thrown an error on design doc"); - } catch (e) { - T(e.error == "unauthorized"); - T(user2Db.last_req.status == 401); - } - - // test the _session API - var resp = userDb.request("GET", "/_session"); - var user = JSON.parse(resp.responseText).userCtx; - T(user.name == "Damien Katz"); - // test that the roles are listed properly - TEquals(user.roles, []); - - - // 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 (before and after compaction) - for (var i=0; i<2; i++) { - try { - userDb.save({foo:1}); - T(false && "Can't get here. Should have thrown an error 2"); - } catch (e) { - T(e.error == "forbidden"); - T(userDb.last_req.status == 403); - } - // compact. - T(db.compact().ok); - T(db.last_req.status == 202); - // compaction isn't instantaneous, loop until done - while (db.info().compact_running) {}; - } - - // Now attempt to update the document as a different user, Jan - var doc = user2Db.open("testdoc"); - doc.foo=3; - try { - user2Db.save(doc); - T(false && "Can't get here. Should have thrown an error 3"); - } catch (e) { - 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); - T(false && "Can't get here. Should have thrown an error 4"); - } catch (e) { - T(e.error == "unauthorized"); - T(userDb.last_req.status == 401); - } - - // admin must save with author field unless admin override - var resp = db.request("GET", "/_session"); - var user = JSON.parse(resp.responseText).userCtx; - T(user.name == null); - // test that we are admin - TEquals(user.roles, ["_admin"]); - - // can't save the doc even though we are admin - var doc = db.open("testdoc"); - doc.foo=3; - try { - db.save(doc); - T(false && "Can't get here. Should have thrown an error 3"); - } catch (e) { - T(e.error == "unauthorized"); - T(db.last_req.status == 401); - } - - // now turn on admin override - T(db.setDbProperty("_security", {admin_override : true}).ok); - T(db.save(doc).ok); - - // try to do something lame - try { - db.setDbProperty("_security", ["foo"]); - T(false && "can't do this"); - } catch(e) {} - - // go back to normal - T(db.setDbProperty("_security", {admin_override : false}).ok); - - // Now delete document - 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: CouchDB.protocol + host + "/test_suite_db_b", - headers: AuthHeaders}}, - - {source:{url:CouchDB.protocol + host + "/test_suite_db_a", - headers: AuthHeaders}, - target:"test_suite_db_b"}, - - {source:{url:CouchDB.protocol + host + "/test_suite_db_a", - headers: AuthHeaders}, - target:{url:CouchDB.protocol + host + "/test_suite_db_b", - headers: AuthHeaders}}, - ] - var adminDbA = new CouchDB("test_suite_db_a", {"X-Couch-Full-Commit":"false"}); - var adminDbB = new CouchDB("test_suite_db_b", {"X-Couch-Full-Commit":"false"}); - 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"); - } - }); -}; http://git-wip-us.apache.org/repos/asf/couchdb/blob/6a4893aa/share/www/script/test/show_documents.js ---------------------------------------------------------------------- diff --git a/share/www/script/test/show_documents.js b/share/www/script/test/show_documents.js deleted file mode 100644 index 618925f..0000000 --- a/share/www/script/test/show_documents.js +++ /dev/null @@ -1,420 +0,0 @@ -// 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.show_documents = function(debug) { - var db = new CouchDB("test_suite_db", {"X-Couch-Full-Commit":"false"}); - db.deleteDb(); - db.createDb(); - if (debug) debugger; - - var designDoc = { - _id:"_design/template", - language: "javascript", - shows: { - "hello" : stringFun(function(doc, req) { - log("hello fun"); - if (doc) { - return "Hello World"; - } else { - if(req.id) { - return "New World"; - } else { - return "Empty World"; - } - } - }), - "just-name" : stringFun(function(doc, req) { - if (doc) { - return { - body : "Just " + doc.name - }; - } else { - return { - body : "No such doc", - code : 404 - }; - } - }), - "json" : stringFun(function(doc, req) { - return { - json : doc - } - }), - "req-info" : stringFun(function(doc, req) { - return { - json : req - } - }), - "show-deleted" : stringFun(function(doc, req) { - if(doc) { - return doc._id; - } else { - return "No doc " + req.id; - } - }), - "render-error" : stringFun(function(doc, req) { - return noSuchVariable; - }), - "empty" : stringFun(function(doc, req) { - return ""; - }), - "fail" : stringFun(function(doc, req) { - return doc._id; - }), - "no-set-etag" : stringFun(function(doc, req) { - return { - headers : { - "Etag" : "skipped" - }, - "body" : "something" - } - }), - "list-api" : stringFun(function(doc, req) { - start({"X-Couch-Test-Header": "Yeah"}); - send("Hey"); - }), - "list-api-provides" : stringFun(function(doc, req) { - provides("text", function(){ - send("foo, "); - send("bar, "); - send("baz!"); - }) - }), - "list-api-provides-and-return" : stringFun(function(doc, req) { - provides("text", function(){ - send("4, "); - send("5, "); - send("6, "); - return "7!"; - }) - send("1, "); - send("2, "); - return "3, "; - }), - "list-api-mix" : stringFun(function(doc, req) { - start({"X-Couch-Test-Header": "Yeah"}); - send("Hey "); - return "Dude"; - }), - "list-api-mix-with-header" : stringFun(function(doc, req) { - start({"X-Couch-Test-Header": "Yeah"}); - send("Hey "); - return { - headers: { - "X-Couch-Test-Header-Awesome": "Oh Yeah!" - }, - body: "Dude" - }; - }), - "accept-switch" : stringFun(function(doc, req) { - if (req.headers["Accept"].match(/image/)) { - return { - // a 16x16 px version of the CouchDB logo - "base64" : -["iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAsV", -"BMVEUAAAD////////////////////////5ur3rEBn////////////////wDBL/", -"AADuBAe9EB3IEBz/7+//X1/qBQn2AgP/f3/ilpzsDxfpChDtDhXeCA76AQH/v7", -"/84eLyWV/uc3bJPEf/Dw/uw8bRWmP1h4zxSlD6YGHuQ0f6g4XyQkXvCA36MDH6", -"wMH/z8/yAwX64ODeh47BHiv/Ly/20dLQLTj98PDXWmP/Pz//39/wGyJ7Iy9JAA", -"AADHRSTlMAbw8vf08/bz+Pv19jK/W3AAAAg0lEQVR4Xp3LRQ4DQRBD0QqTm4Y5", -"zMxw/4OleiJlHeUtv2X6RbNO1Uqj9g0RMCuQO0vBIg4vMFeOpCWIWmDOw82fZx", -"vaND1c8OG4vrdOqD8YwgpDYDxRgkSm5rwu0nQVBJuMg++pLXZyr5jnc1BaH4GT", -"LvEliY253nA3pVhQqdPt0f/erJkMGMB8xucAAAAASUVORK5CYII="].join(''), - headers : { - "Content-Type" : "image/png", - "Vary" : "Accept" // we set this for proxy caches - } - }; - } else { - return { - "body" : "accepting text requests", - headers : { - "Content-Type" : "text/html", - "Vary" : "Accept" - } - }; - } - }), - "provides" : stringFun(function(doc, req) { - registerType("foo", "application/foo","application/x-foo"); - - provides("html", function() { - return "Ha ha, you said \"" + doc.word + "\"."; - }); - - provides("foo", function() { - return "foofoo"; - }); - }), - "withSlash": stringFun(function(doc, req) { - return { json: doc } - }), - "secObj": stringFun(function(doc, req) { - return { json: req.secObj }; - }) - } - }; - T(db.save(designDoc).ok); - - var doc = {"word":"plankton", "name":"Rusty"} - var resp = db.save(doc); - T(resp.ok); - var docid = resp.id; - - // show error - var xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/"); - T(xhr.status == 404, 'Should be missing'); - T(JSON.parse(xhr.responseText).reason == "Invalid path."); - - // hello template world - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/hello/"+docid); - T(xhr.responseText == "Hello World", "hello"); - T(/charset=utf-8/.test(xhr.getResponseHeader("Content-Type"))); - - - // Fix for COUCHDB-379 - T(equals(xhr.getResponseHeader("Server").substr(0,7), "CouchDB")); - - // // error stacktraces - // xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/render-error/"+docid); - // T(JSON.parse(xhr.responseText).error == "render_error"); - - // hello template world (no docid) - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/hello"); - T(xhr.responseText == "Empty World"); - - // hello template world (no docid) - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/empty"); - T(xhr.responseText == ""); - - // // hello template world (non-existing docid) - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/fail/nonExistingDoc"); - T(xhr.status == 404); - var resp = JSON.parse(xhr.responseText); - T(resp.error == "not_found"); - - // show with doc - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/just-name/"+docid); - T(xhr.responseText == "Just Rusty"); - - // show with missing doc - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/just-name/missingdoc"); - T(xhr.status == 404); - TEquals("No such doc", xhr.responseText); - - // show with missing func - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/missing/"+docid); - T(xhr.status == 404, "function is missing"); - - // missing design doc - xhr = CouchDB.request("GET", "/test_suite_db/_design/missingddoc/_show/just-name/"+docid); - T(xhr.status == 404); - var resp = JSON.parse(xhr.responseText); - T(resp.error == "not_found"); - - // query parameters - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/req-info/"+docid+"?foo=bar", { - headers: { - "Accept": "text/html;text/plain;*/*", - "X-Foo" : "bar" - } - }); - var resp = JSON.parse(xhr.responseText); - T(equals(resp.headers["X-Foo"], "bar")); - T(equals(resp.query, {foo:"bar"})); - T(equals(resp.method, "GET")); - T(equals(resp.path[5], docid)); - T(equals(resp.info.db_name, "test_suite_db")); - - // accept header switching - // different mime has different etag - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/accept-switch/"+docid, { - headers: {"Accept": "text/html;text/plain;*/*"} - }); - var ct = xhr.getResponseHeader("Content-Type"); - T(/text\/html/.test(ct)) - T("Accept" == xhr.getResponseHeader("Vary")); - var etag = xhr.getResponseHeader("etag"); - - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/accept-switch/"+docid, { - headers: {"Accept": "image/png;*/*"} - }); - T(xhr.responseText.match(/PNG/)) - T("image/png" == xhr.getResponseHeader("Content-Type")); - var etag2 = xhr.getResponseHeader("etag"); - T(etag2 != etag); - - // proper etags - // show with doc - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/just-name/"+docid); - // extract the ETag header values - etag = xhr.getResponseHeader("etag"); - // get again with etag in request - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/just-name/"+docid, { - headers: {"if-none-match": etag} - }); - // should be 304 - T(xhr.status == 304); - - // update the doc - doc.name = "Crusty"; - resp = db.save(doc); - T(resp.ok); - // req with same etag - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/just-name/"+docid, { - headers: {"if-none-match": etag} - }); - // status is 200 - T(xhr.status == 200); - - // get new etag and request again - etag = xhr.getResponseHeader("etag"); - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/just-name/"+docid, { - headers: {"if-none-match": etag} - }); - // should be 304 - T(xhr.status == 304); - - // update design doc (but not function) - designDoc.isChanged = true; - T(db.save(designDoc).ok); - - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/just-name/"+docid, { - headers: {"if-none-match": etag} - }); - // should not be 304 if we change the doc - T(xhr.status != 304, "changed ddoc"); - - // update design doc function - designDoc.shows["just-name"] = stringFun(function(doc, req) { - return { - body : "Just old " + doc.name - }; - }); - T(db.save(designDoc).ok); - - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/just-name/"+docid, { - headers: {"if-none-match": etag} - }); - // status is 200 - T(xhr.status == 200); - - - // JS can't set etag - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/no-set-etag/"+docid); - // extract the ETag header values - etag = xhr.getResponseHeader("etag"); - T(etag != "skipped") - - // test the provides mime matcher - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/provides/"+docid, { - headers: { - "Accept": 'text/html,application/atom+xml; q=0.9' - } - }); - var ct = xhr.getResponseHeader("Content-Type"); - T(/charset=utf-8/.test(ct)) - T(/text\/html/.test(ct)) - T(xhr.responseText == "Ha ha, you said \"plankton\"."); - - // registering types works - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/provides/"+docid, { - headers: { - "Accept": "application/x-foo" - } - }); - T(xhr.getResponseHeader("Content-Type") == "application/x-foo"); - T(xhr.responseText.match(/foofoo/)); - - // test the provides mime matcher without a match - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/provides/"+docid, { - headers: { - "Accept": 'text/monkeys' - } - }); - var rs = JSON.parse(xhr.responseText); - T(rs.error == "not_acceptable") - - - // test inclusion of conflict state - var doc1 = {_id:"foo", a:1}; - var doc2 = {_id:"foo", a:2}; - db.save(doc1); - - // create the conflict with an all_or_nothing bulk docs request - var docs = [doc2]; - db.bulkSave(docs, {all_or_nothing:true}); - - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/json/foo"); - TEquals(1, JSON.parse(xhr.responseText)._conflicts.length); - - var doc3 = {_id:"a/b/c", a:1}; - db.save(doc3); - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/withSlash/a/b/c"); - T(xhr.status == 200); - - // hello template world (non-existing docid) - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/hello/nonExistingDoc"); - T(xhr.responseText == "New World"); - - // test list() compatible API - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/list-api/foo"); - T(xhr.responseText == "Hey"); - TEquals("Yeah", xhr.getResponseHeader("X-Couch-Test-Header"), "header should be cool"); - - // test list() compatible API with provides function - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/list-api-provides/foo?format=text"); - TEquals(xhr.responseText, "foo, bar, baz!", "should join chunks to response body"); - - // should keep next result order: chunks + return value + provided chunks + provided return value - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/list-api-provides-and-return/foo?format=text"); - TEquals(xhr.responseText, "1, 2, 3, 4, 5, 6, 7!", "should not break 1..7 range"); - - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/list-api-mix/foo"); - T(xhr.responseText == "Hey Dude"); - TEquals("Yeah", xhr.getResponseHeader("X-Couch-Test-Header"), "header should be cool"); - - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/list-api-mix-with-header/foo"); - T(xhr.responseText == "Hey Dude"); - TEquals("Yeah", xhr.getResponseHeader("X-Couch-Test-Header"), "header should be cool"); - TEquals("Oh Yeah!", xhr.getResponseHeader("X-Couch-Test-Header-Awesome"), "header should be cool"); - - // test deleted docs - var doc = {_id:"testdoc",foo:1}; - db.save(doc); - var xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/show-deleted/testdoc"); - TEquals("testdoc", xhr.responseText, "should return 'testdoc'"); - - db.deleteDoc(doc); - var xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/show-deleted/testdoc"); - TEquals("No doc testdoc", xhr.responseText, "should return 'no doc testdoc'"); - - - run_on_modified_server( - [{section: "httpd", - key: "authentication_handlers", - value: "{couch_httpd_auth, special_test_authentication_handler}"}, - {section:"httpd", - key: "WWW-Authenticate", - value: "X-Couch-Test-Auth"}], - - function() { - T(db.setDbProperty("_security", {foo: true}).ok); - T(db.save({_id:"testdoc",foo:1}).ok); - - xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/secObj"); - var resp = JSON.parse(xhr.responseText); - T(resp.foo == true); - } - ); - -}; http://git-wip-us.apache.org/repos/asf/couchdb/blob/6a4893aa/share/www/script/test/stats.js ---------------------------------------------------------------------- diff --git a/share/www/script/test/stats.js b/share/www/script/test/stats.js deleted file mode 100644 index 87440b3..0000000 --- a/share/www/script/test/stats.js +++ /dev/null @@ -1,348 +0,0 @@ -// 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.stats = function(debug) { - - function newDb(name, doSetup) { - var db = new CouchDB(name, {"X-Couch-Full-Commit": "false"}); - if(doSetup) { - db.deleteDb(); - db.createDb(); - } - return db; - }; - - function getStat(path) { - var stat = CouchDB.requestStats(path, true); - return stat ? stat.value : null; - }; - - function doView(db) { - var designDoc = { - _id:"_design/test", // turn off couch.js id escaping? - language: "javascript", - views: { - all_docs: {map: "function(doc) {emit(doc.integer, null);}"} - } - }; - db.save(designDoc); - db.view("test/all_docs"); - }; - - function runTest(path, funcs) { - var db = newDb("test_suite_db", true); - if(funcs.setup) funcs.setup(db); - var before = getStat(path); - if(funcs.run) funcs.run(db); - var after = getStat(path); - if(funcs.test) funcs.test(before, after); - } - - if (debug) debugger; - - (function() { - var db = newDb("test_suite_db"); - db.deleteDb(); - - var before = getStat(["couchdb", "open_databases"]); - db.createDb(); - var after = getStat(["couchdb", "open_databases"]); - TEquals(before+1, after, "Creating a db increments open db count."); - })(); - - runTest(["couchdb", "open_databases"], { - setup: function() {restartServer();}, - run: function(db) {db.open("123");}, - test: function(before, after) { - TEquals(before+1, after, "Opening a db increments open db count."); - } - }); - - runTest(["couchdb", "open_databases"], { - run: function(db) {db.deleteDb();}, - test: function(before, after) { - TEquals(before-1, after, "Deleting a db decrements open db count."); - } - }); - - (function() { - restartServer(); - var max = 5; - - var testFun = function() { - var pre_dbs = getStat(["couchdb", "open_databases"]) || 0; - var pre_files = getStat(["couchdb", "open_os_files"]) || 0; - - var triggered = false; - var db = null; - for(var i = 0; i < max*2; i++) { - while (true) { - try { - db = newDb("test_suite_db_" + i, true); - break; - } catch(e) { - // all_dbs_active error! - triggered = true; - } - } - - // Trigger a delayed commit - db.save({_id: "" + i, "lang": "Awesome!"}); - } - T(triggered, "We managed to force a all_dbs_active error."); - - var open_dbs = getStat(["couchdb", "open_databases"]); - TEquals(open_dbs > 0, true, "We actually opened some dbs."); - TEquals(max, open_dbs, "We only have max db's open."); - - for(var i = 0; i < max * 2; i++) { - newDb("test_suite_db_" + i).deleteDb(); - } - - var post_dbs = getStat(["couchdb", "open_databases"]); - var post_files = getStat(["couchdb", "open_os_files"]); - TEquals(pre_dbs, post_dbs, "We have the same number of open dbs."); - TEquals(pre_files, post_files, "We have the same number of open files."); - }; - - run_on_modified_server( - [{section: "couchdb", key: "max_dbs_open", value: "5"}], - testFun - ); - })(); - - // Just fetching the before value is the extra +1 in test - runTest(["couchdb", "httpd", "requests"], { - run: function() {CouchDB.request("GET", "/");}, - test: function(before, after) { - TEquals(before+2, after, "Request counts are incremented properly."); - } - }); - - runTest(["couchdb", "database_reads"], { - setup: function(db) {db.save({"_id": "test"});}, - run: function(db) {db.open("test");}, - test: function(before, after) { - TEquals(before+1, after, "Reading a doc increments docs reads."); - } - }); - - runTest(["couchdb", "database_reads"], { - setup: function(db) {db.save({"_id": "test"});}, - run: function(db) {db.request("GET", "/");}, - test: function(before, after) { - TEquals(before, after, "Only doc reads increment doc reads."); - } - }); - - runTest(["couchdb", "database_reads"], { - setup: function(db) {db.save({"_id": "test"});}, - run: function(db) {db.open("test", {"open_revs": "all"});}, - test: function(before, after) { - TEquals(before+1, after, "Reading doc revs increments docs reads."); - } - }); - - runTest(["couchdb", "database_writes"], { - run: function(db) {db.save({"a": "1"});}, - test: function(before, after) { - TEquals(before+1, after, "Saving docs incrememnts doc writes."); - } - }); - - runTest(["couchdb", "database_writes"], { - run: function(db) { - CouchDB.request("POST", "/test_suite_db", { - headers: {"Content-Type": "application/json"}, - body: '{"a": "1"}' - }); - }, - test: function(before, after) { - TEquals(before+1, after, "POST'ing new docs increments doc writes."); - } - }); - - runTest(["couchdb", "database_writes"], { - setup: function(db) {db.save({"_id": "test"});}, - run: function(db) {var doc = db.open("test"); db.save(doc);}, - test: function(before, after) { - TEquals(before+1, after, "Updating docs incrememnts doc writes."); - } - }); - - runTest(["couchdb", "database_writes"], { - setup: function(db) {db.save({"_id": "test"});}, - run: function(db) {var doc = db.open("test"); db.deleteDoc(doc);}, - test: function(before, after) { - TEquals(before+1, after, "Deleting docs increments doc writes."); - } - }); - - runTest(["couchdb", "database_writes"], { - setup: function(db) {db.save({"_id": "test"});}, - run: function(db) { - CouchDB.request("COPY", "/test_suite_db/test", { - headers: {"Destination": "copy_of_test"} - }); - }, - test: function(before, after) { - TEquals(before+1, after, "Copying docs increments doc writes."); - } - }); - - runTest(["couchdb", "database_writes"], { - run: function() { - CouchDB.request("PUT", "/test_suite_db/bin_doc2/foo2.txt", { - body: "This is no base64 encoded test", - headers: {"Content-Type": "text/plain;charset=utf-8"} - }); - }, - test: function(before, after) { - TEquals(before+1, after, "Create with attachment increments doc writes."); - } - }); - - runTest(["couchdb", "database_writes"], { - setup: function(db) {db.save({"_id": "test"});}, - run: function(db) { - var doc = db.open("test"); - CouchDB.request("PUT", "/test_suite_db/test/foo2.txt?rev=" + doc._rev, { - body: "This is no base64 encoded text", - headers: {"Content-Type": "text/plainn;charset=utf-8"} - }); - }, - test: function(before, after) { - TEquals(before+1, after, "Adding attachment increments doc writes."); - } - }); - - runTest(["couchdb", "httpd", "bulk_requests"], { - run: function(db) {db.bulkSave(makeDocs(5));}, - test: function(before, after) { - TEquals(before+1, after, "The bulk_requests counter is incremented."); - } - }); - - runTest(["couchdb", "httpd", "view_reads"], { - run: function(db) {doView(db);}, - test: function(before, after) { - TEquals(before+1, after, "Reading a view increments view reads."); - } - }); - - runTest(["couchdb", "httpd", "view_reads"], { - setup: function(db) {db.save({"_id": "test"});}, - run: function(db) {db.open("test");}, - test: function(before, after) { - TEquals(before, after, "Reading a doc doesn't increment view reads."); - } - }); - - runTest(["couchdb", "httpd", "temporary_view_reads"], { - run: function(db) { db.query(function(doc) { emit(doc._id); }); }, - test: function(before, after) { - TEquals(before+1, after, "Temporary views have their own counter."); - } - }); - - runTest(["couchdb", "httpd", "temporary_view_reads"], { - run: function(db) {doView(db);}, - test: function(before, after) { - TEquals(before, after, "Permanent views don't affect temporary views."); - } - }); - - runTest(["couchdb", "httpd", "view_reads"], { - run: function(db) { db.query(function(doc) { emit(doc._id); }); }, - test: function(before, after) { - TEquals(before, after, "Temporary views don't affect permanent views."); - } - }); - - // Relies on getting the stats values being GET requests. - runTest(["couchdb", "httpd_request_methods", "GET"], { - test: function(before, after) { - TEquals(before+1, after, "Get requests are incremented properly."); - } - }); - - runTest(["couchdb", "httpd_request_methods", "GET"], { - run: function() {CouchDB.request("POST", "/");}, - test: function(before, after) { - TEquals(before+1, after, "POST requests don't affect GET counter."); - } - }); - - runTest(["couchdb", "httpd_request_methods", "POST"], { - run: function() {CouchDB.request("POST", "/");}, - test: function(before, after) { - TEquals(before+1, after, "POST requests are incremented properly."); - } - }); - - runTest(["couchdb", "httpd_status_codes", "404"], { - run: function() {CouchDB.request("GET", "/nonexistant_db");}, - test: function(before, after) { - TEquals(before+1, after, "Increments 404 counter on db not found."); - } - }); - - runTest(["couchdb", "httpd_status_codes", "404"], { - run: function() {CouchDB.request("GET", "/");}, - test: function(before, after) { - TEquals(before, after, "Getting DB info doesn't increment 404's"); - } - }); - - var test_metric = function(metric, expected_fields) { - for (var k in metric) { - T(expected_fields.indexOf(k) >= 0, "Unknown property name: " + k); - } - for (var k in expected_fields) { - T(metric[expected_fields[k]] !== undefined, "Missing required property: " + k); - } - }; - - var test_histogram = function(histo) { - test_metric(histo, ["value", "type", "desc"]); - test_metric(histo.value, ["min", "max", "arithmetic_mean", - "geometric_mean", "harmonic_mean", "median", "variance", - "standard_deviation", "skewness", "kurtosis", "percentile", - "histogram", "n"]); - }; - - var test_counter = function(counter) { - test_metric(counter, ["value", "desc", "type"]); - }; - - var test_metrics = function(metrics) { - if (metrics.type === "counter") { - test_counter(metrics); - } else if (metrics.type === "gauge") { - test_counter(metrics); - } else if (metrics.type === "histogram") { - test_histogram(metrics); - } else if (metrics.type === undefined) { - for (var k in metrics) { - test_metrics(metrics[k]); - } - } - }; - - (function() { - var summary = JSON.parse(CouchDB.request("GET", "/_stats", { - headers: {"Accept": "application/json"} - }).responseText); - T(typeof(summary) === 'object'); - test_metrics(summary); - })(); -}; http://git-wip-us.apache.org/repos/asf/couchdb/blob/6a4893aa/share/www/script/test/update_documents.js ---------------------------------------------------------------------- diff --git a/share/www/script/test/update_documents.js b/share/www/script/test/update_documents.js deleted file mode 100644 index bdb7a99..0000000 --- a/share/www/script/test/update_documents.js +++ /dev/null @@ -1,235 +0,0 @@ -// 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.update_documents = function(debug) { - var db = new CouchDB("test_suite_db", {"X-Couch-Full-Commit":"false"}); - db.deleteDb(); - db.createDb(); - if (debug) debugger; - - var designDoc = { - _id:"_design/update", - language: "javascript", - updates: { - "hello" : stringFun(function(doc, req) { - log(doc); - log(req); - if (!doc) { - if (req.id) { - return [ - // Creates a new document with the PUT docid, - { _id : req.id, - reqs : [req] }, - // and returns an HTML response to the client. - "

New World

"]; - }; - // - return [null, "

Empty World

"]; - }; - // we can update the document inline - doc.world = "hello"; - // we can record aspects of the request or use them in application logic. - doc.reqs && doc.reqs.push(req); - doc.edited_by = req.userCtx; - return [doc, "

hello doc

"]; - }), - "in-place" : stringFun(function(doc, req) { - var field = req.query.field; - var value = req.query.value; - var message = "set "+field+" to "+value; - doc[field] = value; - return [doc, message]; - }), - "form-update" : stringFun(function(doc, req) { - for (var field in req.form) { - doc[field] = req.form[field]; - } - var message = "updated doc from form"; - return [doc, message]; - }), - "bump-counter" : stringFun(function(doc, req) { - if (!doc.counter) doc.counter = 0; - doc.counter += 1; - var message = "

bumped it!

"; - return [doc, message]; - }), - "error" : stringFun(function(doc, req) { - superFail.badCrash; - }), - "get-uuid" : stringFun(function(doc, req) { - return [null, req.uuid]; - }), - "code-n-bump" : stringFun(function(doc,req) { - if (!doc.counter) doc.counter = 0; - doc.counter += 1; - var message = "

bumped it!

"; - resp = {"code": 302, "body": message} - return [doc, resp]; - }), - "resp-code" : stringFun(function(doc,req) { - resp = {"code": 302} - return [null, resp]; - }), - "resp-code-and-json" : stringFun(function(doc,req) { - resp = {"code": 302, "json": {"ok": true}} - return [{"_id": req["uuid"]}, resp]; - }), - "binary" : stringFun(function(doc, req) { - var resp = { - "headers" : { - "Content-Type" : "application/octet-stream" - }, - "base64" : "aGVsbG8gd29ybGQh" // "hello world!" encoded - }; - return [doc, resp]; - }), - "empty" : stringFun(function(doc, req) { - return [{}, 'oops']; - }) - } - }; - T(db.save(designDoc).ok); - - var doc = {"word":"plankton", "name":"Rusty"} - var resp = db.save(doc); - T(resp.ok); - var docid = resp.id; - - // update error - var xhr = CouchDB.request("POST", "/test_suite_db/_design/update/_update/"); - T(xhr.status == 404, 'Should be missing'); - T(JSON.parse(xhr.responseText).reason == "Invalid path."); - - // hello update world - xhr = CouchDB.request("PUT", "/test_suite_db/_design/update/_update/hello/"+docid); - T(xhr.status == 201); - T(xhr.responseText == "

hello doc

"); - T(/charset=utf-8/.test(xhr.getResponseHeader("Content-Type"))); - T(equals(docid, xhr.getResponseHeader("X-Couch-Id"))); - - doc = db.open(docid); - T(doc.world == "hello"); - - // Fix for COUCHDB-379 - T(equals(xhr.getResponseHeader("Server").substr(0,7), "CouchDB")); - - // hello update world (no docid) - xhr = CouchDB.request("POST", "/test_suite_db/_design/update/_update/hello"); - T(xhr.status == 200); - T(xhr.responseText == "

Empty World

"); - - // no GET allowed - xhr = CouchDB.request("GET", "/test_suite_db/_design/update/_update/hello"); - // T(xhr.status == 405); // TODO allow qs to throw error code as well as error message - T(JSON.parse(xhr.responseText).error == "method_not_allowed"); - - // // hello update world (non-existing docid) - xhr = CouchDB.request("GET", "/test_suite_db/nonExistingDoc"); - T(xhr.status == 404); - xhr = CouchDB.request("PUT", "/test_suite_db/_design/update/_update/hello/nonExistingDoc"); - T(xhr.status == 201); - T(xhr.responseText == "

New World

"); - xhr = CouchDB.request("GET", "/test_suite_db/nonExistingDoc"); - T(xhr.status == 200); - - // in place update - xhr = CouchDB.request("PUT", "/test_suite_db/_design/update/_update/in-place/"+docid+'?field=title&value=test'); - T(xhr.status == 201); - T(xhr.responseText == "set title to test"); - doc = db.open(docid); - T(doc.title == "test"); - - // form update via application/x-www-form-urlencoded - xhr = CouchDB.request("PUT", "/test_suite_db/_design/update/_update/form-update/"+docid, { - headers : {"Content-Type":"application/x-www-form-urlencoded"}, - body : "formfoo=bar&formbar=foo" - }); - TEquals(201, xhr.status); - TEquals("updated doc from form", xhr.responseText); - doc = db.open(docid); - TEquals("bar", doc.formfoo); - TEquals("foo", doc.formbar); - - // bump counter - xhr = CouchDB.request("PUT", "/test_suite_db/_design/update/_update/bump-counter/"+docid, { - headers : {"X-Couch-Full-Commit":"true"} - }); - T(xhr.status == 201); - T(xhr.responseText == "

bumped it!

"); - doc = db.open(docid); - T(doc.counter == 1); - - // _update honors full commit if you need it to - xhr = CouchDB.request("PUT", "/test_suite_db/_design/update/_update/bump-counter/"+docid, { - headers : {"X-Couch-Full-Commit":"true"} - }); - - var NewRev = xhr.getResponseHeader("X-Couch-Update-NewRev"); - doc = db.open(docid); - T(doc['_rev'] == NewRev); - - - T(doc.counter == 2); - - // Server provides UUID when POSTing without an ID in the URL - xhr = CouchDB.request("POST", "/test_suite_db/_design/update/_update/get-uuid/"); - T(xhr.status == 200); - T(xhr.responseText.length == 32); - - // COUCHDB-1229 - allow slashes in doc ids for update handlers - // /db/_design/doc/_update/handler/doc/id - - var doc = { - _id:"with/slash", - counter:1 - }; - db.save(doc); - xhr = CouchDB.request("PUT", "/test_suite_db/_design/update/_update/bump-counter/with/slash"); - TEquals(201, xhr.status, "should return a 200 status"); - TEquals("

bumped it!

", xhr.responseText, "should report bumping"); - - var doc = db.open("with/slash"); - TEquals(2, doc.counter, "counter should be 2"); - - // COUCHDB-648 - the code in the JSON response should be honored - - xhr = CouchDB.request("PUT", "/test_suite_db/_design/update/_update/code-n-bump/"+docid, { - headers : {"X-Couch-Full-Commit":"true"} - }); - T(xhr.status == 302); - T(xhr.responseText == "

bumped it!

"); - doc = db.open(docid); - T(doc.counter == 3); - - xhr = CouchDB.request("POST", "/test_suite_db/_design/update/_update/resp-code/"); - T(xhr.status == 302); - - xhr = CouchDB.request("POST", "/test_suite_db/_design/update/_update/resp-code-and-json/"); - TEquals(302, xhr.status); - T(JSON.parse(xhr.responseText).ok); - - // base64 response - xhr = CouchDB.request("PUT", "/test_suite_db/_design/update/_update/binary/"+docid, { - headers : {"X-Couch-Full-Commit":"false"}, - body : 'rubbish' - }); - T(xhr.status == 201); - T(xhr.responseText == "hello world!"); - T(/application\/octet-stream/.test(xhr.getResponseHeader("Content-Type"))); - - // Insert doc with empty id - xhr = CouchDB.request("PUT", "/test_suite_db/_design/update/_update/empty/foo"); - TEquals(400, xhr.status); - TEquals("Document id must not be empty", JSON.parse(xhr.responseText).reason); - -}; http://git-wip-us.apache.org/repos/asf/couchdb/blob/6a4893aa/share/www/script/test/users_db.js ---------------------------------------------------------------------- diff --git a/share/www/script/test/users_db.js b/share/www/script/test/users_db.js deleted file mode 100644 index 56dae6b..0000000 --- a/share/www/script/test/users_db.js +++ /dev/null @@ -1,173 +0,0 @@ -// 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.users_db = function(debug) { - // This tests the users db, especially validations - // this should also test that you can log into the couch - - var usersDb = new CouchDB("test_suite_users", {"X-Couch-Full-Commit":"false"}); - - // test that you can treat "_user" as a db-name - // this can complicate people who try to secure the users db with - // an http proxy and fail to get both the actual db and the _user path - // maybe it's not the right approach... - // hard to know what else to do, as we don't let non-admins inspect the config - // to determine the actual users db name. - - function testFun() { - // test that the validation function is installed - var ddoc = usersDb.open("_design/_auth"); - T(ddoc.validate_doc_update); - - // test that you can login as a user using basic auth - var jchrisUserDoc = CouchDB.prepareUserDoc({ - name: "jchris@apache.org" - }, "funnybone"); - T(usersDb.save(jchrisUserDoc).ok); - - T(CouchDB.session().userCtx.name == null); - - // test that you can use basic auth aginst the users db - var s = CouchDB.session({ - headers : { - // base64_encode("jchris@apache.org:funnybone") - "Authorization" : "Basic amNocmlzQGFwYWNoZS5vcmc6ZnVubnlib25l" - } - }); - T(s.userCtx.name == "jchris@apache.org"); - T(s.info.authenticated == "default"); - T(s.info.authentication_db == "test_suite_users"); - TEquals(["oauth", "cookie", "default"], s.info.authentication_handlers); - var s = CouchDB.session({ - headers : { - "Authorization" : "Basic Xzpf" // name and pass of _:_ - } - }); - T(s.name == null); - T(s.info.authenticated == "default"); - - - // ok, now create a conflicting edit on the jchris doc, and make sure there's no login. - var jchrisUser2 = JSON.parse(JSON.stringify(jchrisUserDoc)); - jchrisUser2.foo = "bar"; - T(usersDb.save(jchrisUser2).ok); - try { - usersDb.save(jchrisUserDoc); - T(false && "should be an update conflict"); - } catch(e) { - T(true); - } - // save as bulk with new_edits=false to force conflict save - var resp = usersDb.bulkSave([jchrisUserDoc],{all_or_nothing : true}); - - var jchrisWithConflict = usersDb.open(jchrisUserDoc._id, {conflicts : true}); - T(jchrisWithConflict._conflicts.length == 1); - - // no login with conflicted user doc - try { - var s = CouchDB.session({ - headers : { - "Authorization" : "Basic amNocmlzQGFwYWNoZS5vcmc6ZnVubnlib25l" - } - }); - T(false && "this will throw"); - } catch(e) { - T(e.error == "unauthorized"); - T(/conflict/.test(e.reason)); - } - - // you can delete a user doc - s = CouchDB.session().userCtx; - T(s.name == null); - T(s.roles.indexOf("_admin") !== -1); - T(usersDb.deleteDoc(jchrisWithConflict).ok); - - // you can't change doc from type "user" - jchrisUserDoc = usersDb.open(jchrisUserDoc._id); - jchrisUserDoc.type = "not user"; - try { - usersDb.save(jchrisUserDoc); - T(false && "should only allow us to save doc when type == 'user'"); - } catch(e) { - T(e.reason == "doc.type must be user"); - } - jchrisUserDoc.type = "user"; - - // "roles" must be an array - jchrisUserDoc.roles = "not an array"; - try { - usersDb.save(jchrisUserDoc); - T(false && "should only allow us to save doc when roles is an array"); - } catch(e) { - T(e.reason == "doc.roles must be an array"); - } - jchrisUserDoc.roles = []; - - // "roles" must be an array of strings - jchrisUserDoc.roles = [12]; - try { - usersDb.save(jchrisUserDoc); - T(false && "should only allow us to save doc when roles is an array of strings"); - } catch(e) { - TEquals(e.reason, "doc.roles can only contain strings"); - } - jchrisUserDoc.roles = []; - - // "roles" must exist - delete jchrisUserDoc.roles; - try { - usersDb.save(jchrisUserDoc); - T(false && "should only allow us to save doc when roles exists"); - } catch(e) { - T(e.reason == "doc.roles must exist"); - } - jchrisUserDoc.roles = []; - - // character : is not allowed in usernames - var joeUserDoc = CouchDB.prepareUserDoc({ - name: "joe:erlang" - }, "qwerty"); - try { - usersDb.save(joeUserDoc); - T(false, "shouldn't allow : in usernames"); - } catch(e) { - TEquals("Character `:` is not allowed in usernames.", e.reason); - } - - // test that you can login as a user with a password starting with : - var doc = CouchDB.prepareUserDoc({ - name: "foo@example.org" - }, ":bar"); - T(usersDb.save(doc).ok); - - T(CouchDB.session().userCtx.name == null); - - // test that you can use basic auth aginst the users db - var s = CouchDB.session({ - headers : { - // base64_encode("foo@example.org::bar") - "Authorization" : "Basic Zm9vQGV4YW1wbGUub3JnOjpiYXI=" - } - }); - T(s.userCtx.name == "foo@example.org"); - - }; - - usersDb.deleteDb(); - run_on_modified_server( - [{section: "couch_httpd_auth", - key: "authentication_db", value: usersDb.name}], - testFun - ); - usersDb.deleteDb(); // cleanup - -} http://git-wip-us.apache.org/repos/asf/couchdb/blob/6a4893aa/share/www/script/test/users_db_security.js ---------------------------------------------------------------------- diff --git a/share/www/script/test/users_db_security.js b/share/www/script/test/users_db_security.js deleted file mode 100644 index f2ca8bc..0000000 --- a/share/www/script/test/users_db_security.js +++ /dev/null @@ -1,423 +0,0 @@ -// 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.users_db_security = function(debug) { - var usersDb = new CouchDB("test_suite_users", {"X-Couch-Full-Commit":"false"}); - if (debug) debugger; - - function wait(ms) { - var t0 = new Date(), t1; - do { - CouchDB.request("GET", "/"); - t1 = new Date(); - } while ((t1 - t0) <= ms); - } - - var loginUser = function(username) { - var pws = { - jan: "apple", - jchris: "mp3", - jchris1: "couch", - fdmanana: "foobar", - benoitc: "test" - }; - var username1 = username.replace(/[0-9]$/, ""); - var password = pws[username]; - T(CouchDB.login(username1, pws[username]).ok); - }; - - var open_as = function(db, docId, username) { - loginUser(username); - try { - return db.open(docId, {"anti-cache": Math.round(Math.random() * 100000)}); - } finally { - CouchDB.logout(); - } - }; - - var view_as = function(db, viewname, username) { - loginUser(username); - try { - return db.view(viewname); - } finally { - CouchDB.logout(); - } - }; - - var save_as = function(db, doc, username) - { - loginUser(username); - try { - return db.save(doc); - } catch (ex) { - return ex; - } finally { - CouchDB.logout(); - } - }; - - var changes_as = function(db, username) - { - loginUser(username); - try { - return db.changes(); - } catch(ex) { - return ex; - } finally { - CouchDB.logout(); - } - }; - - var testFun = function() - { - - // _users db - // a doc with a field 'password' should be hashed to 'derived_key' - // with salt and salt stored in 'salt', 'password' is set to null. - // Exising 'derived_key' and 'salt' fields are overwritten with new values - // when a non-null 'password' field exists. - // anonymous should be able to create a user document - var userDoc = { - _id: "org.couchdb.user:jchris", - type: "user", - name: "jchris", - password: "mp3", - roles: [] - }; - - // jan's gonna be admin as he's the first user - TEquals(true, usersDb.save(userDoc).ok, "should save document"); - userDoc = usersDb.open("org.couchdb.user: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"); - - // create server admin - run_on_modified_server([ - { - section: "couch_httpd_auth", - key: "iterations", - value: "1" - }, - { - section: "admins", - key: "jan", - value: "apple" - } - ], function() { - - // anonymous should not be able to read an existing user's user document - var res = usersDb.open("org.couchdb.user:jchris"); - TEquals(null, res, "anonymous user doc read should be not found"); - - // anonymous should not be able to read /_users/_changes - try { - var ch = usersDb.changes(); - T(false, "anonymous can read _changes"); - } catch(e) { - TEquals("unauthorized", e.error, "anoymous can't read _changes"); - } - - // user should be able to read their own document - var jchrisDoc = open_as(usersDb, "org.couchdb.user:jchris", "jchris"); - TEquals("org.couchdb.user:jchris", jchrisDoc._id); - - // user should not be able to read /_users/_changes - var changes = changes_as(usersDb, "jchris"); - TEquals("unauthorized", changes.error, "user can't read _changes"); - - // new 'password' fields should trigger new hashing routine - jchrisDoc.password = "couch"; - - TEquals(true, save_as(usersDb, jchrisDoc, "jchris").ok); - wait(100); - var jchrisDoc = open_as(usersDb, "org.couchdb.user:jchris", "jchris1"); - - 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(true, userDoc.salt != jchrisDoc.salt, "should have new salt"); - TEquals(true, userDoc.derived_key != jchrisDoc.derived_key, - "should have new derived_key"); - - // SHA-1 password hashes are upgraded to PBKDF2 on successful - // authentication - var rnewsonDoc = { - _id: "org.couchdb.user:rnewson", - type: "user", - name: "rnewson", - // password: "plaintext_password", - password_sha: "e29dc3aeed5abf43185c33e479f8998558c59474", - salt: "24f1e0a87c2e374212bda1073107e8ae", - roles: [] - }; - - var password_sha = rnewsonDoc.password_sha, - salt = rnewsonDoc.salt, - derived_key, - iterations; - - usersDb.save(rnewsonDoc); - rnewsonDoc = open_as(usersDb, rnewsonDoc._id, "jan"); - T(!rnewsonDoc.password_scheme); - T(!rnewsonDoc.derived_key); - T(!rnewsonDoc.iterations); - - // check that we don't upgrade when the password is wrong - TEquals("unauthorized", CouchDB.login("rnewson", "wrong_password").error); - rnewsonDoc = open_as(usersDb, rnewsonDoc._id, "jan"); - TEquals(salt, rnewsonDoc.salt); - TEquals(password_sha, rnewsonDoc.password_sha); - T(!rnewsonDoc.password_scheme); - T(!rnewsonDoc.derived_key); - T(!rnewsonDoc.iterations); - - TEquals(true, CouchDB.login("rnewson", "plaintext_password").ok); - rnewsonDoc = usersDb.open(rnewsonDoc._id); - TEquals("pbkdf2", rnewsonDoc.password_scheme); - T(rnewsonDoc.salt != salt); - T(!rnewsonDoc.password_sha); - T(rnewsonDoc.derived_key); - T(rnewsonDoc.iterations); - - salt = rnewsonDoc.salt, - derived_key = rnewsonDoc.derived_key, - iterations = rnewsonDoc.iterations; - - // check that authentication is still working - // and everything is staying the same now - CouchDB.logout(); - TEquals(true, CouchDB.login("rnewson", "plaintext_password").ok); - rnewsonDoc = usersDb.open(rnewsonDoc._id); - TEquals("pbkdf2", rnewsonDoc.password_scheme); - TEquals(salt, rnewsonDoc.salt); - T(!rnewsonDoc.password_sha); - TEquals(derived_key, rnewsonDoc.derived_key); - TEquals(iterations, rnewsonDoc.iterations); - - CouchDB.logout(); - - // user should not be able to read another user's user document - var fdmananaDoc = { - _id: "org.couchdb.user:fdmanana", - type: "user", - name: "fdmanana", - password: "foobar", - roles: [] - }; - - usersDb.save(fdmananaDoc); - - var fdmananaDocAsReadByjchris = - open_as(usersDb, "org.couchdb.user:fdmanana", "jchris1"); - TEquals(null, fdmananaDocAsReadByjchris, - "should not_found opening another user's user doc"); - - - // save a db admin - var benoitcDoc = { - _id: "org.couchdb.user:benoitc", - type: "user", - name: "benoitc", - password: "test", - roles: ["user_admin"] - }; - save_as(usersDb, benoitcDoc, "jan"); - - TEquals(true, CouchDB.login("jan", "apple").ok); - T(usersDb.setSecObj({ - "admins" : { - roles : [], - names : ["benoitc"] - } - }).ok); - CouchDB.logout(); - - // user should not be able to read from any view - var ddoc = { - _id: "_design/user_db_auth", - views: { - test: { - map: "function(doc) { emit(doc._id, null); }" - } - } - }; - - save_as(usersDb, ddoc, "jan"); - - try { - usersDb.view("user_db_auth/test"); - T(false, "user had access to view in admin db"); - } catch(e) { - TEquals("forbidden", e.error, - "non-admins should not be able to read a view"); - } - - // admin should be able to read from any view - var result = view_as(usersDb, "user_db_auth/test", "jan"); - TEquals(4, result.total_rows, "should allow access and list four users to admin"); - - // db admin should be able to read from any view - var result = view_as(usersDb, "user_db_auth/test", "benoitc"); - TEquals(4, result.total_rows, "should allow access and list four users to db admin"); - - - // non-admins can't read design docs - try { - open_as(usersDb, "_design/user_db_auth", "jchris1"); - T(false, "non-admin read design doc, should not happen"); - } catch(e) { - TEquals("forbidden", e.error, "non-admins can't read design docs"); - } - - // admin should be able to read and edit any user doc - fdmananaDoc.password = "mobile"; - var result = save_as(usersDb, fdmananaDoc, "jan"); - TEquals(true, result.ok, "admin should be able to update any user doc"); - - // admin should be able to read and edit any user doc - fdmananaDoc.password = "mobile1"; - var result = save_as(usersDb, fdmananaDoc, "benoitc"); - TEquals(true, result.ok, "db admin by role should be able to update any user doc"); - - TEquals(true, CouchDB.login("jan", "apple").ok); - T(usersDb.setSecObj({ - "admins" : { - roles : ["user_admin"], - names : [] - } - }).ok); - CouchDB.logout(); - - // db admin should be able to read and edit any user doc - fdmananaDoc.password = "mobile2"; - var result = save_as(usersDb, fdmananaDoc, "benoitc"); - TEquals(true, result.ok, "db admin should be able to update any user doc"); - - // ensure creation of old-style docs still works - var robertDoc = CouchDB.prepareUserDoc({ name: "robert" }, "anchovy"); - var result = usersDb.save(robertDoc); - TEquals(true, result.ok, "old-style user docs should still be accepted"); - - // log in one last time so run_on_modified_server can clean up the admin account - TEquals(true, CouchDB.login("jan", "apple").ok); - }); - - run_on_modified_server([ - { - section: "couch_httpd_auth", - key: "iterations", - value: "1" - }, - { - section: "couch_httpd_auth", - key: "public_fields", - value: "name,type" - }, - { - section: "couch_httpd_auth", - key: "users_db_public", - value: "true" - }, - { - section: "admins", - key: "jan", - value: "apple" - } - ], function() { - var res = usersDb.open("org.couchdb.user:jchris"); - TEquals("jchris", res.name); - TEquals("user", res.type); - TEquals(undefined, res.roles); - TEquals(undefined, res.salt); - TEquals(undefined, res.password_scheme); - TEquals(undefined, res.derived_key); - - TEquals(true, CouchDB.login("jchris", "couch").ok); - - var all = usersDb.allDocs({ include_docs: true }); - T(all.rows); - if (all.rows) { - T(all.rows.every(function(row) { - if (row.doc) { - return Object.keys(row.doc).every(function(key) { - return key === 'name' || key === 'type'; - }); - } else { - if(row.id[0] == "_") { - // ignore design docs - return true - } else { - return false; - } - } - })); - } - // log in one last time so run_on_modified_server can clean up the admin account - TEquals(true, CouchDB.login("jan", "apple").ok); - }); - - run_on_modified_server([ - { - section: "couch_httpd_auth", - key: "iterations", - value: "1" - }, - { - section: "couch_httpd_auth", - key: "public_fields", - value: "name" - }, - { - section: "couch_httpd_auth", - key: "users_db_public", - value: "false" - }, - { - section: "admins", - key: "jan", - value: "apple" - } - ], function() { - TEquals(true, CouchDB.login("jchris", "couch").ok); - - try { - var all = usersDb.allDocs({ include_docs: true }); - T(false); // should never hit - } catch(e) { - TEquals("forbidden", e.error, "should throw"); - } - - // COUCHDB-1888 make sure admins always get all fields - TEquals(true, CouchDB.login("jan", "apple").ok); - var all_admin = usersDb.allDocs({ include_docs: "true" }); - TEquals("user", all_admin.rows[2].doc.type, - "should return type"); - - - // log in one last time so run_on_modified_server can clean up the admin account - TEquals(true, CouchDB.login("jan", "apple").ok); - }); - }; - - usersDb.deleteDb(); - run_on_modified_server( - [{section: "couch_httpd_auth", - key: "iterations", value: "1"}, - {section: "couch_httpd_auth", - key: "authentication_db", value: usersDb.name}], - testFun - ); - usersDb.deleteDb(); // cleanup - -}; http://git-wip-us.apache.org/repos/asf/couchdb/blob/6a4893aa/share/www/script/test/utf8.js ---------------------------------------------------------------------- diff --git a/share/www/script/test/utf8.js b/share/www/script/test/utf8.js deleted file mode 100644 index 04f6313..0000000 --- a/share/www/script/test/utf8.js +++ /dev/null @@ -1,42 +0,0 @@ -// 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.utf8 = function(debug) { - var db = new CouchDB("test_suite_db", {"X-Couch-Full-Commit":"false"}); - db.deleteDb(); - db.createDb(); - if (debug) debugger; - - var texts = []; - - texts[0] = "1. Ascii: hello" - texts[1] = "2. Russian: На берегу пустынных волн" - texts[2] = "3. Math: ∮ E⋅da = Q, n → ∞, ∑ f(i) = ∏ g(i)," - texts[3] = "4. Geek: STARGΛ̊TE SG-1" - texts[4] = "5. Braille: ⡌⠁⠧⠑ ⠼⠁⠒ ⡍⠜⠇⠑⠹⠰⠎ ⡣⠕⠌" - texts[5] = "6. null \u0000 byte" - - // check that we can save a reload with full fidelity - for (var i=0; i max_count"); - - run_on_modified_server([{ - "section": "uuids", - "key": "algorithm", - "value": "sequential", - }], - seq_testfun - ); - - // Test utc_random uuids - var utc_testfun = function() { - xhr = CouchDB.request("GET", "/_uuids?count=1000"); - T(xhr.status == 200); - result = JSON.parse(xhr.responseText); - T(result.uuids[1].length == 32); - - // no collisions - var seen = {}; - for(var i in result.uuids) { - var id = result.uuids[i]; - T(seen[id] === undefined); - seen[id] = 1; - } - - // roughly ordered - var u1 = result.uuids[1].substr(0, 13); - var u2 = result.uuids[result.uuids.length-1].substr(0, 13); - T(u1 < u2, "UTC uuids are only roughly ordered, so this assertion may fail occasionally. Don't sweat it."); - }; - - run_on_modified_server([{ - "section": "uuids", - "key": "algorithm", - "value": "utc_random" - }], - utc_testfun - ); - - // Test utc_id uuids - var utc_id_suffix = "frog"; - var suffix_testfun = function() { - xhr = CouchDB.request("GET", "/_uuids?count=10"); - T(xhr.status == 200); - result = JSON.parse(xhr.responseText); - for(var i = 1; i < result.uuids.length; i++) { - T(result.uuids[i].length == 14 + utc_id_suffix.length); - T(result.uuids[i].substring(14) == utc_id_suffix); - T(result.uuids[i-1] < result.uuids[i], "utc_id_suffix uuids are ordered."); - } - }; - - run_on_modified_server([{ - "section": "uuids", - "key": "algorithm", - "value": "utc_id" - }, { - "section": "uuids", - "key": "utc_id_suffix", - "value": utc_id_suffix - }], - suffix_testfun - ); - - }; http://git-wip-us.apache.org/repos/asf/couchdb/blob/6a4893aa/share/www/script/test/view_collation.js ---------------------------------------------------------------------- diff --git a/share/www/script/test/view_collation.js b/share/www/script/test/view_collation.js deleted file mode 100644 index b01a5c5..0000000 --- a/share/www/script/test/view_collation.js +++ /dev/null @@ -1,116 +0,0 @@ -// 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.view_collation = function(debug) { - var db = new CouchDB("test_suite_db", {"X-Couch-Full-Commit":"false"}); - db.deleteDb(); - db.createDb(); - if (debug) debugger; - - // NOTE, the values are already in their correct sort order. Consider this - // a specification of collation of json types. - - var values = []; - - // special values sort before all other types - values.push(null); - values.push(false); - values.push(true); - - // then numbers - values.push(1); - values.push(2); - values.push(3.0); - values.push(4); - - // then text, case sensitive - values.push("a"); - values.push("A"); - values.push("aa"); - values.push("b"); - values.push("B"); - values.push("ba"); - values.push("bb"); - - // then arrays. compared element by element until different. - // Longer arrays sort after their prefixes - values.push(["a"]); - values.push(["b"]); - values.push(["b","c"]); - values.push(["b","c", "a"]); - values.push(["b","d"]); - values.push(["b","d", "e"]); - - // then object, compares each key value in the list until different. - // larger objects sort after their subset objects. - values.push({a:1}); - values.push({a:2}); - values.push({b:1}); - values.push({b:2}); - values.push({b:2, a:1}); // Member order does matter for collation. - // CouchDB preserves member order - // but doesn't require that clients will. - // (this test might fail if used with a js engine - // that doesn't preserve order) - values.push({b:2, c:2}); - - for (var i=0; i