Compare commits
20 Commits
citadel
...
wip/waylan
Author | SHA1 | Date | |
---|---|---|---|
|
28f4030aa2 | ||
|
67fe376564 | ||
|
fb824131ae | ||
|
056375cbcf | ||
|
84431cbc65 | ||
|
92c283da4d | ||
|
6e27ef8ff9 | ||
|
0c511c884b | ||
|
7afb503666 | ||
|
0b9d01a1c0 | ||
|
b978d99820 | ||
|
6d8d094e0c | ||
|
97e0175f48 | ||
|
ebef4ff174 | ||
|
82b8b32355 | ||
|
5b4337f716 | ||
|
5eb377bd3b | ||
|
8173110842 | ||
|
fee97da26b | ||
|
0cc10e0c5d |
@ -2,7 +2,7 @@
|
||||
Type=Application
|
||||
_Name=GNOME Shell (wayland compositor)
|
||||
_Comment=Window management and application launching
|
||||
Exec=@bindir@/mutter-launch -- gnome-shell-wayland --wayland
|
||||
Exec=@bindir@/gnome-shell-wayland --wayland --display-server
|
||||
X-GNOME-Bugzilla-Bugzilla=GNOME
|
||||
X-GNOME-Bugzilla-Product=gnome-shell
|
||||
X-GNOME-Bugzilla-Component=general
|
||||
|
@ -24,24 +24,10 @@ const AuthPromptMode = {
|
||||
UNLOCK_OR_LOG_IN: 1
|
||||
};
|
||||
|
||||
const AuthPromptStatus = {
|
||||
NOT_VERIFYING: 0,
|
||||
VERIFYING: 1,
|
||||
VERIFICATION_FAILED: 2,
|
||||
VERIFICATION_SUCCEEDED: 3
|
||||
};
|
||||
|
||||
const BeginRequestType = {
|
||||
PROVIDE_USERNAME: 0,
|
||||
DONT_PROVIDE_USERNAME: 1
|
||||
};
|
||||
|
||||
const AuthPrompt = new Lang.Class({
|
||||
Name: 'AuthPrompt',
|
||||
|
||||
_init: function(gdmClient, mode) {
|
||||
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
|
||||
|
||||
this._gdmClient = gdmClient;
|
||||
this._mode = mode;
|
||||
|
||||
@ -53,14 +39,11 @@ 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));
|
||||
this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete));
|
||||
this._userVerifier.connect('reset', Lang.bind(this, this._onReset));
|
||||
this._userVerifier.connect('smartcard-status-changed', Lang.bind(this, this._onSmartcardStatusChanged));
|
||||
this._userVerifier.connect('ovirt-user-authenticated', Lang.bind(this, this._onOVirtUserAuthenticated));
|
||||
this.smartcardDetected = this._userVerifier.smartcardDetected;
|
||||
|
||||
this.connect('next', Lang.bind(this, function() {
|
||||
this.updateSensitivity(false);
|
||||
@ -133,6 +116,10 @@ const AuthPrompt = new Lang.Class({
|
||||
this._defaultButtonWell.add_child(this._spinner.actor);
|
||||
},
|
||||
|
||||
get verificationStatus() {
|
||||
return this._userVerifier.verificationStatus;
|
||||
},
|
||||
|
||||
_onDestroy: function() {
|
||||
this._userVerifier.clear();
|
||||
this._userVerifier.disconnectAll();
|
||||
@ -193,6 +180,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)
|
||||
@ -221,30 +216,6 @@ const AuthPrompt = new Lang.Class({
|
||||
this.emit('prompted');
|
||||
},
|
||||
|
||||
_onOVirtUserAuthenticated: function() {
|
||||
if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED)
|
||||
this.reset();
|
||||
},
|
||||
|
||||
_onSmartcardStatusChanged: function() {
|
||||
this.smartcardDetected = this._userVerifier.smartcardDetected;
|
||||
|
||||
// Most of the time we want to reset if the user inserts or removes
|
||||
// a smartcard. Smartcard insertion "preempts" what the user was
|
||||
// doing, and smartcard removal aborts the preemption.
|
||||
// The exceptions are: 1) Don't reset on smartcard insertion if we're already verifying
|
||||
// with a smartcard
|
||||
// 2) Don't reset if we've already succeeded at verification and
|
||||
// the user is getting logged in.
|
||||
if (this._userVerifier.serviceIsDefault(GdmUtil.SMARTCARD_SERVICE_NAME) &&
|
||||
this.verificationStatus == AuthPromptStatus.VERIFYING &&
|
||||
this.smartcardDetected)
|
||||
return;
|
||||
|
||||
if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED)
|
||||
this.reset();
|
||||
},
|
||||
|
||||
_onShowMessage: function(userVerifier, message, type) {
|
||||
this.setMessage(message, type);
|
||||
this.emit('prompted');
|
||||
@ -256,15 +227,11 @@ const AuthPrompt = new Lang.Class({
|
||||
|
||||
this.updateSensitivity(true);
|
||||
this.setActorInDefaultButtonWell(null);
|
||||
this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED;
|
||||
},
|
||||
|
||||
_onVerificationComplete: function() {
|
||||
this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED;
|
||||
this.emit('failed');
|
||||
},
|
||||
|
||||
_onReset: function() {
|
||||
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
|
||||
this.reset();
|
||||
},
|
||||
|
||||
@ -428,39 +395,13 @@ const AuthPrompt = new Lang.Class({
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
let oldStatus = this.verificationStatus;
|
||||
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
|
||||
|
||||
if (oldStatus == AuthPromptStatus.VERIFYING)
|
||||
this._userVerifier.cancel();
|
||||
|
||||
this._queryingService = null;
|
||||
this.clear();
|
||||
this._message.opacity = 0;
|
||||
this.setUser(null);
|
||||
this.stopSpinning();
|
||||
|
||||
if (oldStatus == AuthPromptStatus.VERIFICATION_FAILED)
|
||||
this.emit('failed');
|
||||
|
||||
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) {
|
||||
@ -471,18 +412,13 @@ const AuthPrompt = new Lang.Class({
|
||||
this._entry.clutter_text.insert_unichar(unichar);
|
||||
},
|
||||
|
||||
begin: function(params) {
|
||||
params = Params.parse(params, { userName: null,
|
||||
hold: null });
|
||||
|
||||
begin: function() {
|
||||
this.updateSensitivity(false);
|
||||
this._userVerifier.begin();
|
||||
},
|
||||
|
||||
let hold = params.hold;
|
||||
if (!hold)
|
||||
hold = new Batch.Hold();
|
||||
|
||||
this._userVerifier.begin(params.userName, hold);
|
||||
this.verificationStatus = AuthPromptStatus.VERIFYING;
|
||||
needsUsername: function() {
|
||||
this._userVerifier.begin(userName);
|
||||
},
|
||||
|
||||
finish: function(onComplete) {
|
||||
@ -500,7 +436,6 @@ const AuthPrompt = new Lang.Class({
|
||||
|
||||
cancel: function() {
|
||||
this.reset();
|
||||
this.emit('cancelled');
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(AuthPrompt.prototype);
|
||||
|
@ -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,15 @@ const LoginDialog = new Lang.Class({
|
||||
this._sessionMenuButton.actor.show();
|
||||
this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton.actor);
|
||||
|
||||
this._disableUserList = undefined;
|
||||
this._updateDisableUserList();
|
||||
this._userListLoaded = false;
|
||||
|
||||
LoginManager.getLoginManager().getCurrentSessionProxy(Lang.bind(this, this._gotGreeterSessionProxy));
|
||||
|
||||
// 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 +495,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 == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
|
||||
this._authPrompt.reset();
|
||||
}
|
||||
if (this._authPrompt.verificationStatus == GdmUtil.VerificationStatus.ASKING_FOR_USERNAME)
|
||||
this._reset();
|
||||
},
|
||||
|
||||
_updateCancelButton: function() {
|
||||
@ -509,7 +516,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 == AuthPrompt.AuthPromptStatus.NOT_VERIFYING && this._disableUserList)
|
||||
if (this._authPrompt.verificationStatus == GdmUtil.VerificationStatus.ASKING_FOR_USERNAME && this._disableUserList)
|
||||
cancelVisible = false;
|
||||
else
|
||||
cancelVisible = true;
|
||||
@ -554,19 +561,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) {
|
||||
@ -574,8 +580,8 @@ const LoginDialog = new Lang.Class({
|
||||
},
|
||||
|
||||
_shouldShowSessionMenuButton: function() {
|
||||
if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFYING &&
|
||||
this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFICATION_FAILED)
|
||||
if (this._authPrompt.verificationStatus != GdmUtil.VerificationStatus.VERIFYING &&
|
||||
this._authPrompt.verificationStatus != GdmUtil.VerificationStatus.VERIFICATION_FAILED)
|
||||
return false;
|
||||
|
||||
if (this._user && this._user.is_loaded && this._user.is_logged_in())
|
||||
@ -625,7 +631,7 @@ const LoginDialog = new Lang.Class({
|
||||
this._user = this._userManager.get_user(answer);
|
||||
this._authPrompt.clear();
|
||||
this._authPrompt.startSpinning();
|
||||
this._authPrompt.begin({ userName: answer });
|
||||
this._authPrompt.gotUserName(answer);
|
||||
this._updateCancelButton();
|
||||
|
||||
realmManager.disconnect(realmSignalId)
|
||||
@ -635,6 +641,32 @@ const LoginDialog = new Lang.Class({
|
||||
this._showPrompt();
|
||||
},
|
||||
|
||||
_sessionActivated: function() {
|
||||
// We fade out the shell after logging in, and then re-set
|
||||
// the greeter wen we're VT switched to again.
|
||||
|
||||
// XXX: re-trigger startup animation
|
||||
if (this._authPrompt.verificationStatus == GdmUtil.VerificationStatus.VERIFICATION_SUCCEEDED) {
|
||||
this._reset();
|
||||
|
||||
// XXX: do something better here
|
||||
this.actor.opacity = 255;
|
||||
|
||||
let children = Main.layoutManager.uiGroup.get_children();
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
if (children[i] != Main.layoutManager.screenShieldGroup)
|
||||
children[i].opacity = 255;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_gotGreeterSessionProxy: function(proxy) {
|
||||
proxy.connect('g-properties-changed', Lang.bind(this, function() {
|
||||
if (proxy.Active)
|
||||
this._sessionActivated();
|
||||
}));
|
||||
},
|
||||
|
||||
_startSession: function(serviceName) {
|
||||
Tweener.addTween(this.actor,
|
||||
{ opacity: 0,
|
||||
@ -805,11 +837,6 @@ const LoginDialog = new Lang.Class({
|
||||
this._askForUsernameAndBeginVerification();
|
||||
},
|
||||
|
||||
_hideUserListAndBeginVerification: function() {
|
||||
this._hideUserList();
|
||||
this._authPrompt.begin();
|
||||
},
|
||||
|
||||
_showUserList: function() {
|
||||
this._ensureUserListLoaded();
|
||||
this._authPrompt.hide();
|
||||
@ -823,11 +850,7 @@ const LoginDialog = new Lang.Class({
|
||||
this._authPrompt.setUser(item.user);
|
||||
|
||||
let userName = item.user.get_user_name();
|
||||
let hold = new Batch.Hold();
|
||||
|
||||
this._authPrompt.begin({ userName: userName,
|
||||
hold: hold });
|
||||
return hold;
|
||||
this._authPrompt.gotUserName(userName);
|
||||
},
|
||||
|
||||
_onUserListActivated: function(activatedItem) {
|
||||
@ -842,9 +865,9 @@ const LoginDialog = new Lang.Class({
|
||||
|
||||
this._updateCancelButton();
|
||||
|
||||
let batch = new Batch.ConcurrentBatch(this, [new Batch.ConsecutiveBatch(this, tasks),
|
||||
this._beginVerificationForItem(activatedItem)]);
|
||||
let batch = new Batch.ConsecutiveBatch(this, tasks);
|
||||
batch.run();
|
||||
this._beginVerificationForItem(activatedItem);
|
||||
},
|
||||
|
||||
_onDestroy: function() {
|
||||
|
214
js/gdm/util.js
214
js/gdm/util.js
@ -119,6 +119,14 @@ function cloneAndFadeOutActor(actor) {
|
||||
return hold;
|
||||
}
|
||||
|
||||
const VerificationStatus = {
|
||||
NOT_VERIFYING: 0,
|
||||
ASKING_FOR_USERNAME: 1,
|
||||
VERIFYING: 2,
|
||||
VERIFICATION_FAILED: 3,
|
||||
VERIFICATION_SUCCEEDED: 4,
|
||||
};
|
||||
|
||||
const ShellUserVerifier = new Lang.Class({
|
||||
Name: 'ShellUserVerifier',
|
||||
|
||||
@ -131,7 +139,6 @@ const ShellUserVerifier = new Lang.Class({
|
||||
this._settings = new Gio.Settings({ schema: LOGIN_SCREEN_SCHEMA });
|
||||
this._settings.connect('changed',
|
||||
Lang.bind(this, this._updateDefaultService));
|
||||
this._updateDefaultService();
|
||||
|
||||
this._fprintManager = new Fprint.FprintManager();
|
||||
this._smartcardManager = SmartcardManager.getSmartcardManager();
|
||||
@ -152,45 +159,69 @@ const ShellUserVerifier = new Lang.Class({
|
||||
this.hasPendingMessages = false;
|
||||
this.reauthenticating = false;
|
||||
|
||||
this._failCounter = 0;
|
||||
|
||||
this._oVirtCredentialsManager = OVirt.getOVirtCredentialsManager();
|
||||
|
||||
this._oVirtCredentialsManager.connect('user-authenticated', Lang.bind(this, this._oVirtUserAuthenticated));
|
||||
if (this._oVirtCredentialsManager.hasToken())
|
||||
this._oVirtUserAuthenticated(this._oVirtCredentialsManager.getToken());
|
||||
|
||||
this._oVirtCredentialsManager.connect('user-authenticated',
|
||||
Lang.bind(this, this._oVirtUserAuthenticated));
|
||||
this._reset();
|
||||
},
|
||||
|
||||
begin: function(userName, hold) {
|
||||
this._cancellable = new Gio.Cancellable();
|
||||
this._hold = hold;
|
||||
_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() {
|
||||
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;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
},
|
||||
|
||||
cancel: function() {
|
||||
if (this._cancellable)
|
||||
this._cancellable.cancel();
|
||||
|
||||
if (this._userVerifier) {
|
||||
this._userVerifier.call_cancel_sync(null);
|
||||
this.clear();
|
||||
}
|
||||
},
|
||||
|
||||
clear: function() {
|
||||
if (this._cancellable) {
|
||||
this._cancellable.cancel();
|
||||
@ -198,6 +229,7 @@ const ShellUserVerifier = new Lang.Class({
|
||||
}
|
||||
|
||||
if (this._userVerifier) {
|
||||
this._userVerifier.call_cancel_sync(null);
|
||||
this._userVerifier.run_dispose();
|
||||
this._userVerifier = null;
|
||||
}
|
||||
@ -205,24 +237,29 @@ const ShellUserVerifier = new Lang.Class({
|
||||
this._clearMessageQueue();
|
||||
},
|
||||
|
||||
answerQuery: function(serviceName, answer) {
|
||||
if (!this.hasPendingMessages) {
|
||||
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
|
||||
_doAfterPendingMessages: function(func) {
|
||||
if (this.hasPendingMessages) {
|
||||
let signalId = this.connect('no-more-messages', Lang.bind(this, function() {
|
||||
this.disconnect(signalId);
|
||||
func();
|
||||
}));
|
||||
} else {
|
||||
let signalId = this.connect('no-more-messages',
|
||||
Lang.bind(this, function() {
|
||||
this.disconnect(signalId);
|
||||
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
|
||||
}));
|
||||
func();
|
||||
}
|
||||
},
|
||||
|
||||
answerQuery: function(serviceName, answer) {
|
||||
this._doAfterPendingMessages(Lang.bind(this, function() {
|
||||
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
|
||||
}));
|
||||
},
|
||||
|
||||
_getIntervalForMessage: function(message) {
|
||||
// We probably could be smarter here
|
||||
return message.length * USER_READ_TIME;
|
||||
},
|
||||
|
||||
finishMessageQueue: function() {
|
||||
_finishMessageQueue: function() {
|
||||
if (!this.hasPendingMessages)
|
||||
return;
|
||||
|
||||
@ -234,7 +271,7 @@ const ShellUserVerifier = new Lang.Class({
|
||||
|
||||
_queueMessageTimeout: function() {
|
||||
if (this._messageQueue.length == 0) {
|
||||
this.finishMessageQueue();
|
||||
this._finishMessageQueue();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -263,7 +300,7 @@ const ShellUserVerifier = new Lang.Class({
|
||||
},
|
||||
|
||||
_clearMessageQueue: function() {
|
||||
this.finishMessageQueue();
|
||||
this._finishMessageQueue();
|
||||
|
||||
if (this._messageQueueTimeoutId != 0) {
|
||||
GLib.source_remove(this._messageQueueTimeoutId);
|
||||
@ -288,9 +325,9 @@ const ShellUserVerifier = new Lang.Class({
|
||||
}));
|
||||
},
|
||||
|
||||
_oVirtUserAuthenticated: function(token) {
|
||||
this._preemptingService = OVIRT_SERVICE_NAME;
|
||||
this.emit('ovirt-user-authenticated');
|
||||
_oVirtUserAuthenticated: function() {
|
||||
if (this.verificationStatus != GdmUtil.VerificationStatus.VERIFICATION_SUCCEEDED)
|
||||
this._reset();
|
||||
},
|
||||
|
||||
_checkForSmartcard: function() {
|
||||
@ -303,21 +340,29 @@ const ShellUserVerifier = new Lang.Class({
|
||||
else
|
||||
smartcardDetected = this._smartcardManager.hasInsertedTokens();
|
||||
|
||||
if (smartcardDetected != this.smartcardDetected) {
|
||||
this.smartcardDetected = smartcardDetected;
|
||||
if (this._smartcardDetected == smartcardDetected)
|
||||
return;
|
||||
|
||||
if (this.smartcardDetected)
|
||||
this._preemptingService = SMARTCARD_SERVICE_NAME;
|
||||
else if (this._preemptingService == SMARTCARD_SERVICE_NAME)
|
||||
this._preemptingService = null;
|
||||
this._smartcardDetected = smartcardDetected;
|
||||
|
||||
this.emit('smartcard-status-changed');
|
||||
}
|
||||
// Most of the time we want to reset if the user inserts or removes
|
||||
// a smartcard. Smartcard insertion "preempts" what the user was
|
||||
// doing, and smartcard removal aborts the preemption.
|
||||
// The exceptions are: 1) Don't reset on smartcard insertion if we're already verifying
|
||||
// with a smartcard
|
||||
// 2) Don't reset if we've already succeeded at verification and
|
||||
// the user is getting logged in.
|
||||
if (this._serviceIsDefault(SMARTCARD_SERVICE_NAME) &&
|
||||
this.verificationStatus == VerificationStatus.VERIFYING &&
|
||||
this._smartcardDetected)
|
||||
return;
|
||||
|
||||
if (this.verificationStatus != VerificationStatus.VERIFICATION_SUCCEEDED)
|
||||
this._reset();
|
||||
},
|
||||
|
||||
_reportInitError: function(where, error) {
|
||||
logError(error, where);
|
||||
this._hold.release();
|
||||
|
||||
this._queueMessage(_("Authentication error"), MessageType.ERROR);
|
||||
this._verificationFailed(false);
|
||||
@ -343,7 +388,6 @@ const ShellUserVerifier = new Lang.Class({
|
||||
this.reauthenticating = true;
|
||||
this._connectSignals();
|
||||
this._beginVerification();
|
||||
this._hold.release();
|
||||
},
|
||||
|
||||
_userVerifierGot: function(client, result) {
|
||||
@ -358,7 +402,6 @@ const ShellUserVerifier = new Lang.Class({
|
||||
|
||||
this._connectSignals();
|
||||
this._beginVerification();
|
||||
this._hold.release();
|
||||
},
|
||||
|
||||
_connectSignals: function() {
|
||||
@ -372,31 +415,32 @@ const ShellUserVerifier = new Lang.Class({
|
||||
},
|
||||
|
||||
_getForegroundService: function() {
|
||||
if (this._preemptingService)
|
||||
return this._preemptingService;
|
||||
if (this._oVirtCredentialsManager.hasToken())
|
||||
return OVIRT_SERVICE_NAME;
|
||||
if (this._smartcardDetected)
|
||||
return SMARTCARD_SERVICE_NAME;
|
||||
|
||||
return this._defaultService;
|
||||
},
|
||||
|
||||
serviceIsForeground: function(serviceName) {
|
||||
_serviceIsForeground: function(serviceName) {
|
||||
return serviceName == this._getForegroundService();
|
||||
},
|
||||
|
||||
serviceIsDefault: function(serviceName) {
|
||||
_serviceIsDefault: function(serviceName) {
|
||||
return serviceName == this._defaultService;
|
||||
},
|
||||
|
||||
_updateDefaultService: function() {
|
||||
if (this._settings.get_boolean(PASSWORD_AUTHENTICATION_KEY))
|
||||
this._defaultService = PASSWORD_SERVICE_NAME;
|
||||
else if (this.smartcardDetected)
|
||||
else if (this._smartcardDetected)
|
||||
this._defaultService = SMARTCARD_SERVICE_NAME;
|
||||
else if (this._haveFingerprintReader)
|
||||
this._defaultService = FINGERPRINT_SERVICE_NAME;
|
||||
},
|
||||
|
||||
_startService: function(serviceName) {
|
||||
this._hold.acquire();
|
||||
if (this._userName) {
|
||||
this._userVerifier.call_begin_verification_for_user(serviceName,
|
||||
this._userName,
|
||||
@ -410,8 +454,6 @@ const ShellUserVerifier = new Lang.Class({
|
||||
this._reportInitError('Failed to start verification for user', e);
|
||||
return;
|
||||
}
|
||||
|
||||
this._hold.release();
|
||||
}));
|
||||
} else {
|
||||
this._userVerifier.call_begin_verification(serviceName,
|
||||
@ -425,8 +467,6 @@ const ShellUserVerifier = new Lang.Class({
|
||||
this._reportInitError('Failed to start verification', e);
|
||||
return;
|
||||
}
|
||||
|
||||
this._hold.release();
|
||||
}));
|
||||
}
|
||||
},
|
||||
@ -434,12 +474,12 @@ const ShellUserVerifier = new Lang.Class({
|
||||
_beginVerification: function() {
|
||||
this._startService(this._getForegroundService());
|
||||
|
||||
if (this._userName && this._haveFingerprintReader && !this.serviceIsForeground(FINGERPRINT_SERVICE_NAME))
|
||||
if (this._userName && this._haveFingerprintReader && !this._serviceIsForeground(FINGERPRINT_SERVICE_NAME))
|
||||
this._startService(FINGERPRINT_SERVICE_NAME);
|
||||
},
|
||||
|
||||
_onInfo: function(client, serviceName, info) {
|
||||
if (this.serviceIsForeground(serviceName)) {
|
||||
if (this._serviceIsForeground(serviceName)) {
|
||||
this._queueMessage(info, MessageType.INFO);
|
||||
} else if (serviceName == FINGERPRINT_SERVICE_NAME &&
|
||||
this._haveFingerprintReader) {
|
||||
@ -454,21 +494,21 @@ const ShellUserVerifier = new Lang.Class({
|
||||
},
|
||||
|
||||
_onProblem: function(client, serviceName, problem) {
|
||||
if (!this.serviceIsForeground(serviceName))
|
||||
if (!this._serviceIsForeground(serviceName))
|
||||
return;
|
||||
|
||||
this._queueMessage(problem, MessageType.ERROR);
|
||||
},
|
||||
|
||||
_onInfoQuery: function(client, serviceName, question) {
|
||||
if (!this.serviceIsForeground(serviceName))
|
||||
if (!this._serviceIsForeground(serviceName))
|
||||
return;
|
||||
|
||||
this.emit('ask-question', serviceName, question, '');
|
||||
},
|
||||
|
||||
_onSecretInfoQuery: function(client, serviceName, secretQuestion) {
|
||||
if (!this.serviceIsForeground(serviceName))
|
||||
if (!this._serviceIsForeground(serviceName))
|
||||
return;
|
||||
|
||||
if (serviceName == OVIRT_SERVICE_NAME) {
|
||||
@ -481,24 +521,11 @@ const ShellUserVerifier = new Lang.Class({
|
||||
},
|
||||
|
||||
_onReset: function() {
|
||||
// Clear previous attempts to authenticate
|
||||
this._failCounter = 0;
|
||||
this._updateDefaultService();
|
||||
|
||||
this.emit('reset');
|
||||
this._reset();
|
||||
},
|
||||
|
||||
_onVerificationComplete: function() {
|
||||
this.emit('verification-complete');
|
||||
},
|
||||
|
||||
_cancelAndReset: function() {
|
||||
this.cancel();
|
||||
this._onReset();
|
||||
},
|
||||
|
||||
_retry: function() {
|
||||
this.begin(this._userName, new Batch.Hold());
|
||||
this.verificationStatus = VerificationStatus.VERIFICATION_SUCCEEDED;
|
||||
},
|
||||
|
||||
_verificationFailed: function(retry) {
|
||||
@ -511,38 +538,23 @@ const ShellUserVerifier = new Lang.Class({
|
||||
let canRetry = retry && this._userName &&
|
||||
this._failCounter < this._settings.get_int(ALLOWED_FAILURES_KEY);
|
||||
|
||||
if (canRetry) {
|
||||
if (!this.hasPendingMessages) {
|
||||
this._retry();
|
||||
} else {
|
||||
let signalId = this.connect('no-more-messages',
|
||||
Lang.bind(this, function() {
|
||||
this.disconnect(signalId);
|
||||
this._retry();
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
if (!this.hasPendingMessages) {
|
||||
this._cancelAndReset();
|
||||
} else {
|
||||
let signalId = this.connect('no-more-messages',
|
||||
Lang.bind(this, function() {
|
||||
this.disconnect(signalId);
|
||||
this._cancelAndReset();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
this.verificationStatus = VerificationStatus.VERIFICATION_FAILED;
|
||||
this.emit('verification-failed');
|
||||
|
||||
this._doAfterPendingMessages(Lang.bind(this, function() {
|
||||
if (canRetry)
|
||||
this._beginAuthentication();
|
||||
else
|
||||
this.clear();
|
||||
}));
|
||||
},
|
||||
|
||||
_onConversationStopped: function(client, serviceName) {
|
||||
// If the login failed with the preauthenticated oVirt credentials
|
||||
// then discard the credentials and revert to default authentication
|
||||
// mechanism.
|
||||
if (this.serviceIsForeground(OVIRT_SERVICE_NAME)) {
|
||||
if (this._serviceIsForeground(OVIRT_SERVICE_NAME)) {
|
||||
this._oVirtCredentialsManager.resetToken();
|
||||
this._preemptingService = null;
|
||||
this._verificationFailed(false);
|
||||
return;
|
||||
}
|
||||
@ -550,7 +562,7 @@ const ShellUserVerifier = new Lang.Class({
|
||||
// if the password service fails, then cancel everything.
|
||||
// But if, e.g., fingerprint fails, still give
|
||||
// password authentication a chance to succeed
|
||||
if (this.serviceIsForeground(serviceName)) {
|
||||
if (this._serviceIsForeground(serviceName)) {
|
||||
this._verificationFailed(true);
|
||||
}
|
||||
},
|
||||
|
@ -39,6 +39,7 @@ const SystemdLoginSessionIface = '<node> \
|
||||
<interface name="org.freedesktop.login1.Session"> \
|
||||
<signal name="Lock" /> \
|
||||
<signal name="Unlock" /> \
|
||||
<property name="Active" access="readonly" /> \
|
||||
</interface> \
|
||||
</node>';
|
||||
|
||||
|
@ -203,6 +203,10 @@ function _initializeUI() {
|
||||
ExtensionDownloader.init();
|
||||
ExtensionSystem.init();
|
||||
|
||||
layoutManager.connect('startup-prepared', function() {
|
||||
Meta.activate_session();
|
||||
});
|
||||
|
||||
if (sessionMode.isGreeter && screenShield) {
|
||||
layoutManager.connect('startup-prepared', function() {
|
||||
screenShield.showDialog();
|
||||
|
@ -53,8 +53,8 @@ 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('cancelled', 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");
|
||||
|
||||
@ -101,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);
|
||||
@ -109,7 +113,7 @@ const UnlockDialog = new Lang.Class({
|
||||
userName = null;
|
||||
}
|
||||
|
||||
this._authPrompt.begin({ userName: userName });
|
||||
this._authPrompt.gotUserName(userName);
|
||||
},
|
||||
|
||||
_escape: function() {
|
||||
|
Loading…
Reference in New Issue
Block a user