Skip to content

refactor: remove dconfig and optimize permission management#3048

Open
mhduiy wants to merge 1 commit intolinuxdeepin:masterfrom
mhduiy:privacy
Open

refactor: remove dconfig and optimize permission management#3048
mhduiy wants to merge 1 commit intolinuxdeepin:masterfrom
mhduiy:privacy

Conversation

@mhduiy
Copy link
Contributor

@mhduiy mhduiy commented Mar 5, 2026

  1. Removed org.deepin.dde.control-center.privacy.json dconfig file as permission blacklist caching is no longer needed
  2. Added desktopPath property to ApplicationItem to track desktop file source path
  3. Added new roles to dde-apps.h for categories and desktop source path
  4. Moved getExecutable() and getPackageNameByPath() functions from PrivacySecurityDataProxy to PrivacySecurityWorker
  5. Changed permission blacklist storage from app paths to package names for better consistency
  6. Simplified permission checking logic by using package-based blacklist instead of file-based
  7. Updated copyright years from 2025 to 2025-2026 across multiple files

The changes optimize permission management by:

  • Removing dependency on dconfig for caching, simplifying configuration
  • Using package names instead of file paths for blacklist, making permission management more reliable
  • Centralizing package and executable path resolution logic in PrivacySecurityWorker
  • Adding desktop path tracking to better handle application identification

refactor: 移除 dconfig 并优化权限管理

  1. 移除 org.deepin.dde.control-center.privacy.json dconfig 文件,不再需 要权限黑名单缓存
  2. 为 ApplicationItem 添加 desktopPath 属性以跟踪桌面文件源路径
  3. 在 dde-apps.h 中添加新的角色用于分类和桌面源路径
  4. 将 getExecutable() 和 getPackageNameByPath() 函数从 PrivacySecurityDataProxy 移动到 PrivacySecurityWorker
  5. 将权限黑名单存储从应用路径改为包名,提高一致性
  6. 通过使用基于包的黑名单而非基于文件的黑名单简化权限检查逻辑
  7. 更新多个文件的版权年份从 2025 到 2025-2026

这些更改通过以下方式优化权限管理:

  • 移除对 dconfig 缓存的依赖,简化配置
  • 使用包名而非文件路径作为黑名单,使权限管理更可靠
  • 在 PrivacySecurityWorker 中集中处理包和可执行路径解析逻辑
  • 添加桌面路径跟踪以更好地处理应用识别

PMS: BUG-351621

Summary by Sourcery

Refine privacy plugin permission handling by moving package lookup logic into the worker, switching permission blacklisting to be package-based instead of path-based, and wiring additional app metadata such as desktop file paths from the app model into application items.

New Features:

  • Expose application desktop file source path on ApplicationItem and propagate it from the app model via new roles.
  • Provide helper APIs in PrivacySecurityWorker to resolve package names from paths and list executables for a package.

Bug Fixes:

  • Align permission enablement with package-based blacklists to avoid mismatches caused by file-path-based checks.

Enhancements:

  • Replace file-path-based permission blacklist management with a package-name-based map stored in PrivacySecurityModel.
  • Simplify blacklist propagation by having PrivacySecurityWorker set the full package blacklist map on the model instead of per-file updates.
  • Relocate executable and package resolution logic from PrivacySecurityDataProxy to PrivacySecurityWorker to better match its responsibility.

Build:

  • Remove the org.deepin.dde.control-center.privacy.json dconfig file used for permission blacklist caching.

Chores:

  • Update SPDX copyright years to 2025-2026 across the touched privacy-related source files.

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: mhduiy

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

@sourcery-ai
Copy link

sourcery-ai bot commented Mar 5, 2026

Reviewer's Guide

Refactors the privacy/permissions subsystem to remove dconfig-based blacklist caching and file-path-based blacklists, introduces package-name-based permission management backed by desktop file source paths, and centralizes dpkg querying and executable resolution logic in PrivacySecurityWorker.

Sequence diagram for package-based permission initialization

