Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Don't execute the plugin process synchronously.
  • Loading branch information
adenexter committed Sep 2, 2016
1 parent 58b83ed commit 7d9babb
Show file tree
Hide file tree
Showing 13 changed files with 165 additions and 71 deletions.
3 changes: 2 additions & 1 deletion src/lib/authenticator.h
Expand Up @@ -65,7 +65,8 @@ class Authenticator : public QObject
};

enum Error {
LockedOut
LockedOut,
SoftwareError,
};

enum Method {
Expand Down
1 change: 1 addition & 0 deletions src/lib/devicelock.h
Expand Up @@ -59,6 +59,7 @@ class DeviceLock : public QObject

void locked();
void unlocked();
void unlockError();

private:
QExplicitlySharedDataPointer<SettingsWatcher> m_settings;
Expand Down
6 changes: 3 additions & 3 deletions src/lib/devicereset.h
Expand Up @@ -54,11 +54,11 @@ class DeviceReset : public QObject

virtual Authorization *authorization() = 0;

Q_INVOKABLE virtual bool clearDevice(const QVariant &authenticationToken, ResetMode mode = Shutdown) = 0;
Q_INVOKABLE virtual void clearDevice(const QVariant &authenticationToken, ResetMode mode = Shutdown) = 0;

signals:
void challengeIssued();
void challengeCodeChanged();
void clearingDevice();
void clearDeviceError();
};

#endif
74 changes: 49 additions & 25 deletions src/lib/lockcodewatcher.cpp
Expand Up @@ -48,6 +48,40 @@
#include <QSettings>
#include <QStandardPaths>

PluginCommand::PluginCommand(QObject *caller)
: m_caller(caller)
{
connect(static_cast<QProcess *>(this), static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
this, &PluginCommand::processFinished);
}

void PluginCommand::processFinished(int exitCode, QProcess::ExitStatus status)
{
deleteLater();

QByteArray output = readAllStandardOutput();
if (!output.isEmpty()) {
qDebug() << output.constData();
}

output = readAllStandardError();
if (!output.isEmpty()) {
qWarning() << output.constData();
}

if (!m_caller) {
return;
} else if (exitCode == 0 && status == QProcess::NormalExit) {
emit succeeded();
} else {
emit failed();
}
}

PluginCommand::~PluginCommand()
{
}

static QString pluginName()
{
static const QString pluginName = []() {
Expand Down Expand Up @@ -103,8 +137,12 @@ bool LockCodeWatcher::lockCodeSet() const
{
if (m_codeSetInvalidated) {
m_codeSetInvalidated = false;
m_lockCodeSet = runPlugin(QStringList()
<< QStringLiteral("--is-set") << QStringLiteral("lockcode"));
m_lockCodeSet = false;
if (PluginCommand *command = runPlugin(nullptr, QStringList()
<< QStringLiteral("--is-set") << QStringLiteral("lockcode"))) {
command->waitForFinished();
m_lockCodeSet = command->exitCode() == 0;
}
}
return m_lockCodeSet;
}
Expand All @@ -125,43 +163,29 @@ void LockCodeWatcher::invalidateLockCodeSet()
}
}

bool LockCodeWatcher::checkCode(const QString &code)
PluginCommand *LockCodeWatcher::checkCode(QObject *caller, const QString &code)
{
return runPlugin(QStringList() << QStringLiteral("--check-code") << code);
return runPlugin(caller, QStringList() << QStringLiteral("--check-code") << code);
}

bool LockCodeWatcher::unlock(const QString &code)
PluginCommand *LockCodeWatcher::unlock(QObject *caller, const QString &code)
{
return runPlugin(QStringList() << QStringLiteral("--unlock") << code);
return runPlugin(caller, QStringList() << QStringLiteral("--unlock") << code);
}

bool LockCodeWatcher::runPlugin(const QStringList &arguments) const
PluginCommand *LockCodeWatcher::runPlugin(QObject *caller, const QStringList &arguments) const
{
if (!m_pluginExists) {
return false;
}

QProcess process;
process.start(pluginName(), arguments);
if (!process.waitForFinished()) {
qWarning("DeviceLock: plugin did not finish in time");
return false;
return nullptr;
}

QByteArray output = process.readAllStandardOutput();
if (!output.isEmpty()) {
qDebug() << output.constData();
}
PluginCommand *const process = new PluginCommand(caller);

output = process.readAllStandardError();
if (!output.isEmpty()) {
qWarning() << output.constData();
}
process->start(pluginName(), arguments);

return process.exitCode() == 0;
return process;
}


