mirror of
https://github.com/QuasarApp/installer-framework.git
synced 2025-05-08 02:59:33 +00:00
Gain admin rights for writing MaintenanceTool config files if needed
Running MaintenanceTool from an elevated directory didn't do proper checks for file writing rights when parsing Updates.xml from a repository, for example when a default repository contains actions inside <RepositoryUpdate> tags the MaintenanceTool couldn't write changes to the .ini file immediately. Make MaintenanceTool do proper rights checking when parsing Updates.xml. Create uniform methods for checking directory writing access as it is used on several occasions. Add tests for directory checking methods. Task-number: QTIFW-1363 Change-Id: I6d634ddbd59429e5b98af1d8010e70a71de40f69 Reviewed-by: Katja Marttila <katja.marttila@qt.io>
This commit is contained in:
parent
8d020f1b19
commit
89f772f819
src/libs/installer
metadatajob.cpppackagemanagercore.cpppackagemanagercore.hpackagemanagercore_p.cpppackagemanagercore_p.h
tests/auto/installer/packagemanagercore
@ -328,8 +328,16 @@ void MetadataJob::xmlTaskFinished()
|
||||
|
||||
if (s.updateDefaultRepositories(update) == Settings::UpdatesApplied
|
||||
|| s.updateUserRepositories(update) == Settings::UpdatesApplied) {
|
||||
if (m_core->isMaintainer())
|
||||
if (m_core->isMaintainer()) {
|
||||
bool gainedAdminRights = false;
|
||||
if (!m_core->directoryWritable(m_core->value(scTargetDir))) {
|
||||
m_core->gainAdminRights();
|
||||
gainedAdminRights = true;
|
||||
}
|
||||
m_core->writeMaintenanceConfigFiles();
|
||||
if (gainedAdminRights)
|
||||
m_core->dropAdminRights();
|
||||
}
|
||||
}
|
||||
}
|
||||
status = XmlDownloadRetry;
|
||||
@ -716,8 +724,16 @@ MetadataJob::Status MetadataJob::parseUpdatesXml(const QList<FileTaskResult> &re
|
||||
return XmlDownloadRetry;
|
||||
}
|
||||
} else if (s.updateDefaultRepositories(repositoryUpdates) == Settings::UpdatesApplied) {
|
||||
if (m_core->isMaintainer())
|
||||
if (m_core->isMaintainer()) {
|
||||
bool gainedAdminRights = false;
|
||||
if (!m_core->directoryWritable(m_core->value(scTargetDir))) {
|
||||
m_core->gainAdminRights();
|
||||
gainedAdminRights = true;
|
||||
}
|
||||
m_core->writeMaintenanceConfigFiles();
|
||||
if (gainedAdminRights)
|
||||
m_core->dropAdminRights();
|
||||
}
|
||||
m_metaFromDefaultRepositories.clear();
|
||||
QFile::remove(result.target());
|
||||
return XmlDownloadRetry;
|
||||
|
@ -422,9 +422,7 @@ void PackageManagerCore::writeMaintenanceTool()
|
||||
d->writeMaintenanceTool(d->m_performedOperationsOld + d->m_performedOperationsCurrentSession);
|
||||
|
||||
bool gainedAdminRights = false;
|
||||
QTemporaryFile tempAdminFile(d->targetDir()
|
||||
+ QLatin1String("/testjsfdjlkdsjflkdsjfldsjlfds") + QString::number(qrand() % 1000));
|
||||
if (!tempAdminFile.open() || !tempAdminFile.isWritable()) {
|
||||
if (!directoryWritable(d->targetDir())) {
|
||||
gainAdminRights();
|
||||
gainedAdminRights = true;
|
||||
}
|
||||
@ -1111,8 +1109,7 @@ void PackageManagerCore::networkSettingsChanged()
|
||||
|
||||
if (isMaintainer() ) {
|
||||
bool gainedAdminRights = false;
|
||||
QTemporaryFile tempAdminFile(d->targetDir() + QStringLiteral("/XXXXXX"));
|
||||
if (!tempAdminFile.open() || !tempAdminFile.isWritable()) {
|
||||
if (!directoryWritable(d->targetDir())) {
|
||||
gainAdminRights();
|
||||
gainedAdminRights = true;
|
||||
}
|
||||
@ -1580,6 +1577,16 @@ Component *PackageManagerCore::componentByName(const QString &name, const QList<
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool PackageManagerCore::directoryWritable(const QString &path) const
|
||||
{
|
||||
return d->directoryWritable(path);
|
||||
}
|
||||
|
||||
bool PackageManagerCore::subdirectoriesWritable(const QString &path) const
|
||||
{
|
||||
return d->subdirectoriesWritable(path);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a list of components that are marked for installation. The list can
|
||||
be empty.
|
||||
|
@ -121,6 +121,9 @@ public:
|
||||
|
||||
static Component *componentByName(const QString &name, const QList<Component *> &components);
|
||||
|
||||
bool directoryWritable(const QString &path) const;
|
||||
bool subdirectoriesWritable(const QString &path) const;
|
||||
|
||||
bool fetchLocalPackagesTree();
|
||||
LocalPackagesHash localInstalledPackages();
|
||||
|
||||
|
@ -345,10 +345,19 @@ QString PackageManagerCorePrivate::targetDir() const
|
||||
return m_core->value(scTargetDir);
|
||||
}
|
||||
|
||||
bool PackageManagerCorePrivate::targetSubDirsWritable()
|
||||
bool PackageManagerCorePrivate::directoryWritable(const QString &path) const
|
||||
{
|
||||
QTemporaryFile tempFile(path + QStringLiteral("/tempFile") + QString::number(qrand() % 1000));
|
||||
if (!tempFile.open() || !tempFile.isWritable())
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PackageManagerCorePrivate::subdirectoriesWritable(const QString &path) const
|
||||
{
|
||||
// Iterate over target directory subdirectories for writing access
|
||||
QDirIterator iterator(targetDir(), QDir::AllDirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
|
||||
QDirIterator iterator(path, QDir::AllDirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
|
||||
while (iterator.hasNext()) {
|
||||
QTemporaryFile tempFile(iterator.next() + QLatin1String("/tempFile"));
|
||||
if (!tempFile.open() || !tempFile.isWritable())
|
||||
@ -1156,9 +1165,7 @@ void PackageManagerCorePrivate::writeMaintenanceToolBinaryData(QFileDevice *outp
|
||||
void PackageManagerCorePrivate::writeMaintenanceTool(OperationList performedOperations)
|
||||
{
|
||||
bool gainedAdminRights = false;
|
||||
QTemporaryFile tempAdminFile(targetDir() + QLatin1String("/testjsfdjlkdsjflkdsjfldsjlfds")
|
||||
+ QString::number(qrand() % 1000));
|
||||
if (!tempAdminFile.open() || !tempAdminFile.isWritable()) {
|
||||
if (!directoryWritable(targetDir())) {
|
||||
m_core->gainAdminRights();
|
||||
gainedAdminRights = true;
|
||||
}
|
||||
@ -1467,8 +1474,7 @@ bool PackageManagerCorePrivate::runInstaller()
|
||||
}
|
||||
}
|
||||
} else if (QDir(target).exists()) {
|
||||
QTemporaryFile tempAdminFile(target + QLatin1String("/adminrights"));
|
||||
if (!tempAdminFile.open() || !tempAdminFile.isWritable())
|
||||
if (!directoryWritable(targetDir()))
|
||||
adminRightsGained = m_core->gainAdminRights();
|
||||
}
|
||||
|
||||
@ -1637,11 +1643,11 @@ bool PackageManagerCorePrivate::runPackageUpdater()
|
||||
#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
|
||||
// check if we need admin rights and ask before the action happens
|
||||
// on Linux and macOS also check target directory subdirectories
|
||||
if (!QTemporaryFile(targetDir() + QStringLiteral("/XXXXXX")).open() || !targetSubDirsWritable())
|
||||
if (!directoryWritable(targetDir()) || !subdirectoriesWritable(targetDir()))
|
||||
adminRightsGained = m_core->gainAdminRights();
|
||||
#else
|
||||
// check if we need admin rights and ask before the action happens
|
||||
if (!QTemporaryFile(targetDir() + QStringLiteral("/XXXXXX")).open())
|
||||
if (!directoryWritable(targetDir()))
|
||||
adminRightsGained = m_core->gainAdminRights();
|
||||
#endif
|
||||
const QList<Component *> componentsToInstall = m_core->orderedComponentsToInstall();
|
||||
@ -1810,8 +1816,7 @@ bool PackageManagerCorePrivate::runUninstaller()
|
||||
setStatus(PackageManagerCore::Running);
|
||||
|
||||
// check if we need to run elevated and ask before the action happens
|
||||
QTemporaryFile tempAdminFile(targetDir() + QLatin1String("/adminrights"));
|
||||
if (!tempAdminFile.open() || !tempAdminFile.isWritable())
|
||||
if (!directoryWritable(targetDir()))
|
||||
adminRightsGained = m_core->gainAdminRights();
|
||||
|
||||
OperationList undoOperations = m_performedOperationsOld;
|
||||
|
@ -92,7 +92,8 @@ public:
|
||||
QString targetDir() const;
|
||||
QString registerPath();
|
||||
|
||||
bool targetSubDirsWritable();
|
||||
bool directoryWritable(const QString &path) const;
|
||||
bool subdirectoriesWritable(const QString &path) const;
|
||||
|
||||
QString maintenanceToolName() const;
|
||||
QString installerBinaryPath() const;
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <progresscoordinator.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QTemporaryFile>
|
||||
#include <QTest>
|
||||
|
||||
@ -257,6 +258,58 @@ private slots:
|
||||
core.calculateComponentsToInstall();
|
||||
QCOMPARE(core.requiredDiskSpace(), 250ULL);
|
||||
}
|
||||
|
||||
void testDirectoryWritable()
|
||||
{
|
||||
PackageManagerCore core;
|
||||
|
||||
const QString testDirectory = QInstaller::generateTemporaryFileName();
|
||||
QVERIFY(QDir().mkpath(testDirectory));
|
||||
QVERIFY(QDir(testDirectory).exists());
|
||||
|
||||
// should be writable
|
||||
QVERIFY(core.directoryWritable(testDirectory));
|
||||
|
||||
#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
|
||||
QFile dirDevice(testDirectory);
|
||||
dirDevice.setPermissions(QFileDevice::ReadOwner | QFileDevice::ExeOwner);
|
||||
|
||||
// should not be writable
|
||||
QVERIFY(!core.directoryWritable(testDirectory));
|
||||
|
||||
dirDevice.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner);
|
||||
#endif
|
||||
QVERIFY(QDir().rmdir(testDirectory));
|
||||
}
|
||||
|
||||
void testSubdirectoriesWritable()
|
||||
{
|
||||
PackageManagerCore core;
|
||||
|
||||
const QString testDirectory = QInstaller::generateTemporaryFileName();
|
||||
QVERIFY(QDir().mkpath(testDirectory));
|
||||
QVERIFY(QDir(testDirectory).exists());
|
||||
|
||||
const QString testSubdirectory = testDirectory + "/" + QString::number(qrand() % 1000);
|
||||
|
||||
QVERIFY(QDir().mkpath(testSubdirectory));
|
||||
QVERIFY(QDir(testSubdirectory).exists());
|
||||
|
||||
// should be writable
|
||||
QVERIFY(core.subdirectoriesWritable(testDirectory));
|
||||
|
||||
#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
|
||||
QFile dirDevice(testSubdirectory);
|
||||
dirDevice.setPermissions(QFileDevice::ReadOwner | QFileDevice::ExeOwner);
|
||||
|
||||
// should not be writable
|
||||
QVERIFY(!core.subdirectoriesWritable(testDirectory));
|
||||
|
||||
dirDevice.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner);
|
||||
#endif
|
||||
QVERIFY(QDir().rmdir(testSubdirectory));
|
||||
QVERIFY(QDir().rmdir(testDirectory));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user