Commit 26de76ef authored by Tristan Cavelier's avatar Tristan Cavelier Committed by Sebastien Robin

Jio CryptedStorage completed + Qunit tests

parent 77966ec9
......@@ -50,6 +50,7 @@ module.exports = function(grunt) {
},
globals: {
jQuery: true,
sjcl: true,
LocalOrCookieStorage: true,
Base64: true,
JIO: true,
......
......@@ -57,6 +57,7 @@ module.exports = function(grunt) {
},
globals: {
jQuery: true,
sjcl:true,
LocalOrCookieStorage: true,
Base64: true,
JIO: true,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -1089,17 +1089,47 @@
var that = Jio.newBaseStorage( spec, my ), priv = {};
// TODO : IT IS NOT SECURE AT ALL!
// WE MUST REWORK CRYPTED STORAGE!
priv.encrypt_param_object = {
"iv":"kaprWwY/Ucr7pumXoTHbpA",
"v":1,
"iter":1000,
"ks":256,
"ts":128,
"mode":"ccm",
"adata":"",
"cipher":"aes",
"salt":"K4bmZG9d704"
};
priv.decrypt_param_object = {
"iv":"kaprWwY/Ucr7pumXoTHbpA",
"ks":256,
"ts":128,
"salt":"K4bmZG9d704"
};
priv.encrypt = function (data,callback,index) {
// end with a callback in order to improve encrypt to an
// asynchronous encryption.
var tmp = sjcl.encrypt (that.getStorageUserName()+':'+
that.getStoragePassword(), data);
callback(tmp,index);
that.getStoragePassword(), data,
priv.encrypt_param_object);
callback(JSON.parse(tmp).ct,index);
};
priv.decrypt = function (data,callback,index) {
var tmp = sjcl.decrypt (that.getStorageUserName()+':'+
that.getStoragePassword(), data);
callback(tmp,index);
priv.decrypt = function (data,callback,index,key) {
var tmp, param = $.extend(true,{},priv.decrypt_param_object);
param.ct = data || '';
param = JSON.stringify (param);
try {
tmp = sjcl.decrypt (that.getStorageUserName()+':'+
that.getStoragePassword(),
param);
} catch (e) {
callback({status:0,statusText:'Decrypt Fail',
message:'Unable to decrypt.'},index,key);
return;
}
callback(tmp,index,key);
};
/**
......@@ -1132,15 +1162,10 @@
});
},
_2 = function () {
priv.encrypt(
JSON.stringify({
name: that.getFileName(),
content:that.getFileContent()
}),
function(res) {
newfilecontent = res;
_3();
});
priv.encrypt(that.getFileContent(),function(res) {
newfilecontent = res;
_3();
});
},
_3 = function () {
new_job = that.cloneJob();
......@@ -1166,7 +1191,7 @@
* @method loadDocument
*/
that.loadDocument = function () {
var new_job, new_file_name,
var new_job, new_file_name, option = that.cloneOptionObject(),
_1 = function () {
priv.encrypt(that.getFileName(),function(res) {
new_file_name = res;
......@@ -1178,15 +1203,31 @@
new_job.name = new_file_name;
new_job.storage = that.getSecondStorage();
new_job.callback = loadCallback;
console.log (new_job);
that.addJob ( new_job );
},
loadCallback = function (result) {
if (result.status === 'done') {
priv.decrypt (result.return_value.content,function(res){
that.done(JSON.parse(res));
});
result.return_value.name = that.getFileName();
if (option.metadata_only) {
that.done(result.return_value);
} else {
priv.decrypt (result.return_value.content,function(res){
if (typeof res === 'object') {
that.fail({status:0,statusText:'Decrypt Fail',
message:'Unable to decrypt'});
} else {
result.return_value.content = res;
// content only: the second storage should
// manage content_only option, so it is not
// necessary to manage it.
that.done(result.return_value);
}
});
}
} else {
// NOTE : we can re create an error object instead of
// keep the old ex:status=404,message="document 1y59gyl8g
// not found in localStorage"...
that.fail(result.error);
}
};
......@@ -1198,7 +1239,7 @@
* @method getDocumentList
*/
that.getDocumentList = function () {
var new_job, i, l, cpt = 0, array,
var new_job, i, l, cpt = 0, array, ok = true,
_1 = function () {
new_job = that.cloneJob();
new_job.storage = that.getSecondStorage();
......@@ -1209,20 +1250,29 @@
if (result.status === 'done') {
array = result.return_value;
for (i = 0, l = array.length; i < l; i+= 1) {
priv.decrypt (array[i],
lastCallback,i);
// cpt--;
priv.decrypt (array[i].name,
lastCallback,i,'name');
// priv.decrypt (array[i].content,
// lastCallback,i,'content');
}
} else {
that.fail(result.error);
}
},
lastCallback = function (res,index) {
lastCallback = function (res,index,key) {
var tmp;
cpt++;
tmp = JSON.parse(res);
array[index] = res.name;
array[index] = res.content;
if (cpt === l) {
if (typeof res === 'object') {
if (ok) {
that.fail({status:0,statusText:'Decrypt Fail',
message:'Unable to decrypt.'});
}
ok = false;
return;
}
array[index][key] = res;
if (cpt === l && ok) {
// this is the last callback
that.done(array);
}
......@@ -1235,16 +1285,28 @@
* @method removeDocument
*/
that.removeDocument = function () {
var new_job = that.cloneJob();
new_job.storage = that.getSecondStorage();
new_job.callback = function (result) {
var new_job, new_file_name,
_1 = function () {
priv.encrypt(that.getFileName(),function(res) {
new_file_name = res;
_2();
});
},
_2 = function () {
new_job = that.cloneJob();
new_job.name = new_file_name;
new_job.storage = that.getSecondStorage();
new_job.callback = removeCallback;
that.addJob(new_job);
},
removeCallback = function (result) {
if (result.status === 'done') {
that.done();
} else {
that.fail(result.error);
}
};
that.addJob(new_job);
_1();
};
return that;
};
......
......@@ -24,6 +24,13 @@ var getXML = function (url) {
dataType:'text',success:function(xml){tmp=xml;}});
return tmp;
},
objectifyDocumentArray = function (array) {
var obj = {}, k;
for (k = 0; k < array.length; k += 1) {
obj[array[k].name] = array[k];
}
return obj;
},
addFile = function (user,appid,file) {
var i, l, found = false, filenamearray,
userarray = LocalOrCookieStorage.getItem('jio/local_user_array') || [];
......@@ -408,13 +415,6 @@ test ('Get document list', function () {
doc1 = {}, doc2 = {},
mytest = function (value){
o.f = function (result) {
var objectifyDocumentArray = function (array) {
var obj = {}, k;
for (k = 0; k < array.length; k+=1) {
obj[array[k].name] = array[k];
}
return obj;
};
deepEqual (objectifyDocumentArray(result.return_value),
objectifyDocumentArray(value),'getting list');
};
......@@ -625,13 +625,6 @@ test ('Get Document List', function () {
[errnoprop,{'Content-Type':'text/xml; charset="utf-8"'},
davlist]);
o.f = function (result) {
var objectifyDocumentArray = function (array) {
var obj = {}, k;
for (k = 0; k < array.length; k += 1) {
obj[array[k].name] = array[k];
}
return obj;
};
if (result.status === 'fail') {
deepEqual (result.return_value, value, message);
} else {
......@@ -824,13 +817,6 @@ test ('Get Document List', function () {
var o = {}, clock = this.sandbox.useFakeTimers(), t = this,
mytest = function (message,value) {
o.f = function (result) {
var objectifyDocumentArray = function (array) {
var obj = {}, k;
for (k = 0; k < array.length; k += 1) {
obj[array[k].name] = array[k];
}
return obj;
};
deepEqual (objectifyDocumentArray(result.return_value),
objectifyDocumentArray(value),'getting list');
};
......@@ -1028,10 +1014,11 @@ test ('Check name availability' , function () {
test ('Document save' , function () {
var o = {}, clock = this.sandbox.useFakeTimers();
o.jio=JIO.newJio({type:'crypted',
password:'mypwd',
storage:{type:'local',
user_name:'cryptsave'}},
{ID:'jiotests'});
user_name:'cryptsave',
password:'mypwd',
storage:{type:'local',
user_name:'cryptsavelocal'}},
{ID:'jiotests'});
o.f = function (result) {
deepEqual (result.status,'done','save ok');
};
......@@ -1042,16 +1029,28 @@ test ('Document save' , function () {
if (!o.f.calledOnce) {
ok (false, 'no response / too much results');
}
// encrypt 'testsave' with 'cryptsave:mypwd' password
o.tmp = LocalOrCookieStorage.getItem(
'jio/local/cryptsavelocal/jiotests/rZx5PJxttlf9QpZER/5x354bfX54QFa1');
if (o.tmp) {
delete o.tmp.last_modified;
delete o.tmp.creation_date;
}
deepEqual (o.tmp,
{name:'rZx5PJxttlf9QpZER/5x354bfX54QFa1',
content:'upZkPIpitF3QMT/DU5jM3gP0SEbwo1n81rMOfLE'},
'Check if the document is realy crypted');
o.jio.stop();
});
test ('Document Load' , function () {
var o = {}, clock = this.sandbox.useFakeTimers();
o.jio=JIO.newJio({type:'crypted',
password:'mypwd',
storage:{type:'local',
user_name:'cryptload'}},
{ID:'jiotests'});
user_name:'cryptload',
password:'mypwd',
storage:{type:'local',
user_name:'cryptloadlocal'}},
{ID:'jiotests'});
o.f = function (result) {
if (result.status === 'done') {
deepEqual (result.return_value,{name:'testload',
......@@ -1064,6 +1063,13 @@ test ('Document Load' , function () {
}
};
this.spy(o,'f');
// encrypt 'testload' with 'cryptload:mypwd' password
// and 'contentoftest' with 'cryptload:mypwd'
LocalOrCookieStorage.setItem(
'jio/local/cryptloadlocal/jiotests/hiG4H80pwkXCCrlLl1X0BD0BfWLZwDUX',
{name:'mRyQFcUvUKq6tLGUjBo34P3oc2LPxEju',
content:'kSulH8Qo105dSKHcY2hEBXWXC9b+3PCEFSm1k7k',
last_modified:500,creation_date:500});
o.jio.loadDocument({name:'testload',
max_tries:1,callback:o.f});
clock.tick(1000);
......@@ -1071,8 +1077,90 @@ test ('Document Load' , function () {
ok (false, 'no response / too much results');
}
o.jio.stop();
LocalOrCookieStorage.deleteItem(
'jio/local/cryptloadlocal/jiotests/hiG4H80pwkXCCrlLl1X0BD0BfWLZwDUX');
});
test ('Get Document List', function () {
var o = {}, clock = this.sandbox.useFakeTimers();
o.jio=JIO.newJio({type:'crypted',
user_name:'cryptgetlist',
password:'mypwd',
storage:{type:'local',
user_name:'cryptgetlistlocal'}},
{ID:'jiotests'});
o.f = function (result) {
if (result.status === 'done') {
deepEqual (objectifyDocumentArray(result.return_value),
objectifyDocumentArray(o.doc_list),'Getting list');
} else {
console.warn (result);
ok (false, 'Cannot get list');
}
};
this.spy(o,'f');
o.doc_list = [
{name:'testgetlist1',last_modified:500,creation_date:200},
{name:'testgetlist2',last_modified:300,creation_date:300}
];
o.doc_encrypt_list = [
{name:'541eX0WTMDw7rqIP7Ofxd1nXlPOtejxGnwOzMw',
content:'/4dBPUdmLolLfUaDxPPrhjRPdA',
last_modified:500,creation_date:200},
{name:'541eX0WTMDw7rqIMyJ5tx4YHWSyxJ5UjYvmtqw',
content:'/4FBALhweuyjxxD53eFQDSm4VA',
last_modified:300,creation_date:300}
];
// encrypt with 'cryptgetlist:mypwd' as password
LocalOrCookieStorage.setItem(
'jio/local_file_name_array/cryptgetlistlocal/jiotests',
[o.doc_encrypt_list[0].name,o.doc_encrypt_list[1].name]);
LocalOrCookieStorage.setItem(
'jio/local/cryptgetlistlocal/jiotests/'+o.doc_encrypt_list[0].name,
o.doc_encrypt_list[0]);
LocalOrCookieStorage.setItem(
'jio/local/cryptgetlistlocal/jiotests/'+o.doc_encrypt_list[1].name,
o.doc_encrypt_list[1]);
o.jio.getDocumentList({max_tries:1,callback:o.f});
clock.tick (2000);
if (!o.f.calledOnce) {
ok (false, 'no response / too much results');
}
clock.tick(1000);
o.jio.stop();
});
// end require
test ('Remove document', function () {
var o = {}, clock = this.sandbox.useFakeTimers();
o.jio=JIO.newJio({type:'crypted',
user_name:'cryptremove',
password:'mypwd',
storage:{type:'local',
user_name:'cryptremovelocal'}},
{ID:'jiotests'});
o.f = function (result) {
deepEqual (result.status,'done','Document remove');
};
this.spy(o,'f');
// encrypt with 'cryptremove:mypwd' as password
LocalOrCookieStorage.setItem(
'jio/local_file_name_array/cryptremovelocal/jiotests',
["JqCLTjyxQqO9jwfxD/lyfGIX+qA"]);
LocalOrCookieStorage.setItem(
'jio/local/cryptremovelocal/jiotests/JqCLTjyxQqO9jwfxD/lyfGIX+qA',
{"name":"JqCLTjyxQqO9jwfxD/lyfGIX+qA",
"content":"LKaLZopWgML6IxERqoJ2mUyyO",
"creation_date":500,
"last_modified":500});
o.jio.removeDocument({name:'file',max_tries:1,callback:o.f});
clock.tick(1000);
if (!o.f.calledOnce){
ok (false, 'no response / too much results');
}
o.jio.stop();
});
}; // end thisfun
if (window.requirejs) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment