Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* Any copyright is dedicated to the Public Domain. |
michael@0 | 2 | * http://creativecommons.org/publicdomain/zero/1.0/ */ |
michael@0 | 3 | |
michael@0 | 4 | Cu.import("resource://services-sync/constants.js"); |
michael@0 | 5 | Cu.import("resource://services-sync/identity.js"); |
michael@0 | 6 | Cu.import("resource://services-sync/util.js"); |
michael@0 | 7 | |
michael@0 | 8 | let identity = new IdentityManager(); |
michael@0 | 9 | |
michael@0 | 10 | function run_test() { |
michael@0 | 11 | initTestLogging("Trace"); |
michael@0 | 12 | Log.repository.getLogger("Sync.Identity").level = Log.Level.Trace; |
michael@0 | 13 | |
michael@0 | 14 | run_next_test(); |
michael@0 | 15 | } |
michael@0 | 16 | |
michael@0 | 17 | add_test(function test_username_from_account() { |
michael@0 | 18 | _("Ensure usernameFromAccount works properly."); |
michael@0 | 19 | |
michael@0 | 20 | do_check_eq(identity.usernameFromAccount(null), null); |
michael@0 | 21 | do_check_eq(identity.usernameFromAccount("user"), "user"); |
michael@0 | 22 | do_check_eq(identity.usernameFromAccount("User"), "user"); |
michael@0 | 23 | do_check_eq(identity.usernameFromAccount("john@doe.com"), |
michael@0 | 24 | "7wohs32cngzuqt466q3ge7indszva4of"); |
michael@0 | 25 | |
michael@0 | 26 | run_next_test(); |
michael@0 | 27 | }); |
michael@0 | 28 | |
michael@0 | 29 | add_test(function test_account_username() { |
michael@0 | 30 | _("Ensure the account and username attributes work properly."); |
michael@0 | 31 | |
michael@0 | 32 | _("Verify initial state"); |
michael@0 | 33 | do_check_eq(Svc.Prefs.get("account"), undefined); |
michael@0 | 34 | do_check_eq(Svc.Prefs.get("username"), undefined); |
michael@0 | 35 | do_check_eq(identity.account, null); |
michael@0 | 36 | do_check_eq(identity.username, null); |
michael@0 | 37 | |
michael@0 | 38 | _("The 'username' attribute is normalized to lower case, updates preferences and identities."); |
michael@0 | 39 | identity.username = "TarZan"; |
michael@0 | 40 | do_check_eq(identity.username, "tarzan"); |
michael@0 | 41 | do_check_eq(Svc.Prefs.get("username"), "tarzan"); |
michael@0 | 42 | do_check_eq(identity.username, "tarzan"); |
michael@0 | 43 | |
michael@0 | 44 | _("If not set, the 'account attribute' falls back to the username for backwards compatibility."); |
michael@0 | 45 | do_check_eq(identity.account, "tarzan"); |
michael@0 | 46 | |
michael@0 | 47 | _("Setting 'username' to a non-truthy value resets the pref."); |
michael@0 | 48 | identity.username = null; |
michael@0 | 49 | do_check_eq(identity.username, null); |
michael@0 | 50 | do_check_eq(identity.account, null); |
michael@0 | 51 | const default_marker = {}; |
michael@0 | 52 | do_check_eq(Svc.Prefs.get("username", default_marker), default_marker); |
michael@0 | 53 | do_check_eq(identity.username, null); |
michael@0 | 54 | |
michael@0 | 55 | _("The 'account' attribute will set the 'username' if it doesn't contain characters that aren't allowed in the username."); |
michael@0 | 56 | identity.account = "johndoe"; |
michael@0 | 57 | do_check_eq(identity.account, "johndoe"); |
michael@0 | 58 | do_check_eq(identity.username, "johndoe"); |
michael@0 | 59 | do_check_eq(Svc.Prefs.get("username"), "johndoe"); |
michael@0 | 60 | do_check_eq(identity.username, "johndoe"); |
michael@0 | 61 | |
michael@0 | 62 | _("If 'account' contains disallowed characters such as @, 'username' will the base32 encoded SHA1 hash of 'account'"); |
michael@0 | 63 | identity.account = "John@Doe.com"; |
michael@0 | 64 | do_check_eq(identity.account, "john@doe.com"); |
michael@0 | 65 | do_check_eq(identity.username, "7wohs32cngzuqt466q3ge7indszva4of"); |
michael@0 | 66 | |
michael@0 | 67 | _("Setting 'account' to a non-truthy value resets the pref."); |
michael@0 | 68 | identity.account = null; |
michael@0 | 69 | do_check_eq(identity.account, null); |
michael@0 | 70 | do_check_eq(Svc.Prefs.get("account", default_marker), default_marker); |
michael@0 | 71 | do_check_eq(identity.username, null); |
michael@0 | 72 | do_check_eq(Svc.Prefs.get("username", default_marker), default_marker); |
michael@0 | 73 | |
michael@0 | 74 | Svc.Prefs.resetBranch(""); |
michael@0 | 75 | run_next_test(); |
michael@0 | 76 | }); |
michael@0 | 77 | |
michael@0 | 78 | add_test(function test_basic_password() { |
michael@0 | 79 | _("Ensure basic password setting works as expected."); |
michael@0 | 80 | |
michael@0 | 81 | identity.account = null; |
michael@0 | 82 | do_check_eq(identity.currentAuthState, LOGIN_FAILED_NO_USERNAME); |
michael@0 | 83 | let thrown = false; |
michael@0 | 84 | try { |
michael@0 | 85 | identity.basicPassword = "foobar"; |
michael@0 | 86 | } catch (ex) { |
michael@0 | 87 | thrown = true; |
michael@0 | 88 | } |
michael@0 | 89 | |
michael@0 | 90 | do_check_true(thrown); |
michael@0 | 91 | thrown = false; |
michael@0 | 92 | |
michael@0 | 93 | identity.account = "johndoe"; |
michael@0 | 94 | do_check_eq(identity.currentAuthState, LOGIN_FAILED_NO_PASSWORD); |
michael@0 | 95 | identity.basicPassword = "password"; |
michael@0 | 96 | do_check_eq(identity.basicPassword, "password"); |
michael@0 | 97 | do_check_eq(identity.currentAuthState, LOGIN_FAILED_NO_PASSPHRASE); |
michael@0 | 98 | do_check_true(identity.hasBasicCredentials()); |
michael@0 | 99 | |
michael@0 | 100 | identity.account = null; |
michael@0 | 101 | |
michael@0 | 102 | run_next_test(); |
michael@0 | 103 | }); |
michael@0 | 104 | |
michael@0 | 105 | add_test(function test_basic_password_persistence() { |
michael@0 | 106 | _("Ensure credentials are saved and restored to the login manager properly."); |
michael@0 | 107 | |
michael@0 | 108 | // Just in case. |
michael@0 | 109 | identity.account = null; |
michael@0 | 110 | identity.deleteSyncCredentials(); |
michael@0 | 111 | |
michael@0 | 112 | identity.account = "janesmith"; |
michael@0 | 113 | identity.basicPassword = "ilovejohn"; |
michael@0 | 114 | identity.persistCredentials(); |
michael@0 | 115 | |
michael@0 | 116 | let im1 = new IdentityManager(); |
michael@0 | 117 | do_check_eq(im1._basicPassword, null); |
michael@0 | 118 | do_check_eq(im1.username, "janesmith"); |
michael@0 | 119 | do_check_eq(im1.basicPassword, "ilovejohn"); |
michael@0 | 120 | |
michael@0 | 121 | let im2 = new IdentityManager(); |
michael@0 | 122 | do_check_eq(im2._basicPassword, null); |
michael@0 | 123 | |
michael@0 | 124 | _("Now remove the password and ensure it is deleted from storage."); |
michael@0 | 125 | identity.basicPassword = null; |
michael@0 | 126 | identity.persistCredentials(); // This should nuke from storage. |
michael@0 | 127 | do_check_eq(im2.basicPassword, null); |
michael@0 | 128 | |
michael@0 | 129 | _("Ensure that retrieving an unset but unpersisted removal returns null."); |
michael@0 | 130 | identity.account = "janesmith"; |
michael@0 | 131 | identity.basicPassword = "myotherpassword"; |
michael@0 | 132 | identity.persistCredentials(); |
michael@0 | 133 | |
michael@0 | 134 | identity.basicPassword = null; |
michael@0 | 135 | do_check_eq(identity.basicPassword, null); |
michael@0 | 136 | |
michael@0 | 137 | // Reset for next test. |
michael@0 | 138 | identity.account = null; |
michael@0 | 139 | identity.persistCredentials(); |
michael@0 | 140 | |
michael@0 | 141 | run_next_test(); |
michael@0 | 142 | }); |
michael@0 | 143 | |
michael@0 | 144 | add_test(function test_sync_key() { |
michael@0 | 145 | _("Ensure Sync Key works as advertised."); |
michael@0 | 146 | |
michael@0 | 147 | _("Ensure setting a Sync Key before an account throws."); |
michael@0 | 148 | let thrown = false; |
michael@0 | 149 | try { |
michael@0 | 150 | identity.syncKey = "blahblah"; |
michael@0 | 151 | } catch (ex) { |
michael@0 | 152 | thrown = true; |
michael@0 | 153 | } |
michael@0 | 154 | do_check_true(thrown); |
michael@0 | 155 | thrown = false; |
michael@0 | 156 | |
michael@0 | 157 | identity.account = "johnsmith"; |
michael@0 | 158 | identity.basicPassword = "johnsmithpw"; |
michael@0 | 159 | |
michael@0 | 160 | do_check_eq(identity.syncKey, null); |
michael@0 | 161 | do_check_eq(identity.syncKeyBundle, null); |
michael@0 | 162 | |
michael@0 | 163 | _("An invalid Sync Key is silently accepted for historical reasons."); |
michael@0 | 164 | identity.syncKey = "synckey"; |
michael@0 | 165 | do_check_eq(identity.syncKey, "synckey"); |
michael@0 | 166 | |
michael@0 | 167 | _("But the SyncKeyBundle should not be created from bad keys."); |
michael@0 | 168 | do_check_eq(identity.syncKeyBundle, null); |
michael@0 | 169 | |
michael@0 | 170 | let syncKey = Utils.generatePassphrase(); |
michael@0 | 171 | identity.syncKey = syncKey; |
michael@0 | 172 | do_check_eq(identity.syncKey, syncKey); |
michael@0 | 173 | do_check_neq(identity.syncKeyBundle, null); |
michael@0 | 174 | |
michael@0 | 175 | let im = new IdentityManager(); |
michael@0 | 176 | im.account = "pseudojohn"; |
michael@0 | 177 | do_check_eq(im.syncKey, null); |
michael@0 | 178 | do_check_eq(im.syncKeyBundle, null); |
michael@0 | 179 | |
michael@0 | 180 | identity.account = null; |
michael@0 | 181 | |
michael@0 | 182 | run_next_test(); |
michael@0 | 183 | }); |
michael@0 | 184 | |
michael@0 | 185 | add_test(function test_sync_key_changes() { |
michael@0 | 186 | _("Ensure changes to Sync Key have appropriate side-effects."); |
michael@0 | 187 | |
michael@0 | 188 | let im = new IdentityManager(); |
michael@0 | 189 | let sk1 = Utils.generatePassphrase(); |
michael@0 | 190 | let sk2 = Utils.generatePassphrase(); |
michael@0 | 191 | |
michael@0 | 192 | im.account = "johndoe"; |
michael@0 | 193 | do_check_eq(im.syncKey, null); |
michael@0 | 194 | do_check_eq(im.syncKeyBundle, null); |
michael@0 | 195 | |
michael@0 | 196 | im.syncKey = sk1; |
michael@0 | 197 | do_check_neq(im.syncKeyBundle, null); |
michael@0 | 198 | |
michael@0 | 199 | let ek1 = im.syncKeyBundle.encryptionKeyB64; |
michael@0 | 200 | let hk1 = im.syncKeyBundle.hmacKeyB64; |
michael@0 | 201 | |
michael@0 | 202 | // Change the Sync Key and ensure the Sync Key Bundle is updated. |
michael@0 | 203 | im.syncKey = sk2; |
michael@0 | 204 | let ek2 = im.syncKeyBundle.encryptionKeyB64; |
michael@0 | 205 | let hk2 = im.syncKeyBundle.hmacKeyB64; |
michael@0 | 206 | |
michael@0 | 207 | do_check_neq(ek1, ek2); |
michael@0 | 208 | do_check_neq(hk1, hk2); |
michael@0 | 209 | |
michael@0 | 210 | im.account = null; |
michael@0 | 211 | |
michael@0 | 212 | run_next_test(); |
michael@0 | 213 | }); |
michael@0 | 214 | |
michael@0 | 215 | add_test(function test_current_auth_state() { |
michael@0 | 216 | _("Ensure current auth state is reported properly."); |
michael@0 | 217 | |
michael@0 | 218 | let im = new IdentityManager(); |
michael@0 | 219 | do_check_eq(im.currentAuthState, LOGIN_FAILED_NO_USERNAME); |
michael@0 | 220 | |
michael@0 | 221 | im.account = "johndoe"; |
michael@0 | 222 | do_check_eq(im.currentAuthState, LOGIN_FAILED_NO_PASSWORD); |
michael@0 | 223 | |
michael@0 | 224 | im.basicPassword = "ilovejane"; |
michael@0 | 225 | do_check_eq(im.currentAuthState, LOGIN_FAILED_NO_PASSPHRASE); |
michael@0 | 226 | |
michael@0 | 227 | im.syncKey = "foobar"; |
michael@0 | 228 | do_check_eq(im.currentAuthState, LOGIN_FAILED_INVALID_PASSPHRASE); |
michael@0 | 229 | |
michael@0 | 230 | im.syncKey = null; |
michael@0 | 231 | do_check_eq(im.currentAuthState, LOGIN_FAILED_NO_PASSPHRASE); |
michael@0 | 232 | |
michael@0 | 233 | im.syncKey = Utils.generatePassphrase(); |
michael@0 | 234 | do_check_eq(im.currentAuthState, STATUS_OK); |
michael@0 | 235 | |
michael@0 | 236 | im.account = null; |
michael@0 | 237 | |
michael@0 | 238 | run_next_test(); |
michael@0 | 239 | }); |
michael@0 | 240 | |
michael@0 | 241 | add_test(function test_sync_key_persistence() { |
michael@0 | 242 | _("Ensure Sync Key persistence works as expected."); |
michael@0 | 243 | |
michael@0 | 244 | identity.account = "pseudojohn"; |
michael@0 | 245 | identity.password = "supersecret"; |
michael@0 | 246 | |
michael@0 | 247 | let syncKey = Utils.generatePassphrase(); |
michael@0 | 248 | identity.syncKey = syncKey; |
michael@0 | 249 | |
michael@0 | 250 | identity.persistCredentials(); |
michael@0 | 251 | |
michael@0 | 252 | let im = new IdentityManager(); |
michael@0 | 253 | im.account = "pseudojohn"; |
michael@0 | 254 | do_check_eq(im.syncKey, syncKey); |
michael@0 | 255 | do_check_neq(im.syncKeyBundle, null); |
michael@0 | 256 | |
michael@0 | 257 | let kb1 = identity.syncKeyBundle; |
michael@0 | 258 | let kb2 = im.syncKeyBundle; |
michael@0 | 259 | |
michael@0 | 260 | do_check_eq(kb1.encryptionKeyB64, kb2.encryptionKeyB64); |
michael@0 | 261 | do_check_eq(kb1.hmacKeyB64, kb2.hmacKeyB64); |
michael@0 | 262 | |
michael@0 | 263 | identity.account = null; |
michael@0 | 264 | identity.persistCredentials(); |
michael@0 | 265 | |
michael@0 | 266 | let im2 = new IdentityManager(); |
michael@0 | 267 | im2.account = "pseudojohn"; |
michael@0 | 268 | do_check_eq(im2.syncKey, null); |
michael@0 | 269 | |
michael@0 | 270 | im2.account = null; |
michael@0 | 271 | |
michael@0 | 272 | _("Ensure deleted but not persisted value is retrieved."); |
michael@0 | 273 | identity.account = "someoneelse"; |
michael@0 | 274 | identity.syncKey = Utils.generatePassphrase(); |
michael@0 | 275 | identity.persistCredentials(); |
michael@0 | 276 | identity.syncKey = null; |
michael@0 | 277 | do_check_eq(identity.syncKey, null); |
michael@0 | 278 | |
michael@0 | 279 | // Clean up. |
michael@0 | 280 | identity.account = null; |
michael@0 | 281 | identity.persistCredentials(); |
michael@0 | 282 | |
michael@0 | 283 | run_next_test(); |
michael@0 | 284 | }); |