diff --git a/html/admin/js/bootstrap/errors.js b/html/admin/js/bootstrap/errors.js
index 596e6e5f4e..e037941e2b 100644
--- a/html/admin/js/bootstrap/errors.js
+++ b/html/admin/js/bootstrap/errors.js
@@ -125,6 +125,9 @@
"ERROR_USER_DUPLICATE" : { "code" : 1702, "message" : "duplicate user" },
"ERROR_USER_NOT_FOUND" : { "code" : 1703, "message" : "user not found" },
"ERROR_APPLICATION_NOT_FOUND" : { "code" : 1750, "message" : "application not found" },
+ "ERROR_APPLICATION_INVALID_NAME" : { "code" : 1751, "message" : "invalid application name" },
+ "ERROR_APPLICATION_INVALID_MOUNT" : { "code" : 1752, "message" : "invalid mount" },
+ "ERROR_APPLICATION_DOWNLOAD_FAILED" : { "code" : 1753, "message" : "application download failed" },
"ERROR_KEYVALUE_INVALID_KEY" : { "code" : 1800, "message" : "invalid key declaration" },
"ERROR_KEYVALUE_KEY_EXISTS" : { "code" : 1801, "message" : "key already exists" },
"ERROR_KEYVALUE_KEY_NOT_FOUND" : { "code" : 1802, "message" : "key not found" },
diff --git a/js/client/modules/org/arangodb/aal.js b/js/client/modules/org/arangodb/aal.js
index d9cfa8154b..83bd55557a 100644
--- a/js/client/modules/org/arangodb/aal.js
+++ b/js/client/modules/org/arangodb/aal.js
@@ -36,6 +36,7 @@ var fs = require("fs");
var arangodb = require("org/arangodb");
var arangosh = require("org/arangodb/arangosh");
+var ArangoError = require("org/arangodb/arango-error").ArangoError;
var arango = internal.arango;
var db = internal.db;
@@ -78,25 +79,47 @@ function buildGithubFishbowlUrl (name) {
}
////////////////////////////////////////////////////////////////////////////////
-/// @brief validates the source type specified by the user
+/// @brief thrown an error in case a download failed
////////////////////////////////////////////////////////////////////////////////
-
-function validateSource (origin) {
- var type, location;
-
- if (origin === undefined || origin === null) {
- throw "no application name specified";
+
+function throwDownloadError (msg) {
+ var err = new ArangoError();
+ err.errorNum = arangodb.errors.ERROR_APPLICATION_DOWNLOAD_FAILED.code;
+ err.errorMessage = arangodb.errors.ERROR_APPLICATION_DOWNLOAD_FAILED.message + ': ' + String(msg);
+
+ throw err;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// @brief validate an app name and fail if it is invalid
+////////////////////////////////////////////////////////////////////////////////
+
+function validateAppName (name) {
+ if (typeof name === 'string' && name.length > 0) {
+ return;
}
- if (origin && origin.location && origin.type) {
- type = origin.type;
- location = origin.location;
- }
- else {
- throw "invalid application declaration";
+ var err = new ArangoError();
+ err.errorNum = arangodb.errors.ERROR_APPLICATION_INVALID_NAME.code;
+ err.errorMessage = arangodb.errors.ERROR_APPLICATION_INVALID_NAME.message;
+
+ throw err;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// @brief validate a mount and fail if it is invalid
+////////////////////////////////////////////////////////////////////////////////
+
+function validateMount (mnt) {
+ if (typeof mnt === 'string' && mnt.substr(0, 1) === '/') {
+ return;
}
- return { location: location, type: type };
+ var err = new ArangoError();
+ err.errorNum = arangodb.errors.ERROR_APPLICATION_INVALID_MOUNT.code;
+ err.errorMessage = arangodb.errors.ERROR_APPLICATION_INVALID_MOUNT.message;
+
+ throw err;
}
////////////////////////////////////////////////////////////////////////////////
@@ -271,11 +294,11 @@ function processGithubRepository (source) {
source.removeFile = true;
}
else {
- throw "github download failed";
+ throwDownloadError("could not download from repository '" + url + "'");
}
}
catch (err) {
- throw "could not download from repository '" + url + "'";
+ throwDownloadError("could not download from repository '" + url + "': " + String(err));
}
repackZipFile(source);
@@ -351,11 +374,11 @@ exports.load = function (type, location, version) {
filename = processSource(source);
if (typeof source.name === "undefined") {
- throw "name is missing for '" + JSON.stringify(source);
+ throw "name is missing for '" + JSON.stringify(source) + "'";
}
if (typeof source.version === "undefined") {
- throw "version is missing for '" + JSON.stringify(source);
+ throw "version is missing for '" + JSON.stringify(source) + "'";
}
req = {
@@ -381,6 +404,9 @@ exports.installApp = function (appId, mount, options) {
mount: mount,
options: options
};
+
+ validateAppName(appId);
+ validateMount(mount);
res = arango.POST("/_admin/foxx/install", JSON.stringify(req));
arangosh.checkRequestResult(res);
@@ -399,6 +425,9 @@ exports.installDevApp = function (name, mount, options) {
mount: mount,
options: options
};
+
+ validateAppName(name);
+ validateMount(mount);
res = arango.POST("/_admin/foxx/dev-install", JSON.stringify(req));
arangosh.checkRequestResult(res);
@@ -416,6 +445,8 @@ exports.uninstallApp = function (key) {
key: key
};
+ validateAppName(key);
+
res = arango.POST("/_admin/foxx/uninstall", JSON.stringify(req));
arangosh.checkRequestResult(res);
};
@@ -520,6 +551,8 @@ exports.listAvailable = function () {
exports.details = function (name) {
'use strict';
+ validateAppName(name);
+
var i;
var tempFile = fs.getTempFile("downloads", false);
@@ -530,15 +563,21 @@ exports.details = function (name) {
var result = internal.download(url, "get", tempFile);
if (result.code < 200 || result.code > 299) {
- throw "github download failed";
+ throwDownloadError("could not download from repository '" + url + "'");
}
content = fs.read(tempFile);
fs.remove(tempFile);
}
catch (err1) {
- fs.remove(tempFile);
- throw "could not download from repository '" + url + "': " + String(err1);
+ if (fs.exists(tempFile)) {
+ try {
+ fs.remove(tempFile);
+ }
+ catch (err2) {
+ }
+ }
+ throwDownloadError("could not download from repository '" + url + "': " + String(err1));
}
var desc;
diff --git a/js/common/bootstrap/errors.js b/js/common/bootstrap/errors.js
index 596e6e5f4e..e037941e2b 100644
--- a/js/common/bootstrap/errors.js
+++ b/js/common/bootstrap/errors.js
@@ -125,6 +125,9 @@
"ERROR_USER_DUPLICATE" : { "code" : 1702, "message" : "duplicate user" },
"ERROR_USER_NOT_FOUND" : { "code" : 1703, "message" : "user not found" },
"ERROR_APPLICATION_NOT_FOUND" : { "code" : 1750, "message" : "application not found" },
+ "ERROR_APPLICATION_INVALID_NAME" : { "code" : 1751, "message" : "invalid application name" },
+ "ERROR_APPLICATION_INVALID_MOUNT" : { "code" : 1752, "message" : "invalid mount" },
+ "ERROR_APPLICATION_DOWNLOAD_FAILED" : { "code" : 1753, "message" : "application download failed" },
"ERROR_KEYVALUE_INVALID_KEY" : { "code" : 1800, "message" : "invalid key declaration" },
"ERROR_KEYVALUE_KEY_EXISTS" : { "code" : 1801, "message" : "key already exists" },
"ERROR_KEYVALUE_KEY_NOT_FOUND" : { "code" : 1802, "message" : "key not found" },
diff --git a/js/server/modules/org/arangodb/foxx-manager.js b/js/server/modules/org/arangodb/foxx-manager.js
index 890283477c..d9f342afb9 100644
--- a/js/server/modules/org/arangodb/foxx-manager.js
+++ b/js/server/modules/org/arangodb/foxx-manager.js
@@ -107,7 +107,7 @@ function buildAssetContent (app, assets) {
content += c;
}
catch (err) {
- console.error("cannot read asset '%s'", files[i]);
+ console.error("cannot read asset '%s'", files[i]);
}
}
@@ -126,6 +126,9 @@ function installAssets (app, routes) {
var route;
desc = app._manifest;
+ if (! desc) {
+ throw "invalid application manifest";
+ }
if (desc.hasOwnProperty('assets')) {
for (path in desc.assets) {
@@ -190,6 +193,10 @@ function executeAppScript (app, name, mount, prefix) {
};
desc = app._manifest;
+
+ if (! desc) {
+ throw "invalid application manifest";
+ }
if (desc.hasOwnProperty(name)) {
var cp = appContext.collectionPrefix;
diff --git a/lib/BasicsC/errors.dat b/lib/BasicsC/errors.dat
index 50c24d006a..9fb83d9eb1 100755
--- a/lib/BasicsC/errors.dat
+++ b/lib/BasicsC/errors.dat
@@ -180,6 +180,9 @@ ERROR_USER_NOT_FOUND,1703,"user not found","Will be raised when a user name is u
################################################################################
ERROR_APPLICATION_NOT_FOUND,1750,"application not found","Will be raised when an application is not found or not present in the specified version."
+ERROR_APPLICATION_INVALID_NAME,1751,"invalid application name","Will be raised when an invalid application name is specified."
+ERROR_APPLICATION_INVALID_MOUNT,1752,"invalid mount","Will be raised when an invalid mount is specified."
+ERROR_APPLICATION_DOWNLOAD_FAILED,1753,"application download failed","Will be raised when an application download from the central repository failed."
################################################################################
## Key value access
diff --git a/lib/BasicsC/voc-errors.c b/lib/BasicsC/voc-errors.c
index 21fb29f865..4d030e6199 100644
--- a/lib/BasicsC/voc-errors.c
+++ b/lib/BasicsC/voc-errors.c
@@ -121,6 +121,9 @@ void TRI_InitialiseErrorMessages (void) {
REG_ERROR(ERROR_USER_DUPLICATE, "duplicate user");
REG_ERROR(ERROR_USER_NOT_FOUND, "user not found");
REG_ERROR(ERROR_APPLICATION_NOT_FOUND, "application not found");
+ REG_ERROR(ERROR_APPLICATION_INVALID_NAME, "invalid application name");
+ REG_ERROR(ERROR_APPLICATION_INVALID_MOUNT, "invalid mount");
+ REG_ERROR(ERROR_APPLICATION_DOWNLOAD_FAILED, "application download failed");
REG_ERROR(ERROR_KEYVALUE_INVALID_KEY, "invalid key declaration");
REG_ERROR(ERROR_KEYVALUE_KEY_EXISTS, "key already exists");
REG_ERROR(ERROR_KEYVALUE_KEY_NOT_FOUND, "key not found");
diff --git a/lib/BasicsC/voc-errors.h b/lib/BasicsC/voc-errors.h
index 431eba5d98..18d8e2de6b 100644
--- a/lib/BasicsC/voc-errors.h
+++ b/lib/BasicsC/voc-errors.h
@@ -267,6 +267,13 @@ extern "C" {
/// - 1750: @LIT{application not found}
/// Will be raised when an application is not found or not present in the
/// specified version.
+/// - 1751: @LIT{invalid application name}
+/// Will be raised when an invalid application name is specified.
+/// - 1752: @LIT{invalid mount}
+/// Will be raised when an invalid mount is specified.
+/// - 1753: @LIT{application download failed}
+/// Will be raised when an application download from the central repository
+/// failed.
/// - 1800: @LIT{invalid key declaration}
/// Will be raised when an invalid key specification is passed to the server
/// - 1801: @LIT{key already exists}
@@ -1534,6 +1541,37 @@ void TRI_InitialiseErrorMessages (void);
#define TRI_ERROR_APPLICATION_NOT_FOUND (1750)
+////////////////////////////////////////////////////////////////////////////////
+/// @brief 1751: ERROR_APPLICATION_INVALID_NAME
+///
+/// invalid application name
+///
+/// Will be raised when an invalid application name is specified.
+////////////////////////////////////////////////////////////////////////////////
+
+#define TRI_ERROR_APPLICATION_INVALID_NAME (1751)
+
+////////////////////////////////////////////////////////////////////////////////
+/// @brief 1752: ERROR_APPLICATION_INVALID_MOUNT
+///
+/// invalid mount
+///
+/// Will be raised when an invalid mount is specified.
+////////////////////////////////////////////////////////////////////////////////
+
+#define TRI_ERROR_APPLICATION_INVALID_MOUNT (1752)
+
+////////////////////////////////////////////////////////////////////////////////
+/// @brief 1753: ERROR_APPLICATION_DOWNLOAD_FAILED
+///
+/// application download failed
+///
+/// Will be raised when an application download from the central repository
+/// failed.
+////////////////////////////////////////////////////////////////////////////////
+
+#define TRI_ERROR_APPLICATION_DOWNLOAD_FAILED (1753)
+
////////////////////////////////////////////////////////////////////////////////
/// @brief 1800: ERROR_KEYVALUE_INVALID_KEY
///