sequenceDiagram
    participant DdeAppItemModel
    participant PrivacySecurityWorker
    participant ApplicationItem
    participant QtConcurrent
    participant DpkgQuery
    participant PrivacySecurityModel

    PrivacySecurityWorker->>DdeAppItemModel: data(index, DesktopSourcePathRole)
    DdeAppItemModel-->>PrivacySecurityWorker: desktopSourcePath
    PrivacySecurityWorker->>ApplicationItem: onDesktopPathChanged(desktopSourcePath)

    PrivacySecurityWorker->>QtConcurrent: run(updateAppPath with execs, item)
    QtConcurrent->>PrivacySecurityWorker: getAppPath(execs)
    QtConcurrent-->>PrivacySecurityWorker: appPath

    alt item.desktopPath is empty
        QtConcurrent->>PrivacySecurityWorker: getPackageNameByPath(appPath)
    else item.desktopPath is set
        QtConcurrent->>PrivacySecurityWorker: getPackageNameByPath(item.desktopPath)
    end

    PrivacySecurityWorker->>DpkgQuery: dpkg-query -S path
    DpkgQuery-->>PrivacySecurityWorker: packageName

    QtConcurrent-->>PrivacySecurityWorker: invokeMethod(this, path, packageName)
    PrivacySecurityWorker->>ApplicationItem: onAppPathChanged(path)
    PrivacySecurityWorker->>ApplicationItem: onPackageChanged(packageName)
    PrivacySecurityWorker->>PrivacySecurityModel: updatePermission(item)
    PrivacySecurityWorker->>PrivacySecurityModel: emitAppDataChanged(item)
Loading

Class diagram for updated privacy permission management

classDiagram

class ApplicationItem {
    +QString id
    +QString name
    +QString appPath
    +QString package()
    +QString icon() const
    +QString sortField() const
    +QString desktopPath() const
    +bool isPremissionEnabled(int premission) const
    +void setPremissionEnabled(int premission, bool enabled)
    +void onAppPathChanged(QString path)
    +void onPackageChanged(QString package)
    +void onExecsChanged(QMap<QString,QString> execs)
    +void onExecutablePathsChanged(QStringList paths)
    +void onIconChanged(QString icon)
    +bool onPremissionEnabledChanged(int premission, bool enabled)
    +void onDesktopPathChanged(QString desktopPath)
}

class PrivacySecurityModel {
    +QMap<int,int> m_premissionMap
    +QMap<QString,QSet<QString>> m_blacklistByPackage
    +unsigned m_uniqueID
    +bool m_updating
    +void updatePermission()
    +bool updatePermission(ApplicationItem *item)
    +const QString premissiontoPath(int premission) const
    +int pathtoPremission(const QString &path, bool mainPremission) const
    +bool isPremissionEnabled(int premission) const
    +void setBlackListByPackage(QMap<QString,QSet<QString>> blacklistByPackage)
    +unsigned createUniqueID()
    +bool addApplictionItem(ApplicationItem *item)
    +void removeApplictionItem(const QString &id)
}

class PrivacySecurityWorker {
    -PrivacySecurityModel *m_model
    -QAbstractItemModel *m_ddeAmModel
    -PrivacySecurityDataProxy *m_dataProxy
    -QMap<QString,QSet<QString>> m_blacklistByPackage
    +PrivacySecurityWorker(PrivacySecurityModel *appsModel, QObject *parent)
    +void init()
    +void initApp()
    +void updateAllPermission()
    +ApplicationItem *addAppItem(int dataIndex)
    +void updateAppPath(ApplicationItem *item)
    +void setAppPermissionEnableByCheck(bool ok)
    +QStringList getExecutable(const QString &packageName)
    +QString getPackageNameByPath(const QString &path)
}

class PrivacySecurityDataProxy {
    -bool m_serviceExists
    -DConfig *m_dconfig
    +PrivacySecurityDataProxy(QObject *parent)
    +bool existsService() const
    +QMap<QString,QSet<QString>> getCacheBlacklist()
    +void setCacheBlacklist(const QMap<QString,QSet<QString>> &cacheBlacklist)
}

class AppItemModel {
    <<enum Roles>>
    +int IdRole
    +int XCreatedByRole
    +int ExecsRole
    +int CategoriesRole
    +int DesktopSourcePathRole
}

PrivacySecurityWorker --> PrivacySecurityModel : manages
PrivacySecurityWorker --> PrivacySecurityDataProxy : uses
PrivacySecurityModel --> ApplicationItem : owns items
PrivacySecurityWorker --> ApplicationItem : populates and updates
PrivacySecurityWorker --> AppItemModel : reads roles
Loading

