services/sync/tests/unit/test_service_login.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* Any copyright is dedicated to the Public Domain.
     2    http://creativecommons.org/publicdomain/zero/1.0/ */
     4 Cu.import("resource://gre/modules/Log.jsm");
     5 Cu.import("resource://services-sync/constants.js");
     6 Cu.import("resource://services-sync/service.js");
     7 Cu.import("resource://services-sync/policies.js");
     8 Cu.import("resource://services-sync/util.js");
     9 Cu.import("resource://testing-common/services/sync/utils.js");
    11 function login_handling(handler) {
    12   return function (request, response) {
    13     if (basic_auth_matches(request, "johndoe", "ilovejane") ||
    14         basic_auth_matches(request, "janedoe", "ilovejohn")) {
    15       handler(request, response);
    16     } else {
    17       let body = "Unauthorized";
    18       response.setStatusLine(request.httpVersion, 401, "Unauthorized");
    19       response.setHeader("Content-Type", "text/plain");
    20       response.bodyOutputStream.write(body, body.length);
    21     }
    22   };
    23 }
    25 function run_test() {
    26   let logger = Log.repository.rootLogger;
    27   Log.repository.rootLogger.addAppender(new Log.DumpAppender());
    29   run_next_test();
    30 }
    32 add_test(function test_offline() {
    33   try {
    34     _("The right bits are set when we're offline.");
    35     Services.io.offline = true;
    36     do_check_false(!!Service.login());
    37     do_check_eq(Service.status.login, LOGIN_FAILED_NETWORK_ERROR);
    38     Services.io.offline = false;
    39   } finally {
    40     Svc.Prefs.resetBranch("");
    41     run_next_test();
    42   }
    43 });
    45 function setup() {
    46   let janeHelper = track_collections_helper();
    47   let janeU      = janeHelper.with_updated_collection;
    48   let janeColls  = janeHelper.collections;
    49   let johnHelper = track_collections_helper();
    50   let johnU      = johnHelper.with_updated_collection;
    51   let johnColls  = johnHelper.collections;
    53   let server = httpd_setup({
    54     "/1.1/johndoe/info/collections": login_handling(johnHelper.handler),
    55     "/1.1/janedoe/info/collections": login_handling(janeHelper.handler),
    57     // We need these handlers because we test login, and login
    58     // is where keys are generated or fetched.
    59     // TODO: have Jane fetch her keys, not generate them...
    60     "/1.1/johndoe/storage/crypto/keys": johnU("crypto", new ServerWBO("keys").handler()),
    61     "/1.1/johndoe/storage/meta/global": johnU("meta",   new ServerWBO("global").handler()),
    62     "/1.1/janedoe/storage/crypto/keys": janeU("crypto", new ServerWBO("keys").handler()),
    63     "/1.1/janedoe/storage/meta/global": janeU("meta",   new ServerWBO("global").handler())
    64   });
    66   Service.serverURL = server.baseURI;
    67   return server;
    68 }
    70 add_test(function test_login_logout() {
    71   let server = setup();
    73   try {
    74     _("Force the initial state.");
    75     ensureLegacyIdentityManager();
    76     Service.status.service = STATUS_OK;
    77     do_check_eq(Service.status.service, STATUS_OK);
    79     _("Try logging in. It won't work because we're not configured yet.");
    80     Service.login();
    81     do_check_eq(Service.status.service, CLIENT_NOT_CONFIGURED);
    82     do_check_eq(Service.status.login, LOGIN_FAILED_NO_USERNAME);
    83     do_check_false(Service.isLoggedIn);
    85     _("Try again with username and password set.");
    86     Service.identity.account = "johndoe";
    87     Service.identity.basicPassword = "ilovejane";
    88     Service.login();
    89     do_check_eq(Service.status.service, CLIENT_NOT_CONFIGURED);
    90     do_check_eq(Service.status.login, LOGIN_FAILED_NO_PASSPHRASE);
    91     do_check_false(Service.isLoggedIn);
    93     _("Success if passphrase is set.");
    94     Service.identity.syncKey = "foo";
    95     Service.login();
    96     do_check_eq(Service.status.service, STATUS_OK);
    97     do_check_eq(Service.status.login, LOGIN_SUCCEEDED);
    98     do_check_true(Service.isLoggedIn);
   100     _("We can also pass username, password and passphrase to login().");
   101     Service.login("janedoe", "incorrectpassword", "bar");
   102     setBasicCredentials("janedoe", "incorrectpassword", "bar");
   103     do_check_eq(Service.status.service, LOGIN_FAILED);
   104     do_check_eq(Service.status.login, LOGIN_FAILED_LOGIN_REJECTED);
   105     do_check_false(Service.isLoggedIn);
   107     _("Try again with correct password.");
   108     Service.login("janedoe", "ilovejohn");
   109     do_check_eq(Service.status.service, STATUS_OK);
   110     do_check_eq(Service.status.login, LOGIN_SUCCEEDED);
   111     do_check_true(Service.isLoggedIn);
   113     _("Calling login() with parameters when the client is unconfigured sends notification.");
   114     let notified = false;
   115     Svc.Obs.add("weave:service:setup-complete", function() {
   116       notified = true;
   117     });
   118     setBasicCredentials(null, null, null);
   119     Service.login("janedoe", "ilovejohn", "bar");
   120     do_check_true(notified);
   121     do_check_eq(Service.status.service, STATUS_OK);
   122     do_check_eq(Service.status.login, LOGIN_SUCCEEDED);
   123     do_check_true(Service.isLoggedIn);
   125     _("Logout.");
   126     Service.logout();
   127     do_check_false(Service.isLoggedIn);
   129     _("Logging out again won't do any harm.");
   130     Service.logout();
   131     do_check_false(Service.isLoggedIn);
   133   } finally {
   134     Svc.Prefs.resetBranch("");
   135     server.stop(run_next_test);
   136   }
   137 });
   139 add_test(function test_login_on_sync() {
   140   let server = setup();
   141   setBasicCredentials("johndoe", "ilovejane", "bar");
   143   try {
   144     _("Sync calls login.");
   145     let oldLogin = Service.login;
   146     let loginCalled = false;
   147     Service.login = function() {
   148       loginCalled = true;
   149       Service.status.login = LOGIN_SUCCEEDED;
   150       this._loggedIn = false;           // So that sync aborts.
   151       return true;
   152     };
   154     Service.sync();
   156     do_check_true(loginCalled);
   157     Service.login = oldLogin;
   159     // Stub mpLocked.
   160     let mpLockedF = Utils.mpLocked;
   161     let mpLocked = true;
   162     Utils.mpLocked = function() mpLocked;
   164     // Stub scheduleNextSync. This gets called within checkSyncStatus if we're
   165     // ready to sync, so use it as an indicator.
   166     let scheduleNextSyncF = Service.scheduler.scheduleNextSync;
   167     let scheduleCalled = false;
   168     Service.scheduler.scheduleNextSync = function(wait) {
   169       scheduleCalled = true;
   170       scheduleNextSyncF.call(this, wait);
   171     };
   173     // Autoconnect still tries to connect in the background (useful behavior:
   174     // for non-MP users and unlocked MPs, this will detect version expiry
   175     // earlier).
   176     //
   177     // Consequently, non-MP users will be logged in as in the pre-Bug 543784 world,
   178     // and checkSyncStatus reflects that by waiting for login.
   179     //
   180     // This process doesn't apply if your MP is still locked, so we make
   181     // checkSyncStatus accept a locked MP in place of being logged in.
   182     //
   183     // This test exercises these two branches.
   185     _("We're ready to sync if locked.");
   186     Service.enabled = true;
   187     Services.io.offline = false;
   188     Service.scheduler.checkSyncStatus();
   189     do_check_true(scheduleCalled);
   191     _("... and also if we're not locked.");
   192     scheduleCalled = false;
   193     mpLocked = false;
   194     Service.scheduler.checkSyncStatus();
   195     do_check_true(scheduleCalled);
   196     Service.scheduler.scheduleNextSync = scheduleNextSyncF;
   198     // TODO: need better tests around master password prompting. See Bug 620583.
   200     mpLocked = true;
   202     // Testing exception handling if master password dialog is canceled.
   203     // Do this by monkeypatching.
   204     let oldGetter = Service.identity.__lookupGetter__("syncKey");
   205     let oldSetter = Service.identity.__lookupSetter__("syncKey");
   206     _("Old passphrase function is " + oldGetter);
   207     Service.identity.__defineGetter__("syncKey",
   208                            function() {
   209                              throw "User canceled Master Password entry";
   210                            });
   212     let oldClearSyncTriggers = Service.scheduler.clearSyncTriggers;
   213     let oldLockedSync = Service._lockedSync;
   215     let cSTCalled = false;
   216     let lockedSyncCalled = false;
   218     Service.scheduler.clearSyncTriggers = function() { cSTCalled = true; };
   219     Service._lockedSync = function() { lockedSyncCalled = true; };
   221     _("If master password is canceled, login fails and we report lockage.");
   222     do_check_false(!!Service.login());
   223     do_check_eq(Service.status.login, MASTER_PASSWORD_LOCKED);
   224     do_check_eq(Service.status.service, LOGIN_FAILED);
   225     _("Locked? " + Utils.mpLocked());
   226     _("checkSync reports the correct term.");
   227     do_check_eq(Service._checkSync(), kSyncMasterPasswordLocked);
   229     _("Sync doesn't proceed and clears triggers if MP is still locked.");
   230     Service.sync();
   232     do_check_true(cSTCalled);
   233     do_check_false(lockedSyncCalled);
   235     Service.identity.__defineGetter__("syncKey", oldGetter);
   236     Service.identity.__defineSetter__("syncKey", oldSetter);
   238     // N.B., a bunch of methods are stubbed at this point. Be careful putting
   239     // new tests after this point!
   241   } finally {
   242     Svc.Prefs.resetBranch("");
   243     server.stop(run_next_test);
   244   }
   245 });

mercurial