// 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 users_db_name = '_users';
  var usersDb = new CouchDB(users_db_name, {"X-Couch-Full-Commit":"false"});
  try { usersDb.createDb(); } catch (e) { /* ignore if exists*/ }
  // have a 2nd "normal" DB 2 provoke conflicts
  var usersDbAlt = new CouchDB(get_random_db_name(), {"X-Couch-Full-Commit":"false"});
  usersDbAlt.createDb();

  // 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
    // this will fail When the test is run in isolation,
    // since it doesn’t wait for the ddoc to be created.
    // in a full test suite run, this is fine.
    // dev trick: run `test/javascript/run basics users_db`
    // 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 == "" + users_db_name + "");
    TEquals(["cookie", "default"], s.info.authentication_handlers);
    var s = CouchDB.session({
      headers : {
        "Authorization" : "Basic Xzpf" // name and pass of _:_
      }
    });
    T(s.name == null);
    T(typeof(s.info.authenticated) === 'undefined');
    CouchDB.logout();
    
    // ok, now create a conflicting edit on the jchris doc, and make sure there's no login.
    // (use replication to create the conflict) - need 2 be admin
    CouchDB.login("jan", "apple");
    CouchDB.replicate(usersDb.name, usersDbAlt.name);
    // save in one DB
    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);
    }

    // then in the other
    var jchrisUser3 = JSON.parse(JSON.stringify(jchrisUserDoc));
    jchrisUser3.foo = "barrrr";
    T(usersDbAlt.save(jchrisUser3).ok);
    CouchDB.replicate(usersDbAlt.name, usersDb.name); // now we should have a conflict

    var jchrisWithConflict = usersDb.open(jchrisUserDoc._id, {conflicts : true});
    T(jchrisWithConflict._conflicts.length == 1);
    CouchDB.logout();

    wait(5000) // wait for auth_cache invalidation

    // 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
    // there is NO admin party here - so we have to login again
    CouchDB.login("jan", "apple");
    s = CouchDB.session().userCtx;
    //T(s.name == null);
    //console.log(JSON.stringify(usersDb.allDocs()));
    T(s.roles.indexOf("_admin") !== -1);
// TODO: fix deletion of user docs
//    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);
    CouchDB.logout();

    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");

  };

  run_on_modified_server(
    [{section: "couch_httpd_auth",
      key: "authentication_db", value: usersDb.name},
     {section: "chttpd_auth",
       key: "authentication_db", value: usersDb.name},
     {section: "couch_httpd_auth",
      key: "iterations", value: "1"},
     {section: "admins",
      key: "jan", value: "apple"}],
    function() {
      try {
        testFun();
      } finally {
        CouchDB.login("jan", "apple");
        usersDb.deleteDb(); // cleanup
        waitForSuccess(function() {
            var req = CouchDB.request("GET", usersDb.name);
            if (req.status == 404) {
              return true
            }
            throw({});
        }, "usersdb.deleteDb")
        usersDb.createDb();
        usersDbAlt.deleteDb(); // cleanup
      }
    }
  );
  CouchDB.logout();
}
