Skip to content

refactor: add polkit authorization to PM#1666

Merged
reddevillg merged 1 commit into
OpenAtom-Linyaps:masterfrom
reddevillg:refactor_polkit
May 27, 2026
Merged

refactor: add polkit authorization to PM#1666
reddevillg merged 1 commit into
OpenAtom-Linyaps:masterfrom
reddevillg:refactor_polkit

Conversation

@reddevillg

Copy link
Copy Markdown
Collaborator

Add PolkitAuthority helper class to check authorization before Install, InstallFromFile, Uninstall, Update, Prune and SetConfiguration operations.

Move interaction interface from PM to Task.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the authentication and interaction model of the Linglong Package Manager. It replaces the previous client-side authorization logic with server-side Polkit checks for privileged operations such as installation, uninstallation, updates, and configuration changes. Additionally, the interaction signals and methods have been moved from the global PackageManager interface to individual Task objects. Feedback for this PR focuses on several critical areas: a potential deadlock issue where QEventLoop is used within a std::thread without a dispatcher, the risk of freezing the service's main thread due to synchronous Polkit authorization calls, and suggestions for improving code safety and organization through better DBus argument validation and namespace management.

Comment thread libs/linglong/src/linglong/package_manager/package_task.cpp
Comment thread libs/linglong/src/linglong/package_manager/polkit_authority.cpp Outdated
Comment thread libs/linglong/src/linglong/package_manager/polkit_authority.cpp Outdated
Comment thread libs/linglong/src/linglong/package_manager/polkit_authority.cpp
@codecov