void LockCodeWatcher::lockCodeSetInvalidated()
{
if (!m_codeSetInvalidated) {
Expand Down
38 changes: 35 additions & 3 deletions src/lib/lockcodewatcher.h
Expand Up @@ -34,9 +34,41 @@
#define LOCKCODEWATCHER_H

#include <QDateTime>
#include <QPointer>
#include <QProcess>
#include <QSharedData>
#include <QVector>

class PluginCommand : public QProcess
{
Q_OBJECT
public:
PluginCommand(QObject *caller);

template <typename Success> void onSuccess(const Success &success)
{
connect(this, &PluginCommand::succeeded, success);
}

template <typename Failure> void onFailure(const Failure &failure)
{
connect(this, &PluginCommand::failed, failure);
}

signals:
void succeeded();
void failed();

private:
friend class LockCodeWatcher;

~PluginCommand();

void processFinished(int exitCode, QProcess::ExitStatus status);

QPointer<QObject> m_caller;
};

class LockCodeWatcher : public QObject, public QSharedData
{
Q_OBJECT
Expand All @@ -48,10 +80,10 @@ class LockCodeWatcher : public QObject, public QSharedData
bool lockCodeSet() const;
void invalidateLockCodeSet();

bool checkCode(const QString &code);
bool unlock(const QString &code);
PluginCommand *checkCode(QObject *caller, const QString &code);
PluginCommand *unlock(QObject *caller, const QString &code);

bool runPlugin(const QStringList &arguments) const;
PluginCommand *runPlugin(QObject *caller, const QStringList &arguments) const;

signals:
void lockCodeSetChanged();
Expand Down
42 changes: 24 additions & 18 deletions src/lib/nemoauthenticator.cpp
Expand Up @@ -109,30 +109,36 @@ void NemoAuthenticator::enterLockCode(const QString &code)
return;
}

if (m_watcher->checkCode(code)) {
confirmAuthentication(code);
} else {
const int maximum = maximumAttempts();
if (PluginCommand *command = m_watcher->checkCode(this, code)) {
command->onSuccess([this, code]() {
confirmAuthentication(code);
});

command->onFailure([this]() {
const int maximum = maximumAttempts();

if (maximum > 0) {
const int attempts = m_attemptCount.value(0).toInt() + 1;
m_attemptCount.set(attempts);
if (maximum > 0) {
const int attempts = m_attemptCount.value(0).toInt() + 1;
m_attemptCount.set(attempts);

emit feedback(IncorrectLockCode, qMax(0, maximum - attempts));
emit feedback(IncorrectLockCode, qMax(0, maximum - attempts));

if (attempts >= maximum) {
m_authenticating = false;
m_utilizedMethods = Methods();
if (attempts >= maximum) {
m_authenticating = false;
m_utilizedMethods = Methods();

authenticationEnded(false);
authenticationEnded(false);

emit error(LockedOut);
emit authenticatingChanged();
emit utilizedMethodsChanged();
emit error(LockedOut);
emit authenticatingChanged();
emit utilizedMethodsChanged();
}
} else {
emit feedback(IncorrectLockCode, -1);
}
} else {
emit feedback(IncorrectLockCode, -1);
}
});
} else {
emit error(SoftwareError);
}
}

Expand Down
3 changes: 0 additions & 3 deletions src/lib/nemoauthenticator.h
Expand Up @@ -58,9 +58,6 @@ class NemoAuthenticator : public Authenticator

void abort(Error error);

static QString pluginName();
static bool runPlugin(const QStringList &arguments);

protected:
virtual void authenticationStarted(Methods methods);
virtual void authenticationEnded(bool confirmed);
Expand Down
15 changes: 12 additions & 3 deletions src/lib/nemodevicelock.cpp
Expand Up @@ -59,8 +59,17 @@ Authorization *NemoDeviceLock::authorization()

void NemoDeviceLock::unlock(const QVariant &authenticationToken)
{
if (m_authorization.status() == Authorization::ChallengeIssued
&& m_watcher->unlock(authenticationToken.toString())) {
setState(Unlocked);
if (m_authorization.status() == Authorization::ChallengeIssued) {
if (PluginCommand *command = m_watcher->unlock(this, authenticationToken.toString())) {
command->onSuccess([this]() {
setState(Unlocked);
});

command->onFailure([this]() {
emit unlockError();
});
} else {
emit unlockError();
}
}
}
2 changes: 1 addition & 1 deletion src/lib/nemodevicelocksettings.cpp
Expand Up @@ -53,7 +53,7 @@ void NemoDeviceLockSettings::changeSetting(
const QVariant &authenticationToken, const QString &key, const QVariant &value)
{
if (m_authorization.status() == Authorization::ChallengeIssued) {
m_watcher->runPlugin(QStringList()
m_watcher->runPlugin(this, QStringList()
<< QStringLiteral("--set-config-key")
<< authenticationToken.toString()
<< key
Expand Down
13 changes: 10 additions & 3 deletions src/lib/nemodevicereset.cpp
Expand Up @@ -51,7 +51,7 @@ Authorization *NemoDeviceReset::authorization()
return &m_authorization;
}

bool NemoDeviceReset::clearDevice(const QVariant &authenticationToken, ResetMode mode)
void NemoDeviceReset::clearDevice(const QVariant &authenticationToken, ResetMode mode)
{
if (m_authorization.status() == Authorization::ChallengeIssued) {
QStringList arguments = QStringList()
Expand All @@ -60,8 +60,15 @@ bool NemoDeviceReset::clearDevice(const QVariant &authenticationToken, ResetMode
if (mode == Reboot) {
arguments << QStringLiteral("--reboot");
}
return m_watcher->runPlugin(arguments);
if (PluginCommand *command = m_watcher->runPlugin(this, arguments)) {
command->onSuccess([this]() {
emit clearingDevice();
});
command->onFailure([this]() {
emit clearDeviceError();
});
};
} else {
return false;
emit clearDeviceError();
}
}
2 changes: 1 addition & 1 deletion src/lib/nemodevicereset.h
Expand Up @@ -50,7 +50,7 @@ class NemoDeviceReset : public DeviceReset

Authorization *authorization() override;

bool clearDevice(const QVariant &authenticationToken, ResetMode mode) override;
void clearDevice(const QVariant &authenticationToken, ResetMode mode) override;

private:
NemoAuthorization m_authorization;
Expand Down
9 changes: 7 additions & 2 deletions src/lib/nemoencryptionsettings.cpp
Expand Up @@ -52,10 +52,15 @@ Authorization *NemoEncryptionSettings::authorization()
void NemoEncryptionSettings::encryptHome(const QVariant &authenticationToken)
{
if (m_authorization.status() == Authorization::ChallengeIssued) {
if (m_watcher->runPlugin(QStringList()
if (PluginCommand *command = m_watcher->runPlugin(this, QStringList()
<< QStringLiteral("--encrypt-home")
<< authenticationToken.toString())) {
emit encryptingHome();
command->onSuccess([this]() {
emit encryptingHome();
});
command->onFailure([this]() {
emit encryptHomeError();
});
} else {
emit encryptHomeError();
}
Expand Down
28 changes: 20 additions & 8 deletions src/lib/nemolockcodesettings.cpp
Expand Up @@ -59,23 +59,35 @@ bool NemoLockCodeSettings::isSet() const

void NemoLockCodeSettings::change(const QString &oldCode, const QString &newCode)
{
if (m_watcher->runPlugin(QStringList() << QStringLiteral("--set-code") << oldCode << newCode)) {
if (!m_watcher->lockCodeSet()) {
m_watcher->invalidateLockCodeSet();
}
if (PluginCommand *command = m_watcher->runPlugin(
this, QStringList() << QStringLiteral("--set-code") << oldCode << newCode)) {
command->onSuccess([this]() {
if (!m_watcher->lockCodeSet()) {
m_watcher->invalidateLockCodeSet();
}

emit changed();
emit changed();
});
command->onFailure([this]() {
emit changeError();
});
} else {
emit changeError();
}
}

void NemoLockCodeSettings::clear(const QString &currentCode)
{
if (m_watcher->runPlugin(QStringList() << QStringLiteral("--clear-code") << currentCode)) {
m_watcher->invalidateLockCodeSet();
if (PluginCommand *command = m_watcher->runPlugin(
this, QStringList() << QStringLiteral("--clear-code") << currentCode)) {
command->onSuccess([this]() {
m_watcher->invalidateLockCodeSet();

emit cleared();
emit cleared();
});
command->onFailure([this]() {
emit clearError();
});
} else {
emit clearError();
}
Expand Down

0 comments on commit 7d9babb

Please sign in to comment.