gdm: Refactor oVirt to a generic CredentialManager interface
Commit 4cda61a1
added support for pre-authenticated logins in
oVirt environments. This feature prevents a user from having
to type their password twice (once to the oVirt management machine,
and then immediately again in the provisioned guest running gnome-shell).
That feature is currently oVirt specific, but a similar feature would
be useful in non-oVirt based virt farm environments.
Toward that end, this commit generalizes the various aspects of the
oVirt integration code, so that it can be reused in a subsequent
commit for adding single sign on support in vmware deployments, too.
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/1983
This commit is contained in:
parent
75235624b2
commit
809f820cd4
@ -71,7 +71,7 @@ var AuthPrompt = GObject.registerClass({
|
|||||||
this._userVerifier.connect('verification-complete', this._onVerificationComplete.bind(this));
|
this._userVerifier.connect('verification-complete', this._onVerificationComplete.bind(this));
|
||||||
this._userVerifier.connect('reset', this._onReset.bind(this));
|
this._userVerifier.connect('reset', this._onReset.bind(this));
|
||||||
this._userVerifier.connect('smartcard-status-changed', this._onSmartcardStatusChanged.bind(this));
|
this._userVerifier.connect('smartcard-status-changed', this._onSmartcardStatusChanged.bind(this));
|
||||||
this._userVerifier.connect('ovirt-user-authenticated', this._onOVirtUserAuthenticated.bind(this));
|
this._userVerifier.connect('credential-manager-authenticated', this._onCredentialManagerAuthenticated.bind(this));
|
||||||
this.smartcardDetected = this._userVerifier.smartcardDetected;
|
this.smartcardDetected = this._userVerifier.smartcardDetected;
|
||||||
|
|
||||||
this.connect('destroy', this._onDestroy.bind(this));
|
this.connect('destroy', this._onDestroy.bind(this));
|
||||||
@ -242,7 +242,7 @@ var AuthPrompt = GObject.registerClass({
|
|||||||
this.emit('prompted');
|
this.emit('prompted');
|
||||||
}
|
}
|
||||||
|
|
||||||
_onOVirtUserAuthenticated() {
|
_onCredentialManagerAuthenticated() {
|
||||||
if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED)
|
if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED)
|
||||||
this.reset();
|
this.reset();
|
||||||
}
|
}
|
||||||
|
24
js/gdm/credentialManager.js
Normal file
24
js/gdm/credentialManager.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
/* exported CredentialManager */
|
||||||
|
|
||||||
|
class CredentialManager {
|
||||||
|
constructor(service) {
|
||||||
|
this._token = null;
|
||||||
|
this._service = service;
|
||||||
|
this._authenticatedSignalId = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
get token() {
|
||||||
|
return this._token;
|
||||||
|
}
|
||||||
|
|
||||||
|
set token(t) {
|
||||||
|
this._token = t;
|
||||||
|
if (this._token)
|
||||||
|
this.emit('user-authenticated', this._token);
|
||||||
|
}
|
||||||
|
|
||||||
|
get service() {
|
||||||
|
return this._service;
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
|
const Credential = imports.gdm.credentialManager;
|
||||||
|
|
||||||
|
var SERVICE_NAME = 'gdm-ovirtcred';
|
||||||
|
|
||||||
const OVirtCredentialsIface = `
|
const OVirtCredentialsIface = `
|
||||||
<node>
|
<node>
|
||||||
@ -28,30 +31,14 @@ function OVirtCredentials() {
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
var OVirtCredentialsManager = class {
|
var OVirtCredentialsManager = class OVirtCredentialsManager extends Credential.CredentialManager {
|
||||||
constructor() {
|
constructor() {
|
||||||
this._token = null;
|
super(SERVICE_NAME);
|
||||||
|
|
||||||
this._credentials = new OVirtCredentials();
|
this._credentials = new OVirtCredentials();
|
||||||
this._credentials.connectSignal('UserAuthenticated',
|
this._credentials.connectSignal('UserAuthenticated',
|
||||||
this._onUserAuthenticated.bind(this));
|
(proxy, sender, [token]) => {
|
||||||
}
|
this.token = token;
|
||||||
|
});
|
||||||
_onUserAuthenticated(proxy, sender, [token]) {
|
|
||||||
this._token = token;
|
|
||||||
this.emit('user-authenticated', token);
|
|
||||||
}
|
|
||||||
|
|
||||||
hasToken() {
|
|
||||||
return this._token != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
getToken() {
|
|
||||||
return this._token;
|
|
||||||
}
|
|
||||||
|
|
||||||
resetToken() {
|
|
||||||
this._token = null;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Signals.addSignalMethods(OVirtCredentialsManager.prototype);
|
Signals.addSignalMethods(OVirtCredentialsManager.prototype);
|
||||||
|
@ -24,7 +24,6 @@ Gio._promisify(Gdm.UserVerifierProxy.prototype,
|
|||||||
var PASSWORD_SERVICE_NAME = 'gdm-password';
|
var PASSWORD_SERVICE_NAME = 'gdm-password';
|
||||||
var FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint';
|
var FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint';
|
||||||
var SMARTCARD_SERVICE_NAME = 'gdm-smartcard';
|
var SMARTCARD_SERVICE_NAME = 'gdm-smartcard';
|
||||||
var OVIRT_SERVICE_NAME = 'gdm-ovirtcred';
|
|
||||||
var FADE_ANIMATION_TIME = 160;
|
var FADE_ANIMATION_TIME = 160;
|
||||||
var CLONE_FADE_ANIMATION_TIME = 250;
|
var CLONE_FADE_ANIMATION_TIME = 250;
|
||||||
|
|
||||||
@ -160,13 +159,19 @@ var ShellUserVerifier = class {
|
|||||||
|
|
||||||
this._failCounter = 0;
|
this._failCounter = 0;
|
||||||
|
|
||||||
this._oVirtCredentialsManager = OVirt.getOVirtCredentialsManager();
|
this._credentialManagers = {};
|
||||||
|
this._credentialManagers[OVirt.SERVICE_NAME] = OVirt.getOVirtCredentialsManager();
|
||||||
|
|
||||||
if (this._oVirtCredentialsManager.hasToken())
|
for (let service in this._credentialManagers) {
|
||||||
this._oVirtUserAuthenticated(this._oVirtCredentialsManager.getToken());
|
if (this._credentialManagers[service].token) {
|
||||||
|
this._onCredentialManagerAuthenticated(this._credentialManagers[service],
|
||||||
|
this._credentialManagers[service].token);
|
||||||
|
}
|
||||||
|
|
||||||
this._oVirtUserAuthenticatedId = this._oVirtCredentialsManager.connect('user-authenticated',
|
this._credentialManagers[service]._authenticatedSignalId =
|
||||||
this._oVirtUserAuthenticated.bind(this));
|
this._credentialManagers[service].connect('user-authenticated',
|
||||||
|
this._onCredentialManagerAuthenticated.bind(this));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
begin(userName, hold) {
|
begin(userName, hold) {
|
||||||
@ -222,8 +227,11 @@ var ShellUserVerifier = class {
|
|||||||
this._smartcardManager.disconnect(this._smartcardRemovedId);
|
this._smartcardManager.disconnect(this._smartcardRemovedId);
|
||||||
this._smartcardManager = null;
|
this._smartcardManager = null;
|
||||||
|
|
||||||
this._oVirtCredentialsManager.disconnect(this._oVirtUserAuthenticatedId);
|
for (let service in this._credentialManagers) {
|
||||||
this._oVirtCredentialsManager = null;
|
let credentialManager = this._credentialManagers[service];
|
||||||
|
credentialManager.disconnect(credentialManager._authenticatedSignalId);
|
||||||
|
credentialManager = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
answerQuery(serviceName, answer) {
|
answerQuery(serviceName, answer) {
|
||||||
@ -311,9 +319,9 @@ var ShellUserVerifier = class {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_oVirtUserAuthenticated(_token) {
|
_onCredentialManagerAuthenticated(credentialManager, _token) {
|
||||||
this._preemptingService = OVIRT_SERVICE_NAME;
|
this._preemptingService = credentialManager.service;
|
||||||
this.emit('ovirt-user-authenticated');
|
this.emit('credential-manager-authenticated');
|
||||||
}
|
}
|
||||||
|
|
||||||
_checkForSmartcard() {
|
_checkForSmartcard() {
|
||||||
@ -490,9 +498,12 @@ var ShellUserVerifier = class {
|
|||||||
if (!this.serviceIsForeground(serviceName))
|
if (!this.serviceIsForeground(serviceName))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (serviceName == OVIRT_SERVICE_NAME) {
|
let token = null;
|
||||||
// The only question asked by this service is "Token?"
|
if (this._credentialManagers[serviceName])
|
||||||
this.answerQuery(serviceName, this._oVirtCredentialsManager.getToken());
|
token = this._credentialManagers[serviceName].token;
|
||||||
|
|
||||||
|
if (token) {
|
||||||
|
this.answerQuery(serviceName, token);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -560,8 +571,10 @@ var ShellUserVerifier = class {
|
|||||||
// If the login failed with the preauthenticated oVirt credentials
|
// If the login failed with the preauthenticated oVirt credentials
|
||||||
// then discard the credentials and revert to default authentication
|
// then discard the credentials and revert to default authentication
|
||||||
// mechanism.
|
// mechanism.
|
||||||
if (this.serviceIsForeground(OVIRT_SERVICE_NAME)) {
|
let foregroundService = Object.keys(this._credentialManagers).find(service =>
|
||||||
this._oVirtCredentialsManager.resetToken();
|
this.serviceIsForeground(service));
|
||||||
|
if (foregroundService) {
|
||||||
|
this._credentialManagers[foregroundService].token = null;
|
||||||
this._preemptingService = null;
|
this._preemptingService = null;
|
||||||
this._verificationFailed(false);
|
this._verificationFailed(false);
|
||||||
return;
|
return;
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
<file>gdm/fingerprint.js</file>
|
<file>gdm/fingerprint.js</file>
|
||||||
<file>gdm/loginDialog.js</file>
|
<file>gdm/loginDialog.js</file>
|
||||||
<file>gdm/oVirt.js</file>
|
<file>gdm/oVirt.js</file>
|
||||||
|
<file>gdm/credentialManager.js</file>
|
||||||
<file>gdm/realmd.js</file>
|
<file>gdm/realmd.js</file>
|
||||||
<file>gdm/util.js</file>
|
<file>gdm/util.js</file>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user