@via-profit/ability 1.1.0 → 2.0.0-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +155 -310
- package/assets/ability-01.drawio.png +0 -0
- package/build/playground.js +910 -0
- package/build/playground.js.map +1 -0
- package/dist/AbilityCode.d.ts +7 -0
- package/dist/AbilityCompare.d.ts +6 -0
- package/dist/AbilityCondition.d.ts +12 -0
- package/dist/AbilityError.d.ts +9 -0
- package/dist/AbilityMatch.d.ts +7 -0
- package/dist/AbilityParser.d.ts +33 -0
- package/dist/AbilityPolicy.d.ts +44 -53
- package/dist/AbilityPolicyEffect.d.ts +6 -0
- package/dist/AbilityPolicyResult.d.ts +6 -0
- package/dist/AbilityResolver.d.ts +30 -0
- package/dist/AbilityRule.d.ts +29 -97
- package/dist/AbilityRuleSet.d.ts +44 -0
- package/dist/index.d.ts +9 -3
- package/dist/index.js +624 -380
- package/dist/playground.d.ts +26 -0
- package/package.json +4 -2
- package/dist/AbilityService.d.ts +0 -74
package/README.md
CHANGED
|
@@ -1,123 +1,186 @@
|
|
|
1
1
|
# @via-profit/Ability
|
|
2
2
|
|
|
3
|
-
> Набор сервисов,
|
|
3
|
+
> Набор сервисов, частично реализующих
|
|
4
|
+
> принцип [Attribute Based Access Control](https://en.wikipedia.org/wiki/Attribute-based_access_control)
|
|
5
|
+
|
|
6
|
+
Данный сервис позволяет создать правила или политики, а затем применить их по отношению к каким-либо данным для того
|
|
7
|
+
чтобы проверить наличие доступа к этим данным.
|
|
8
|
+
|
|
9
|
+
# Draft
|
|
4
10
|
|
|
5
11
|
## Содержание
|
|
6
12
|
|
|
7
|
-
1.
|
|
13
|
+
1. [Описание и общие принципы](#overview)
|
|
14
|
+
|
|
15
|
+
1.1 [Состав пакета](#structure)
|
|
16
|
+
|
|
17
|
+
1.2 [Общие принципы](#principles)
|
|
8
18
|
|
|
9
|
-
2.
|
|
19
|
+
2. [Правила](#rules)
|
|
10
20
|
|
|
11
|
-
|
|
21
|
+
2.1 [Синтаксис правил](#rule-syntax)
|
|
12
22
|
|
|
13
|
-
|
|
23
|
+
2.2 [Примеры](#rule-recipes)
|
|
14
24
|
|
|
15
|
-
|
|
25
|
+
2.3 [Класс AbilityRule](#ability-rule-class)
|
|
16
26
|
|
|
17
|
-
3.
|
|
27
|
+
3. [Политики](#policies)
|
|
18
28
|
|
|
19
|
-
|
|
29
|
+
3.1 [Синтаксис правил](#policy-syntax)
|
|
20
30
|
|
|
21
|
-
|
|
31
|
+
3.2 [Примеры](#policy-recipes)
|
|
22
32
|
|
|
23
|
-
|
|
33
|
+
3.3 [Класс AbilityPolicy](#ability-policy-class)
|
|
24
34
|
|
|
25
|
-
4.
|
|
35
|
+
4. [Создание политики из конфига](#policy-config)
|
|
26
36
|
|
|
27
37
|
## Описание и общие принципы <a name="overview"></a>
|
|
28
38
|
|
|
29
|
-
|
|
39
|
+
### Состав пакета <a name="structure"></a>
|
|
30
40
|
|
|
31
|
-
|
|
41
|
+
- `AbilityPolicy` - класс политики
|
|
42
|
+
- `AbilityRuleSet` - класс группы правил
|
|
43
|
+
- `AbilityRule` - класс правила
|
|
44
|
+
- `AbilityParser` - парсер конфигурационных правил из/в JSON
|
|
45
|
+
- `AbilityResolver` - класс управления политиками
|
|
46
|
+
- `AbilityMatch` - Класс констант для определния соответствия правил (`PENDING` `MATCH` `MISMATCH`)
|
|
47
|
+
- `AbilityPolicyEffect` - Класс констант для определния эффекта политик (`DENY` `PERMIT`)
|
|
48
|
+
- `AbilityCompare` - Класс констант для определния способа сравнения правил и групп (`OR` `AND`)
|
|
49
|
+
- `AbilityCondition` - Класс констант для определния метода вычисления правил (`EQUAL` `NOT_EQUAL` `MORE_THAN`
|
|
50
|
+
`LESS_THAN` `LESS_OR_EQUAL` `MORE_OR_EQUAL` `IN` `NOT_IN`)
|
|
51
|
+
- `AbilityError` - Класс инстанса ошибки
|
|
52
|
+
- `AbilityCode` - Базовый клас констанкт
|
|
32
53
|
|
|
33
|
-
|
|
54
|
+
### Общие принципы <a name="principles"></a>
|
|
34
55
|
|
|
35
|
-
|
|
56
|
+
Принцип работы основан на формировании правил, объединения их в политики и запуске этих политик.
|
|
36
57
|
|
|
37
|
-
|
|
58
|
+
Предположим, что необходимо запретить доступ пользователям из отдела менеджеров и причастным к ним, за исключением
|
|
59
|
+
администраторов. Пользователи относятся к отделу менеджеров, если их отдел называется `managers`. Причастные
|
|
60
|
+
пользователи являются те пользователи, среди ролей которых имеется роль `manager`. Администраторы - пользователи имеющие
|
|
61
|
+
соответствующую роль (`administrator`).
|
|
38
62
|
|
|
39
|
-
|
|
40
|
-
// Пользователь
|
|
41
|
-
const user = {
|
|
42
|
-
id: '123',
|
|
43
|
-
name: 'Oleg',
|
|
44
|
-
age: 26,
|
|
45
|
-
departament: 'analytics',
|
|
46
|
-
};
|
|
63
|
+
Для решения поставленной задачи нам понадобится объединить несколько правил в группы согласно изображению ниже:
|
|
47
64
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
65
|
+

|
|
66
|
+
|
|
67
|
+
JSON представление такой политики будет иметь следующий вид:
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"name": "Запретить доступ пользователям из отдела менеджеров и причастным к ним за исключением администраторов",
|
|
72
|
+
"compareMethod": 1,
|
|
73
|
+
"action": "order.update",
|
|
74
|
+
"effect": 0,
|
|
75
|
+
"ruleSet": [
|
|
76
|
+
{
|
|
77
|
+
"name": "Менеджеры",
|
|
78
|
+
"compareMethod": 0,
|
|
79
|
+
"rules": [
|
|
80
|
+
{
|
|
81
|
+
"name": "Пользователь состоит в отделе managers",
|
|
82
|
+
"matches": [
|
|
83
|
+
"user.department",
|
|
84
|
+
"=",
|
|
85
|
+
"managers"
|
|
86
|
+
]
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"name": "Пользователь имеет роль manager",
|
|
90
|
+
"matches": [
|
|
91
|
+
"user.roles",
|
|
92
|
+
"in",
|
|
93
|
+
"manager"
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"name": "Не администраторы",
|
|
100
|
+
"compareMethod": 1,
|
|
101
|
+
"rules": [
|
|
102
|
+
{
|
|
103
|
+
"name": "Пользователь не является администратором",
|
|
104
|
+
"matches": [
|
|
105
|
+
"user.roles",
|
|
106
|
+
"not in",
|
|
107
|
+
"administrator"
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
}
|
|
59
114
|
```
|
|
60
115
|
|
|
61
|
-
|
|
116
|
+
Теперь для того чтобы применить (проверить политику) необходимо её восстановить из JSON (метод `parse`) и запустить
|
|
117
|
+
проверку (метод `check`):
|
|
62
118
|
|
|
63
119
|
```ts
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
// Создание правила
|
|
67
|
-
const rule = new AbilityRule('Пользователь должен быть из отдела аналитики', [
|
|
68
|
-
'subject.departament', // субъект и адрес поля, в которое записано название отдела
|
|
69
|
-
'=', // оператор сравнения
|
|
70
|
-
'resource.type', // Ресурс и адрес поля, в которое записан тип отчета
|
|
71
|
-
]);
|
|
72
|
-
```
|
|
120
|
+
const jsonConfig = { ... }
|
|
73
121
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
122
|
+
const result = AbilityPolicy.parse(jsonConfig).check({
|
|
123
|
+
user: {
|
|
124
|
+
department: 'managers',
|
|
125
|
+
roles: ['manager', 'couch']
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
````
|
|
77
129
|
|
|
78
|
-
|
|
130
|
+
## Правила <a name="rules"></a>
|
|
79
131
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const isPermit = rule.check(user, report); // true
|
|
83
|
-
```
|
|
132
|
+
Правила позволяют создавать условия, которые в последствии будут сгруппированы в группу правил, а те, в свою очередь, в
|
|
133
|
+
политику.
|
|
84
134
|
|
|
85
|
-
|
|
135
|
+
Класс `AbilityRule`
|
|
86
136
|
|
|
87
|
-
|
|
137
|
+
Правило определяется необязательных названием и обязательным массивом `matches`, который и несёт самую важную роль в
|
|
138
|
+
данном модуле.
|
|
139
|
+
|
|
140
|
+
_Пример простого правила:_
|
|
88
141
|
|
|
89
142
|
```ts
|
|
90
|
-
import { AbilityRule } from '@via-profit/ability';
|
|
143
|
+
import { AbilityRule, AbilityCondition } from '@via-profit/ability';
|
|
144
|
+
|
|
145
|
+
const rule = new AbilityRule({
|
|
146
|
+
name: 'Simple rule',
|
|
147
|
+
matches: [
|
|
148
|
+
'user.department', // dot notation путь до проверяемого поля
|
|
149
|
+
AbilityCondition.EQUAL, // определяет метод сравнения "="
|
|
150
|
+
'managers' // искомое значение
|
|
151
|
+
],
|
|
152
|
+
});
|
|
91
153
|
|
|
92
|
-
|
|
93
|
-
const rule = new AbilityRule('Пользователь должен быть из отдела аналитики', [
|
|
94
|
-
'subject.departament', // субъект и адрес поля, в которое записано название отдела
|
|
95
|
-
'=', // оператор сравнения
|
|
96
|
-
'resource.type', // Ресурс и адрес поля, в которое записан тип отчета
|
|
97
|
-
]);
|
|
154
|
+
```
|
|
98
155
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
id: '123',
|
|
102
|
-
name: 'Oleg',
|
|
103
|
-
age: 26,
|
|
104
|
-
departament: 'analytics',
|
|
105
|
-
};
|
|
156
|
+
Правило выше будет выполнено в случае, если среди проверямых данных будет ключ `user`, содержащий ключ `department`,
|
|
157
|
+
значение которого будет равно (`=`) `managers`
|
|
106
158
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
159
|
+
Адрес поля `user.department`, представляет собой запись в
|
|
160
|
+
формате [dot notation](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics#dot_notation), что
|
|
161
|
+
указывает, что для сравнения данных будет использоваться поле department ресурса `user`.
|
|
162
|
+
Для сравнения двух отделов будет использоваться оператор сравнения `=`.
|
|
163
|
+
|
|
164
|
+
Теперь, для того чтобы проверить правило, необходимо выполнить метод `check` передав необходимые ресурсы:
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
import { AbilityRule, AbilityCondition } from '@via-profit/ability';
|
|
168
|
+
|
|
169
|
+
const rule = new AbilityRule({
|
|
170
|
+
name: 'Simple rule',
|
|
171
|
+
matches: [
|
|
172
|
+
'user.department', // dot notation путь до проверяемого поля
|
|
173
|
+
AbilityCondition.EQUAL, // определяет метод сравнения "="
|
|
174
|
+
'managers' // искомое значение
|
|
175
|
+
],
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
const result = rule.check({
|
|
179
|
+
user: {
|
|
180
|
+
department: 'managers',
|
|
181
|
+
}
|
|
182
|
+
});
|
|
118
183
|
|
|
119
|
-
rule.check(user, reports[0]); // --> вернет true
|
|
120
|
-
rule.check(user, reports[1]); // --> вернет false, так как user.departament не соответствует значение поля type отчета
|
|
121
184
|
```
|
|
122
185
|
|
|
123
186
|
### Синтаксис правил <a name="rule-syntax"></a>
|
|
@@ -127,20 +190,21 @@ rule.check(user, reports[1]); // --> вернет false, так как user.depa
|
|
|
127
190
|
```ts
|
|
128
191
|
type AbilityRuleMatches = [
|
|
129
192
|
string, // dot notation путь до поля в субъекте или энвайронменте
|
|
130
|
-
|
|
131
|
-
|
|
193
|
+
'=' | '<>' | '>' | '<' | '<=' | '>=' | 'in', // оператор сравнения
|
|
194
|
+
string | number | boolean, // dot notation путь до поля в ресурсе или энвайронменте или просто значение
|
|
132
195
|
];
|
|
133
196
|
```
|
|
134
197
|
|
|
135
198
|
### Операторы сравнения <a name="rule-operators"></a>
|
|
136
199
|
|
|
137
|
-
`=` Прямое сравнение
|
|
138
|
-
`<>` Не равно
|
|
139
|
-
`>` Больше
|
|
140
|
-
`<` Меньше
|
|
141
|
-
`<=` Меньше или равно
|
|
142
|
-
`>=` Больше или равно
|
|
143
|
-
`in` Вхождение в массив. Позволяет проверять вхождение значения в массив
|
|
200
|
+
- `AbilityCondition.EQUAL` (`=`) Прямое сравнение
|
|
201
|
+
- `AbilityCondition.NOT_EQUAL` (`<>`) Не равно
|
|
202
|
+
- `AbilityCondition.MORE_THAN` (`>`) Больше
|
|
203
|
+
- `AbilityCondition.LESS_THAN` (`<`) Меньше
|
|
204
|
+
- `AbilityCondition.LESS_OR_EQUAL` (`<=`) Меньше или равно
|
|
205
|
+
- `AbilityCondition.MORE_OR_EQUAL` (`>=`) Больше или равно
|
|
206
|
+
- `AbilityCondition.IN` (`in` Вхождение в массив. Позволяет проверять вхождение значения в массив
|
|
207
|
+
- `AbilityCondition.NOT_IN` (`not in` Нет вхождения в массив. Позволяет проверять отсутствие значения в массив
|
|
144
208
|
|
|
145
209
|
### Примеры правил <a name="rule-recipes"></a>
|
|
146
210
|
|
|
@@ -196,226 +260,7 @@ const isPermit = new AbilityRule('owner', ['subject.id', '=', 'resource.owner'])
|
|
|
196
260
|
|
|
197
261
|
Политики позволяют группировать правила или создавать вложенные друг в друга политики.
|
|
198
262
|
|
|
199
|
-
_Замечание: Одна политика может содержать либо правила, либо иметь вложенные политики. Одновременно иметь и правила и вложенные политики невозможно._
|
|
200
|
-
|
|
201
|
-
Предположим, необходимо создать правило, которое будет разрешать доступ к финансовому отчету только пользователю из отдела аналитики (`analytics`) и только при условии, что он является его владельцем. Таким образом нам необходимо сформировать политику, состоящую из двух обязательных правил.
|
|
202
|
-
|
|
203
|
-
_Псевдокод:_
|
|
204
|
-
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
Политика (разрешить), если:
|
|
208
|
-
Правило 1 — пользователь.departament = analytics
|
|
209
|
-
(и)
|
|
210
|
-
Правило 2 — отчет.владелец = пользователь.id
|
|
211
|
-
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
_Реализация:_
|
|
215
|
-
|
|
216
|
-
```ts
|
|
217
|
-
import { Abilitypolicy, AbilityRule } from '@via-profit/ability';
|
|
218
|
-
|
|
219
|
-
const user = {
|
|
220
|
-
id: '1655',
|
|
221
|
-
departament: 'analytics',
|
|
222
|
-
};
|
|
223
|
-
|
|
224
|
-
const report = {
|
|
225
|
-
id: '6',
|
|
226
|
-
owner: '1655',
|
|
227
|
-
};
|
|
228
|
-
|
|
229
|
-
// Создание первого правила
|
|
230
|
-
const departamentRule = new AbilityRule('Пользователь должен быть из отдела аналитики', [
|
|
231
|
-
'subject.departament',
|
|
232
|
-
'=',
|
|
233
|
-
'analytics',
|
|
234
|
-
]);
|
|
235
|
-
|
|
236
|
-
// Создание второго правила
|
|
237
|
-
const orderOwner = new AbilityRule('Пользователь должен быть владельцем отчета', [
|
|
238
|
-
'subject.id',
|
|
239
|
-
'=',
|
|
240
|
-
'resource.owner',
|
|
241
|
-
]);
|
|
242
|
-
|
|
243
|
-
// Создание политики
|
|
244
|
-
const policy = new AbilityPolicy('Доступ к отчету', '1');
|
|
245
|
-
|
|
246
|
-
// Добавление правил в политику
|
|
247
|
-
// Второй аргумент («and») устанавливает, что
|
|
248
|
-
// политика будет разрешена только если переданные
|
|
249
|
-
// данные будут соответствовать обеим правилам сразу.
|
|
250
|
-
// Альтернативный вариант - «or». В таком случае, политика
|
|
251
|
-
// разрешится, если будет удовлетворено хотя бы одно правило
|
|
252
|
-
policy.addRules([departamentRule, orderOwner], 'and');
|
|
253
|
-
|
|
254
|
-
// запуск политики
|
|
255
|
-
// если данные, переданные в политику удовлетворяют ее правилам,
|
|
256
|
-
// то политика позволит выполниться коду, который следует за ней.
|
|
257
|
-
// в противном случае будет брошего исключение с сообщением
|
|
258
|
-
// о запрете доступа и перечислением правил, которые были нарушены
|
|
259
|
-
policy.enforce(user, report);
|
|
260
|
-
|
|
261
|
-
// какой-то код
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
### Вложенные политики
|
|
265
|
-
|
|
266
|
-
Политики могут состоять не из правил, а из других политик.
|
|
267
|
-
|
|
268
|
-
_Замечание: Одна политика может содержать либо правила, либо иметь вложенные политики. Одновременно иметь и правила и вложенные политики невозможно._
|
|
269
|
-
|
|
270
|
-
Например, Пользователь может установить статус заказа на «подтвержденный», но только в случаях, если: предыдущий статус заказа был «новый заказ», устанавливаемый статус заказа будет «подтвержденный заказ» и пользователь относится к отделу «manager» или в случае, если пользователь является старшим администратором
|
|
271
|
-
|
|
272
|
-
_Псевдокод:_
|
|
273
|
-
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
Политика (разрешить), если:
|
|
277
|
-
Политика 1
|
|
278
|
-
Правило 1 — пользователь.departament = managers
|
|
279
|
-
(и)
|
|
280
|
-
Правило 2 — заказ.предыдущий статус = новый заказ
|
|
281
|
-
(и)
|
|
282
|
-
Правило 3 — заказ.новый статус = подтвержденный заказ
|
|
283
|
-
(или)
|
|
284
|
-
Политика 2
|
|
285
|
-
Правило 1 — пользователь.роль = administrator
|
|
286
|
-
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
_Реализация:_
|
|
290
|
-
|
|
291
|
-
Для создания политики будет задействован механизм парсинга конфиигурацонного файла. Подробнее см. раздел [Создание политики из конфига](#policy-config)
|
|
292
|
-
|
|
293
|
-
```ts
|
|
294
|
-
import { Abilitypolicy, AbilityRule } from '@via-profit/ability';
|
|
295
|
-
|
|
296
|
-
const user = {
|
|
297
|
-
id: '1655',
|
|
298
|
-
departament: 'manager',
|
|
299
|
-
roles: ['super-admin', 'viewer'],
|
|
300
|
-
};
|
|
301
|
-
|
|
302
|
-
const order = {
|
|
303
|
-
id: '6',
|
|
304
|
-
status: 'новый заказ',
|
|
305
|
-
};
|
|
306
|
-
|
|
307
|
-
const policy = AbilityPolicy.parse({
|
|
308
|
-
name: 'Политика',
|
|
309
|
-
id: '1',
|
|
310
|
-
policiesCompareMethod: 'or',
|
|
311
|
-
policies: [
|
|
312
|
-
{
|
|
313
|
-
id: '2',
|
|
314
|
-
name: 'Только менеджер может сменить статус с «новый заказ» на «подтвержденный заказ»',
|
|
315
|
-
rulesCompareMethod: 'and',
|
|
316
|
-
rules: [
|
|
317
|
-
{
|
|
318
|
-
name: 'Пользователь должен быть из отдела менеджеров',
|
|
319
|
-
matches: ['subject.departament', '=', 'managers'],
|
|
320
|
-
},
|
|
321
|
-
{
|
|
322
|
-
name: 'Предыдущий статус должен быть «новый заказ»',
|
|
323
|
-
matches: ['environment.prevStatus', '=', 'новый заказ'],
|
|
324
|
-
},
|
|
325
|
-
{
|
|
326
|
-
name: 'Устанавливаемый статус должен быть «подтвержденный заказ»',
|
|
327
|
-
matches: ['environment.nextStatus', '=', 'подтвержденный заказ'],
|
|
328
|
-
},
|
|
329
|
-
],
|
|
330
|
-
},
|
|
331
|
-
{
|
|
332
|
-
id: '3',
|
|
333
|
-
name: 'Пользователь должен быть старшим администратором',
|
|
334
|
-
rules: [
|
|
335
|
-
{
|
|
336
|
-
name: 'Пользователь должен быть старшим администратором',
|
|
337
|
-
matches: ['subject.rules', 'in', 'super-admin'],
|
|
338
|
-
},
|
|
339
|
-
],
|
|
340
|
-
},
|
|
341
|
-
],
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
policy.enforce(user, order, {
|
|
345
|
-
prevStatus: order.status,
|
|
346
|
-
nextStatus: 'подтвержденный заказ',
|
|
347
|
-
});
|
|
348
|
-
```
|
|
349
263
|
|
|
350
264
|
## Создание политики из конфига <a name="policy-config"></a>
|
|
351
265
|
|
|
352
266
|
Политику и правила можно создавать не только по средствам классов, но и при помощи конфигураций.
|
|
353
|
-
|
|
354
|
-
Структура конфигураций правила:
|
|
355
|
-
|
|
356
|
-
```ts
|
|
357
|
-
type AbilityRuleConfig = {
|
|
358
|
-
readonly name: string;
|
|
359
|
-
readonly effect?: AbilityRuleStatus;
|
|
360
|
-
readonly matches: AbilityRuleMatches;
|
|
361
|
-
};
|
|
362
|
-
|
|
363
|
-
type AbilityRuleMatches = [
|
|
364
|
-
`${SubjectPrefix}${string}`,
|
|
365
|
-
'=' | '<>' | '>' | '<' | '<=' | '>=' | 'in'
|
|
366
|
-
string | number | boolean,
|
|
367
|
-
];
|
|
368
|
-
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
Структура конфигураций политики:
|
|
372
|
-
|
|
373
|
-
```ts
|
|
374
|
-
type AbilityPolicyConfig = {
|
|
375
|
-
readonly id: string;
|
|
376
|
-
readonly name: string;
|
|
377
|
-
readonly description?: string;
|
|
378
|
-
readonly rulesCompareMethod?: 'or' | 'and';
|
|
379
|
-
readonly policiesCompareMethod?: 'or' | 'and';
|
|
380
|
-
readonly rules?: AbilityRuleConfig[] | null;
|
|
381
|
-
readonly policies?: AbilityPolicyConfig[] | null;
|
|
382
|
-
};
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
Пример создания простой политики через конфигурацию:
|
|
386
|
-
|
|
387
|
-
```ts
|
|
388
|
-
import { AbilityPolicy } from '@via-profit/ability';
|
|
389
|
-
|
|
390
|
-
const policy = AbilityPolicy.parse({
|
|
391
|
-
name: 'Название политики',
|
|
392
|
-
id: '1',
|
|
393
|
-
policiesCompareMethod: 'or',
|
|
394
|
-
policies: [
|
|
395
|
-
{
|
|
396
|
-
id: '2',
|
|
397
|
-
name: 'Название вложенной политики',
|
|
398
|
-
rulesCompareMethod: 'and',
|
|
399
|
-
rules: [
|
|
400
|
-
{ name: 'Правило 1', matches: ['subject.id', '=', 'resource.creatable'] },
|
|
401
|
-
{ name: 'Правило 2', matches: ['environment.prevStatus', '=', 'unknown'] },
|
|
402
|
-
],
|
|
403
|
-
},
|
|
404
|
-
],
|
|
405
|
-
});
|
|
406
|
-
```
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
## Класс AbilityRule <a name="ability-rule-class"></a>
|
|
410
|
-
|
|
411
|
-
Класс `AbilityRule` предназначен для создания правил
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
## Класс AbilityPolicy <a name="ability-policy-class"></a>
|
|
415
|
-
|
|
416
|
-
Класс `AbilityPolicy` предназначен для создания политик
|
|
417
|
-
|
|
418
|
-
Метод `enforce`. В качестве текста сообщения об ошибке доступа, будет возвращено название политики, причем, только первой, политики, которая не прошла проверку.
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
### Синтаксис политик <a name="policy-syntax"></a>
|
|
Binary file
|