Система разрешений используется для контроля доступа к ресурсам или функциональности в Baserow. Она определяет, кто имеет право выполнять определенные операции или получать доступ к определенным данным.
Система разрешений модульна и позволяет легко добавлять или заменять различные компоненты, отвечающие за авторизацию пользовательских операций. Это обеспечивает гибкость и модульность в контроле доступа к ресурсам или функциональности в Baserow.
Это позволяет легко реализовывать и заменять различные стратегии авторизации по мере необходимости без значительных изменений в общем коде.
Прежде чем продолжать, нам нужно договориться о определении некоторых терминов:
Объект: представляет собой элемент данных в Baserow. Один из Field, Row, Table, Database, Workspace, User, Team, Role, Webhook, …
Иерархические объекты: в Baserow Объекты связаны друг с другом, и между двумя Объектами может быть зависимость родитель-потомок. Можно создать полное иерархическое дерево со всеми объектами Baserow. Например, Объект Table
является потомком Объекта Database
.
Актор: общий термин, объединяющий все, что может выполнять Операции над Объектом в Baserow. Может быть User
, но также и Personal API Token
или AnonymousUser
…
Операция: действие, которое Актор выполняет над Объектом. Некоторые примеры:
database.list_tables
: операция для получения списка Tables
, связанных с Database
.database_table.create_row
: действие для создания Row
в Table
.database_table.update
: действие для обновления Объекта Table
.Контекст: Объект, на котором применяется Операция. Например:
database.list_tables
контекстный объект — это Database
, для которого мы хотим получить список Table
.database_table.create_row
контекстный объект — это Table
, для которой мы хотим создать Row
.database_table.update
контекстный объект — это также Table
, которую мы хотим обновить.Запрос разрешения: Запрос разрешения представляется тройкой, состоящей из Актора, Операции и Контекста, которая используется для определения, предоставляется ли доступ к конкретному ресурсу или функциональности системой разрешений. Контекст может быть опущен, если Операция не требует его.
Система разрешений: весь механизм в Baserow, который решает, разрешен ли Запрос разрешения или нет. Система разрешений полагается на Менеджеры разрешений для принятия решения по конкретному Запросу разрешения в определенном Рабочем пространстве.
Менеджер разрешений: Менеджер разрешений — это модульная часть Системы разрешений, которая может решать, разрешен ли Запрос разрешения или нет, при выполнении определенных критериев. Каждый Менеджер разрешений отвечает за принятие решения в определенных ситуациях. Например, StaffOnlyPermissionManager
может решить запретить Операцию, если данный Актор не является частью персонала.
Рабочее пространство: Операция может выполняться в конкретном Рабочем пространстве (ранее называлось Group).
Субъект: включает всех Акторов, а также группы Акторов, такие как Teams
.
Персональный API токен: токен аутентификации, который пользователи могут создать в своих настройках в Baserow. Он принадлежит User
, для Рабочего пространства, позволяя доступ к некоторым из наших API-эндпоинтов.
Для каждой Операции, которую Актор хочет выполнить на Контексте, система разрешений проверяет Запрос разрешения. Внутри системы каждый Менеджер разрешений проверяет Запрос разрешения по одному и тому же порядку. Каждый Менеджер разрешений может:
Если ни один из менеджеров разрешений не разрешил или не запретил запрос, то по умолчанию доступ запрещен.
Пример:
Table
в Database
своего Workspace
, проверяется следующее разрешение: (user, "database.create_table", database)
системой разрешений.CorePermissionManager
, который не может принять решение, так как это не ядро операции. Затем он передается StaffOnlyPermissionManager
, который также не может принять решение, так как это не операция только для персонала.BasicPermissionManager
, который позволит запрос разрешения, так как это не операция только для администраторов, поэтому пользователь может выполнить его.Большая часть системы разрешений управляется бэкендом. Основные компоненты системы разрешений следующие:
OperationType
: для каждой Операции, которую вы хотите проверить, вам нужен OperationType
.PermissionManagerType
: Менеджеры разрешений отвечают за то, чтобы позволить или запретить запросы разрешений.SubjectType
: каждый Актор, который вы хотите использовать в системе разрешений, должен принадлежать к SubjectType
.ObjectScopeType
: каждый контекстный объект должен быть частью иерархии объектов Baserow. На данный момент это реализовано путем наличия связанного ObjectScopeType
для каждого типа объекта.Все они являются объектами, которые можно зарегистрировать в соответствующем реестре для расширения основных функций системы разрешений Baserow.
Когда вы хотите проверить разрешение на бэкенде, вам нужно использовать метод CoreHandler.check_permission
.
CoreHandler().check_permission(
# Актор может быть пользователем, который выполнил запрос: actor = request.user.
actor,
# CreateRowDatabaseTable — это класс `OperationType`, а `.type` — его имя.
CreateRowDatabaseTable.type,
context=table,
workspace=workspace
)
Если запрос разрешения разрешен, этот метод вернет True
. В противном случае он вызовет исключение PermissionException
.
Рабочее пространство (ранее известное как группа) является необязательным параметром, если операция является ядерной операцией и не относится к какому-либо конкретному рабочему пространству.
Другой распространенный случай использования, связанный с разрешениями, — это фильтрация Django Queryset на основе прав пользователя. Вы можете достичь фильтрации Queryset с помощью этого метода.
CoreHandler().filter_queryset(
# Актор может быть пользователем, который выполнил запрос: actor = request.user.
actor,
# ListTablesDatabaseTableOperationType — это класс `OperationType`, а `.type` — его имя.
ListTablesDatabaseTableOperationType.type,
queryset,
workspace=workspace
)
Здесь контекст — это база данных, так как мы выводим таблицы этой базы данных, но Queryset — это Queryset таблиц. Это согласуется с свойством object_scope
класса ListTablesDatabaseTableOperationType
, которое равно TableObjectScope
. Цель свойства object_scope
заключается в том, чтобы помочь определить, какие объекты являются целью операции.
Для каждой операции, которую вы хотите проверить, должен быть зарегистрирован экземпляр OperationType
. Его можно объявить следующим образом:
from baserow.core.registries import OperationType
class ListTablesDatabaseTableOperationType(OperationType):
type = "database.list_tables" # Тип
context_scope_name = "database" # Имя типа контекста, необходимого для проверки прав
object_scope_name = "database_table" # Имя типа объектов, обрабатываемых операцией
Для большинства операций context_scope_name
и object_scope_name
совпадают, поэтому последнее можно опустить. Однако для всех операций "list" object_scope_name
обычно является одним из потомков контекстного объекта в иерархии объектов. Когда вы хотите вывести все Tables
базы данных Database
, контекст — это база данных Database
, а объекты — это таблицы Tables
. Когда вы выводите все базы данных приложения Application
, контекст — это приложение Application
, а объекты — связанные базы данных.
Этот класс должен быть зарегистрирован в реестре operation_type_registry
, чтобы его можно было использовать.
from baserow.core.registries import operation_type_registry
operation_type_registry.register(ListTablesDatabaseTableOperationType())
Для каждой зарегистрированной операции создается экземпляр Operation
, который сохраняется в базе данных. Вы можете использовать их позже в коде вашего менеджера разрешений при необходимости.
Менеджер разрешений отвечает за то, чтобы решать, разрешен ли запрос разрешения для определенной области приложения. Для обеспечения правильного разделения ответственности хороший менеджер разрешений должен обрабатывать только один случай проверки прав. Менеджеры разрешений затем накладываются друг на друга для создания сложного и мощного алгоритма проверки прав. Вы можете думать о них как о Django middleware, но вместо этого для запроса разрешения.
Для создания нового менеджера разрешений вам нужно создать новый класс PermissionManagerType
и реализовать необходимые методы.
from baserow.core.registries import PermissionManagerType
class OwnedTablePermissionManagerType(PermissionManagerType):
type = "owned_table"
def check_multiple_permissions(self, check, workspace=None, include_trash=False):
...
def get_permissions_object(self, actor, workspace=None):
...
def filter_queryset(self, actor, operation_name, queryset, workspace=None):
...
Краткий обзор этих методов:
.check_multiple_permissions
— это метод проверки прав сам по себе. Он принимает несколько проверок сразу для лучшей производительности. Для каждой проверки результат должен содержать значение True
, если менеджер прав может принять запрос на право доступа, или экземпляр PermissionException
, если нет или он вообще не должен включать эту проверку.get_permissions_object
должен возвращать любое значение, которое будет полезно фронтенд-менеджеру прав для проверки фронтенд-права доступа. Данные должны быть достаточными для того, чтобы фронтенд мог принять решение без необходимости запрашивать дополнительные данные с бэкенда.filter_queryset
используется для фильтрации Queryset на основе прав актора на объекты, возвращаемые Queryset. Метод должен исключать те же объекты, которые были бы исключены методом .check_permission
, если бы он был вызван для каждого объекта Queryset.Вы можете прочитать связанные строки документации для получения более подробной информации о этих методах.
Затем вы можете зарегистрировать его в реестре permission_manager_type_registry
.
from baserow.core.registries import permission_manager_type_registry
permission_manager_type_registry.register(OwnedTablePermissionManagerType())
Вы должны добавить ваш менеджер прав в список активных менеджеров прав в настройках Django:
PERMISSION_MANAGERS = [
'core',
'staff_only',
...
'owned_table', # <- здесь
...
'basic'
]
Позиция менеджера прав в списке зависит от его приоритета над другими менеджерами прав. В нашем случае мы хотим, чтобы менеджер прав ответил до того, как базовый менеджер прав откажется от него.
Теперь вы можете проверить право доступа, обрабатываемое вашим менеджером прав 🎯.
Помните, что вам вероятно потребуется фронтенд-менеджер прав для каждого бэкенд-менеджера прав. См. раздел фронтенд для получения дополнительной информации.
На фронтенде вы можете проверить право доступа с помощью метода $hasPermission
, доступного на экземпляре Vue:
// Внутри компонента Vue
// this.$hasPermission(<operationName>, <contextObject>, <currentWorkspaceId>)
this.$hasPermission("database.create_table", database, workspace.id);
Этот вызов вернет true
, если операция допускается, иначе — false
.
Фронтенд права доступа рассчитываются с помощью объекта прав доступа, отправляемого бэкендом при входе пользователя в систему для каждого рабочего пространства, к которому у пользователя есть доступ. Проверьте метод .get_permissions_object
каждого бэкенд-менеджера прав.
Объект прав доступа выглядит следующим образом:
[
{
"name": "core",
"permissions": [
"list_workspaces"
]
},
{
"name": "staff",
"permissions": {
"staff_only_operations": [
"settings.update"
],
"is_staff": true
}
},
{
"name": "basic",
"permissions": {
"admin_only_operations": [
"workspace.list_invitations",
"...",
"workspace.delete"
],
"is_admin": true
}
}
]
Каждый элемент списка был сгенерирован менеджером прав на бэкенде. Свойство name
— это .type
самого менеджера прав, а свойство permissions
может содержать любое значение, которое помогает фронтенду решить, можно ли предоставить право доступа. Для каждого бэкенд-менеджера прав должен быть зарегистрирован фронтенд-менеджер прав для обработки его значения.
Для проверки прав доступа плагин фронтенд $hasPermission
спрашивает у каждого менеджера прав по порядку списка (в порядке списка), предоставлен ли право доступа или нет на основе данных из свойства permissions
.
Например, метод
BasicPermissionManagerType.hasPermission(permissions, operation, context, workspaceId)
будет вызван с следующим объектом:
{
"admin_only_operations": [
"workspace.list_invitations",
"...",
"workspace_user.delete"
],
"is_admin": true
}
См. следующий раздел для получения информации о том, как создать фронтенд-менеджер прав.
Для каждого бэкенд-менеджера прав вам вероятно потребуется фронтенд-менеджер прав (некоторые менеджеры прав не требуют этого).
Вы можете создать фронтенд-менеджер прав следующим образом:
import { PermissionManagerType } from '@baserow/modules/core/permissionManagerTypes'
export class OwnedTablePermissionManagerType extends PermissionManagerType {
static getType() {
return 'owned_table'
}
hasPermission(permissions, operation, context) {
// ...
}
}
Проверьте документацию методов класса PermissionManagerType
, чтобы понять, как реализовать метод hasPermission
для вашего менеджера прав.
Затем вам нужно зарегистрировать его во время инициализации плагина Vue в файле фронтенда plugin.js
вашего проекта.
app.$registry.register('permissionManager', new OwnedTablePermissionManagerType(context))
И вот оно что — у вас есть полностью функциональный фронтенд-менеджер прав.
Если вы хотите создать новый способ проверки прав доступа, вам нужно:
Система прав доступа была спроектирована с учетом следующих ограничений:
.has_user
)Это может объяснить некоторые из принятых решений.
Более технически:
Database
) не является рабочее пространство (Workspace
), как можно было бы подумать сначала, а более общий тип — приложение (Application
). Это решает множество проблем (хотя и создает некоторые при недостаточном внимании).User
) базовый менеджер прав имеет две роли: ADMIN
и MEMBER
, что совместимо с предыдущей системой прав доступа. Имя роли хранится в поле WorkspaceUser.permissions
. Идея заключается в том, чтобы другие системы ролей использовали это поле для совместимости и избегания дублирования данных или синхронизации при переходе от одной системы к другой. Для типа менеджера прав BasicPermissionManagerType
значение ADMIN
в этом свойстве означает, что пользователь является администратором (ADMIN
). Для любых других значений пользователь рассматривается как обычный участник (MEMBER
) рабочего пространства.AnonymousUser
) является типом субъекта (SubjectType
), который может обрабатываться некоторыми менеджерами прав.Планируется:
.permissions
в более понятное.Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )