权限系统
权限系统
相关源文件
本章引用的主要源码文件:
src-ui/src/app/components/admin/settings/settings.component.htmlsrc-ui/src/app/components/admin/settings/settings.component.spec.tssrc-ui/src/app/components/admin/settings/settings.component.tssrc-ui/src/app/components/common/permissions-select/permissions-select.component.spec.tssrc-ui/src/app/data/ui-settings.tssrc-ui/src/app/services/permissions.service.spec.tssrc-ui/src/app/services/permissions.service.tssrc/documents/filters.pysrc/documents/management/commands/document_fuzzy_match.pysrc/documents/permissions.pysrc/documents/serialisers.pysrc/documents/tests/test_api_custom_fields.pysrc/documents/tests/test_api_documents.pysrc/documents/tests/test_api_filter_by_custom_fields.pysrc/documents/tests/test_api_uisettings.pysrc/documents/tests/test_management_fuzzy.pysrc/documents/views.pysrc/paperless/auth.pysrc/paperless/migrations/0009_alter_applicationconfiguration_options.pysrc/paperless/urls.py
Paperless-ngx 的权限系统控制对文档和其他对象的访问。它结合了基于所有者的访问控制、全局 Django 权限以及通过 django-guardian 管理的对象级权限。
概述
Paperless-ngx 实现了一个多层权限系统,与 REST API 和全文检索引擎无缝集成。
来源:src/documents/permissions.py:28-52, src/documents/filters.py:137-138, src-ui/src/app/services/permissions.service.ts:13-15
后端实现
对象所有权与全局权限
Paperless-ngx 中的大多数模型都继承自 ModelWithOwner(例如 Document、Tag、Correspondent),该基类提供了 owner 字段。
- 超级用户:绕过所有权限检查,可以访问所有对象
src/documents/permissions.py:179-180。 - 所有权:
PaperlessObjectPermissions类(扩展自DjangoObjectPermissions)允许在request.user == obj.owner时进行访问src/documents/permissions.py:44-51。 - 员工用户:某些视图(如系统监控)要求用户具有
is_staff属性或特定的全局权限,例如paperless.view_system_monitoringsrc/documents/permissions.py:54-56,src/documents/permissions.py:68-76。
对象级权限(Guardian)
Paperless-ngx 使用 django-guardian 向特定用户或用户组授予对单个对象的访问权限。
view_<model>:允许查看对象。change_<model>:允许编辑对象。delete_<model>:允许删除对象。
过滤与混入类
为确保用户只能看到其有权查看的内容,Paperless-ngx 在其 ViewSet 中使用了自定义过滤器和混入类:
| 组件 | 作用 | 文件引用 |
|---|---|---|
ObjectOwnedOrGrantedPermissionsFilter | 过滤查询集,仅包含用户拥有或通过 Guardian 授予权限的对象。 | src/documents/filters.py:137-138 |
PaperlessObjectPermissions | REST 框架权限类,检查所有权或对象级权限。 | src/documents/permissions.py:28-32 |
SetPermissionsMixin | 通过 API 更新权限时,校验用户/用户组 ID。 | src/documents/serialisers.py:170-171 |
BulkPermissionMixin | 处理同时对多个对象设置权限。 | src/documents/views.py:171-171 |
来源:src/documents/permissions.py:28-52, src/documents/filters.py:137-138, src/documents/serialisers.py:170-186
API 数据流
当客户端请求或更新对象时,OwnedObjectSerializer 负责管理权限元数据。
来源:src/documents/serialisers.py:232-366, src/documents/permissions.py:93-164, src/documents/filters.py:137-138
前端:PermissionsService
Angular 前端使用 PermissionsService 来条件性地显示 UI 元素并执行客户端限制。
主要功能
- 全局检查:
isAdmin()检查用户是否为超级用户src-ui/src/app/services/permissions.service.ts:51-53。 - 操作检查:
currentUserCan(type, action)检查用户是否具有全局权限(例如PermissionType.Document+PermissionAction.Add)src-ui/src/app/services/permissions.service.ts:55-61。 - 对象级检查:
currentUserHasObjectPermissions(action, object)检查用户是否为所有者,或者是否在对象的permissions数组中具有所需权限src-ui/src/app/services/permissions.service.ts:74-90。
UI 集成
IfPermissionsDirective 和 IfOwnerDirective 在模板中用于隐藏按钮或字段:
<!-- 来自设置组件的示例 -->
@if (canViewSystemStatus) {
<button ...>系统状态</button>
}
@if (permissionsService.isAdmin()) {
<a href="admin/">打开 Django 管理后台</a>
}
来源:src-ui/src/app/services/permissions.service.ts:13-100, src-ui/src/app/components/admin/settings/settings.component.html:10-35
搜索中的权限逻辑
搜索结果在返回给用户之前,会在数据库层面进行限制。_permitted_document_ids(user) 函数会生成一个子查询,包含用户有权查看的文档 ID。
- 超级用户:获取所有未删除的文档 ID
src/documents/permissions.py:179-180。 - 普通用户:结果包含
owner == user的文档,或者UserObjectPermission或GroupObjectPermission中存在view_document条目的文档src/documents/permissions.py:182-209。
来源:src/documents/permissions.py:166-210, src/documents/filters.py:242-259