services/sync/tests/unit/test_service_login.js

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:80a2e25528e0
1 /* Any copyright is dedicated to the Public Domain.
2 http://creativecommons.org/publicdomain/zero/1.0/ */
3
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");
10
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 }
24
25 function run_test() {
26 let logger = Log.repository.rootLogger;
27 Log.repository.rootLogger.addAppender(new Log.DumpAppender());
28
29 run_next_test();
30 }
31
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 });
44
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;
52
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),
56
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 });
65
66 Service.serverURL = server.baseURI;
67 return server;
68 }
69
70 add_test(function test_login_logout() {
71 let server = setup();
72
73 try {
74 _("Force the initial state.");
75 ensureLegacyIdentityManager();
76 Service.status.service = STATUS_OK;
77 do_check_eq(Service.status.service, STATUS_OK);
78
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);
84
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);
92
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);
99
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);
106
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);
112
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);
124
125 _("Logout.");
126 Service.logout();
127 do_check_false(Service.isLoggedIn);
128
129 _("Logging out again won't do any harm.");
130 Service.logout();
131 do_check_false(Service.isLoggedIn);
132
133 } finally {
134 Svc.Prefs.resetBranch("");
135 server.stop(run_next_test);
136 }
137 });
138
139 add_test(function test_login_on_sync() {
140 let server = setup();
141 setBasicCredentials("johndoe", "ilovejane", "bar");
142
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 };
153
154 Service.sync();
155
156 do_check_true(loginCalled);
157 Service.login = oldLogin;
158
159 // Stub mpLocked.
160 let mpLockedF = Utils.mpLocked;
161 let mpLocked = true;
162 Utils.mpLocked = function() mpLocked;
163
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 };
172
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.
184
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);
190
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;
197
198 // TODO: need better tests around master password prompting. See Bug 620583.
199
200 mpLocked = true;
201
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 });
211
212 let oldClearSyncTriggers = Service.scheduler.clearSyncTriggers;
213 let oldLockedSync = Service._lockedSync;
214
215 let cSTCalled = false;
216 let lockedSyncCalled = false;
217
218 Service.scheduler.clearSyncTriggers = function() { cSTCalled = true; };
219 Service._lockedSync = function() { lockedSyncCalled = true; };
220
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);
228
229 _("Sync doesn't proceed and clears triggers if MP is still locked.");
230 Service.sync();
231
232 do_check_true(cSTCalled);
233 do_check_false(lockedSyncCalled);
234
235 Service.identity.__defineGetter__("syncKey", oldGetter);
236 Service.identity.__defineSetter__("syncKey", oldSetter);
237
238 // N.B., a bunch of methods are stubbed at this point. Be careful putting
239 // new tests after this point!
240
241 } finally {
242 Svc.Prefs.resetBranch("");
243 server.stop(run_next_test);
244 }
245 });

mercurial