feat: add env option and refactor command generate method
Signed-off-by: ComixHe <heyuming@deepin.org>
This commit is contained in:
parent
8ab6adc290
commit
1fb4539792
@ -80,7 +80,14 @@
|
||||
Extra options can be passed in `options` argument:
|
||||
1. `uid` (type u):
|
||||
The user id as who is that application will be run.
|
||||
This option might request a polikit authentication."
|
||||
This option might request a polikit authentication.
|
||||
2. `env` (type s):
|
||||
passing some specific environment variables to Launch
|
||||
this application, eg. 'LANG=en_US;PATH=xxx:yyy;'
|
||||
|
||||
NOTE:
|
||||
when application try to be launched by other user identity,
|
||||
all environment variables will be ignored.
|
||||
/>
|
||||
</method>
|
||||
</interface>
|
||||
|
@ -42,4 +42,8 @@ constexpr auto ApplicationManagerInterface = "org.desktopspec.ApplicationManager
|
||||
constexpr auto InstanceInterface = "org.desktopspec.ApplicationManager1.Instance";
|
||||
constexpr auto ApplicationInterface = "org.desktopspec.ApplicationManager1.Application";
|
||||
|
||||
constexpr auto systemdOption = u8"systemd";
|
||||
constexpr auto splitOption = u8"split";
|
||||
constexpr auto AppExecOption = u8"appExec";
|
||||
|
||||
#endif
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "APPobjectmanager1adaptor.h"
|
||||
#include "applicationmanager1service.h"
|
||||
#include "dbus/instanceadaptor.h"
|
||||
#include "pwd.h"
|
||||
#include "launchoptions.h"
|
||||
#include <QUuid>
|
||||
#include <QStringList>
|
||||
#include <QList>
|
||||
@ -125,27 +125,13 @@ QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringL
|
||||
}
|
||||
}
|
||||
|
||||
auto [bin, cmds, res] = unescapeExec(execStr, fields);
|
||||
auto cmds = generateCommand(options);
|
||||
|
||||
uid_t uid;
|
||||
auto it = options.find("uid");
|
||||
if (it != options.cend()) {
|
||||
uid = it->toUInt(&ok);
|
||||
if (!ok) {
|
||||
qWarning() << "convert uid string to uint failed: " << *it;
|
||||
return {};
|
||||
}
|
||||
auto [bin, execCmds, res] = unescapeExec(execStr, fields);
|
||||
|
||||
if (uid != getCurrentUID()) {
|
||||
cmds.prepend(userNameLookup(uid));
|
||||
cmds.prepend("--user");
|
||||
cmds.prepend("pkexec");
|
||||
}
|
||||
} else {
|
||||
uid = getCurrentUID();
|
||||
}
|
||||
cmds.append(std::move(execCmds));
|
||||
|
||||
cmds.prepend("--");
|
||||
qDebug() << "run application with:" << cmds;
|
||||
|
||||
auto &jobManager = static_cast<ApplicationManager1Service *>(parent())->jobManager();
|
||||
|
||||
@ -348,12 +334,6 @@ void ApplicationService::resetEntry(DesktopEntry *newEntry) noexcept
|
||||
m_entry.reset(newEntry);
|
||||
}
|
||||
|
||||
QString ApplicationService::userNameLookup(uid_t uid)
|
||||
{
|
||||
auto *pws = getpwuid(uid);
|
||||
return pws->pw_name;
|
||||
}
|
||||
|
||||
LaunchTask ApplicationService::unescapeExec(const QString &str, const QStringList &fields)
|
||||
{
|
||||
LaunchTask task;
|
||||
|
@ -97,7 +97,6 @@ private:
|
||||
DesktopFile m_desktopSource;
|
||||
QSharedPointer<DesktopEntry> m_entry{nullptr};
|
||||
QMap<QDBusObjectPath, QSharedPointer<InstanceService>> m_Instances;
|
||||
static QString userNameLookup(uid_t uid);
|
||||
[[nodiscard]] LaunchTask unescapeExec(const QString &str, const QStringList &fields);
|
||||
[[nodiscard]] QVariant findEntryValue(const QString &group,
|
||||
const QString &valueKey,
|
||||
|
101
src/launchoptions.cpp
Normal file
101
src/launchoptions.cpp
Normal file
@ -0,0 +1,101 @@
|
||||
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
#include <pwd.h>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include "global.h"
|
||||
#include "launchoptions.h"
|
||||
|
||||
QStringList generateCommand(const QVariantMap &props) noexcept
|
||||
{
|
||||
std::vector<std::unique_ptr<LaunchOption>> options;
|
||||
for (const auto &[key, value] : props.asKeyValueRange()) {
|
||||
if (key == setUserLaunchOption::key()) {
|
||||
options.push_back(std::make_unique<setUserLaunchOption>(value));
|
||||
} else if (key == setEnvLaunchOption::key()) {
|
||||
options.push_back(std::make_unique<setEnvLaunchOption>(value));
|
||||
} else {
|
||||
qWarning() << "unsupported options" << key;
|
||||
}
|
||||
}
|
||||
|
||||
options.push_back(std::make_unique<splitLaunchOption>());
|
||||
|
||||
std::sort(options.begin(),
|
||||
options.end(),
|
||||
[](const std::unique_ptr<LaunchOption> &lOption, const std::unique_ptr<LaunchOption> &rOption) {
|
||||
if (lOption->type() == AppExecOption and rOption->type() == systemdOption) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lOption->type() == AppExecOption and rOption->type() == splitOption) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lOption->type() == splitOption and rOption->type() == systemdOption) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
QStringList ret;
|
||||
std::for_each(options.begin(), options.end(), [&ret](const std::unique_ptr<LaunchOption> &option) {
|
||||
auto str = option->generateCommandLine();
|
||||
if (!str.isEmpty()) {
|
||||
ret.append(std::move(str));
|
||||
}
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QStringList setUserLaunchOption::generateCommandLine() const noexcept
|
||||
{
|
||||
QStringList ret;
|
||||
|
||||
bool ok{false};
|
||||
auto uid = m_val.toUInt(&ok);
|
||||
if (!ok) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto curUID = getCurrentUID();
|
||||
|
||||
if (uid == curUID) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret.append("pkexec");
|
||||
ret.append("--user");
|
||||
|
||||
struct passwd *destUser = getpwuid(uid);
|
||||
QString userName = destUser->pw_name;
|
||||
ret.append(userName);
|
||||
|
||||
struct passwd *curUser = getpwuid(curUID);
|
||||
ret.append("env");
|
||||
ret.append("DISPLAY=:0");
|
||||
|
||||
auto authFile = qgetenv("XAUTHORITY");
|
||||
ret.append(QString{"XAUTHORITY=%1"}.arg(authFile));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QStringList splitLaunchOption::generateCommandLine() const noexcept
|
||||
{
|
||||
return QStringList{m_val.toString()};
|
||||
}
|
||||
|
||||
QStringList setEnvLaunchOption::generateCommandLine() const noexcept
|
||||
{
|
||||
auto str = m_val.toString();
|
||||
if (str.isEmpty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return QStringList{QString{"--Environment=%1"}.arg(str)};
|
||||
}
|
73
src/launchoptions.h
Normal file
73
src/launchoptions.h
Normal file
@ -0,0 +1,73 @@
|
||||
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
#include <QVariantMap>
|
||||
#include "constant.h"
|
||||
|
||||
struct LaunchOption
|
||||
{
|
||||
explicit LaunchOption(QVariant v)
|
||||
: m_val(std::move(v))
|
||||
{
|
||||
}
|
||||
virtual ~LaunchOption() = default;
|
||||
[[nodiscard]] virtual QStringList generateCommandLine() const noexcept = 0;
|
||||
[[nodiscard]] static const QString &key() noexcept
|
||||
{
|
||||
static QString none;
|
||||
return none;
|
||||
};
|
||||
[[nodiscard]] virtual const QString &type() const noexcept = 0;
|
||||
|
||||
QVariant m_val;
|
||||
};
|
||||
|
||||
struct setUserLaunchOption : public LaunchOption
|
||||
{
|
||||
using LaunchOption::LaunchOption;
|
||||
[[nodiscard]] const QString &type() const noexcept override
|
||||
{
|
||||
static QString tp{AppExecOption};
|
||||
return tp;
|
||||
}
|
||||
[[nodiscard]] static const QString &key() noexcept
|
||||
{
|
||||
static QString uid{"uid"};
|
||||
return uid;
|
||||
}
|
||||
[[nodiscard]] QStringList generateCommandLine() const noexcept override;
|
||||
};
|
||||
|
||||
struct setEnvLaunchOption : public LaunchOption
|
||||
{
|
||||
using LaunchOption::LaunchOption;
|
||||
[[nodiscard]] const QString &type() const noexcept override
|
||||
{
|
||||
static QString tp{systemdOption};
|
||||
return tp;
|
||||
}
|
||||
[[nodiscard]] static const QString &key() noexcept
|
||||
{
|
||||
static QString env{"env"};
|
||||
return env;
|
||||
}
|
||||
[[nodiscard]] QStringList generateCommandLine() const noexcept override;
|
||||
};
|
||||
|
||||
struct splitLaunchOption : public LaunchOption
|
||||
{
|
||||
splitLaunchOption()
|
||||
: LaunchOption(QString{"--"})
|
||||
{
|
||||
}
|
||||
|
||||
[[nodiscard]] const QString &type() const noexcept override
|
||||
{
|
||||
static QString tp{splitOption};
|
||||
return tp;
|
||||
}
|
||||
[[nodiscard]] QStringList generateCommandLine() const noexcept override;
|
||||
};
|
||||
|
||||
QStringList generateCommand(const QVariantMap &props) noexcept;
|
Loading…
Reference in New Issue
Block a user