|
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/keys.js"); |
|
7 Cu.import("resource://services-sync/service.js"); |
|
8 Cu.import("resource://services-sync/util.js"); |
|
9 Cu.import("resource://testing-common/services/sync/fakeservices.js"); |
|
10 Cu.import("resource://testing-common/services/sync/utils.js"); |
|
11 |
|
12 function run_test() { |
|
13 let logger = Log.repository.rootLogger; |
|
14 Log.repository.rootLogger.addAppender(new Log.DumpAppender()); |
|
15 |
|
16 let guidSvc = new FakeGUIDService(); |
|
17 let clients = new ServerCollection(); |
|
18 let meta_global = new ServerWBO('global'); |
|
19 |
|
20 let collectionsHelper = track_collections_helper(); |
|
21 let upd = collectionsHelper.with_updated_collection; |
|
22 let collections = collectionsHelper.collections; |
|
23 |
|
24 function wasCalledHandler(wbo) { |
|
25 let handler = wbo.handler(); |
|
26 return function() { |
|
27 wbo.wasCalled = true; |
|
28 handler.apply(this, arguments); |
|
29 }; |
|
30 } |
|
31 |
|
32 let keysWBO = new ServerWBO("keys"); |
|
33 let cryptoColl = new ServerCollection({keys: keysWBO}); |
|
34 let metaColl = new ServerCollection({global: meta_global}); |
|
35 do_test_pending(); |
|
36 |
|
37 /** |
|
38 * Handle the bulk DELETE request sent by wipeServer. |
|
39 */ |
|
40 function storageHandler(request, response) { |
|
41 do_check_eq("DELETE", request.method); |
|
42 do_check_true(request.hasHeader("X-Confirm-Delete")); |
|
43 |
|
44 _("Wiping out all collections."); |
|
45 cryptoColl.delete({}); |
|
46 clients.delete({}); |
|
47 metaColl.delete({}); |
|
48 |
|
49 let ts = new_timestamp(); |
|
50 collectionsHelper.update_collection("crypto", ts); |
|
51 collectionsHelper.update_collection("clients", ts); |
|
52 collectionsHelper.update_collection("meta", ts); |
|
53 return_timestamp(request, response, ts); |
|
54 } |
|
55 |
|
56 let server = httpd_setup({ |
|
57 "/1.1/johndoe/storage": storageHandler, |
|
58 "/1.1/johndoe/storage/crypto/keys": upd("crypto", keysWBO.handler()), |
|
59 "/1.1/johndoe/storage/crypto": upd("crypto", cryptoColl.handler()), |
|
60 "/1.1/johndoe/storage/clients": upd("clients", clients.handler()), |
|
61 "/1.1/johndoe/storage/meta/global": upd("meta", wasCalledHandler(meta_global)), |
|
62 "/1.1/johndoe/storage/meta": upd("meta", wasCalledHandler(metaColl)), |
|
63 "/1.1/johndoe/info/collections": collectionsHelper.handler |
|
64 }); |
|
65 |
|
66 try { |
|
67 _("Log in."); |
|
68 ensureLegacyIdentityManager(); |
|
69 Service.serverURL = server.baseURI; |
|
70 |
|
71 _("Checking Status.sync with no credentials."); |
|
72 Service.verifyAndFetchSymmetricKeys(); |
|
73 do_check_eq(Service.status.sync, CREDENTIALS_CHANGED); |
|
74 do_check_eq(Service.status.login, LOGIN_FAILED_NO_PASSPHRASE); |
|
75 |
|
76 _("Log in with an old secret phrase, is upgraded to Sync Key."); |
|
77 Service.login("johndoe", "ilovejane", "my old secret phrase!!1!"); |
|
78 _("End of login"); |
|
79 do_check_true(Service.isLoggedIn); |
|
80 do_check_true(Utils.isPassphrase(Service.identity.syncKey)); |
|
81 let syncKey = Service.identity.syncKey; |
|
82 Service.startOver(); |
|
83 |
|
84 Service.serverURL = server.baseURI; |
|
85 Service.login("johndoe", "ilovejane", syncKey); |
|
86 do_check_true(Service.isLoggedIn); |
|
87 |
|
88 _("Checking that remoteSetup returns true when credentials have changed."); |
|
89 Service.recordManager.get(Service.metaURL).payload.syncID = "foobar"; |
|
90 do_check_true(Service._remoteSetup()); |
|
91 |
|
92 _("Do an initial sync."); |
|
93 let beforeSync = Date.now()/1000; |
|
94 Service.sync(); |
|
95 |
|
96 _("Checking that remoteSetup returns true."); |
|
97 do_check_true(Service._remoteSetup()); |
|
98 |
|
99 _("Verify that the meta record was uploaded."); |
|
100 do_check_eq(meta_global.data.syncID, Service.syncID); |
|
101 do_check_eq(meta_global.data.storageVersion, STORAGE_VERSION); |
|
102 do_check_eq(meta_global.data.engines.clients.version, Service.clientsEngine.version); |
|
103 do_check_eq(meta_global.data.engines.clients.syncID, Service.clientsEngine.syncID); |
|
104 |
|
105 _("Set the collection info hash so that sync() will remember the modified times for future runs."); |
|
106 collections.meta = Service.clientsEngine.lastSync; |
|
107 collections.clients = Service.clientsEngine.lastSync; |
|
108 Service.sync(); |
|
109 |
|
110 _("Sync again and verify that meta/global wasn't downloaded again"); |
|
111 meta_global.wasCalled = false; |
|
112 Service.sync(); |
|
113 do_check_false(meta_global.wasCalled); |
|
114 |
|
115 _("Fake modified records. This will cause a redownload, but not reupload since it hasn't changed."); |
|
116 collections.meta += 42; |
|
117 meta_global.wasCalled = false; |
|
118 |
|
119 let metaModified = meta_global.modified; |
|
120 |
|
121 Service.sync(); |
|
122 do_check_true(meta_global.wasCalled); |
|
123 do_check_eq(metaModified, meta_global.modified); |
|
124 |
|
125 _("Checking bad passphrases."); |
|
126 let pp = Service.identity.syncKey; |
|
127 Service.identity.syncKey = "notvalid"; |
|
128 do_check_false(Service.verifyAndFetchSymmetricKeys()); |
|
129 do_check_eq(Service.status.sync, CREDENTIALS_CHANGED); |
|
130 do_check_eq(Service.status.login, LOGIN_FAILED_INVALID_PASSPHRASE); |
|
131 Service.identity.syncKey = pp; |
|
132 do_check_true(Service.verifyAndFetchSymmetricKeys()); |
|
133 |
|
134 // changePassphrase wipes our keys, and they're regenerated on next sync. |
|
135 _("Checking changed passphrase."); |
|
136 let existingDefault = Service.collectionKeys.keyForCollection(); |
|
137 let existingKeysPayload = keysWBO.payload; |
|
138 let newPassphrase = "bbbbbabcdeabcdeabcdeabcdea"; |
|
139 Service.changePassphrase(newPassphrase); |
|
140 |
|
141 _("Local key cache is full, but different."); |
|
142 do_check_true(!!Service.collectionKeys._default); |
|
143 do_check_false(Service.collectionKeys._default.equals(existingDefault)); |
|
144 |
|
145 _("Server has new keys."); |
|
146 do_check_true(!!keysWBO.payload); |
|
147 do_check_true(!!keysWBO.modified); |
|
148 do_check_neq(keysWBO.payload, existingKeysPayload); |
|
149 |
|
150 // Try to screw up HMAC calculation. |
|
151 // Re-encrypt keys with a new random keybundle, and upload them to the |
|
152 // server, just as might happen with a second client. |
|
153 _("Attempting to screw up HMAC by re-encrypting keys."); |
|
154 let keys = Service.collectionKeys.asWBO(); |
|
155 let b = new BulkKeyBundle("hmacerror"); |
|
156 b.generateRandom(); |
|
157 collections.crypto = keys.modified = 100 + (Date.now()/1000); // Future modification time. |
|
158 keys.encrypt(b); |
|
159 keys.upload(Service.resource(Service.cryptoKeysURL)); |
|
160 |
|
161 do_check_false(Service.verifyAndFetchSymmetricKeys()); |
|
162 do_check_eq(Service.status.login, LOGIN_FAILED_INVALID_PASSPHRASE); |
|
163 |
|
164 } finally { |
|
165 Svc.Prefs.resetBranch(""); |
|
166 server.stop(do_test_finished); |
|
167 } |
|
168 } |