polkitAgent: Use dialog as confirmation when the user has no password
When a user has no password and a polkit authentication is started, instead of blindly initiating the admin session, show the regular "Authentication Requested" dialog (but without the password entry). This makes sure that the user's admin session is only effectively started after the user chooses to proceed with the authentication, which provides an extra confirmation step that can be vital for critical tasks. To do this, we show the dialog inside `_onUserChanged()` right after the dialog was created instead of calling `performAuthentication()` from `_onInitiate()`. The bug mentioned in `_onInitiate()` is no longer an issue since we show the dialog in all cases now anyway. Ideally we should use a different wording than "authentication" when the user has no password set, and use "confirmation" instead. However polkit already sends the requests with such messages (e.g. "Authentication is required to configure software repositories"), and it's important to show those to the user, so this patch keeps the regular wording. https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/829
This commit is contained in:
parent
3a7228cf2f
commit
89bf360bad
@ -11,6 +11,11 @@ const ModalDialog = imports.ui.modalDialog;
|
|||||||
const ShellEntry = imports.ui.shellEntry;
|
const ShellEntry = imports.ui.shellEntry;
|
||||||
const UserWidget = imports.ui.userWidget;
|
const UserWidget = imports.ui.userWidget;
|
||||||
|
|
||||||
|
const DialogMode = {
|
||||||
|
AUTH: 0,
|
||||||
|
CONFIRM: 1,
|
||||||
|
};
|
||||||
|
|
||||||
var DIALOG_ICON_SIZE = 48;
|
var DIALOG_ICON_SIZE = 48;
|
||||||
|
|
||||||
var WORK_SPINNER_ICON_SIZE = 16;
|
var WORK_SPINNER_ICON_SIZE = 16;
|
||||||
@ -79,12 +84,6 @@ var AuthenticationDialog = GObject.registerClass({
|
|||||||
|
|
||||||
userBox.add_child(this._userLabel);
|
userBox.add_child(this._userLabel);
|
||||||
|
|
||||||
this._userLoadedId = this._user.connect('notify::is-loaded',
|
|
||||||
this._onUserChanged.bind(this));
|
|
||||||
this._userChangedId = this._user.connect('changed',
|
|
||||||
this._onUserChanged.bind(this));
|
|
||||||
this._onUserChanged();
|
|
||||||
|
|
||||||
this._passwordBox = new St.BoxLayout({ vertical: false, style_class: 'prompt-dialog-password-box' });
|
this._passwordBox = new St.BoxLayout({ vertical: false, style_class: 'prompt-dialog-password-box' });
|
||||||
content.messageBox.add(this._passwordBox);
|
content.messageBox.add(this._passwordBox);
|
||||||
this._passwordLabel = new St.Label({
|
this._passwordLabel = new St.Label({
|
||||||
@ -150,8 +149,16 @@ var AuthenticationDialog = GObject.registerClass({
|
|||||||
|
|
||||||
this._doneEmitted = false;
|
this._doneEmitted = false;
|
||||||
|
|
||||||
|
this._mode = -1;
|
||||||
|
|
||||||
this._identityToAuth = Polkit.UnixUser.new_for_name(userName);
|
this._identityToAuth = Polkit.UnixUser.new_for_name(userName);
|
||||||
this._cookie = cookie;
|
this._cookie = cookie;
|
||||||
|
|
||||||
|
this._userLoadedId = this._user.connect('notify::is-loaded',
|
||||||
|
this._onUserChanged.bind(this));
|
||||||
|
this._userChangedId = this._user.connect('changed',
|
||||||
|
this._onUserChanged.bind(this));
|
||||||
|
this._onUserChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
_setWorking(working) {
|
_setWorking(working) {
|
||||||
@ -161,7 +168,7 @@ var AuthenticationDialog = GObject.registerClass({
|
|||||||
this._workSpinner.stop();
|
this._workSpinner.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
performAuthentication() {
|
_initiateSession() {
|
||||||
this._destroySession(DELAYED_RESET_TIMEOUT);
|
this._destroySession(DELAYED_RESET_TIMEOUT);
|
||||||
|
|
||||||
this._session = new PolkitAgent.Session({ identity: this._identityToAuth,
|
this._session = new PolkitAgent.Session({ identity: this._identityToAuth,
|
||||||
@ -220,7 +227,10 @@ var AuthenticationDialog = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
_onAuthenticateButtonPressed() {
|
_onAuthenticateButtonPressed() {
|
||||||
this._onEntryActivate();
|
if (this._mode === DialogMode.CONFIRM)
|
||||||
|
this._initiateSession();
|
||||||
|
else
|
||||||
|
this._onEntryActivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
_onSessionCompleted(session, gainedAuthorization) {
|
_onSessionCompleted(session, gainedAuthorization) {
|
||||||
@ -251,7 +261,7 @@ var AuthenticationDialog = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Try and authenticate again */
|
/* Try and authenticate again */
|
||||||
this.performAuthentication();
|
this._initiateSession();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,6 +356,28 @@ var AuthenticationDialog = GObject.registerClass({
|
|||||||
this._userLabel.set_text(realName);
|
this._userLabel.set_text(realName);
|
||||||
|
|
||||||
this._userAvatar.update();
|
this._userAvatar.update();
|
||||||
|
|
||||||
|
if (this._user.get_password_mode() === AccountsService.UserPasswordMode.NONE) {
|
||||||
|
if (this._mode === DialogMode.CONFIRM)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._mode = DialogMode.CONFIRM;
|
||||||
|
this._destroySession();
|
||||||
|
|
||||||
|
this._okButton.reactive = true;
|
||||||
|
|
||||||
|
/* We normally open the dialog when we get a "request" signal, but
|
||||||
|
* since in this case initiating a session would perform the
|
||||||
|
* authentication, only open the dialog and initiate the session
|
||||||
|
* when the user confirmed. */
|
||||||
|
this._ensureOpen();
|
||||||
|
} else {
|
||||||
|
if (this._mode === DialogMode.AUTH)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._mode = DialogMode.AUTH;
|
||||||
|
this._initiateSession();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cancel() {
|
cancel() {
|
||||||
@ -412,19 +444,7 @@ class AuthenticationAgent extends Shell.PolkitAuthenticationAgent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._currentDialog = new AuthenticationDialog(actionId, message, cookie, userNames);
|
this._currentDialog = new AuthenticationDialog(actionId, message, cookie, userNames);
|
||||||
|
|
||||||
// We actually don't want to open the dialog until we know for
|
|
||||||
// sure that we're going to interact with the user. For
|
|
||||||
// example, if the password for the identity to auth is blank
|
|
||||||
// (which it will be on a live CD) then there will be no
|
|
||||||
// conversation at all... of course, we don't *know* that
|
|
||||||
// until we actually try it.
|
|
||||||
//
|
|
||||||
// See https://bugzilla.gnome.org/show_bug.cgi?id=643062 for more
|
|
||||||
// discussion.
|
|
||||||
|
|
||||||
this._currentDialog.connect('done', this._onDialogDone.bind(this));
|
this._currentDialog.connect('done', this._onDialogDone.bind(this));
|
||||||
this._currentDialog.performAuthentication();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_onCancel(_nativeAgent) {
|
_onCancel(_nativeAgent) {
|
||||||
|
Loading…
Reference in New Issue
Block a user