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; ...@@ -7863,6 +7863,195 @@ Query.searchTextToRegExp = searchTextToRegExp;
jIO.addStorage('zip', ZipStorage); jIO.addStorage('zip', ZipStorage);
}(RSVP, Blob, LZString, DOMException)); }(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 * Copyright 2013, Nexedi SA
* Released under the LGPL license. * Released under the LGPL license.
...@@ -8342,7 +8531,7 @@ Query.searchTextToRegExp = searchTextToRegExp; ...@@ -8342,7 +8531,7 @@ Query.searchTextToRegExp = searchTextToRegExp;
}); });
}) })
.push(undefined, function (error) { .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 new jIO.util.jIOError("Cannot access subdocument", 404);
} }
throw error; throw error;
...@@ -8691,9 +8880,11 @@ Query.searchTextToRegExp = searchTextToRegExp; ...@@ -8691,9 +8880,11 @@ Query.searchTextToRegExp = searchTextToRegExp;
// } // }
/*jslint nomen: true, unparam: true */ /*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"; "use strict";
function getSiteDocument(storage) { function getSiteDocument(storage) {
...@@ -9079,6 +9270,38 @@ Query.searchTextToRegExp = searchTextToRegExp; ...@@ -9079,6 +9270,38 @@ Query.searchTextToRegExp = searchTextToRegExp;
(name === "sort")); (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) { ERP5Storage.prototype.buildQuery = function (options) {
// if (typeof options.query !== "string") { // if (typeof options.query !== "string") {
// options.query = (options.query ? // options.query = (options.query ?
...@@ -9087,15 +9310,63 @@ Query.searchTextToRegExp = searchTextToRegExp; ...@@ -9087,15 +9310,63 @@ Query.searchTextToRegExp = searchTextToRegExp;
// } // }
return getSiteDocument(this) return getSiteDocument(this)
.push(function (site_hal) { .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({ return jIO.util.ajax({
"type": "GET", "type": "GET",
"url": UriTemplate.parse(site_hal._links.raw_search.href) "url": UriTemplate.parse(site_hal._links.raw_search.href)
.expand({ .expand({
query: options.query, query: query,
// XXX Force erp5 to return embedded document // XXX Force erp5 to return embedded document
select_list: options.select_list || ["title", "reference"], select_list: options.select_list || ["title", "reference"],
limit: options.limit, limit: options.limit,
sort_on: options.sort_on sort_on: options.sort_on,
local_roles: local_roles
}), }),
"xhrFields": { "xhrFields": {
withCredentials: true withCredentials: true
...@@ -9127,7 +9398,8 @@ Query.searchTextToRegExp = searchTextToRegExp; ...@@ -9127,7 +9398,8 @@ Query.searchTextToRegExp = searchTextToRegExp;
jIO.addStorage("erp5", ERP5Storage); jIO.addStorage("erp5", ERP5Storage);
}(jIO, UriTemplate, FormData, RSVP, URI, Blob)); }(jIO, UriTemplate, FormData, RSVP, URI, Blob, objectToSearchText,
SimpleQuery, ComplexQuery));
;/*jslint nomen: true*/ ;/*jslint nomen: true*/
/*global RSVP*/ /*global RSVP*/
(function (jIO, RSVP) { (function (jIO, RSVP) {
...@@ -10170,6 +10442,7 @@ Query.searchTextToRegExp = searchTextToRegExp; ...@@ -10170,6 +10442,7 @@ Query.searchTextToRegExp = searchTextToRegExp;
var array_buffer_list = [], var array_buffer_list = [],
blob, blob,
i, i,
index,
len = result_list.length; len = result_list.length;
for (i = 0; i < len; i += 1) { for (i = 0; i < len; i += 1) {
array_buffer_list.push(result_list[i].blob); array_buffer_list.push(result_list[i].blob);
...@@ -10177,8 +10450,10 @@ Query.searchTextToRegExp = searchTextToRegExp; ...@@ -10177,8 +10450,10 @@ Query.searchTextToRegExp = searchTextToRegExp;
if ((options.start === undefined) && (options.end === undefined)) { if ((options.start === undefined) && (options.end === undefined)) {
return new Blob(array_buffer_list, {type: type}); return new Blob(array_buffer_list, {type: type});
} }
index = Math.floor(start / UNITE) * UNITE;
blob = new Blob(array_buffer_list, {type: "application/octet-stream"}); 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", "name": "jio",
"version": "v3.4.1", "version": "v3.5.0",
"license": "LGPLv3", "license": "LGPLv3",
"author": "Nexedi SA", "author": "Nexedi SA",
"contributors": [ "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