[enh] Warn user about possible security flaws when installing custom app. Fix #78

This commit is contained in:
opi 2014-10-13 16:00:30 +02:00
parent 3eea7fd634
commit 515d285d57
3 changed files with 100 additions and 91 deletions

185
js/app.js
View file

@ -926,112 +926,119 @@ app = Sammy('#main', function (sam) {
// Install custom app from github // Install custom app from github
sam.post('#/apps/install/custom', function(c) { sam.post('#/apps/install/custom', function(c) {
params = { 'label': c.params['label'], 'app': c.params['url'] } if (confirm(y18n.t('confirm_install_custom_app'))) {
delete c.params['label']; params = { 'label': c.params['label'], 'app': c.params['url'] }
delete c.params['url']; delete c.params['label'];
delete c.params['url'];
// Force trailing slash // Force trailing slash
params.app = params.app.replace(/\/?$/, '/'); params.app = params.app.replace(/\/?$/, '/');
// Get manifest.json to get additional parameters // Get manifest.json to get additional parameters
jQuery.ajax({ jQuery.ajax({
url: params.app.replace('github.com', 'rawgit.com') + 'master/manifest.json', url: params.app.replace('github.com', 'rawgit.com') + 'master/manifest.json',
type: 'GET', type: 'GET',
crossdomain: true, crossdomain: true,
dataType: 'json', dataType: 'json',
}) })
.done(function(manifest) { .done(function(manifest) {
manifest = manifest || {}; manifest = manifest || {};
// Fake appData (see '#/apps/install/:app' route) // Fake appData (see '#/apps/install/:app' route)
var appData = { var appData = {
manifest : manifest, manifest : manifest,
id : params.app, id : params.app,
multi_instance : manifest.multi_instance, multi_instance : manifest.multi_instance,
}; };
if (typeof appData.manifest.arguments.install !== 'undefined') { if (typeof appData.manifest.arguments.install !== 'undefined') {
$.each(appData.manifest.arguments.install, function(k, v) { $.each(appData.manifest.arguments.install, function(k, v) {
// Default values // Default values
appData.manifest.arguments.install[k].type = 'text'; appData.manifest.arguments.install[k].type = 'text';
appData.manifest.arguments.install[k].required = 'required'; appData.manifest.arguments.install[k].required = 'required';
// Radio button // Radio button
if (typeof appData.manifest.arguments.install[k].choices !== 'undefined') { if (typeof appData.manifest.arguments.install[k].choices !== 'undefined') {
// Update choices values with key and checked data // Update choices values with key and checked data
$.each(appData.manifest.arguments.install[k].choices, function(ck, cv){ $.each(appData.manifest.arguments.install[k].choices, function(ck, cv){
appData.manifest.arguments.install[k].choices[ck] = { appData.manifest.arguments.install[k].choices[ck] = {
value: cv, value: cv,
label: cv, label: cv,
selected: (cv == appData.manifest.arguments.install[k].default) ? true : false, selected: (cv == appData.manifest.arguments.install[k].default) ? true : false,
}; };
});
}
// Special case for domain input.
// Display a list of available domains
if (v.name == 'domain') {
appData.manifest.arguments.install[k].choices = [];
$.each(c.params.domains, function(key, domain){
appData.manifest.arguments.install[k].choices.push({
value: domain,
label: domain,
selected: false
}); });
}); }
appData.manifest.arguments.install[k].help = "<a href='#/domains'>"+y18n.t('manage_domains')+"</a>";
}
// Special case for admin input. // Special case for domain input.
// Display a list of available users // Display a list of available domains
if (v.name == 'admin') { if (v.name == 'domain') {
appData.manifest.arguments.install[k].choices = []; appData.manifest.arguments.install[k].choices = [];
$.each(c.params.users, function(key, user){ $.each(c.params.domains, function(key, domain){
appData.manifest.arguments.install[k].choices.push({ appData.manifest.arguments.install[k].choices.push({
value: user.username, value: domain,
label: user.fullname+' ('+user.mail+')', label: domain,
selected: false selected: false
});
}); });
}); appData.manifest.arguments.install[k].help = "<a href='#/domains'>"+y18n.t('manage_domains')+"</a>";
appData.manifest.arguments.install[k].help = "<a href='#/users'>"+y18n.t('manage_users')+"</a>"; }
}
// Special case for password input. // Special case for admin input.
if (v.name == 'password') { // Display a list of available users
appData.manifest.arguments.install[k].type = 'password'; if (v.name == 'admin') {
} appData.manifest.arguments.install[k].choices = [];
$.each(c.params.users, function(key, user){
appData.manifest.arguments.install[k].choices.push({
value: user.username,
label: user.fullname+' ('+user.mail+')',
selected: false
});
});
appData.manifest.arguments.install[k].help = "<a href='#/users'>"+y18n.t('manage_users')+"</a>";
}
// Optional field // Special case for password input.
if (typeof v.optional !== 'undefined' && v.optional == "true") { if (v.name == 'password') {
appData.manifest.arguments.install[k].required = ''; appData.manifest.arguments.install[k].type = 'password';
} }
// Multilingual description // Optional field
appData.manifest.arguments.install[k].label = (typeof appData.manifest.arguments.install[k].ask[y18n.locale] !== 'undefined') ? if (typeof v.optional !== 'undefined' && v.optional == "true") {
appData.manifest.arguments.install[k].ask[y18n.locale] : appData.manifest.arguments.install[k].required = '';
appData.manifest.arguments.install[k].ask['en'] }
// Multilingual description
appData.manifest.arguments.install[k].label = (typeof appData.manifest.arguments.install[k].ask[y18n.locale] !== 'undefined') ?
appData.manifest.arguments.install[k].ask[y18n.locale] :
appData.manifest.arguments.install[k].ask['en']
;
});
}
// Multilingual description
appData.description = (typeof appData.manifest.description[y18n.locale] !== 'undefined') ?
appData.manifest.description[y18n.locale] :
appData.manifest.description['en']
; ;
});
}
// Multilingual description // Multi Instance settings
appData.description = (typeof appData.manifest.description[y18n.locale] !== 'undefined') ? appData.manifest.multi_instance = (appData.manifest.multi_instance == 'true') ? y18n.t('yes') : y18n.t('no');
appData.manifest.description[y18n.locale] :
appData.manifest.description['en']
;
// Multi Instance settings // View app install form
appData.manifest.multi_instance = (appData.manifest.multi_instance == 'true') ? y18n.t('yes') : y18n.t('no'); c.view('app/app_install', appData);
})
// View app install form .fail(function(xhr) {
c.view('app/app_install', appData); c.flash('fail', y18n.t('app_install_custom_no_manifest'));
}) store.clear('slide');
.fail(function(xhr) { c.redirect('#/apps/install');
c.flash('fail', y18n.t('app_install_custom_no_manifest')); });
}
else {
c.flash('warning', y18n.t('app_install_cancel'));
store.clear('slide'); store.clear('slide');
c.redirect('#/apps/install'); c.redirect('#/apps/install');
}); }
}); });

