automount: re-use the same dialog when passphrase doesn't match

Wait until the completion of the mount operation before dismissing the
passphrase dialog, so in case it fails, we can re-use the same dialog
with an error message (like e.g. PolicyKit auth dialogs) instead of
showing a brand new one.

https://bugzilla.gnome.org/show_bug.cgi?id=674962
This commit is contained in:
Cosimo Cecchi 2012-06-19 20:22:26 -04:00
parent d1815a36d0
commit 66af7de6d6
2 changed files with 75 additions and 39 deletions

View File

@ -238,7 +238,7 @@ const AutomountManager = new Lang.Class({
if (params.useMountOp) { if (params.useMountOp) {
let operation = new ShellMountOperation.ShellMountOperation(volume); let operation = new ShellMountOperation.ShellMountOperation(volume);
this._mountVolume(volume, operation.mountOp, params.allowAutorun); this._mountVolume(volume, operation, params.allowAutorun);
} else { } else {
this._mountVolume(volume, null, params.allowAutorun); this._mountVolume(volume, null, params.allowAutorun);
} }
@ -248,7 +248,10 @@ const AutomountManager = new Lang.Class({
if (allowAutorun) if (allowAutorun)
this._allowAutorun(volume); this._allowAutorun(volume);
volume.mount(0, operation, null, let mountOp = operation ? operation.mountOp : null;
volume._operation = operation;
volume.mount(0, mountOp, null,
Lang.bind(this, this._onVolumeMounted)); Lang.bind(this, this._onVolumeMounted));
}, },
@ -257,15 +260,17 @@ const AutomountManager = new Lang.Class({
try { try {
volume.mount_finish(res); volume.mount_finish(res);
this._closeOperation(volume);
} catch (e) { } catch (e) {
let string = e.toString(); // FIXME: we will always get G_IO_ERROR_FAILED from the gvfs udisks
// backend in this case, see
// FIXME: needs proper error code handling instead of this // https://bugs.freedesktop.org/show_bug.cgi?id=51271
// See https://bugzilla.gnome.org/show_bug.cgi?id=591480 if (e.message.indexOf('No key available with this passphrase') != -1) {
if (string.indexOf('No key available with this passphrase') != -1)
this._reaskPassword(volume); this._reaskPassword(volume);
else } else {
log('Unable to mount volume ' + volume.get_name() + ': ' + string); log('Unable to mount volume ' + volume.get_name() + ': ' + e.toString());
this._closeOperation(volume);
}
} }
}, },
@ -277,8 +282,16 @@ const AutomountManager = new Lang.Class({
}, },
_reaskPassword: function(volume) { _reaskPassword: function(volume) {
let operation = new ShellMountOperation.ShellMountOperation(volume, { reaskPassword: true }); let existingDialog = volume._operation ? volume._operation.borrowDialog() : null;
this._mountVolume(volume, operation.mountOp); let operation =
new ShellMountOperation.ShellMountOperation(volume,
{ existingDialog: existingDialog });
this._mountVolume(volume, operation);
},
_closeOperation: function(volume) {
if (volume._operation)
volume._operation.close();
}, },
_allowAutorun: function(volume) { _allowAutorun: function(volume) {

View File

@ -99,11 +99,11 @@ const ShellMountOperation = new Lang.Class({
Name: 'ShellMountOperation', Name: 'ShellMountOperation',
_init: function(source, params) { _init: function(source, params) {
params = Params.parse(params, { reaskPassword: false }); params = Params.parse(params, { existingDialog: null });
this._reaskPassword = params.reaskPassword;
this._dialog = null; this._dialog = null;
this._dialogId = 0;
this._existingDialog = params.existingDialog;
this._processesDialog = null; this._processesDialog = null;
this.mountOp = new Shell.MountOperation(); this.mountOp = new Shell.MountOperation();
@ -115,21 +115,29 @@ const ShellMountOperation = new Lang.Class({
this.mountOp.connect('show-processes-2', this.mountOp.connect('show-processes-2',
Lang.bind(this, this._onShowProcesses2)); Lang.bind(this, this._onShowProcesses2));
this.mountOp.connect('aborted', this.mountOp.connect('aborted',
Lang.bind(this, this._onAborted)); Lang.bind(this, this.close));
this._gicon = source.get_icon(); this._gicon = source.get_icon();
}, },
_closeExistingDialog: function() {
if (!this._existingDialog)
return;
this._existingDialog.close(global.get_current_time());
this._existingDialog = null;
},
_onAskQuestion: function(op, message, choices) { _onAskQuestion: function(op, message, choices) {
this._closeExistingDialog();
this._dialog = new ShellMountQuestionDialog(this._gicon); this._dialog = new ShellMountQuestionDialog(this._gicon);
this._dialog.connect('response', this._dialogId = this._dialog.connect('response',
Lang.bind(this, function(object, choice) { Lang.bind(this, function(object, choice) {
this.mountOp.set_choice(choice); this.mountOp.set_choice(choice);
this.mountOp.reply(Gio.MountOperationResult.HANDLED); this.mountOp.reply(Gio.MountOperationResult.HANDLED);
this._dialog.close(global.get_current_time()); this.close();
this._dialog = null;
})); }));
this._dialog.update(message, choices); this._dialog.update(message, choices);
@ -137,11 +145,15 @@ const ShellMountOperation = new Lang.Class({
}, },
_onAskPassword: function(op, message) { _onAskPassword: function(op, message) {
this._dialog = new ShellMountPasswordDialog( if (this._existingDialog) {
message, this._gicon, this._reaskPassword); this._dialog = this._existingDialog;
this._dialog.reaskPassword();
} else {
this._dialog = new ShellMountPasswordDialog(message, this._gicon);
}
this._dialog.connect('response', Lang.bind(this, this._dialogId = this._dialog.connect('response', Lang.bind(this,
function(object, choice, password, remember) { function(object, choice, password, remember) {
if (choice == '-1') { if (choice == '-1') {
this.mountOp.reply(Gio.MountOperationResult.ABORTED); this.mountOp.reply(Gio.MountOperationResult.ABORTED);
} else { } else {
@ -153,16 +165,13 @@ const ShellMountOperation = new Lang.Class({
this.mountOp.set_password(password); this.mountOp.set_password(password);
this.mountOp.reply(Gio.MountOperationResult.HANDLED); this.mountOp.reply(Gio.MountOperationResult.HANDLED);
} }
this._dialog.close(global.get_current_time());
this._dialog = null;
})); }));
this._dialog.open(global.get_current_time()); this._dialog.open(global.get_current_time());
}, },
_onAborted: function(op) { close: function(op) {
if (!this._dialog) this._closeExistingDialog();
return; this._processesDialog = null;
if (this._dialog) { if (this._dialog) {
this._dialog.close(global.get_current_time()); this._dialog.close(global.get_current_time());
@ -171,6 +180,8 @@ const ShellMountOperation = new Lang.Class({
}, },
_onShowProcesses2: function(op) { _onShowProcesses2: function(op) {
this._closeExistingDialog();
let processes = op.get_show_processes_pids(); let processes = op.get_show_processes_pids();
let choices = op.get_show_processes_choices(); let choices = op.get_show_processes_choices();
let message = op.get_show_processes_message(); let message = op.get_show_processes_message();
@ -179,7 +190,7 @@ const ShellMountOperation = new Lang.Class({
this._processesDialog = new ShellProcessesDialog(this._gicon); this._processesDialog = new ShellProcessesDialog(this._gicon);
this._dialog = this._processesDialog; this._dialog = this._processesDialog;
this._processesDialog.connect('response', this._dialogId = this._processesDialog.connect('response',
Lang.bind(this, function(object, choice) { Lang.bind(this, function(object, choice) {
if (choice == -1) { if (choice == -1) {
this.mountOp.reply(Gio.MountOperationResult.ABORTED); this.mountOp.reply(Gio.MountOperationResult.ABORTED);
@ -188,14 +199,22 @@ const ShellMountOperation = new Lang.Class({
this.mountOp.reply(Gio.MountOperationResult.HANDLED); this.mountOp.reply(Gio.MountOperationResult.HANDLED);
} }
this._processesDialog.close(global.get_current_time()); this.close();
this._dialog = null;
})); }));
this._processesDialog.open(global.get_current_time()); this._processesDialog.open(global.get_current_time());
} }
this._processesDialog.update(message, processes, choices); this._processesDialog.update(message, processes, choices);
}, },
borrowDialog: function() {
if (this._dialogId != 0) {
this._dialog.disconnect(this._dialogId);
this._dialogId = 0;
}
return this._dialog;
}
}); });
const ShellMountQuestionDialog = new Lang.Class({ const ShellMountQuestionDialog = new Lang.Class({
@ -248,7 +267,7 @@ const ShellMountPasswordDialog = new Lang.Class({
Name: 'ShellMountPasswordDialog', Name: 'ShellMountPasswordDialog',
Extends: ModalDialog.ModalDialog, Extends: ModalDialog.ModalDialog,
_init: function(message, gicon, reaskPassword) { _init: function(message, gicon) {
let strings = message.split('\n'); let strings = message.split('\n');
this.parent({ styleClass: 'prompt-dialog' }); this.parent({ styleClass: 'prompt-dialog' });
@ -300,13 +319,12 @@ const ShellMountPasswordDialog = new Lang.Class({
this._passwordBox.add(this._passwordEntry, {expand: true }); this._passwordBox.add(this._passwordEntry, {expand: true });
this.setInitialKeyFocus(this._passwordEntry); this.setInitialKeyFocus(this._passwordEntry);
if (reaskPassword) { this._errorMessageLabel = new St.Label({ style_class: 'prompt-dialog-error-label',
this._errorMessageLabel = new St.Label({ style_class: 'prompt-dialog-error-label', text: _("Sorry, that didn\'t work. Please try again.") });
text: _("Sorry, that didn\'t work. Please try again.") }); this._errorMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._errorMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE; this._errorMessageLabel.clutter_text.line_wrap = true;
this._errorMessageLabel.clutter_text.line_wrap = true; this._errorMessageLabel.hide();
this._messageBox.add(this._errorMessageLabel); this._messageBox.add(this._errorMessageLabel);
}
this._rememberChoice = new CheckBox.CheckBox(); this._rememberChoice = new CheckBox.CheckBox();
this._rememberChoice.getLabelActor().text = _("Remember Passphrase"); this._rememberChoice.getLabelActor().text = _("Remember Passphrase");
@ -324,6 +342,11 @@ const ShellMountPasswordDialog = new Lang.Class({
this.setButtons(buttons); this.setButtons(buttons);
}, },
reaskPassword: function() {
this._passwordEntry.set_text('');
this._errorMessageLabel.show();
},
_onCancelButton: function() { _onCancelButton: function() {
this.emit('response', -1, '', false); this.emit('response', -1, '', false);
}, },