Commit 369b078d authored by Romain Courteaud's avatar Romain Courteaud

Release version 3.5.0

Include new cryptstorage, pywebdav support, local_roles parameter support in ERP5Storage.
parent d8604d34
......@@ -7863,6 +7863,195 @@ Query.searchTextToRegExp = searchTextToRegExp;
jIO.addStorage('zip', ZipStorage);
}(RSVP, Blob, LZString, DOMException));
;/*
* Copyright 2015, Nexedi SA
* Released under the LGPL license.
* http://www.gnu.org/licenses/lgpl.html
*/
/*jslint nomen: true*/
/*global jIO, RSVP, DOMException, Blob, crypto, Uint8Array, ArrayBuffer*/
(function (jIO, RSVP, DOMException, Blob, crypto, Uint8Array, ArrayBuffer) {
"use strict";
// you the cryptography system used by this storage is AES-GCM.
// here is an example of how to generate a key to the json format.
// var key,
// jsonKey;
// crypto.subtle.generateKey({name: "AES-GCM",length: 256},
// (true), ["encrypt", "decrypt"])
// .then(function(res){key = res;});
//
// window.crypto.subtle.exportKey("jwk", key)
// .then(function(res){jsonKey = val})
//
//var storage = jIO.createJIO({type: "crypt", key: jsonKey,
// sub_storage: {...}});
// find more informations about this cryptography system on
// https://github.com/diafygi/webcrypto-examples#aes-gcm
/**
* The JIO Cryptography Storage extension
*
* @class CryptStorage
* @constructor
*/
var MIME_TYPE = "application/x-jio-aes-gcm-encryption";
function CryptStorage(spec) {
this._key = spec.key;
this._jsonKey = true;
this._sub_storage = jIO.createJIO(spec.sub_storage);
}
function convertKey(that) {
return new RSVP.Queue()
.push(function () {
return crypto.subtle.importKey("jwk", that._key,
"AES-GCM", false,
["encrypt", "decrypt"]);
})
.push(function (res) {
that._key = res;
that._jsonKey = false;
return;
}, function () {
throw new TypeError(
"'key' must be a CryptoKey to JSON Web Key format"
);
});
}
CryptStorage.prototype.get = function () {
return this._sub_storage.get.apply(this._sub_storage,
arguments);
};
CryptStorage.prototype.post = function () {
return this._sub_storage.post.apply(this._sub_storage,
arguments);
};
CryptStorage.prototype.put = function () {
return this._sub_storage.put.apply(this._sub_storage,
arguments);
};
CryptStorage.prototype.remove = function () {
return this._sub_storage.remove.apply(this._sub_storage,
arguments);
};
CryptStorage.prototype.hasCapacity = function () {
return this._sub_storage.hasCapacity.apply(this._sub_storage,
arguments);
};
CryptStorage.prototype.buildQuery = function () {
return this._sub_storage.buildQuery.apply(this._sub_storage,
arguments);
};
CryptStorage.prototype.putAttachment = function (id, name, blob) {
var initializaton_vector = crypto.getRandomValues(new Uint8Array(12)),
that = this;
return new RSVP.Queue()
.push(function () {
if (that._jsonKey === true) {
return convertKey(that);
}
return;
})
.push(function () {
return jIO.util.readBlobAsDataURL(blob);
})
.push(function (dataURL) {
//string->arraybuffer
var strLen = dataURL.currentTarget.result.length,
buf = new ArrayBuffer(strLen),
bufView = new Uint8Array(buf),
i;
dataURL = dataURL.currentTarget.result;
for (i = 0; i < strLen; i += 1) {
bufView[i] = dataURL.charCodeAt(i);
}
return crypto.subtle.encrypt({
name : "AES-GCM",
iv : initializaton_vector
},
that._key, buf);
})
.push(function (coded) {
var blob = new Blob([initializaton_vector, coded], {type: MIME_TYPE});
return that._sub_storage.putAttachment(id, name, blob);
});
};
CryptStorage.prototype.getAttachment = function (id, name) {
var that = this;
return that._sub_storage.getAttachment(id, name)
.push(function (blob) {
if (blob.type !== MIME_TYPE) {
return blob;
}
return new RSVP.Queue()
.push(function () {
if (that._jsonKey === true) {
return convertKey(that);
}
return;
})
.push(function () {
return jIO.util.readBlobAsArrayBuffer(blob);
})
.push(function (coded) {
var initializaton_vector;
coded = coded.currentTarget.result;
initializaton_vector = new Uint8Array(coded.slice(0, 12));
return crypto.subtle.decrypt({
name : "AES-GCM",
iv : initializaton_vector
},
that._key, coded.slice(12));
})
.push(function (arr) {
//arraybuffer->string
arr = String.fromCharCode.apply(null, new Uint8Array(arr));
try {
return jIO.util.dataURItoBlob(arr);
} catch (error) {
if (error instanceof DOMException) {
return blob;
}
throw error;
}
}, function () { return blob; });
});
};
CryptStorage.prototype.removeAttachment = function () {
return this._sub_storage.removeAttachment.apply(this._sub_storage,
arguments);
};
CryptStorage.prototype.allAttachments = function () {
return this._sub_storage.allAttachments.apply(this._sub_storage,
arguments);
};
jIO.addStorage('crypt', CryptStorage);
}(jIO, RSVP, DOMException, Blob, crypto, Uint8Array, ArrayBuffer));
;/*
* Copyright 2013, Nexedi SA
* Released under the LGPL license.
......@@ -8342,7 +8531,7 @@ Query.searchTextToRegExp = searchTextToRegExp;
});
})
.push(undefined, function (error) {
if (error.target.status === 403) {
if (error.target.status === 403 || error.target.status === 424) {
throw new jIO.util.jIOError("Cannot access subdocument", 404);
}
throw error;
......@@ -8691,9 +8880,11 @@ Query.searchTextToRegExp = searchTextToRegExp;
// }
/*jslint nomen: true, unparam: true */
/*global jIO, UriTemplate, FormData, RSVP, URI, Blob*/
/*global jIO, UriTemplate, FormData, RSVP, URI, Blob, objectToSearchText,
SimpleQuery, ComplexQuery*/
(function (jIO, UriTemplate, FormData, RSVP, URI, Blob) {
(function (jIO, UriTemplate, FormData, RSVP, URI, Blob, objectToSearchText,
SimpleQuery, ComplexQuery) {
"use strict";
function getSiteDocument(storage) {
......@@ -9079,6 +9270,38 @@ Query.searchTextToRegExp = searchTextToRegExp;
(name === "sort"));
};
function isSingleLocalRoles(parsed_query) {
if ((parsed_query instanceof SimpleQuery) &&
(parsed_query.key === 'local_roles')) {
// local_roles:"Assignee"
return parsed_query.value;
}
}
function isMultipleLocalRoles(parsed_query) {
var i,
sub_query,
is_multiple = true,
local_role_list = [];
if ((parsed_query instanceof ComplexQuery) &&
(parsed_query.operator === 'OR')) {
for (i = 0; i < parsed_query.query_list.length; i += 1) {
sub_query = parsed_query.query_list[i];
if ((sub_query instanceof SimpleQuery) &&
(sub_query.key === 'local_roles')) {
local_role_list.push(sub_query.value);
} else {
is_multiple = false;
}
}
if (is_multiple) {
// local_roles:"Assignee" OR local_roles:"Assignor"
return local_role_list;
}
}
}
ERP5Storage.prototype.buildQuery = function (options) {
// if (typeof options.query !== "string") {
// options.query = (options.query ?
......@@ -9087,15 +9310,63 @@ Query.searchTextToRegExp = searchTextToRegExp;
// }
return getSiteDocument(this)
.push(function (site_hal) {
var query = options.query,
i,
parsed_query,
sub_query,
result_list,
local_roles;
if (options.query) {
parsed_query = jIO.QueryFactory.create(options.query);
result_list = isSingleLocalRoles(parsed_query);
if (result_list) {
query = undefined;
local_roles = result_list;
} else {
result_list = isMultipleLocalRoles(parsed_query);
if (result_list) {
query = undefined;
local_roles = result_list;
} else if ((parsed_query instanceof ComplexQuery) &&
(parsed_query.operator === 'AND')) {
// portal_type:"Person" AND local_roles:"Assignee"
for (i = 0; i < parsed_query.query_list.length; i += 1) {
sub_query = parsed_query.query_list[i];
result_list = isSingleLocalRoles(sub_query);
if (result_list) {
local_roles = result_list;
parsed_query.query_list.splice(i, 1);
query = objectToSearchText(parsed_query);
i = parsed_query.query_list.length;
} else {
result_list = isMultipleLocalRoles(sub_query);
if (result_list) {
local_roles = result_list;
parsed_query.query_list.splice(i, 1);
query = objectToSearchText(parsed_query);
i = parsed_query.query_list.length;
}
}
}
}
}
}
return jIO.util.ajax({
"type": "GET",
"url": UriTemplate.parse(site_hal._links.raw_search.href)
.expand({
query: options.query,
query: query,
// XXX Force erp5 to return embedded document
select_list: options.select_list || ["title", "reference"],
limit: options.limit,
sort_on: options.sort_on
sort_on: options.sort_on,
local_roles: local_roles
}),
"xhrFields": {
withCredentials: true
......@@ -9127,7 +9398,8 @@ Query.searchTextToRegExp = searchTextToRegExp;
jIO.addStorage("erp5", ERP5Storage);
}(jIO, UriTemplate, FormData, RSVP, URI, Blob));
}(jIO, UriTemplate, FormData, RSVP, URI, Blob, objectToSearchText,
SimpleQuery, ComplexQuery));
;/*jslint nomen: true*/
/*global RSVP*/
(function (jIO, RSVP) {
......@@ -10170,6 +10442,7 @@ Query.searchTextToRegExp = searchTextToRegExp;
var array_buffer_list = [],
blob,
i,
index,
len = result_list.length;
for (i = 0; i < len; i += 1) {
array_buffer_list.push(result_list[i].blob);
......@@ -10177,8 +10450,10 @@ Query.searchTextToRegExp = searchTextToRegExp;
if ((options.start === undefined) && (options.end === undefined)) {
return new Blob(array_buffer_list, {type: type});
}
index = Math.floor(start / UNITE) * UNITE;
blob = new Blob(array_buffer_list, {type: "application/octet-stream"});
return blob.slice(start, end, "application/octet-stream");
return blob.slice(start - index, end - index,
"application/octet-stream");
});
};
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "jio",
"version": "v3.4.1",
"version": "v3.5.0",
"license": "LGPLv3",
"author": "Nexedi SA",
"contributors": [
......
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