Merge branch 'expire-preemptive-auth-input' into 'main'

Draft: Various downstream smartcard fixes

See merge request GNOME/gnome-shell!3297
This commit is contained in:
Ray Strode 2024-06-29 19:45:50 +00:00
commit b2e51db356
4 changed files with 71 additions and 10 deletions

View file

@ -21,6 +21,7 @@ const DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1000;
const DEFAULT_BUTTON_WELL_ANIMATION_TIME = 300;
const MESSAGE_FADE_OUT_ANIMATION_TIME = 500;
const PREEMPTIVE_ANSWER_TIMEOUT = 500;
/** @enum {number} */
export const AuthPromptMode = {
@ -70,6 +71,8 @@ export const AuthPrompt = GObject.registerClass({
this._defaultButtonWellActor = null;
this._cancelledRetries = 0;
this._idleMonitor = global.backend.get_core_idle_monitor();
let reauthenticationOnly;
if (this._mode === AuthPromptMode.UNLOCK_ONLY)
reauthenticationOnly = true;
@ -127,8 +130,14 @@ export const AuthPrompt = GObject.registerClass({
}
_onDestroy() {
if (this._preemptiveAnswerWatchId) {
this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId);
this._preemptiveAnswerWatchId = 0;
}
this._inactiveEntry.destroy();
this._inactiveEntry = null;
this._userVerifier.destroy();
this._userVerifier = null;
}
@ -211,7 +220,7 @@ export const AuthPrompt = GObject.registerClass({
[this._textEntry, this._passwordEntry].forEach(entry => {
entry.clutter_text.connect('text-changed', () => {
if (!this._userVerifier.hasPendingMessages)
if (!this._userVerifier.hasPendingMessages && this._queryingService && !this._preemptiveAnswer)
this._fadeOutMessage();
});
@ -275,13 +284,19 @@ export const AuthPrompt = GObject.registerClass({
this.verificationStatus = AuthPromptStatus.VERIFICATION_IN_PROGRESS;
this.updateSensitivity(false);
if (shouldSpin)
this.startSpinning();
if (this._queryingService) {
if (shouldSpin)
this.startSpinning();
if (this._queryingService)
this._userVerifier.answerQuery(this._queryingService, this._entry.text);
else
} else {
this._preemptiveAnswer = this._entry.text;
}
if (this._preemptiveAnswerWatchId) {
this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId);
this._preemptiveAnswerWatchId = 0;
}
this.emit('next');
}
@ -492,6 +507,11 @@ export const AuthPrompt = GObject.registerClass({
}
setQuestion(question) {
if (this._preemptiveAnswerWatchId) {
this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId);
this._preemptiveAnswerWatchId = 0;
}
this._entry.hint_text = question;
this._authList.hide();
@ -613,6 +633,19 @@ export const AuthPrompt = GObject.registerClass({
this._updateEntry(false);
}
_onUserStoppedTypePreemptiveAnswer() {
if (!this._preemptiveAnswerWatchId ||
this._preemptiveAnswer ||
this._queryingService)
return;
this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId);
this._preemptiveAnswerWatchId = 0;
this._entry.text = '';
this.updateSensitivity(false);
}
reset() {
let oldStatus = this.verificationStatus;
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
@ -620,6 +653,11 @@ export const AuthPrompt = GObject.registerClass({
this.cancelButton.can_focus = this._hasCancelButton;
this._preemptiveAnswer = null;
if (this._preemptiveAnswerWatchId)
this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId);
this._preemptiveAnswerWatchId = this._idleMonitor.add_idle_watch(PREEMPTIVE_ANSWER_TIMEOUT,
this._onUserStoppedTypePreemptiveAnswer.bind(this));
if (this._userVerifier)
this._userVerifier.cancel();

View file

@ -642,7 +642,10 @@ export class ShellUserVerifier extends Signals.EventEmitter {
}
_getDetectedDefaultService() {
if (this._settings.get_boolean(PASSWORD_AUTHENTICATION_KEY))
if (this._smartcardManager.loggedInWithToken() &&
this._smartcardManager.lockOnRemoval())
return SMARTCARD_SERVICE_NAME;
else if (this._settings.get_boolean(PASSWORD_AUTHENTICATION_KEY))
return PASSWORD_SERVICE_NAME;
else if (this._smartcardManager)
return SMARTCARD_SERVICE_NAME;

View file

@ -5,6 +5,9 @@ import * as Signals from './signals.js';
import * as ObjectManager from './objectManager.js';
const SMARTCARD_SETTINGS_SCHEMA = 'org.gnome.settings-daemon.peripherals.smartcard';
const SMARTCARD_REMOVAL_ACTION = 'removal-action';
const SmartcardTokenIface = `
<node>
<interface name="org.gnome.SettingsDaemon.Smartcard.Token">
@ -38,6 +41,7 @@ class SmartcardManager extends Signals.EventEmitter {
knownInterfaces: [SmartcardTokenIface],
onLoaded: this._onLoaded.bind(this),
});
this._settings = new Gio.Settings({schema_id: SMARTCARD_SETTINGS_SCHEMA});
this._insertedTokens = {};
this._loginToken = null;
}
@ -74,7 +78,7 @@ class SmartcardManager extends Signals.EventEmitter {
_addToken(token) {
this._updateToken(token);
token.connect('g-properties-changed', (proxy, properties) => {
token._smartcardSignalId = token.connect('g-properties-changed', (proxy, properties) => {
const isInsertedChanged = !!properties.lookup_value('IsInserted', null);
if (isInsertedChanged) {
this._updateToken(token);
@ -99,10 +103,13 @@ class SmartcardManager extends Signals.EventEmitter {
this.emit('smartcard-removed', token);
}
if (token._smartcardSignalId) {
token.disconnect(token._smartcardSignalId);
delete token._smartcardSignalId;
}
if (this._loginToken === token)
this._loginToken = null;
token.disconnectAll();
}
hasInsertedTokens() {
@ -117,5 +124,16 @@ class SmartcardManager extends Signals.EventEmitter {
return false;
return true;
},
loggedInWithToken() {
if (this._loginToken)
return true;
return false;
}
lockOnRemoval() {
return this._settings.get_string(SMARTCARD_REMOVAL_ACTION) === 'lock-screen';
}
}

View file

@ -94,8 +94,10 @@ export class ScreenShield extends Signals.EventEmitter {
this._smartcardManager = SmartcardManager.getSmartcardManager();
this._smartcardManager.connect('smartcard-inserted',
(manager, token) => {
if (this._isLocked && token.UsedToLogin)
if (this._isLocked && token.UsedToLogin) {
this._wakeUpScreen();
this._activateDialog();
}
});
this._credentialManagers = {};