File-Level Changes

Change Details Files
Switch permission blacklist from file-path-based to package-name-based and update permission evaluation accordingly.
  • Replace m_blacklist and m_cacheBlacklist maps with m_blacklistByPackage keyed by permission to sets of package names
  • Update PrivacySecurityModel::updatePermission to check membership in m_blacklistByPackage using ApplicationItem::package instead of appPath
  • Remove now-unused blacklist(), onAppPremissionEnabledChanged(), and onCacheBlacklistChanged() methods and related signal/slot wiring
  • Add PrivacySecurityModel::setBlackListByPackage to allow worker to push package-based blacklist and trigger permission recomputation
src/plugin-privacy/operation/privacysecuritymodel.cpp
src/plugin-privacy/operation/privacysecuritymodel.h
Move package/executable resolution from PrivacySecurityDataProxy into PrivacySecurityWorker and adapt call sites to use package-based lookup.
  • Introduce PrivacySecurityWorker::getExecutable(packageName) that reads /var/lib/dpkg/info/[ :arch].list and filters to executable non-library files
  • Introduce PrivacySecurityWorker::getPackageNameByPath(path) using dpkg-query -S and reuse local getDpkgArch helper moved from data proxy
  • Update updateAppPath to derive package name from ApplicationItem::desktopPath when available, falling back to app path, and set both appPath and package on the item before updating permissions
  • Update setAppPermissionEnableByCheck to call getExecutable(item->package()) instead of PrivacySecurityDataProxy::getExecutable and drop package out-parameter logic
  • Have updateAllPermission delegate to m_model->setBlackListByPackage(m_blacklistByPackage) instead of recomputing per-file app sets
src/plugin-privacy/operation/privacysecurityworker.cpp
src/plugin-privacy/operation/privacysecurityworker.h
Remove dconfig-backed permission blacklist caching and associated configuration file.
  • Delete org.deepin.dde.control-center.privacy.json config file from misc/configs
  • Remove PrivacySecurityDataProxy::getCacheBlacklist, blacklist JSON parsing, and dconfig reads
  • Keep setCacheBlacklist but now only used to persist cache; worker/model no longer pull from it on init
  • Drop getExecutable(path, package*) and local getDpkgArch() from PrivacySecurityDataProxy as that logic is moved to the worker
src/plugin-privacy/operation/privacysecuritydataproxy.cpp
src/plugin-privacy/operation/privacysecuritydataproxy.h
misc/configs/org.deepin.dde.control-center.privacy.json
Extend ApplicationItem and dde-apps roles to carry desktop file source path and categories for improved app identification.
  • Add m_desktopPath field, desktopPath() accessor, and onDesktopPathChanged() mutator to ApplicationItem
  • In PrivacySecurityWorker::addAppItem, read DesktopSourcePathRole from the dde-apps model and propagate it via onDesktopPathChanged
  • Define new enum roles CategoriesRole and DesktopSourcePathRole in dde-apps.h for use by the app model
src/plugin-privacy/operation/applicationitem.cpp
src/plugin-privacy/operation/applicationitem.h
src/plugin-privacy/operation/dde-apps.h
src/plugin-privacy/operation/privacysecurityworker.cpp
General maintenance and metadata updates.
  • Update SPDX-FileCopyrightText in touched source files from 2025 to 2025-2026
src/plugin-privacy/operation/privacysecurityworker.cpp
src/plugin-privacy/operation/privacysecuritydataproxy.cpp
src/plugin-privacy/operation/privacysecuritymodel.cpp
src/plugin-privacy/operation/applicationitem.cpp
src/plugin-privacy/operation/privacysecuritymodel.h
src/plugin-privacy/operation/privacysecuritydataproxy.h
src/plugin-privacy/operation/privacysecurityworker.h
src/plugin-privacy/operation/applicationitem.h
src/plugin-privacy/operation/dde-apps.h

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 2 issues, and left some high level feedback:

  • PrivacySecurityDataProxy still declares getCacheBlacklist() in the header but its implementation has been removed from the .cpp, which will cause a linker error; either restore the implementation or drop the declaration (and any remaining uses) completely.
  • In PrivacySecurityWorker::addAppItem the variable name desktopSoucePath is misspelled; consider renaming it to desktopSourcePath for consistency and readability.
  • The helper methods getExecutable() and getPackageNameByPath() in PrivacySecurityWorker are declared as private slots but are only used as internal helpers; making them regular private methods instead of slots would clarify their intent and avoid unnecessary exposure to the signal/slot system.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- PrivacySecurityDataProxy still declares getCacheBlacklist() in the header but its implementation has been removed from the .cpp, which will cause a linker error; either restore the implementation or drop the declaration (and any remaining uses) completely.