codecov Bot commented May 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 312 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...g/src/linglong/package_manager/package_manager.cpp 0.00% 169 Missing ⚠️
...long/src/linglong/package_manager/package_task.cpp 0.00% 60 Missing ⚠️
.../src/linglong/package_manager/polkit_authority.cpp 0.00% 56 Missing ⚠️
libs/linglong/src/linglong/cli/cli.cpp 0.00% 18 Missing ⚠️
...nglong/src/linglong/package_manager/package_task.h 0.00% 6 Missing ⚠️
apps/ll-package-manager/src/main.cpp 0.00% 1 Missing ⚠️
.../src/linglong/package_manager/ref_installation.cpp 0.00% 1 Missing ⚠️
.../src/linglong/package_manager/uab_installation.cpp 0.00% 1 Missing ⚠️
Files with missing lines Coverage Δ
libs/linglong/src/linglong/cli/cli.h 8.33% <ø> (ø)
libs/utils/src/linglong/utils/error/error.h 50.94% <ø> (ø)
apps/ll-package-manager/src/main.cpp 0.00% <0.00%> (ø)
.../src/linglong/package_manager/ref_installation.cpp 32.83% <0.00%> (ø)
.../src/linglong/package_manager/uab_installation.cpp 11.96% <0.00%> (ø)
...nglong/src/linglong/package_manager/package_task.h 15.38% <0.00%> (-2.01%) ⬇️
libs/linglong/src/linglong/cli/cli.cpp 1.78% <0.00%> (+0.09%) ⬆️
.../src/linglong/package_manager/polkit_authority.cpp 0.00% <0.00%> (ø)
...long/src/linglong/package_manager/package_task.cpp 33.53% <0.00%> (-17.39%) ⬇️
...g/src/linglong/package_manager/package_manager.cpp 0.81% <0.00%> (-0.11%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@reddevillg reddevillg requested review from ComixHe and dengbo11 May 19, 2026 12:06
public:
PolkitAuthority() = delete;

static utils::error::Result<bool> checkAuthorization(const std::string &actionId,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

要不直接写成方法?

{
LINGLONG_TRACE("check polkit authorization");

static std::once_flag flag;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. 这里是单线程,没必要用once_flag
  2. qtbus相关的要不统一放到ll-cli的main.cpp里,那里已经有 qDBusRegisterMetaType<QDBusObjectPath>();了。

Comment thread libs/linglong/src/linglong/package_manager/polkit_authority.cpp Outdated
Comment thread libs/linglong/src/linglong/package_manager/package_task.cpp
auto PackageManager::Update(const QVariantMap &parameters) noexcept -> QVariantMap
{
// Polkit authorization check
if (calledFromDBus()) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

要不封装成一个函数?下面的鉴权代码基本是重复的

@ComixHe

ComixHe commented May 21, 2026

Copy link
Copy Markdown
Collaborator

我还遇到了一个问题,如果长时间不确定授权,超时之后cli会因为json反序列化缺少字段而崩溃

@reddevillg reddevillg marked this pull request as draft May 25, 2026 05:14
@reddevillg reddevillg marked this pull request as ready for review May 25, 2026 09:36
@reddevillg reddevillg requested a review from ComixHe May 25, 2026 09:36
@reddevillg

Copy link
Copy Markdown
Collaborator Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the Linglong Package Manager's authorization and interaction model. It moves Polkit-based permission checks from the CLI to the daemon, allowing for more secure and fine-grained access control, and introduces a peer-to-peer DBus mode. Additionally, interaction signals and methods have been moved from the PackageManager interface to the Task interface to better associate user prompts with specific operations. Review feedback focused on ensuring that DBus connections are correctly passed to internal implementation methods in peer mode to allow task exposure, adding safety checks for null pointers when deserializing interaction replies, and improving the robustness of the task confirmation event loop by handling external cancellations.

Comment thread libs/linglong/src/linglong/package_manager/package_manager.cpp Outdated
Comment thread libs/linglong/src/linglong/package_manager/package_manager.cpp Outdated
Comment thread libs/linglong/src/linglong/package_manager/package_manager.cpp Outdated
Comment thread libs/linglong/src/linglong/package_manager/package_manager.cpp Outdated
Comment thread libs/linglong/src/linglong/package_manager/package_task.cpp Outdated
Comment thread libs/linglong/src/linglong/package_manager/package_task.cpp
@reddevillg reddevillg marked this pull request as draft May 25, 2026 10:10
@reddevillg

Copy link
Copy Markdown
Collaborator Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the permission and authentication model of the Linglong package manager. It replaces the old client-side authorization checks with daemon-side asynchronous Polkit authorization, defining fine-grained Polkit actions for operations like install, update, uninstall, prune, and configuration changes. Additionally, the user interaction flow (RequestInteraction/ReplyInteraction) has been moved from the package manager interface to individual tasks.

Our review identified a critical issue in PackageTask::waitConfirm where a deserialized object is dereferenced without a null check, which could lead to a daemon crash. There is also a thread-safety concern regarding signal-slot connections and QEventLoop::exit across different threads; passing the event loop as a context object to connect is recommended to ensure safe execution.

Comment thread libs/linglong/src/linglong/package_manager/package_task.cpp
@reddevillg

Copy link
Copy Markdown
Collaborator Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the permission control mechanism of the package manager by delegating authorization checks to Polkit instead of using custom DBus permissions. It introduces a new PolkitAuthority helper class to perform asynchronous authorization checks, modifies the DBus interface and system policies, and updates task interaction logic to handle caller disconnections. The review feedback highlights critical issues in PackageTask::waitConfirm regarding incorrect service names for local peer signals and thread-safety violations when exiting the event loop from a different thread, as well as a recommendation to avoid declaring Qt metatypes for structs defined in anonymous namespaces.

Comment thread libs/linglong/src/linglong/package_manager/package_task.cpp Outdated
Comment thread libs/linglong/src/linglong/package_manager/package_task.cpp
Comment on lines +23 to +34
struct PolkitSubject
{
QString kind;
QVariantMap details;
};

struct PolkitResult
{
bool isAuthorized = false;
bool isChallenge = false;
QMap<QString, QString> details;
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Declaring metatypes for types defined in an anonymous namespace is generally discouraged in Qt because anonymous namespace types have internal linkage and their names are not globally unique or stable across translation units. This can lead to duplicate registration or compilation issues.

Consider defining PolkitSubject and PolkitResult inside the linglong::service namespace (or a private sub-namespace like linglong::service::detail) and declaring their metatypes there.

Comment thread libs/linglong/src/linglong/package_manager/package_task.cpp Outdated
Comment thread libs/linglong/src/linglong/package_manager/package_task.cpp Outdated
msg.service().toStdString(),
[this, parameters, msg, conn](utils::error::Result<void> authResult) {
if (!authResult) {
conn.send(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

connection的send返回值都没检查,false代表发送失败,下同

Comment thread libs/linglong/src/linglong/package_manager/package_task.h Outdated
Comment thread libs/linglong/src/linglong/package_manager/package_task.h
@reddevillg reddevillg marked this pull request as ready for review May 26, 2026 09:58
@18202781743 18202781743 requested a review from Copilot May 26, 2026 13:50

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds polkit-based authorization checks to the PackageManager D-Bus service for privileged operations and refactors the user-interaction flow so that interaction requests/replies are handled by per-task (Task1) objects rather than the PackageManager itself.

Changes:

  • Introduce PolkitAuthority and gate Install/InstallFromFile/Uninstall/Update/Prune/SetConfiguration behind polkit authorization.
  • Move interaction APIs/signals from PackageManager1 to Task1 (task emits RequestInteraction, client replies via Task1.ReplyInteraction).
  • Relax D-Bus daemon policy to allow access to the service, relying on service-side polkit checks for permission enforcement.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
misc/share/polkit-1/actions/org.deepin.linglong.PackageManager1.policy Defines new per-operation polkit action IDs and defaults.
misc/share/dbus-1/system.d/org.deepin.linglong.PackageManager1.conf Opens D-Bus access broadly, expecting polkit enforcement in-service.
libs/utils/src/linglong/utils/error/error.h Adds ErrorCode::PermissionDenied for authorization failures.
libs/linglong/src/linglong/package_manager/uab_installation.cpp Switches upgrade confirmation from PM-level interaction to task-level waitConfirm().
libs/linglong/src/linglong/package_manager/ref_installation.cpp Same interaction refactor as UAB path.
libs/linglong/src/linglong/package_manager/polkit_authority.h Declares async polkit authorization helper.
libs/linglong/src/linglong/package_manager/polkit_authority.cpp Implements polkit CheckAuthorization call over system bus.
libs/linglong/src/linglong/package_manager/package_task.h Adds caller context + interaction request/reply API on tasks.
libs/linglong/src/linglong/package_manager/package_task.cpp Implements interaction waiting, timeout handling, and caller-disconnect handling.
libs/linglong/src/linglong/package_manager/package_manager.h Refactors privileged methods, adds SetConfiguration, and threads caller context through task creation.
libs/linglong/src/linglong/package_manager/package_manager.cpp Adds polkit gating and async reply handling around privileged operations.
libs/linglong/src/linglong/cli/cli.h Updates CLI interfaces to match interaction refactor.
libs/linglong/src/linglong/cli/cli.cpp Connects to Task1 interaction signal, replies via Task1 method, adjusts error handling and timeouts.
libs/linglong/CMakeLists.txt Adds new polkit authority sources to build.
apps/ll-package-manager/src/main.cpp Passes peer-mode flag into PM initialization.
api/dbus/org.deepin.linglong.Task1.xml Adds ReplyInteraction method + RequestInteraction signal to Task1 interface.
api/dbus/org.deepin.linglong.PackageManager1.xml Removes PM-level interaction API, adds SetConfiguration, updates Configuration property access.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

#include <optional>
#include <thread>

using namespace std::chrono_literals;
return LINGLONG_ERR("failed to initialize package manager signals", ret.error());
}

this->pkgMan->setTimeout(INT_MAX);
Comment on lines +855 to +879
if (!m_peerMode) {
auto msg = message();
auto conn = connection();
setDelayedReply(true);

CallerContext ctx{ conn, msg };

checkPolkitAuthorizationAsync(
"org.deepin.linglong.PackageManager1.install",
msg.service().toStdString(),
[this, parameters, ctx](utils::error::Result<void> authResult) {
if (!authResult) {
ctx.connection.send(ctx.message.createErrorReply(
QDBusError::AccessDenied,
QString::fromStdString(authResult.error().message())));
return;
}

auto result = installImpl(parameters, ctx);
ctx.connection.send(ctx.message.createReply(result));
});
return {};
}

return installImpl(parameters, CallerContext{ connection(), message() });
Comment on lines +867 to +869
ctx.connection.send(ctx.message.createErrorReply(
QDBusError::AccessDenied,
QString::fromStdString(authResult.error().message())));
Comment on lines +2444 to +2446
case utils::error::ErrorCode::PermissionDenied:
this->printer.printMessage(_("Permission denied, authentication is required"));
break;
Comment on lines +52 to +70
<action id="org.deepin.linglong.PackageManager1.prune">
<description>Prune package cache</description>
<message>Authentication is required to prune package cache</message>
<defaults>
<allow_any>auth_admin</allow_any>
<allow_inactive>auth_admin</allow_inactive>
<allow_active>auth_admin</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.owner">unix-user:@LINGLONG_USERNAME@</annotate>
</action>

<action id="org.deepin.linglong.PackageManager1.set-configuration">
<description>Modify package manager configuration</description>
<message>Authentication is required to modify package manager configuration</message>
<defaults>
<allow_any>auth_admin</allow_any>
<allow_inactive>auth_admin</allow_inactive>
<allow_active>auth_admin</allow_active>
</defaults>
Comment on lines +109 to +116
bool PackageTask::waitConfirm(
api::types::v1::InteractionMessageType msgType,
const api::types::v1::PackageManager1RequestInteractionAdditionalMessage &additionalMessage,
std::chrono::milliseconds timeout) noexcept
{
Q_EMIT RequestInteraction(static_cast<int>(msgType),
common::serialize::toQVariantMap(additionalMessage));
QEventLoop loop;
@reddevillg reddevillg requested a review from ComixHe May 27, 2026 06:53
Add PolkitAuthority helper class to check authorization before Install,
InstallFromFile, Uninstall, Update, Prune and SetConfiguration
operations.

Move interaction interface from PM to Task and add timeout.

Signed-off-by: reddevillg <reddevillg@gmail.com>
@deepin-ci-robot

Copy link
Copy Markdown
Collaborator

deepin pr auto review

本次代码审查主要针对将权限校验从前端CLI转移到后端Daemon、引入Polkit异步鉴权机制、以及将交互信号从PackageManager下沉到Task对象的重大重构。

整体来看,这次重构的方向非常正确,将鉴权逻辑下沉到服务端大大提高了安全性,避免了客户端绕过的风险,同时任务级别的交互信号设计也更加合理。但代码中存在一些严重的并发逻辑隐患、资源泄漏风险以及架构设计问题,需要重点关注和修改。

以下是详细的审查意见:

1. 严重逻辑/并发问题

1.1 PackageTask::waitConfirm 中的竞态条件与信号丢失

  • 文件: package_task.cpp
  • 问题: 在 waitConfirm 方法中,先 Q_EMIT RequestInteraction(...),然后才创建 QEventLoopconnect ReplyReceived 信号。如果客户端响应极快,信号会在 connect 之前发出,导致回复丢失,任务永久阻塞在 loop.exec()
  • 改进意见: 必须先建立信号连接,然后再发射请求信号。
    // 先连接信号
    auto replyConn = connect(this, &PackageTask::ReplyReceived, &loop, [this, &loop](const QVariantMap &reply) {
        // ...
    });
    // 再发射信号
    Q_EMIT RequestInteraction(static_cast<int>(msgType), common::serialize::toQVariantMap(additionalMessage));

1.2 PackageTask::waitConfirm 中的 QDBusServiceWatcher 生命周期与悬空引用

  • 文件: package_task.cpp
  • 问题: lambda 中捕获了 this 并直接操作 loop。如果 PackageTask 对象在 QEventLoop 运行期间被销毁,会导致严重的悬空引用和崩溃。另外,QDBusServiceWatcher 绑定到了 loop 的生命周期,但 watcher 本身是 new 出来的,如果 loop.quit() 时没有正确清理,会内存泄漏。
  • 改进意见:
    1. 确保调用 waitConfirm 的上下文能保证 PackageTask 在事件循环期间不被销毁。
    2. watcherdeleteLater 绑定到循环退出。

1.3 PackageManager 中异步回调捕获 this 导致的潜在崩溃

  • 文件: package_manager.cpp
  • 问题: 在 SetConfigurationInstallFromFile 等方法中,checkPolkitAuthorizationAsync 的回调 lambda 捕获了 this
    [this, parameters, msg, conn](utils::error::Result<void> authResult) {
        // ...
        auto result = setConfigurationImpl(parameters);
        // ...
    }
    如果在 Polkit 弹窗等待期间,PackageManager 服务被关闭或对象被销毁,回调触发时访问 this 将导致段错误。
  • 改进意见: 使用 QPointer<PackageManager> 进行捕获,并在回调入口检查对象是否依然存在:
    QPointer<PackageManager> guard(this);
    checkPolkitAuthorizationAsync(..., [guard, parameters, msg, conn](...) {
        if (!guard) return; // 对象已销毁,直接返回
        // 继续正常逻辑...
    });

2. 资源泄漏

2.1 QDBusUnixFileDescriptor 的拷贝与文件描述符泄漏

  • 文件: package_manager.cpp
  • 问题: 在 InstallFromFile 中:
    [this, fdDup = fd, fileType, options, ctx](utils::error::Result<void> authResult) {
        auto result = installFromFileImpl(fdDup, fileType, options, ctx);
    QDBusUnixFileDescriptor 是隐式共享的,拷贝 fdDup 会增加底层文件描述符的引用计数。当 fdDup 析构时,底层的 UNIX FD 会被关闭。但是,如果 installFromFileImpl 内部或后续逻辑通过 fdDup.fileDescriptor() 再次获取 FD 并传递给底层(如 LayerFile::New),且底层期望 FD 在跨线程/异步期间保持打开,当前逻辑可能会因为生命周期不可控导致 FD 提前关闭。
  • 改进意见: 明确 FD 的所有权。如果异步任务需要持有 FD,必须确保 QDBusUnixFileDescriptor 对象在异步任务结束前一直存活(例如通过智能指针或 QObject 父子关系管理)。

3. 架构与代码质量

3.1 Polkit 鉴权逻辑的代码冗余

  • 文件: package_manager.cpp
  • 问题: Install, Uninstall, Update, SetConfiguration 等方法中,处理 m_peerModecheckPolkitAuthorizationAsync 的代码结构几乎完全一致,存在大量的复制粘贴。
  • 改进意见: 提取一个通用的模板函数或包装器来处理鉴权与异步转发,减少冗余代码。例如:
    template <typename Func>
    void PackageManager::authorizeAndExecute(const QString &actionId, Func &&implFunc) {
        if (!daemonModeInitialized) { /* ... */ }
        if (!m_peerMode) {
            auto msg = message(); auto conn = connection();
            setDelayedReply(true);
            CallerContext ctx{conn, msg};
            checkPolkitAuthorizationAsync(actionId, msg.service().toStdString(),
                [this, ctx, impl = std::forward<Func>(implFunc)](auto authResult) {
                    if (!authResult) { /* send error */ return; }
                    auto result = impl();
                    ctx.connection.send(ctx.message.createReply(result));
                });
            return;
        }
        auto result = implFunc();
        // 处理同步返回
    }

3.2 CallerContext 的拷贝语义与 QDBusMessage

  • 文件: package_task.h
  • 问题: CallerContext 包含 QDBusMessage,而 QDBusMessage 的拷贝开销较大,且在某些 Qt 版本中可能不是完全预期的深拷贝行为。
  • 改进意见: 将 CallerContext 中的 message 改为 QDBusMessage 的共享指针,或者使用 std::shared_ptr<QDBusMessage>,避免在 lambda 和队列中频繁拷贝。

3.3 QEventLoop 嵌套调用的风险

  • 文件: package_task.cpp
  • 问题: waitConfirm 中使用了 QEventLoop::exec() 阻塞当前线程等待用户交互。如果这是在主事件循环或者 DBus 线程中运行,可能会导致复杂的重入问题(如客户端在未回复前又发来 Cancel 请求)。
  • 改进意见: 虽然在任务队列的独立线程中可能可以接受,但必须确保所有相关的信号(如 Cancel)也能正确打断这个 QEventLoop,否则任务无法被取消。当前代码中 Cancel 只是设置了 g_cancellable_cancel,并没有退出 waitConfirmQEventLoop,这会导致取消操作延迟甚至失效。
    修复: 在 Cancel 方法中,也需要检查并退出当前可能存在的等待循环。

4. 安全性

4.1 DBus 配置过度放宽

  • 文件: org.deepin.linglong.PackageManager1.conf
  • 问题: 修改后的配置将默认策略改为了完全开放:
    <policy context="default">
      <allow send_destination="org.deepin.linglong.PackageManager1"/>
      <allow receive_sender="org.deepin.linglong.PackageManager1"/>
    </policy>
    虽然鉴权逻辑已经交由 Polkit 在服务端处理,但 DBus 层面的完全开放意味着任何用户都可以触发服务端的 Polkit 鉴权流程,这会被恶意程序利用,疯狂弹出鉴权弹窗进行干扰(类似弹窗炸弹)。
  • 改进意见: 保留 DBus 层面的基本限制,对于不需要特权的只读操作(如 SearchGet)可以开放,但对于会触发 Polkit 的写操作,在 DBus 配置中依然应该限制为仅活动用户可调用,而不是完全 default 放开。

4.2 Polkit 策略的 keep 缓存时间

  • 文件: org.deepin.linglong.PackageManager1.policy
  • 问题: 对于 installupdate 等操作使用了 auth_admin_keep,这是合理的。但对于 set-configuration 这种修改全局配置的高危操作,使用 auth_admin(每次都需要认证)比 auth_admin_keep 更安全。当前代码中 set-configuration 已经是 auth_admin,这点做得很好,请保持。

5. 性能

5.1 PolkitSubject 的频繁注册

  • 文件: polkit_authority.cpp
  • 问题: register_type() 使用了 std::call_once 保证只注册一次,这是好的。但 checkAuthorizationAsync 每次调用都会构造 QDBusMessage 并进行一次异步 DBus 调用。
  • 改进意见: 逻辑上没有明显性能瓶颈,Polkit 调用本身就是较重的外部进程交互,当前的异步设计是合理的,无需特别修改。

总结

本次提交的核心风险在于异步回调中对象生命周期的管理以及事件循环阻塞期间的信号时序与取消逻辑。强烈建议:

  1. 修复 waitConfirm 中信号连接与发射的时序问题。
  2. 为所有异步 Polkit 回调增加 QPointer 生命周期守卫。
  3. 完善 CancelwaitConfirm 阻塞状态的打断机制。
  4. 收紧 DBus 默认策略,防止 Polkit 弹窗轰炸。

@deepin-ci-robot

Copy link
Copy Markdown
Collaborator

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: ComixHe, reddevillg

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@reddevillg reddevillg merged commit 9937c54 into OpenAtom-Linyaps:master May 27, 2026
16 of 17 checks passed
@reddevillg reddevillg deleted the refactor_polkit branch May 27, 2026 09:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants