diff --git a/js/gdm/authPrompt.js b/js/gdm/authPrompt.js index a0420a609..fb8500421 100644 --- a/js/gdm/authPrompt.js +++ b/js/gdm/authPrompt.js @@ -24,11 +24,6 @@ const AuthPromptMode = { UNLOCK_OR_LOG_IN: 1 }; -const BeginRequestType = { - PROVIDE_USERNAME: 0, - DONT_PROVIDE_USERNAME: 1 -}; - const AuthPrompt = new Lang.Class({ Name: 'AuthPrompt', @@ -44,6 +39,7 @@ const AuthPrompt = new Lang.Class({ this._userVerifier = new GdmUtil.ShellUserVerifier(this._gdmClient, { reauthenticationOnly: reauthenticationOnly }); + this._userVerifier.connect('needs-username', Lang.bind(this, this._onNeedsUserName)); this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion)); this._userVerifier.connect('show-message', Lang.bind(this, this._onShowMessage)); this._userVerifier.connect('verification-failed', Lang.bind(this, this._onVerificationFailed)); @@ -186,6 +182,14 @@ const AuthPrompt = new Lang.Class({ })); }, + _onNeedsUserName: function() { + this.emit('needs-username'); + }, + + gotUserName: function(userName) { + this._userVerifier.gotUserName(userName); + }, + _onAskQuestion: function(verifier, serviceName, question, passwordChar) { if (this._preemptiveAnswer) { if (this._queryingService) @@ -403,24 +407,7 @@ const AuthPrompt = new Lang.Class({ this.setUser(null); this.stopSpinning(); - let beginRequestType; - - if (this._mode == AuthPromptMode.UNLOCK_ONLY) { - // The user is constant at the unlock screen, so it will immediately - // respond to the request with the username - beginRequestType = BeginRequestType.PROVIDE_USERNAME; - } else if (this._userVerifier.serviceIsForeground(GdmUtil.OVIRT_SERVICE_NAME) || - (this.smartcardDetected && - this._userVerifier.serviceIsForeground(GdmUtil.SMARTCARD_SERVICE_NAME))) { - // We don't need to know the username if the user preempted the login screen - // with a smartcard or with preauthenticated oVirt credentials - beginRequestType = BeginRequestType.DONT_PROVIDE_USERNAME; - } else { - // In all other cases, we should get the username up front. - beginRequestType = BeginRequestType.PROVIDE_USERNAME; - } - - this.emit('reset', beginRequestType); + this.emit('reset'); }, addCharacter: function(unichar) { @@ -431,9 +418,12 @@ const AuthPrompt = new Lang.Class({ this._entry.clutter_text.insert_unichar(unichar); }, - begin: function(userName) { + begin: function() { this.updateSensitivity(false); + this._userVerifier.begin(); + }, + needsUsername: function() { this._userVerifier.begin(userName); }, diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js index 84a38a6b1..b4953b950 100644 --- a/js/gdm/loginDialog.js +++ b/js/gdm/loginDialog.js @@ -421,6 +421,7 @@ const LoginDialog = new Lang.Class({ this._authPrompt = new AuthPrompt.AuthPrompt(gdmClient, AuthPrompt.AuthPromptMode.UNLOCK_OR_LOG_IN); this._authPrompt.connect('prompted', Lang.bind(this, this._onPrompted)); this._authPrompt.connect('reset', Lang.bind(this, this._onReset)); + this._authPrompt.connect('needs-username', Lang.bind(this, this._onNeedsUserName)); this._authPrompt.hide(); this.actor.add_child(this._authPrompt.actor); @@ -469,14 +470,13 @@ const LoginDialog = new Lang.Class({ this._sessionMenuButton.actor.show(); this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton.actor); - this._disableUserList = undefined; + this._updateDisableUserList(); this._userListLoaded = false; // If the user list is enabled, it should take key focus; make sure the // screen shield is initialized first to prevent it from stealing the // focus later - Main.layoutManager.connect('startup-complete', - Lang.bind(this, this._updateDisableUserList)); + Main.layoutManager.connect('startup-complete', Lang.bind(this, this._reset)); }, _ensureUserListLoaded: function() { @@ -493,15 +493,20 @@ const LoginDialog = new Lang.Class({ GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, this._loadUserList)); }, + _reset: function() { + this._authPrompt.reset(); + this._authPrompt.begin(); + }, + _updateDisableUserList: function() { let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY); + if (disableUserList == this._disableUserList) + return; - if (disableUserList != this._disableUserList) { - this._disableUserList = disableUserList; + this._disableUserList = disableUserList; - if (this._authPrompt.verificationStatus == GdmUtil.VerificationStatus.NOT_VERIFYING) - this._authPrompt.reset(); - } + if (this._authPrompt.verificationStatus == GdmUtil.VerificationStatus.ASKING_FOR_USERNAME) + this._reset(); }, _updateCancelButton: function() { @@ -509,7 +514,7 @@ const LoginDialog = new Lang.Class({ // Hide the cancel button if the user list is disabled and we're asking for // a username - if (this._authPrompt.verificationStatus == GdmUtil.VerificationStatus.NOT_VERIFYING && this._disableUserList) + if (this._authPrompt.verificationStatus == GdmUtil.VerificationStatus.ASKING_FOR_USERNAME && this._disableUserList) cancelVisible = false; else cancelVisible = true; @@ -554,19 +559,18 @@ const LoginDialog = new Lang.Class({ this._showPrompt(); }, - _onReset: function(authPrompt, beginRequest) { + _onReset: function() { this._sessionMenuButton.updateSensitivity(true); - this._user = null; - if (beginRequest == AuthPrompt.BeginRequestType.PROVIDE_USERNAME) { - if (!this._disableUserList) - this._showUserList(); - else - this._hideUserListAskForUsernameAndBeginVerification(); - } else { - this._hideUserListAndBeginVerification(); - } + this._reset(); + }, + + _onNeedsUserName: function() { + if (!this._disableUserList) + this._showUserList(); + else + this._hideUserListAskForUsernameAndBeginVerification(); }, _onDefaultSessionChanged: function(client, sessionId) { @@ -625,7 +629,7 @@ const LoginDialog = new Lang.Class({ this._user = this._userManager.get_user(answer); this._authPrompt.clear(); this._authPrompt.startSpinning(); - this._authPrompt.begin(answer); + this._authPrompt.gotUserName(answer); this._updateCancelButton(); realmManager.disconnect(realmSignalId) @@ -805,11 +809,6 @@ const LoginDialog = new Lang.Class({ this._askForUsernameAndBeginVerification(); }, - _hideUserListAndBeginVerification: function() { - this._hideUserList(); - this._authPrompt.begin(); - }, - _showUserList: function() { this._ensureUserListLoaded(); this._authPrompt.hide(); @@ -823,7 +822,7 @@ const LoginDialog = new Lang.Class({ this._authPrompt.setUser(item.user); let userName = item.user.get_user_name(); - this._authPrompt.begin(userName); + this._authPrompt.gotUserName(userName); }, _onUserListActivated: function(activatedItem) { diff --git a/js/gdm/util.js b/js/gdm/util.js index 076007e30..24c70e2d2 100644 --- a/js/gdm/util.js +++ b/js/gdm/util.js @@ -121,9 +121,10 @@ function cloneAndFadeOutActor(actor) { const VerificationStatus = { NOT_VERIFYING: 0, - VERIFYING: 1, - VERIFICATION_FAILED: 2, - VERIFICATION_SUCCEEDED: 3 + ASKING_FOR_USERNAME: 1, + VERIFYING: 2, + VERIFICATION_FAILED: 3, + VERIFICATION_SUCCEEDED: 4, }; const ShellUserVerifier = new Lang.Class({ @@ -169,24 +170,52 @@ const ShellUserVerifier = new Lang.Class({ _reset: function() { // Clear previous attempts to authenticate this.verificationStatus = VerificationStatus.NOT_VERIFYING; + this._userName = null; this._failCounter = 0; this._updateDefaultService(); this.emit('reset'); }, - begin: function(userName) { - this.verificationStatus = VerificationStatus.VERIFYING; + begin: function() { + if (this._mode == AuthPromptMode.UNLOCK_ONLY) { + // The user is constant at the unlock screen, so it will immediately + // respond to the request with the username + needsUsername = true; + } else if (this.serviceIsForeground(GdmUtil.OVIRT_SERVICE_NAME) || + (this.smartcardDetected && + this.serviceIsForeground(GdmUtil.SMARTCARD_SERVICE_NAME))) { + // We don't need to know the username if the user preempted the login screen + // with a smartcard or with preauthenticated oVirt credentials + needsUsername = false; + } else { + // In all other cases, we should get the username up front. + needsUsername = true; + } - this._cancellable = new Gio.Cancellable(); + if (needsUsername) { + this.verificationStatus = VerificationStatus.ASKING_FOR_USERNAME; + this.emit('needs-username'); + } else { + this._beginAuthentication(); + } + }, + + gotUserName: function(userName) { this._userName = userName; + this._beginAuthentication(); + }, + + _beginAuthentication: function() { + this.verificationStatus = VerificationStatus.VERIFYING; + this._cancellable = new Gio.Cancellable(); this.reauthenticating = false; this._checkForFingerprintReader(); - if (userName) { + if (this._userName) { // If possible, reauthenticate an already running session, // so any session specific credentials get updated appropriately - this._client.open_reauthentication_channel(userName, this._cancellable, + this._client.open_reauthentication_channel(this._userName, this._cancellable, Lang.bind(this, this._reauthenticationChannelOpened)); } else { this._client.get_user_verifier(this._cancellable, Lang.bind(this, this._userVerifierGot)); @@ -501,10 +530,6 @@ const ShellUserVerifier = new Lang.Class({ this.verificationStatus = VerificationStatus.VERIFICATION_SUCCEEDED; }, - _retry: function() { - this.begin(this._userName); - }, - _verificationFailed: function(retry) { // For Not Listed / enterprise logins, immediately reset // the dialog @@ -520,7 +545,7 @@ const ShellUserVerifier = new Lang.Class({ this._doAfterPendingMessages(Lang.bind(this, function() { if (canRetry) - this._retry(); + this._beginAuthentication(); else this.clear(); })); diff --git a/js/ui/unlockDialog.js b/js/ui/unlockDialog.js index 001aabc8d..84d72502a 100644 --- a/js/ui/unlockDialog.js +++ b/js/ui/unlockDialog.js @@ -54,6 +54,7 @@ const UnlockDialog = new Lang.Class({ this._authPrompt = new AuthPrompt.AuthPrompt(new Gdm.Client(), AuthPrompt.AuthPromptMode.UNLOCK_ONLY); this._authPrompt.connect('failed', Lang.bind(this, this._fail)); this._authPrompt.connect('reset', Lang.bind(this, this._onReset)); + this._authPrompt.connect('needs-username', Lang.bind(this, this._onNeedsUserName)); this._authPrompt.setPasswordChar('\u25cf'); this._authPrompt.nextButton.label = _("Unlock"); @@ -100,6 +101,10 @@ const UnlockDialog = new Lang.Class({ }, _onReset: function(authPrompt, beginRequest) { + this._authPrompt.begin(); + }, + + _onNeedsUserName: function() { let userName; if (beginRequest == AuthPrompt.BeginRequestType.PROVIDE_USERNAME) { this._authPrompt.setUser(this._user); @@ -108,7 +113,7 @@ const UnlockDialog = new Lang.Class({ userName = null; } - this._authPrompt.begin(userName); + this._authPrompt.gotUserName(userName); }, _escape: function() {