- In PrivacySecurityWorker::addAppItem the variable name `desktopSoucePath` is misspelled; consider renaming it to `desktopSourcePath` for consistency and readability.
- The helper methods getExecutable() and getPackageNameByPath() in PrivacySecurityWorker are declared as private slots but are only used as internal helpers; making them regular private methods instead of slots would clarify their intent and avoid unnecessary exposure to the signal/slot system.

## Individual Comments

### Comment 1
<location path="src/plugin-privacy/operation/privacysecurityworker.cpp" line_range="43-52" />
<code_context>
-        QProcess pro;
-        pro.start("/usr/bin/dpkg", QStringList() << "--print-architecture");
-        pro.waitForFinished(2000);
-        if (pro.exitCode() != 0) {
-            qCWarning(DCC_PRIVACY) << "Failed to get dpkg architecture, dpkg error: " << pro.readAllStandardError().simplified() 
-                << ", fallback to QSysInfo architecture:" << arch;
</code_context>
<issue_to_address>
**issue (bug_risk):** qDebug(DCC_PRIVACY) is not a valid Qt logging call and will fail to compile

Use a categorized logging macro here, e.g. `qCWarning(DCC_PRIVACY)` (to match other error paths in this module) or `qCDebug(DCC_PRIVACY)` if you prefer a debug-level message.
</issue_to_address>

### Comment 2
<location path="src/plugin-privacy/operation/privacysecurityworker.h" line_range="56-57" />
<code_context>
     void init();
     void initApp();

+    QStringList getExecutable(const QString &packageName);
+    QString getPackageNameByPath(const QString &path);
+
 private:
</code_context>
<issue_to_address>
**suggestion:** Helper methods are declared as slots even though they are not used as signals/slots

`getExecutable` and `getPackageNameByPath` are currently declared as slots but only used as private helpers and not connected to any signals. This is slightly misleading and adds unnecessary meta-object overhead. Please move them to the `private:` section unless you intend to use them as slots.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

1. Removed org.deepin.dde.control-center.privacy.json dconfig file as
permission blacklist caching is no longer needed
2. Added desktopPath property to ApplicationItem to track desktop file
source path
3. Added new roles to dde-apps.h for categories and desktop source path
4. Moved getExecutable() and getPackageNameByPath() functions from
PrivacySecurityDataProxy to PrivacySecurityWorker
5. Changed permission blacklist storage from app paths to package names
for better consistency
6. Simplified permission checking logic by using package-based blacklist
instead of file-based
7. Updated copyright years from 2025 to 2025-2026 across multiple files

The changes optimize permission management by:
- Removing dependency on dconfig for caching, simplifying configuration
- Using package names instead of file paths for blacklist, making
permission management more reliable
- Centralizing package and executable path resolution logic in
PrivacySecurityWorker
- Adding desktop path tracking to better handle application
identification

refactor: 移除 dconfig 并优化权限管理

1. 移除 org.deepin.dde.control-center.privacy.json dconfig 文件,不再需
要权限黑名单缓存
2. 为 ApplicationItem 添加 desktopPath 属性以跟踪桌面文件源路径
3. 在 dde-apps.h 中添加新的角色用于分类和桌面源路径
4. 将 getExecutable() 和 getPackageNameByPath() 函数从
PrivacySecurityDataProxy 移动到 PrivacySecurityWorker
5. 将权限黑名单存储从应用路径改为包名,提高一致性
6. 通过使用基于包的黑名单而非基于文件的黑名单简化权限检查逻辑
7. 更新多个文件的版权年份从 2025 到 2025-2026

这些更改通过以下方式优化权限管理:
- 移除对 dconfig 缓存的依赖,简化配置
- 使用包名而非文件路径作为黑名单,使权限管理更可靠
- 在 PrivacySecurityWorker 中集中处理包和可执行路径解析逻辑
- 添加桌面路径跟踪以更好地处理应用识别

PMS: BUG-351621
@deepin-ci-robot
Copy link

deepin pr auto review

Git Diff 代码审查报告

总体评估

本次代码变更主要涉及隐私权限模块的重构,从基于文件路径的权限管理转向基于包名的权限管理。主要改动包括删除配置文件、重构数据模型和代理类、添加桌面路径支持等。整体代码质量良好,但存在一些可以改进的地方。

详细审查

1. 语法与逻辑问题

  1. ApplicationItem::desktopPath() 方法

    QString ApplicationItem::desktopPath() const 
    • 尾部有多余空格,建议删除
    • 建议在头文件中添加 Q_PROPERTY 声明,以便在 QML 中使用
  2. getDpkgArch() 函数重复定义

    • 该函数在 privacysecurityworker.cpp 和之前删除的 privacysecuritydataproxy.cpp 中都有定义
    • 建议将其提取到公共工具类中,避免代码重复
  3. 文件操作安全性

    QFile listFile(listFilePath);
    if (!listFile.exists() || !listFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qCWarning(DCC_PRIVACY) << "Failed to open list file:" << listFilePath;
        return {};
    }
    • 存在潜在的 TOCTOU (Time-of-check to time-of-use) 问题:exists() 检查和 open() 操作之间文件可能被删除
    • 建议直接尝试 open() 并检查返回值

2. 代码质量问题

  1. 命名一致性

    • premission 拼写错误,应为 permission
    • premissiontoPath 方法名应改为 permissionToPath (驼峰命名)
    • setBlackListByPackage 应改为 setBlacklistByPackage (Blacklist 是一个词)
  2. 魔法数字

    pro.waitForFinished(2000);
    • 2000 毫秒硬编码,建议定义为常量 DPKG_QUERY_TIMEOUT
  3. 错误处理

    • getPackageNameByPath 方法在失败时返回空字符串,但调用方没有检查返回值
    • 建议添加返回值检查或使用 std::optional<QString> 作为返回类型
  4. 资源管理

    QFile listFile(listFilePath);
    // ...
    listFile.close();
    return files;
    • close() 调用是多余的,析构函数会自动处理

3. 性能问题

  1. 同步进程调用

    QProcess pro;
    pro.start("/usr/bin/dpkg-query", args);
    pro.waitForFinished(2000);
    • 使用 waitForFinished() 会阻塞线程
    • 建议使用异步方式或将调用移到单独线程
  2. 文件读取效率

    while (!stream.atEnd()) {
        QString filePath = stream.readLine().trimmed();
        // ...
    }
    • 逐行读取大文件可能效率不高
    • 建议考虑批量读取或使用更高效的方式

4. 安全问题

  1. 路径注入风险

    • getPackageNameByPath 直接使用用户提供的路径调用 dpkg-query
    • 建议添加路径验证,确保路径合法
  2. 权限管理

    • setCacheBlacklist 方法直接写入配置文件,没有权限检查
    • 建议添加适当的权限验证
  3. 敏感信息处理

    • 日志中可能包含敏感路径信息
    • 建议对敏感信息进行脱敏处理

改进建议

  1. 代码重构

    • 将重复的 getDpkgArch() 函数提取到公共工具类
    • 统一命名规范,修正拼写错误
    • 添加单元测试覆盖核心功能
  2. 性能优化

    • 将阻塞操作移到后台线程
    • 考虑缓存频繁查询的数据
  3. 安全增强

    • 添加输入验证
    • 实现适当的权限检查
    • 脱敏处理日志中的敏感信息
  4. 文档完善

    • 添加类和方法的详细注释
    • 说明权限管理的变更原因和影响

总结

本次代码变更实现了从基于文件路径到基于包名的权限管理转换,整体方向正确。主要需要关注的是代码重复、命名一致性和安全防护等方面的问题。建议在合并前进行适当的重构和测试。

@mhduiy
Copy link
Contributor Author

mhduiy commented Mar 5, 2026

am 的 desktopsourcepath 是被override过的path,不一定是安装包内部的,使用这个来判断包名并不靠谱

@deepin-bot
Copy link

deepin-bot bot commented Mar 5, 2026

TAG Bot

New tag: 6.1.75
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #3051

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.

2 participants