From 0656c73c1b28d855661001f6127062cf7bfab3bc Mon Sep 17 00:00:00 2001 From: Dario Chiappetta Date: Wed, 26 Aug 2015 10:13:29 +0200 Subject: [PATCH] Fixed OTP Handling in Dev backend: all test are passing --- frontend/delta/js/Clipperz/PM/Crypto.js | 2 +- .../DataModel/User.Header.OneTimePasswords.js | 3 +- .../PM/Proxy/Proxy.Offline.DataStore.js | 52 +++++++++++++++---- .../Proxy.Offline.LocalStorageDataStore.js | 4 +- .../PM/Proxy/Proxy.Offline.MemoryDataStore.js | 4 +- .../Clipperz/PM/UI/Components/Cards/Detail.js | 1 + .../PM/UI/Components/ExtraFeatures/OTP.js | 2 +- frontend/delta/js/TestData/User.data.js | 4 +- .../PM/DataModel/OneTimePassword.test.js | 2 + .../tests/Clipperz/PM/DataModel/User.data.js | 4 +- 10 files changed, 57 insertions(+), 21 deletions(-) diff --git a/frontend/delta/js/Clipperz/PM/Crypto.js b/frontend/delta/js/Clipperz/PM/Crypto.js index 91a1683..a61f9a6 100644 --- a/frontend/delta/js/Clipperz/PM/Crypto.js +++ b/frontend/delta/js/Clipperz/PM/Crypto.js @@ -105,7 +105,7 @@ MochiKit.Base.update(Clipperz.PM.Crypto, { 'hash': function(aValue) { var result; - var strngResult; + var stringResult; stringResult = Clipperz.Crypto.Base.computeHashValue(aValue.asString()); // !!!!!!! result = new Clipperz.ByteArray("0x" + stringResult); diff --git a/frontend/delta/js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js b/frontend/delta/js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js index cbd2e6c..1fa9d38 100644 --- a/frontend/delta/js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js +++ b/frontend/delta/js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js @@ -152,9 +152,8 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.OneTimePasswords, Clipper newOneTimePassword = Clipperz.PM.DataModel.OneTimePassword.createNewOneTimePassword(aUsername, aPassphraseCallback); // TODO: this is deferred --> change everything to deferred - // TestData include 'created' and 'status' + // TODO: TestData include 'created' and 'status': check if status is necessary this.setValue(newOneTimePassword.reference(), { - // 'created': newOneTimePassword.creationDate().toString(), // won't work: creation date is no more stored in OTP 'password': newOneTimePassword.password(), 'label': newOneTimePassword.label() // 'status': newOneTimePassword.status() diff --git a/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js b/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js index 790492b..b4e564a 100644 --- a/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js +++ b/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js @@ -325,8 +325,12 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { var randomBytes; var v; + if (typeof(this.data()['onetimePasswords']) == 'undefined') { + this.data()['onetimePasswords'] = {}; + } + userData = this.data()['users'][someParameters.parameters.C]; - otpsData = (typeof(this.data()['onetimePasswords']) != 'undefined') ? this.data()['onetimePasswords'] : {}; + otpsData = this.data()['onetimePasswords']; //console.log("Proxy.Offline.DataStore._handshake: otpsData:", otpsData); @@ -397,22 +401,21 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { nextTollRequestType = 'MESSAGE'; } else if (someParameters.message == "oneTimePassword") { - var otpData; - - otpData = this.data()['onetimePasswords'][someParameters.parameters.oneTimePasswordKey]; + var otpData = this.getOneTimePasswordFromKey(someParameters.parameters.oneTimePasswordKey); try { if (typeof(otpData) != 'undefined') { if (otpData['status'] == 'ACTIVE') { - if (otpData['key_checksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) { + if (otpData['keyChecksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) { result = { 'data': otpData['data'], 'version': otpData['version'] } - otpData['status'] = 'REQUESTED'; + otpData['status'] = 'USED'; } else { otpData['status'] = 'DISABLED'; + throw "The requested One Time Password has been disabled, due to a wrong keyChecksum"; } } else { @@ -422,6 +425,7 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { throw "The requested One Time Password has not been found" } } catch (exception) { +// console.log("connect.oneTimePassword: Exception!", exception); result = { 'data': Clipperz.PM.Crypto.randomKey(), 'version': Clipperz.PM.Connection.communicationProtocol.currentVersion @@ -490,7 +494,11 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { var result = MochiKit.Iter.reduce(function(prev, cur){ prev[cur.reference] = { 'status': cur.status, - 'usage_date': cur.usage_date + 'usageDate': cur.usage_date, + 'connection': { + 'ip': 'n/a', + 'browser': 'n/a' + } }; return prev; }, MochiKit.Base.values(aConnection['userOTPs']), {}); @@ -517,8 +525,9 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { ) { result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; } else { - var oldCValue; - oldCValue = aConnection['C']; + var key; + var onetimePasswords = this.data()['onetimePasswords']; + var oldCValue = aConnection['C']; this.data()['users'][credentials['C']] = aConnection['userData']; aConnection['C'] = credentials['C']; @@ -532,6 +541,12 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { aConnection['userData']['statistics'] = parameters['user']['statistics']; aConnection['userData']['lock'] = parameters['user']['lock']; + + for (key in onetimePasswords) { + onetimePasswords[key]['user'] = credentials['C']; + onetimePasswords[key]['data'] = parameters['oneTimePasswords'][key]['data']; + onetimePasswords[key]['version'] = parameters['oneTimePasswords'][key]['version']; + } delete this.data()['users'][oldCValue]; @@ -659,6 +674,7 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { //console.log("Proxy.Offline.DataStore.addNewOneTimePassword: someParameters:", someParameters); var otpKey = someParameters['parameters']['oneTimePassword'].key; + var otpReference = someParameters['parameters']['oneTimePassword'].reference; if (aConnection['userData']['lock'] != someParameters['parameters']['user']['lock']) { throw "the lock attribute is not processed correctly" @@ -674,6 +690,8 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { aConnection['userOTPs'][otpKey]['creation_date'] = new Date().toISOString().substr(0, 19).replace('T', ' '); // Not an elegant way to give the date the same format as the others aConnection['userOTPs'][otpKey]['request_date'] = "4001-01-01 09:00:00"; aConnection['userOTPs'][otpKey]['usage_date'] = "4001-01-01 09:00:00"; + + this.data()['onetimePasswords'][otpReference] = aConnection['userOTPs'][otpKey]; //console.log("Proxy.Offline.DataStore.addNewOneTimePassword: aConnection:", aConnection); } else { throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; @@ -729,6 +747,22 @@ console.log("Proxy.Offline.DataStore.updateOneTimePasswords: userOTPs:", aConnec //========================================================================= //######################################################################### + 'getOneTimePasswordFromKey': function(aKey) { + var result,i; + + var onetimePasswordsValues = MochiKit.Base.values(this.data()['onetimePasswords']); + + for (i = 0; i < onetimePasswordsValues.length; i++) { + if (onetimePasswordsValues[i]['key'] == aKey) { + result = onetimePasswordsValues[i]; + } + } + + return result; + }, + + //========================================================================= + 'isTestData': function(aConnection) { return (typeof(aConnection['userData']['__masterkey_test_value__']) != 'undefined'); }, diff --git a/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js b/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js index d7f9268..996afde 100644 --- a/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js +++ b/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js @@ -140,13 +140,13 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.LocalStorageDataStore, Clipperz.P try { if (typeof(otpData) != 'undefined') { if (otpData['status'] == 'ACTIVE') { - if (otpData['key_checksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) { + if (otpData['keyChecksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) { result = { 'data': otpData['data'], 'version': otpData['version'] } - otpData['status'] = 'REQUESTED'; + otpData['status'] = 'USED'; } else { otpData['status'] = 'DISABLED'; throw "The requested One Time Password has been disabled, due to a wrong keyChecksum"; diff --git a/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.MemoryDataStore.js b/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.MemoryDataStore.js index 29b169e..3ec5d05 100644 --- a/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.MemoryDataStore.js +++ b/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.MemoryDataStore.js @@ -342,13 +342,13 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.MemoryDataStore, Clipperz.PM.Prox try { if (typeof(otpData) != 'undefined') { if (otpData['status'] == 'ACTIVE') { - if (otpData['key_checksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) { + if (otpData['keyChecksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) { result = { 'data': otpData['data'], 'version': otpData['version'] } - otpData['status'] = 'REQUESTED'; + otpData['status'] = 'USED'; } else { otpData['status'] = 'DISABLED'; throw "The requested One Time Password has been disabled, due to a wrong keyChecksum"; diff --git a/frontend/delta/js/Clipperz/PM/UI/Components/Cards/Detail.js b/frontend/delta/js/Clipperz/PM/UI/Components/Cards/Detail.js index fa2ab79..5672bf7 100644 --- a/frontend/delta/js/Clipperz/PM/UI/Components/Cards/Detail.js +++ b/frontend/delta/js/Clipperz/PM/UI/Components/Cards/Detail.js @@ -46,6 +46,7 @@ Clipperz.PM.UI.Components.Cards.DetailClass = React.createClass({ render: function () { var result; + if (this.props['mode'] == 'edit') { result = Clipperz.PM.UI.Components.Cards.Edit(this.viewComponentProps()); } else { diff --git a/frontend/delta/js/Clipperz/PM/UI/Components/ExtraFeatures/OTP.js b/frontend/delta/js/Clipperz/PM/UI/Components/ExtraFeatures/OTP.js index ad76586..389cd6e 100644 --- a/frontend/delta/js/Clipperz/PM/UI/Components/ExtraFeatures/OTP.js +++ b/frontend/delta/js/Clipperz/PM/UI/Components/ExtraFeatures/OTP.js @@ -168,7 +168,7 @@ Clipperz.PM.UI.Components.ExtraFeatures.OTPClass = React.createClass({ if (otpDetailInfo['status'] != 'ACTIVE') { otpStatusInfo = React.DOM.div({'className':'otpStatusInfo'}, [ React.DOM.span({'className':'otpStatus'}, otpDetailInfo['status']), - React.DOM.span({'className':'requestDate'}, otpDetailInfo['requestDate']), + React.DOM.span({'className':'requestDate'}, otpDetailInfo['usageDate']), React.DOM.span({'className':'connectionIp'}, otpDetailInfo['connection']['ip']), React.DOM.span({'className':'connectionBrowser'}, otpDetailInfo['connection']['browser']), ]) diff --git a/frontend/delta/js/TestData/User.data.js b/frontend/delta/js/TestData/User.data.js index 704e9c6..eba86c2 100644 --- a/frontend/delta/js/TestData/User.data.js +++ b/frontend/delta/js/TestData/User.data.js @@ -1774,12 +1774,12 @@ testData = { 'c3664af5744319c6d3b874895f803df19cb0492acf27cb51912110d023ba9b38': { // reference 'reference': "c3664af5744319c6d3b874895f803df19cb0492acf27cb51912110d023ba9b38", 'user': "9a984e219b07f9b645ef35f4de938b4741abe2e0b4adc88b40e9367170c91cc8", - 'status': 'ACTIVE', // 1: 'ACTIVE', 2: 'REQUESTED', 3: 'USED', 4: 'DISABLED' + 'status': 'ACTIVE', // 1: 'ACTIVE', 2: 'USED', 3: 'DISABLED' 'creation_date': "2010-02-09 17:57:14", 'request_date': "4001-01-01 09:00:00", 'usage_date': "4001-01-01 09:00:00", 'key': "7074103e8ce35f813dbfb9c90665bd66ba3f5b1c9e4fa7a3d8aee679b7a38102", - "key_checksum": "53739910c97d74c80c6028eb3293ffbc652def811d9aa11725fefa3139dfcf29", + "keyChecksum": "53739910c97d74c80c6028eb3293ffbc652def811d9aa11725fefa3139dfcf29", "data": "aN3rPl5rusBWXveUpjKqZNFLRPWJgH2Zs8HYQIaS65QObQFWFTZ8lRpBXFoPlvSOHcHQpEavZUuq31Y/2Y9sI/scvmZjQ8UEaT2GY9NiWJVswGq1W3AX8zs32jOgf1L5iBVxK54mfig2vXFoL8lG0JGGY1zHZXlkCvFPWuvwuCcH+uRE0oP3it0FvNFBV4+TiiGnGYgD9LPAVevzr/Doq5UXjn9VplVU+upeDTWY+7rlOdIOnZG/A9P9/dQtsyMb5c5zABD2FNpQQ40JDfG/nHt5WvfuWmPwUisW1181oBAd5BwF9LgVHdrhcSh8OuUL7rdbKTPTlWT826I6JNrFMzYGMY+NV6gllDvc6eCNrgI98ABhL1AoZNpAXXuCy4uQhEYmj+O71C/eXEDw+crMAXiCn6SZrbTM8GT5TQ5yF2NcxhudopO4qoILjnwEHZZ+i37kRDFg6oCBccCD67oHTPexUkSqnKIIYLli5CdmE7UdvX6LuVG/VYJKevOUgMf0UzHDPgvtlp3gsSo09TfNPOtoeAiogL6cAHb1seZwv+6E8Pz7WqkkOTsBQYeHIfPE0OnQPDtUjVRA5MTTX5zt6rCCNDKNbqfkPu8V4am26ykaWOSTXZYIcfnywkG0TfPzdAyQvyxdUyl/r1b36bclQFiXcRzkz9zS9xx14Il3QjYXRbIFWcwm/mEFltBFPdATKo5Zh+wcTLiFh56YEUVa9/h6oN8281X6zxH4DOw=", 'version': "0.3" }, diff --git a/frontend/delta/tests/tests/Clipperz/PM/DataModel/OneTimePassword.test.js b/frontend/delta/tests/tests/Clipperz/PM/DataModel/OneTimePassword.test.js index 512f120..ba4fd75 100644 --- a/frontend/delta/tests/tests/Clipperz/PM/DataModel/OneTimePassword.test.js +++ b/frontend/delta/tests/tests/Clipperz/PM/DataModel/OneTimePassword.test.js @@ -59,6 +59,8 @@ var tests = { deferredResult = new Clipperz.Async.Deferred("loginUsingOtp_test", someTestArgs); deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_with_otps']); + // TODO: Apparently these tests are skipped when they fail, not showing up in the results + deferredResult.addMethod(user, 'login'); deferredResult.addMethod(user, 'getRecords'); deferredResult.addCallback(MochiKit.Base.itemgetter('length')); diff --git a/frontend/delta/tests/tests/Clipperz/PM/DataModel/User.data.js b/frontend/delta/tests/tests/Clipperz/PM/DataModel/User.data.js index 40cf586..b069923 100644 --- a/frontend/delta/tests/tests/Clipperz/PM/DataModel/User.data.js +++ b/frontend/delta/tests/tests/Clipperz/PM/DataModel/User.data.js @@ -1835,12 +1835,12 @@ testData = { 'c3664af5744319c6d3b874895f803df19cb0492acf27cb51912110d023ba9b38': { // key 'reference': "c3664af5744319c6d3b874895f803df19cb0492acf27cb51912110d023ba9b38", 'user': "9a984e219b07f9b645ef35f4de938b4741abe2e0b4adc88b40e9367170c91cc8", - 'status': 'ACTIVE', // 1: 'ACTIVE', 2: 'REQUESTED', 3: 'USED', 4: 'DISABLED' + 'status': 'ACTIVE', // 1: 'ACTIVE', 2: 'USED', 3: 'DISABLED' 'creation_date': "2010-02-09 17:57:14", 'request_date': "4001-01-01 09:00:00", 'usage_date': "4001-01-01 09:00:00", 'key': "7074103e8ce35f813dbfb9c90665bd66ba3f5b1c9e4fa7a3d8aee679b7a38102", - "key_checksum": "53739910c97d74c80c6028eb3293ffbc652def811d9aa11725fefa3139dfcf29", + "keyChecksum": "53739910c97d74c80c6028eb3293ffbc652def811d9aa11725fefa3139dfcf29", "data": "aN3rPl5rusBWXveUpjKqZNFLRPWJgH2Zs8HYQIaS65QObQFWFTZ8lRpBXFoPlvSOHcHQpEavZUuq31Y/2Y9sI/scvmZjQ8UEaT2GY9NiWJVswGq1W3AX8zs32jOgf1L5iBVxK54mfig2vXFoL8lG0JGGY1zHZXlkCvFPWuvwuCcH+uRE0oP3it0FvNFBV4+TiiGnGYgD9LPAVevzr/Doq5UXjn9VplVU+upeDTWY+7rlOdIOnZG/A9P9/dQtsyMb5c5zABD2FNpQQ40JDfG/nHt5WvfuWmPwUisW1181oBAd5BwF9LgVHdrhcSh8OuUL7rdbKTPTlWT826I6JNrFMzYGMY+NV6gllDvc6eCNrgI98ABhL1AoZNpAXXuCy4uQhEYmj+O71C/eXEDw+crMAXiCn6SZrbTM8GT5TQ5yF2NcxhudopO4qoILjnwEHZZ+i37kRDFg6oCBccCD67oHTPexUkSqnKIIYLli5CdmE7UdvX6LuVG/VYJKevOUgMf0UzHDPgvtlp3gsSo09TfNPOtoeAiogL6cAHb1seZwv+6E8Pz7WqkkOTsBQYeHIfPE0OnQPDtUjVRA5MTTX5zt6rCCNDKNbqfkPu8V4am26ykaWOSTXZYIcfnywkG0TfPzdAyQvyxdUyl/r1b36bclQFiXcRzkz9zS9xx14Il3QjYXRbIFWcwm/mEFltBFPdATKo5Zh+wcTLiFh56YEUVa9/h6oN8281X6zxH4DOw=", 'version': "0.3" }