View file

@ -117,7 +117,8 @@
"custom_app_install" : "Install custom app", "custom_app_install" : "Install custom app",
"custom_app_url_only_github" : "Currently only from GitHub", "custom_app_url_only_github" : "Currently only from GitHub",
"confirm_install_domain_root" : "You will not be able to install any other app on %s. Continue ?", "confirm_install_domain_root" : "You will not be able to install any other app on %s. Continue ?",
"app_install_cancel" : "Installation cancelled", "app_install_cancel" : "Installation cancelled.",
"confirm_install_custom_app" : "Installing 3rd party applications may compromise the security of your system. Use at your own risks.",
"backup" : "Backup", "backup" : "Backup",
"backup_warning_title" : "The backup system is not implemented yet.", "backup_warning_title" : "The backup system is not implemented yet.",

View file

@ -116,7 +116,8 @@
"custom_app_install" : "Installer une application personnalisée", "custom_app_install" : "Installer une application personnalisée",
"custom_app_url_only_github" : "Uniquement depuis GitHub", "custom_app_url_only_github" : "Uniquement depuis GitHub",
"confirm_install_domain_root" : "Vous ne pourrez pas installer d'autres applications sur %s. Continuer ?", "confirm_install_domain_root" : "Vous ne pourrez pas installer d'autres applications sur %s. Continuer ?",
"app_install_cancel" : "Installation annulée", "app_install_cancel" : "Installation annulée.",
"confirm_install_custom_app" : "L'installation d'application tierce peut comprometre la sécurité du système. Continuer à vos risques ?",
"backup" : "Sauvegarde", "backup" : "Sauvegarde",
"backup_warning_title" : "Le système de sauvegarde n'est pas encore implémenté.", "backup_warning_title" : "Le système de sauvegarde n'est pas encore implémenté.",