[gnome-shell/hotplug: 16/21] mount-operation: implement ask-password for mounting encrypted volumes
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/hotplug: 16/21] mount-operation: implement ask-password for mounting encrypted volumes
- Date: Mon, 27 Jun 2011 19:53:18 +0000 (UTC)
commit bb1bca679a2f902d3e97f9dadbc17568efe9cf2d
Author: Cosimo Cecchi <cosimoc gnome org>
Date: Thu Jun 23 17:48:20 2011 -0400
mount-operation: implement ask-password for mounting encrypted volumes
data/theme/gnome-shell.css | 4 ++
js/ui/automountManager.js | 18 ++++++-
js/ui/shellMountOperation.js | 109 ++++++++++++++++++++++++++++++++++++++++-
src/shell-mount-operation.c | 11 ++++
4 files changed, 136 insertions(+), 6 deletions(-)
---
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index 4a15fd6..84c4086 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -1661,6 +1661,10 @@ StTooltip StLabel {
icon-size: 32px;
}
+.mount-password-reask {
+ color: red;
+}
+
.show-processes-dialog,
.mount-question-dialog {
spacing: 24px;
diff --git a/js/ui/automountManager.js b/js/ui/automountManager.js
index d475a8c..9b32cc9 100644
--- a/js/ui/automountManager.js
+++ b/js/ui/automountManager.js
@@ -226,7 +226,7 @@ AutomountManager.prototype = {
return;
}
- let operation = new ShellMountOperation.ShellMountOperation(volume)
+ let operation = new ShellMountOperation.ShellMountOperation(volume);
this._mountVolume(volume, operation.mountOp);
},
@@ -241,8 +241,15 @@ AutomountManager.prototype = {
try {
volume.mount_finish(res);
} catch (e) {
- log('Unable to mount volume ' + volume.get_name() + ': ' +
- e.toString());
+ let string = e.toString();
+
+ // FIXME: needs proper error code handling instead of this
+ // See https://bugzilla.gnome.org/show_bug.cgi?id=591480
+ if (string.indexOf('No key available with this passphrase') != -1)
+ this._reaskPassword(volume);
+ else
+ log('Unable to mount volume ' + volume.get_name() + ': ' + string);
+
return;
}
},
@@ -254,6 +261,11 @@ AutomountManager.prototype = {
});
},
+ _reaskPassword: function(volume) {
+ let operation = new ShellMountOperation.ShellMountOperation(volume, { reaskPassword: true });
+ this._mountVolume(volume, operation.mountOp);
+ },
+
_allowAutorun: function(volume) {
volume.allowAutorun = true;
},
diff --git a/js/ui/shellMountOperation.js b/js/ui/shellMountOperation.js
index 2185bb0..2c07fca 100644
--- a/js/ui/shellMountOperation.js
+++ b/js/ui/shellMountOperation.js
@@ -8,7 +8,10 @@ const Pango = imports.gi.Pango;
const St = imports.gi.St;
const Shell = imports.gi.Shell;
+const Main = imports.ui.main;
+const MessageTray = imports.ui.messageTray;
const ModalDialog = imports.ui.modalDialog;
+const Params = imports.misc.params;
/* ------ Common Utils ------- */
@@ -86,12 +89,15 @@ ListItem.prototype = {
};
Signals.addSignalMethods(ListItem.prototype);
-function ShellMountOperation(source) {
- this._init(source);
+function ShellMountOperation(source, params) {
+ this._init(source, params);
}
ShellMountOperation.prototype = {
- _init: function(source) {
+ _init: function(source, params) {
+ params = Params.parse(params, { reaskPassword: false });
+
+ this._reaskPassword = params.reaskPassword;
this._initMountOp();
this._initIcon(source);
},
@@ -101,6 +107,8 @@ ShellMountOperation.prototype = {
this.mountOp.connect('ask-question',
Lang.bind(this, this._onAskQuestion));
+ this.mountOp.connect('ask-password',
+ Lang.bind(this, this._onAskPassword));
this.mountOp.connect('show-processes-2',
Lang.bind(this, this._onShowProcesses2));
this.mountOp.connect('aborted',
@@ -129,6 +137,29 @@ ShellMountOperation.prototype = {
questionDialog.open(global.get_current_time());
},
+ _onAskPassword: function(op, message) {
+ this._notificationShowing = true;
+ this._source = new ShellMountPasswordSource(message, this._icon, this._reaskPassword);
+
+ this._source.connect('password-ready',
+ Lang.bind(this, function(source, password) {
+ this.mountOp.set_password(password);
+ this.mountOp.reply(Gio.MountOperationResult.HANDLED);
+
+ this._notificationShowing = false;
+ this._source.destroy();
+ }));
+
+ this._source.connect('destroy',
+ Lang.bind(this, function() {
+ if (!this._notificationShowing)
+ return;
+
+ this._notificationShowing = false;
+ this.mountOp.reply(Gio.MountOperationResult.ABORTED);
+ }));
+ },
+
_onAborted: function(op) {
if (!this._dialog)
return;
@@ -216,6 +247,78 @@ ShellMountQuestionDialog.prototype = {
}
Signals.addSignalMethods(ShellMountQuestionDialog.prototype);
+function ShellMountPasswordSource(message, icon, reaskPassword) {
+ this._init(message, icon, reaskPassword);
+}
+
+ShellMountPasswordSource.prototype = {
+ __proto__: MessageTray.Source.prototype,
+
+ _init: function(message, icon, reaskPassword) {
+ let strings = message.split('\n');
+ MessageTray.Source.prototype._init.call(this, strings[0]);
+
+ this._notification = new ShellMountPasswordNotification(this, strings, icon, reaskPassword);
+
+ // add ourselves as a source, and popup the notification
+ Main.messageTray.add(this);
+ this.notify(this._notification);
+ },
+}
+Signals.addSignalMethods(ShellMountPasswordSource.prototype);
+
+function ShellMountPasswordNotification(source, strings, icon, reaskPassword) {
+ this._init(source, strings, icon, reaskPassword);
+}
+
+ShellMountPasswordNotification.prototype = {
+ __proto__: MessageTray.Notification.prototype,
+
+ _init: function(source, strings, icon, reaskPassword) {
+ MessageTray.Notification.prototype._init.call(this, source,
+ strings[0], null,
+ { customContent: true,
+ icon: icon });
+
+ // set the notification to transient and urgent, so that it
+ // expands out
+ this.setTransient(true);
+ this.setUrgency(MessageTray.Urgency.CRITICAL);
+
+ if (strings[1])
+ this.addBody(strings[1]);
+
+ this._buildUI(reaskPassword);
+ },
+
+ _buildUI: function(reaskPassword) {
+ if (reaskPassword) {
+ let label = new St.Label({ style_class: 'mount-password-reask',
+ text: _("Wrong password, please try again") });
+
+ this.addActor(label);
+ }
+
+ this._responseEntry = new St.Entry({ style_class: 'mount-password-entry',
+ can_focus: true });
+ this.setActionArea(this._responseEntry);
+
+ this._responseEntry.clutter_text.connect('activate',
+ Lang.bind(this, this._onEntryActivated));
+ this._responseEntry.clutter_text.set_password_char('\u25cf'); // â U+25CF BLACK CIRCLE
+
+ this._responseEntry.grab_key_focus();
+ },
+
+ _onEntryActivated: function() {
+ let text = this._responseEntry.get_text();
+ if (text == '')
+ return;
+
+ this.source.emit('password-ready', text);
+ }
+}
+
function ShellProcessesDialog(icon) {
this._init(icon);
}
diff --git a/src/shell-mount-operation.c b/src/shell-mount-operation.c
index 4d03f51..9f172ed 100644
--- a/src/shell-mount-operation.c
+++ b/src/shell-mount-operation.c
@@ -57,6 +57,16 @@ shell_mount_operation_init (ShellMountOperation *self)
}
static void
+shell_mount_operation_ask_password (GMountOperation *op,
+ const char *message,
+ const char *default_user,
+ const char *default_domain,
+ GAskPasswordFlags flags)
+{
+ /* do nothing */
+}
+
+static void
shell_mount_operation_ask_question (GMountOperation *op,
const char *message,
const char *choices[])
@@ -115,6 +125,7 @@ shell_mount_operation_class_init (ShellMountOperationClass *klass)
mclass = G_MOUNT_OPERATION_CLASS (klass);
mclass->show_processes = shell_mount_operation_show_processes;
mclass->ask_question = shell_mount_operation_ask_question;
+ mclass->ask_password = shell_mount_operation_ask_password;
oclass = G_OBJECT_CLASS (klass);
oclass->finalize = shell_mount_operation_finalize;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]