Commit 8dbec4a1 authored by David Edmundson's avatar David Edmundson
Browse files

Wait for screenlocker UI to call close

This is important as it allows the screenlocker to show a prompt for
passwordless users before unlocking. For example mobile having a simple
swipe to unlock.

It also potentially allows a future successful login animation.

An additional guard is added so rogue QML can't trivially bypass the
user password; though pragamtically they could before if they emit the
right signal in the authenticator.
parent 5550c13a
Pipeline #183596 passed with stage
in 4 minutes and 22 seconds
......@@ -130,23 +130,13 @@ UnlockApp::UnlockApp(int &argc, char **argv)
, m_testing(false)
, m_ignoreRequests(false)
, m_immediateLock(false)
, m_authenticator(new PamAuthenticator("kde", KUser().loginName(), this))
, m_graceTime(0)
, m_noLock(false)
, m_defaultToSwitchUser(false)
, m_wallpaperIntegration(new WallpaperIntegration(this))
, m_lnfIntegration(new LnFIntegration(this))
{
m_authenticator = new PamAuthenticator("kde", KUser().loginName(), this);
// It's a queued connection to give the QML part time to eventually execute code connected to Authenticator::succeeded if any
connect(
m_authenticator,
&PamAuthenticator::succeeded,
this,
[]() {
qApp->quit();
},
Qt::QueuedConnection);
initialize();
if (QX11Info::isPlatformX11()) {
......@@ -339,6 +329,13 @@ KQuickAddons::QuickViewSharedEngine *UnlockApp::createViewForScreen(QScreen *scr
// engine stuff
QQmlContext *context = view->engine()->rootContext();
connect(view->engine(), &QQmlEngine::quit, this, [this]() {
if (m_authenticator->isUnlocked()) {
QCoreApplication::quit();
} else {
qCWarning(KSCREENLOCKER_GREET) << "Greeter tried to quit without being unlocked";
}
});
context->setContextProperty(QStringLiteral("kscreenlocker_userName"), m_userName);
context->setContextProperty(QStringLiteral("kscreenlocker_userImage"), m_userImage);
......
......@@ -201,7 +201,10 @@ PamAuthenticator::PamAuthenticator(const QString &service, const QString &user,
connect(d, &PamWorker::infoMessage, this, &PamAuthenticator::infoMessage);
connect(d, &PamWorker::errorMessage, this, &PamAuthenticator::errorMessage);
connect(d, &PamWorker::succeeded, this, &PamAuthenticator::succeeded);
connect(d, &PamWorker::succeeded, this, [this]() {
m_unlocked = true;
Q_EMIT succeeded();
});
connect(d, &PamWorker::failed, this, &PamAuthenticator::failed);
m_thread.start();
......@@ -222,8 +225,14 @@ void PamAuthenticator::init(const QString &service, const QString &user)
});
}
bool PamAuthenticator::isUnlocked() const
{
return m_unlocked;
}
void PamAuthenticator::tryUnlock()
{
m_unlocked = false;
QMetaObject::invokeMethod(d, &PamWorker::authenticate);
}
......
......@@ -33,6 +33,8 @@ public:
PamAuthenticator(const QString &service, const QString &user, QObject *parent = nullptr);
~PamAuthenticator();
bool isUnlocked() const;
Q_SIGNALS:
void promptForSecret(const QString &msg);
void prompt(const QString &msg);
......@@ -50,6 +52,7 @@ protected:
void init(const QString &service, const QString &user);
private:
bool m_unlocked = false;
QThread m_thread;
PamWorker *d;
};
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment