@contember/engine-content-api 2.0.0-rc.1 → 2.0.0

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.
@@ -61,7 +61,7 @@ class PermissionFactory {
61
61
  const predicateReferences = Object.entries(fieldPermissions).filter(([key]) => key !== entity.primary).map(([key, value]) => value).filter((value) => value !== false).filter((value, index, array) => array.indexOf(value) === index);
62
62
  let idPermissions = fieldPermissions[entity.primary] || false;
63
63
  for (let predicateReference of predicateReferences) {
64
- const [predicateDefinition, predicate] = this.mergePredicates(
64
+ const { predicateDefinition, predicate } = this.mergePredicates(
65
65
  entityPredicates,
66
66
  idPermissions,
67
67
  entityPredicates,
@@ -100,36 +100,24 @@ class PermissionFactory {
100
100
  operations.customPrimary = true;
101
101
  }
102
102
  const noRoot = [];
103
- const operationNames = [
103
+ for (let operation of [
104
104
  "create",
105
105
  "read",
106
106
  "update"
107
- ];
108
- for (let operation of operationNames) {
109
- const leftNoRoot = left.operations.noRoot?.includes(operation) || false;
110
- const rightNoRoot = right.operations.noRoot?.includes(operation) || false;
111
- if (leftNoRoot && rightNoRoot) {
107
+ ]) {
108
+ const { predicates: opPredicates, permissions: fieldPermissions, noRoot: opNoRoot2 } = this.mergeOperationPermissions(left, right, operation);
109
+ if (opNoRoot2) {
112
110
  noRoot.push(operation);
113
111
  }
114
- const leftFieldPermissions = leftNoRoot && !rightNoRoot ? {} : left.operations[operation] || {};
115
- const rightFieldPermissions = rightNoRoot && !leftNoRoot ? {} : right.operations[operation] || {};
116
- const [operationPredicates, fieldPermissions] = this.mergeFieldPermissions(
117
- left.predicates,
118
- leftFieldPermissions,
119
- right.predicates,
120
- rightFieldPermissions
121
- );
122
- predicates = { ...predicates, ...operationPredicates };
112
+ predicates = { ...predicates, ...opPredicates };
123
113
  if (Object.keys(fieldPermissions).length > 0) {
124
114
  operations[operation] = fieldPermissions;
125
115
  }
126
116
  }
127
- const [predicateDefinition, predicate] = this.mergePredicates(
128
- left.predicates,
129
- left.operations.delete || false,
130
- right.predicates,
131
- right.operations.delete || false
132
- );
117
+ const { predicateDefinition, predicate, noRoot: opNoRoot } = this.mergeDeletePermissions(left, right);
118
+ if (opNoRoot) {
119
+ noRoot.push("delete");
120
+ }
133
121
  if (predicate === true) {
134
122
  operations.delete = true;
135
123
  } else if (predicateDefinition !== void 0 && typeof predicate === "string") {
@@ -144,47 +132,94 @@ class PermissionFactory {
144
132
  operations
145
133
  };
146
134
  }
147
- mergeFieldPermissions(leftPredicates, leftFieldPermissions, rightPredicates, rightFieldPermissions) {
148
- const fields = {};
135
+ mergeOperationPermissions(left, right, operation) {
136
+ const { noRoot, leftPermissions, rightPermissions } = this.resolveNoRoot(left, right, operation);
137
+ return {
138
+ noRoot,
139
+ ...this.mergeFieldPermissions(
140
+ left.predicates,
141
+ leftPermissions,
142
+ right.predicates,
143
+ rightPermissions
144
+ )
145
+ };
146
+ }
147
+ mergeDeletePermissions(left, right) {
148
+ const { noRoot, leftPermissions, rightPermissions } = this.resolveNoRoot(left, right, "delete");
149
+ return {
150
+ noRoot,
151
+ ...this.mergePredicates(
152
+ left.predicates,
153
+ leftPermissions,
154
+ right.predicates,
155
+ rightPermissions
156
+ )
157
+ };
158
+ }
159
+ resolveNoRoot(left, right, operation) {
160
+ const leftRootForbidden = left.operations.noRoot?.includes(operation) || false;
161
+ const rightRootForbidden = right.operations.noRoot?.includes(operation) || false;
162
+ const leftPermissions = left.operations[operation];
163
+ const rightPermissions = right.operations[operation];
164
+ const rootForbidden = leftRootForbidden && rightRootForbidden || leftRootForbidden && !rightPermissions || rightRootForbidden && !leftPermissions;
165
+ const resolvedLeftPermissions = !rootForbidden && leftRootForbidden ? void 0 : leftPermissions;
166
+ const resolvedRightPermissions = !rootForbidden && rightRootForbidden ? void 0 : rightPermissions;
167
+ return {
168
+ noRoot: rootForbidden,
169
+ leftPermissions: resolvedLeftPermissions,
170
+ rightPermissions: resolvedRightPermissions
171
+ };
172
+ }
173
+ mergeFieldPermissions(leftPredicates, leftFieldPermissions = {}, rightPredicates, rightFieldPermissions = {}) {
174
+ const permissions = {};
149
175
  const predicates = {};
150
176
  for (let field in { ...leftFieldPermissions, ...rightFieldPermissions }) {
151
- const [predicateDefinition, predicate] = this.mergePredicates(
177
+ const { predicateDefinition, predicate } = this.mergePredicates(
152
178
  leftPredicates,
153
179
  leftFieldPermissions[field] || false,
154
180
  rightPredicates,
155
181
  rightFieldPermissions[field] || false
156
182
  );
157
183
  if (predicate === true) {
158
- fields[field] = true;
184
+ permissions[field] = true;
159
185
  } else if (predicateDefinition !== void 0 && typeof predicate === "string") {
160
- fields[field] = predicate;
186
+ permissions[field] = predicate;
161
187
  predicates[predicate] = predicateDefinition;
162
188
  }
163
189
  }
164
- return [predicates, fields];
190
+ return { predicates, permissions };
165
191
  }
166
- mergePredicates(leftPredicates, leftReference, rightPredicates, rightReference) {
192
+ mergePredicates(leftPredicates, leftReference = false, rightPredicates, rightReference = false) {
167
193
  if (leftReference === true || rightReference === true) {
168
- return [void 0, true];
194
+ return {
195
+ predicate: true,
196
+ predicateDefinition: void 0
197
+ };
169
198
  }
170
199
  if (leftReference !== false && rightReference !== false) {
171
200
  const leftPredicate = leftPredicates[leftReference];
172
201
  const rightPredicate = rightPredicates[rightReference];
173
202
  if (leftPredicate === rightPredicate) {
174
- return [leftPredicate, leftReference];
203
+ return {
204
+ predicate: leftReference,
205
+ predicateDefinition: leftPredicate
206
+ };
175
207
  }
176
208
  let predicateName = "__merge__" + leftReference + "__" + rightReference;
177
209
  while (leftPredicates[predicateName]) {
178
210
  predicateName += "_";
179
211
  }
180
- return [
181
- {
212
+ return {
213
+ predicate: predicateName,
214
+ predicateDefinition: {
182
215
  or: [leftPredicate, rightPredicate]
183
- },
184
- predicateName
185
- ];
216
+ }
217
+ };
186
218
  } else if (leftReference !== false) {
187
- return [leftPredicates[leftReference], leftReference];
219
+ return {
220
+ predicate: leftReference,
221
+ predicateDefinition: leftPredicates[leftReference]
222
+ };
188
223
  } else if (rightReference !== false) {
189
224
  let predicateName = rightReference;
190
225
  if (rightPredicates !== leftPredicates) {
@@ -192,9 +227,15 @@ class PermissionFactory {
192
227
  predicateName += "_";
193
228
  }
194
229
  }
195
- return [rightPredicates[rightReference], predicateName];
230
+ return {
231
+ predicate: predicateName,
232
+ predicateDefinition: rightPredicates[rightReference]
233
+ };
196
234
  } else {
197
- return [void 0, false];
235
+ return {
236
+ predicate: false,
237
+ predicateDefinition: void 0
238
+ };
198
239
  }
199
240
  }
200
241
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PermissionFactory.cjs","sources":["../../../../../packages/engine-content-api/src/acl/PermissionFactory.ts"],"sourcesContent":["import { Acl, Model, Schema, Writable } from '@contember/schema'\nimport { getEntity, PredicateDefinitionProcessor } from '@contember/schema-utils'\nimport { mapObject } from '../utils'\nimport { prefixVariable } from './VariableUtils'\n\nexport interface Identity {\n\tprojectRoles: readonly string[]\n}\n\nexport class PermissionFactory {\n\tpublic create(schema: Schema, roles: readonly string[], prefix?: string): Acl.Permissions {\n\t\tlet result: Acl.Permissions = {}\n\t\tfor (let role of roles) {\n\t\t\tconst roleDefinition = schema.acl.roles[role] || { entities: {} }\n\t\t\tlet rolePermissions: Acl.Permissions = this.prefixPredicatesWithRole(schema.model, roleDefinition.entities, prefix || role)\n\t\t\tif (roleDefinition.inherits) {\n\t\t\t\tconst inheritedPermissions = this.create(schema, roleDefinition.inherits, prefix || role)\n\t\t\t\trolePermissions = this.mergePermissions(inheritedPermissions, rolePermissions)\n\t\t\t}\n\t\t\tresult = this.mergePermissions(result, rolePermissions)\n\t\t}\n\t\tresult = this.makePrimaryPredicatesUnionOfAllFields(schema.model, result)\n\n\t\treturn result\n\t}\n\n\tprivate prefixPredicatesWithRole(model: Model.Schema, permissions: Acl.Permissions, role: string): Acl.Permissions {\n\t\treturn mapObject(permissions, ({ operations, predicates }, entityName) => ({\n\t\t\toperations,\n\t\t\tpredicates: mapObject(predicates, predicate => {\n\t\t\t\tconst predicateDefinitionProcessor = new PredicateDefinitionProcessor(model)\n\t\t\t\treturn predicateDefinitionProcessor.process(getEntity(model, entityName), predicate, {\n\t\t\t\t\thandleColumn: ({ value }) => {\n\t\t\t\t\t\tif (typeof value === 'string') {\n\t\t\t\t\t\t\treturn prefixVariable(role, value)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn value\n\t\t\t\t\t},\n\t\t\t\t\thandleRelation: ({ value }) => {\n\t\t\t\t\t\tif (typeof value === 'string') {\n\t\t\t\t\t\t\treturn prefixVariable(role, value)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn value\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t}),\n\t\t}))\n\t}\n\n\tprivate makePrimaryPredicatesUnionOfAllFields(model: Model.Schema, permissions: Acl.Permissions): Acl.Permissions {\n\t\treturn mapObject(permissions, (permission, entityName): Acl.EntityPermissions => {\n\t\t\tconst entity = getEntity(model, entityName)\n\t\t\tconst entityPredicates: Writable<Acl.PredicateMap> = { ...permission.predicates }\n\t\t\tconst entityOperations: Writable<Acl.EntityOperations> = { ...permission.operations }\n\n\t\t\tconst operationNames = ['read', 'create', 'update'] as const\n\t\t\tfor (let operation of operationNames) {\n\t\t\t\tif (!entityOperations[operation]) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst fieldPermissions: Writable<Acl.FieldPermissions> = { ...entityOperations[operation] }\n\t\t\t\tentityOperations[operation] = fieldPermissions\n\n\t\t\t\tif (Object.values(fieldPermissions).some(it => it === true)) {\n\t\t\t\t\tfieldPermissions[entity.primary] = true\n\t\t\t\t}\n\t\t\t\tif (fieldPermissions[entity.primary] === true) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst predicateReferences: string[] = Object.entries(fieldPermissions)\n\t\t\t\t\t.filter(([key]) => key !== entity.primary)\n\t\t\t\t\t.map(([key, value]) => value)\n\t\t\t\t\t.filter(value => value !== false)\n\t\t\t\t\t.filter((value, index, array): value is string => array.indexOf(value) === index)\n\n\t\t\t\tlet idPermissions: Acl.Predicate = fieldPermissions[entity.primary] || false\n\n\t\t\t\tfor (let predicateReference of predicateReferences) {\n\t\t\t\t\tconst [predicateDefinition, predicate] = this.mergePredicates(\n\t\t\t\t\t\tentityPredicates,\n\t\t\t\t\t\tidPermissions,\n\t\t\t\t\t\tentityPredicates,\n\t\t\t\t\t\tpredicateReference,\n\t\t\t\t\t)\n\t\t\t\t\tif (typeof predicate !== 'string' || predicateDefinition === undefined) {\n\t\t\t\t\t\tthrow new Error('should not happen')\n\t\t\t\t\t}\n\t\t\t\t\tidPermissions = predicate\n\t\t\t\t\tentityPredicates[predicate] = predicateDefinition\n\t\t\t\t}\n\t\t\t\tfieldPermissions[entity.primary] = idPermissions\n\t\t\t\tentityPredicates[idPermissions as Acl.PredicateReference] = entityPredicates[idPermissions as Acl.PredicateReference]\n\t\t\t}\n\t\t\treturn {\n\t\t\t\toperations: entityOperations,\n\t\t\t\tpredicates: entityPredicates,\n\t\t\t}\n\t\t})\n\t}\n\n\tprivate mergePermissions(left: Acl.Permissions, right: Acl.Permissions): Acl.Permissions {\n\t\tconst result = { ...left }\n\t\tfor (let entityName in right) {\n\t\t\tif (result[entityName] !== undefined) {\n\t\t\t\tresult[entityName] = this.mergeEntityPermissions(result[entityName], right[entityName])\n\t\t\t} else {\n\t\t\t\tresult[entityName] = right[entityName]\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n\n\tprivate mergeEntityPermissions(left: Acl.EntityPermissions, right: Acl.EntityPermissions): Acl.EntityPermissions {\n\t\tlet predicates: Writable<Acl.PredicateMap> = {}\n\t\tconst operations: Writable<Acl.EntityOperations> = {}\n\t\tif (left.operations.customPrimary || right.operations.customPrimary) {\n\t\t\toperations.customPrimary = true\n\t\t}\n\t\tconst noRoot: `${Acl.Operation}`[] = []\n\n\t\tconst operationNames: (keyof Pick<Acl.EntityOperations, 'create' | 'read' | 'update'>)[] = [\n\t\t\t'create',\n\t\t\t'read',\n\t\t\t'update',\n\t\t]\n\n\t\tfor (let operation of operationNames) {\n\t\t\tconst leftNoRoot = left.operations.noRoot?.includes(operation) || false\n\t\t\tconst rightNoRoot = right.operations.noRoot?.includes(operation) || false\n\t\t\tif (leftNoRoot && rightNoRoot) {\n\t\t\t\tnoRoot.push(operation)\n\t\t\t}\n\n\t\t\tconst leftFieldPermissions: Acl.FieldPermissions = leftNoRoot && !rightNoRoot ? {} : (left.operations[operation] || {})\n\t\t\tconst rightFieldPermissions: Acl.FieldPermissions = rightNoRoot && !leftNoRoot ? {} : (right.operations[operation] || {})\n\t\t\tconst [operationPredicates, fieldPermissions] = this.mergeFieldPermissions(\n\t\t\t\tleft.predicates,\n\t\t\t\tleftFieldPermissions,\n\t\t\t\tright.predicates,\n\t\t\t\trightFieldPermissions,\n\t\t\t)\n\t\t\tpredicates = { ...predicates, ...operationPredicates }\n\t\t\tif (Object.keys(fieldPermissions).length > 0) {\n\t\t\t\toperations[operation] = fieldPermissions\n\t\t\t}\n\t\t}\n\n\t\tconst [predicateDefinition, predicate] = this.mergePredicates(\n\t\t\tleft.predicates,\n\t\t\tleft.operations.delete || false,\n\t\t\tright.predicates,\n\t\t\tright.operations.delete || false,\n\t\t)\n\t\tif (predicate === true) {\n\t\t\toperations.delete = true\n\t\t} else if (predicateDefinition !== undefined && typeof predicate === 'string') {\n\t\t\tpredicates[predicate] = predicateDefinition\n\t\t\toperations.delete = predicate\n\t\t}\n\t\tif (noRoot.length > 0) {\n\t\t\toperations.noRoot = noRoot\n\t\t}\n\n\t\treturn {\n\t\t\tpredicates: predicates,\n\t\t\toperations: operations,\n\t\t}\n\t}\n\n\tprivate mergeFieldPermissions(\n\t\tleftPredicates: Acl.PredicateMap,\n\t\tleftFieldPermissions: Acl.FieldPermissions,\n\t\trightPredicates: Acl.PredicateMap,\n\t\trightFieldPermissions: Acl.FieldPermissions,\n\t): [Acl.PredicateMap, Acl.FieldPermissions] {\n\t\tconst fields: Writable<Acl.FieldPermissions> = {}\n\t\tconst predicates: Writable<Acl.PredicateMap> = {}\n\n\t\tfor (let field in { ...leftFieldPermissions, ...rightFieldPermissions }) {\n\t\t\tconst [predicateDefinition, predicate] = this.mergePredicates(\n\t\t\t\tleftPredicates,\n\t\t\t\tleftFieldPermissions[field] || false,\n\t\t\t\trightPredicates,\n\t\t\t\trightFieldPermissions[field] || false,\n\t\t\t)\n\t\t\tif (predicate === true) {\n\t\t\t\tfields[field] = true\n\t\t\t} else if (predicateDefinition !== undefined && typeof predicate === 'string') {\n\t\t\t\tfields[field] = predicate\n\t\t\t\tpredicates[predicate] = predicateDefinition\n\t\t\t}\n\t\t}\n\n\t\treturn [predicates, fields]\n\t}\n\n\tprivate mergePredicates(\n\t\tleftPredicates: Acl.PredicateMap,\n\t\tleftReference: Acl.Predicate,\n\t\trightPredicates: Acl.PredicateMap,\n\t\trightReference: Acl.Predicate,\n\t): [Acl.PredicateDefinition, Acl.PredicateReference] | [undefined, boolean] {\n\t\tif (leftReference === true || rightReference === true) {\n\t\t\treturn [undefined, true]\n\t\t}\n\n\t\tif (leftReference !== false && rightReference !== false) {\n\t\t\tconst leftPredicate: Acl.PredicateDefinition = leftPredicates[leftReference]\n\t\t\tconst rightPredicate: Acl.PredicateDefinition = rightPredicates[rightReference]\n\t\t\tif (leftPredicate === rightPredicate) {\n\t\t\t\treturn [leftPredicate, leftReference]\n\t\t\t}\n\n\t\t\tlet predicateName = '__merge__' + leftReference + '__' + rightReference\n\t\t\twhile (leftPredicates[predicateName]) {\n\t\t\t\tpredicateName += '_'\n\t\t\t}\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tor: [leftPredicate, rightPredicate],\n\t\t\t\t} as Acl.PredicateDefinition,\n\t\t\t\tpredicateName,\n\t\t\t]\n\t\t} else if (leftReference !== false) {\n\t\t\treturn [leftPredicates[leftReference], leftReference]\n\t\t} else if (rightReference !== false) {\n\t\t\tlet predicateName = rightReference\n\t\t\tif (rightPredicates !== leftPredicates) {\n\t\t\t\twhile (leftPredicates[predicateName]) {\n\t\t\t\t\tpredicateName += '_'\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn [rightPredicates[rightReference], predicateName]\n\t\t} else {\n\t\t\treturn [undefined, false]\n\t\t}\n\t}\n}\n"],"names":["mapObject","PredicateDefinitionProcessor","getEntity","prefixVariable"],"mappings":"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"}
1
+ {"version":3,"file":"PermissionFactory.cjs","sources":["../../../../../packages/engine-content-api/src/acl/PermissionFactory.ts"],"sourcesContent":["import { Acl, Model, Schema, Writable } from '@contember/schema'\nimport { getEntity, PredicateDefinitionProcessor } from '@contember/schema-utils'\nimport { mapObject } from '../utils'\nimport { prefixVariable } from './VariableUtils'\n\nexport interface Identity {\n\tprojectRoles: readonly string[]\n}\n\nexport class PermissionFactory {\n\tpublic create(schema: Schema, roles: readonly string[], prefix?: string): Acl.Permissions {\n\t\tlet result: Acl.Permissions = {}\n\t\tfor (let role of roles) {\n\t\t\tconst roleDefinition = schema.acl.roles[role] || { entities: {} }\n\t\t\tlet rolePermissions: Acl.Permissions = this.prefixPredicatesWithRole(schema.model, roleDefinition.entities, prefix || role)\n\t\t\tif (roleDefinition.inherits) {\n\t\t\t\tconst inheritedPermissions = this.create(schema, roleDefinition.inherits, prefix || role)\n\t\t\t\trolePermissions = this.mergePermissions(inheritedPermissions, rolePermissions)\n\t\t\t}\n\t\t\tresult = this.mergePermissions(result, rolePermissions)\n\t\t}\n\t\tresult = this.makePrimaryPredicatesUnionOfAllFields(schema.model, result)\n\n\t\treturn result\n\t}\n\n\tprivate prefixPredicatesWithRole(model: Model.Schema, permissions: Acl.Permissions, role: string): Acl.Permissions {\n\t\treturn mapObject(permissions, ({ operations, predicates }, entityName) => ({\n\t\t\toperations,\n\t\t\tpredicates: mapObject(predicates, predicate => {\n\t\t\t\tconst predicateDefinitionProcessor = new PredicateDefinitionProcessor(model)\n\t\t\t\treturn predicateDefinitionProcessor.process(getEntity(model, entityName), predicate, {\n\t\t\t\t\thandleColumn: ({ value }) => {\n\t\t\t\t\t\tif (typeof value === 'string') {\n\t\t\t\t\t\t\treturn prefixVariable(role, value)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn value\n\t\t\t\t\t},\n\t\t\t\t\thandleRelation: ({ value }) => {\n\t\t\t\t\t\tif (typeof value === 'string') {\n\t\t\t\t\t\t\treturn prefixVariable(role, value)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn value\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t}),\n\t\t}))\n\t}\n\n\tprivate makePrimaryPredicatesUnionOfAllFields(model: Model.Schema, permissions: Acl.Permissions): Acl.Permissions {\n\t\treturn mapObject(permissions, (permission, entityName): Acl.EntityPermissions => {\n\t\t\tconst entity = getEntity(model, entityName)\n\t\t\tconst entityPredicates: Writable<Acl.PredicateMap> = { ...permission.predicates }\n\t\t\tconst entityOperations: Writable<Acl.EntityOperations> = { ...permission.operations }\n\n\t\t\tconst operationNames = ['read', 'create', 'update'] as const\n\t\t\tfor (let operation of operationNames) {\n\t\t\t\tif (!entityOperations[operation]) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst fieldPermissions: Writable<Acl.FieldPermissions> = { ...entityOperations[operation] }\n\t\t\t\tentityOperations[operation] = fieldPermissions\n\n\t\t\t\tif (Object.values(fieldPermissions).some(it => it === true)) {\n\t\t\t\t\tfieldPermissions[entity.primary] = true\n\t\t\t\t}\n\t\t\t\tif (fieldPermissions[entity.primary] === true) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst predicateReferences: string[] = Object.entries(fieldPermissions)\n\t\t\t\t\t.filter(([key]) => key !== entity.primary)\n\t\t\t\t\t.map(([key, value]) => value)\n\t\t\t\t\t.filter(value => value !== false)\n\t\t\t\t\t.filter((value, index, array): value is string => array.indexOf(value) === index)\n\n\t\t\t\tlet idPermissions: Acl.Predicate = fieldPermissions[entity.primary] || false\n\n\t\t\t\tfor (let predicateReference of predicateReferences) {\n\t\t\t\t\tconst { predicateDefinition, predicate } = this.mergePredicates(\n\t\t\t\t\t\tentityPredicates,\n\t\t\t\t\t\tidPermissions,\n\t\t\t\t\t\tentityPredicates,\n\t\t\t\t\t\tpredicateReference,\n\t\t\t\t\t)\n\t\t\t\t\tif (typeof predicate !== 'string' || predicateDefinition === undefined) {\n\t\t\t\t\t\tthrow new Error('should not happen')\n\t\t\t\t\t}\n\t\t\t\t\tidPermissions = predicate\n\t\t\t\t\tentityPredicates[predicate] = predicateDefinition\n\t\t\t\t}\n\t\t\t\tfieldPermissions[entity.primary] = idPermissions\n\t\t\t\tentityPredicates[idPermissions as Acl.PredicateReference] = entityPredicates[idPermissions as Acl.PredicateReference]\n\t\t\t}\n\t\t\treturn {\n\t\t\t\toperations: entityOperations,\n\t\t\t\tpredicates: entityPredicates,\n\t\t\t}\n\t\t})\n\t}\n\n\tprivate mergePermissions(left: Acl.Permissions, right: Acl.Permissions): Acl.Permissions {\n\t\tconst result = { ...left }\n\t\tfor (let entityName in right) {\n\t\t\tif (result[entityName] !== undefined) {\n\t\t\t\tresult[entityName] = this.mergeEntityPermissions(result[entityName], right[entityName])\n\t\t\t} else {\n\t\t\t\tresult[entityName] = right[entityName]\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n\n\tprivate mergeEntityPermissions(left: Acl.EntityPermissions, right: Acl.EntityPermissions): Acl.EntityPermissions {\n\t\tlet predicates: Writable<Acl.PredicateMap> = {}\n\t\tconst operations: Writable<Acl.EntityOperations> = {}\n\t\tif (left.operations.customPrimary || right.operations.customPrimary) {\n\t\t\toperations.customPrimary = true\n\t\t}\n\t\tconst noRoot: `${Acl.Operation}`[] = []\n\n\t\tfor (let operation of [\n\t\t\t'create',\n\t\t\t'read',\n\t\t\t'update',\n\t\t] as const) {\n\n\t\t\tconst { predicates: opPredicates, permissions: fieldPermissions, noRoot: opNoRoot } = this.mergeOperationPermissions(left, right, operation)\n\n\t\t\tif (opNoRoot) {\n\t\t\t\tnoRoot.push(operation)\n\t\t\t}\n\n\t\t\tpredicates = { ...predicates, ...opPredicates }\n\t\t\tif (Object.keys(fieldPermissions).length > 0) {\n\t\t\t\toperations[operation] = fieldPermissions\n\t\t\t}\n\t\t}\n\n\t\tconst { predicateDefinition, predicate, noRoot: opNoRoot } = this.mergeDeletePermissions(left, right)\n\t\tif (opNoRoot) {\n\t\t\tnoRoot.push('delete')\n\t\t}\n\t\tif (predicate === true) {\n\t\t\toperations.delete = true\n\t\t} else if (predicateDefinition !== undefined && typeof predicate === 'string') {\n\t\t\tpredicates[predicate] = predicateDefinition\n\t\t\toperations.delete = predicate\n\t\t}\n\n\n\t\tif (noRoot.length > 0) {\n\t\t\toperations.noRoot = noRoot\n\t\t}\n\n\t\treturn {\n\t\t\tpredicates: predicates,\n\t\t\toperations: operations,\n\t\t}\n\t}\n\n\n\tprivate mergeOperationPermissions(left: Acl.EntityPermissions, right: Acl.EntityPermissions, operation: 'create' | 'read' | 'update'): {\n\t\tnoRoot: boolean\n\t\tpredicates: Acl.PredicateMap\n\t\tpermissions: Acl.FieldPermissions\n\t} {\n\t\tconst { noRoot, leftPermissions, rightPermissions } = this.resolveNoRoot(left, right, operation)\n\t\treturn {\n\t\t\tnoRoot,\n\t\t\t...this.mergeFieldPermissions(\n\t\t\t\tleft.predicates,\n\t\t\t\tleftPermissions,\n\t\t\t\tright.predicates,\n\t\t\t\trightPermissions,\n\t\t\t),\n\t\t}\n\t}\n\n\tprivate mergeDeletePermissions(left: Acl.EntityPermissions, right: Acl.EntityPermissions): {\n\t\tnoRoot: boolean\n\t\tpredicate: Acl.PredicateReference | boolean\n\t\tpredicateDefinition: Acl.PredicateDefinition | undefined\n\t} {\n\t\tconst { noRoot, leftPermissions, rightPermissions } = this.resolveNoRoot(left, right, 'delete')\n\n\t\treturn {\n\t\t\tnoRoot,\n\t\t\t...this.mergePredicates(\n\t\t\t\tleft.predicates,\n\t\t\t\tleftPermissions,\n\t\t\t\tright.predicates,\n\t\t\t\trightPermissions,\n\t\t\t),\n\t\t}\n\t}\n\n\tprivate resolveNoRoot<const Op extends`${Acl.Operation}`>(left: Acl.EntityPermissions, right: Acl.EntityPermissions, operation: Op): {\n\t\tnoRoot: boolean\n\t\tleftPermissions: Acl.EntityPermissions['operations'][Op] | undefined\n\t\trightPermissions: Acl.EntityPermissions['operations'][Op] | undefined\n\t} {\n\t\tconst leftRootForbidden = left.operations.noRoot?.includes(operation) || false\n\t\tconst rightRootForbidden = right.operations.noRoot?.includes(operation) || false\n\t\tconst leftPermissions = left.operations[operation]\n\t\tconst rightPermissions = right.operations[operation]\n\n\t\tconst rootForbidden = (leftRootForbidden && rightRootForbidden)\n\t\t\t|| (leftRootForbidden && !rightPermissions)\n\t\t\t|| (rightRootForbidden && !leftPermissions)\n\n\t\tconst resolvedLeftPermissions = !rootForbidden && leftRootForbidden ? undefined : leftPermissions\n\t\tconst resolvedRightPermissions = !rootForbidden && rightRootForbidden ? undefined : rightPermissions\n\n\t\treturn {\n\t\t\tnoRoot: rootForbidden,\n\t\t\tleftPermissions: resolvedLeftPermissions,\n\t\t\trightPermissions: resolvedRightPermissions,\n\t\t}\n\t}\n\n\tprivate mergeFieldPermissions(\n\t\tleftPredicates: Acl.PredicateMap,\n\t\tleftFieldPermissions: Acl.FieldPermissions | undefined = {},\n\t\trightPredicates: Acl.PredicateMap,\n\t\trightFieldPermissions: Acl.FieldPermissions | undefined = {},\n\t): {predicates: Acl.PredicateMap; permissions: Acl.FieldPermissions} {\n\t\tconst permissions: Writable<Acl.FieldPermissions> = {}\n\t\tconst predicates: Writable<Acl.PredicateMap> = {}\n\n\t\tfor (let field in { ...leftFieldPermissions, ...rightFieldPermissions }) {\n\t\t\tconst { predicateDefinition, predicate } = this.mergePredicates(\n\t\t\t\tleftPredicates,\n\t\t\t\tleftFieldPermissions[field] || false,\n\t\t\t\trightPredicates,\n\t\t\t\trightFieldPermissions[field] || false,\n\t\t\t)\n\t\t\tif (predicate === true) {\n\t\t\t\tpermissions[field] = true\n\t\t\t} else if (predicateDefinition !== undefined && typeof predicate === 'string') {\n\t\t\t\tpermissions[field] = predicate\n\t\t\t\tpredicates[predicate] = predicateDefinition\n\t\t\t}\n\t\t}\n\n\t\treturn { predicates, permissions }\n\t}\n\n\tprivate mergePredicates(\n\t\tleftPredicates: Acl.PredicateMap,\n\t\tleftReference: Acl.Predicate | undefined = false,\n\t\trightPredicates: Acl.PredicateMap,\n\t\trightReference: Acl.Predicate | undefined = false,\n\t): {\n\t\tpredicate: Acl.PredicateReference | boolean\n\t\tpredicateDefinition: Acl.PredicateDefinition | undefined\n\t} {\n\t\tif (leftReference === true || rightReference === true) {\n\t\t\treturn {\n\t\t\t\tpredicate: true,\n\t\t\t\tpredicateDefinition: undefined,\n\t\t\t}\n\t\t}\n\n\t\tif (leftReference !== false && rightReference !== false) {\n\t\t\tconst leftPredicate: Acl.PredicateDefinition = leftPredicates[leftReference]\n\t\t\tconst rightPredicate: Acl.PredicateDefinition = rightPredicates[rightReference]\n\t\t\tif (leftPredicate === rightPredicate) {\n\t\t\t\treturn {\n\t\t\t\t\tpredicate: leftReference,\n\t\t\t\t\tpredicateDefinition: leftPredicate,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet predicateName = '__merge__' + leftReference + '__' + rightReference\n\t\t\twhile (leftPredicates[predicateName]) {\n\t\t\t\tpredicateName += '_'\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tpredicate: predicateName,\n\t\t\t\tpredicateDefinition: {\n\t\t\t\t\tor: [leftPredicate, rightPredicate],\n\t\t\t\t} as Acl.PredicateDefinition,\n\t\t\t}\n\t\t} else if (leftReference !== false) {\n\t\t\treturn {\n\t\t\t\tpredicate: leftReference,\n\t\t\t\tpredicateDefinition: leftPredicates[leftReference],\n\t\t\t}\n\t\t} else if (rightReference !== false) {\n\t\t\tlet predicateName = rightReference\n\t\t\tif (rightPredicates !== leftPredicates) {\n\t\t\t\twhile (leftPredicates[predicateName]) {\n\t\t\t\t\tpredicateName += '_'\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tpredicate: predicateName,\n\t\t\t\tpredicateDefinition: rightPredicates[rightReference],\n\t\t\t}\n\t\t} else {\n\t\t\treturn {\n\t\t\t\tpredicate: false,\n\t\t\t\tpredicateDefinition: undefined,\n\t\t\t}\n\t\t}\n\t}\n}\n"],"names":["mapObject","PredicateDefinitionProcessor","getEntity","prefixVariable","opNoRoot"],"mappings":"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"}
@@ -59,7 +59,7 @@ class PermissionFactory {
59
59
  const predicateReferences = Object.entries(fieldPermissions).filter(([key]) => key !== entity.primary).map(([key, value]) => value).filter((value) => value !== false).filter((value, index, array) => array.indexOf(value) === index);
60
60
  let idPermissions = fieldPermissions[entity.primary] || false;
61
61
  for (let predicateReference of predicateReferences) {
62
- const [predicateDefinition, predicate] = this.mergePredicates(
62
+ const { predicateDefinition, predicate } = this.mergePredicates(
63
63
  entityPredicates,
64
64
  idPermissions,
65
65
  entityPredicates,
@@ -98,36 +98,24 @@ class PermissionFactory {
98
98
  operations.customPrimary = true;
99
99
  }
100
100
  const noRoot = [];
101
- const operationNames = [
101
+ for (let operation of [
102
102
  "create",
103
103
  "read",
104
104
  "update"
105
- ];
106
- for (let operation of operationNames) {
107
- const leftNoRoot = left.operations.noRoot?.includes(operation) || false;
108
- const rightNoRoot = right.operations.noRoot?.includes(operation) || false;
109
- if (leftNoRoot && rightNoRoot) {
105
+ ]) {
106
+ const { predicates: opPredicates, permissions: fieldPermissions, noRoot: opNoRoot2 } = this.mergeOperationPermissions(left, right, operation);
107
+ if (opNoRoot2) {
110
108
  noRoot.push(operation);
111
109
  }
112
- const leftFieldPermissions = leftNoRoot && !rightNoRoot ? {} : left.operations[operation] || {};
113
- const rightFieldPermissions = rightNoRoot && !leftNoRoot ? {} : right.operations[operation] || {};
114
- const [operationPredicates, fieldPermissions] = this.mergeFieldPermissions(
115
- left.predicates,
116
- leftFieldPermissions,
117
- right.predicates,
118
- rightFieldPermissions
119
- );
120
- predicates = { ...predicates, ...operationPredicates };
110
+ predicates = { ...predicates, ...opPredicates };
121
111
  if (Object.keys(fieldPermissions).length > 0) {
122
112
  operations[operation] = fieldPermissions;
123
113
  }
124
114
  }
125
- const [predicateDefinition, predicate] = this.mergePredicates(
126
- left.predicates,
127
- left.operations.delete || false,
128
- right.predicates,
129
- right.operations.delete || false
130
- );
115
+ const { predicateDefinition, predicate, noRoot: opNoRoot } = this.mergeDeletePermissions(left, right);
116
+ if (opNoRoot) {
117
+ noRoot.push("delete");
118
+ }
131
119
  if (predicate === true) {
132
120
  operations.delete = true;
133
121
  } else if (predicateDefinition !== void 0 && typeof predicate === "string") {
@@ -142,47 +130,94 @@ class PermissionFactory {
142
130
  operations
143
131
  };
144
132
  }
145
- mergeFieldPermissions(leftPredicates, leftFieldPermissions, rightPredicates, rightFieldPermissions) {
146
- const fields = {};
133
+ mergeOperationPermissions(left, right, operation) {
134
+ const { noRoot, leftPermissions, rightPermissions } = this.resolveNoRoot(left, right, operation);
135
+ return {
136
+ noRoot,
137
+ ...this.mergeFieldPermissions(
138
+ left.predicates,
139
+ leftPermissions,
140
+ right.predicates,
141
+ rightPermissions
142
+ )
143
+ };
144
+ }
145
+ mergeDeletePermissions(left, right) {
146
+ const { noRoot, leftPermissions, rightPermissions } = this.resolveNoRoot(left, right, "delete");
147
+ return {
148
+ noRoot,
149
+ ...this.mergePredicates(
150
+ left.predicates,
151
+ leftPermissions,
152
+ right.predicates,
153
+ rightPermissions
154
+ )
155
+ };
156
+ }
157
+ resolveNoRoot(left, right, operation) {
158
+ const leftRootForbidden = left.operations.noRoot?.includes(operation) || false;
159
+ const rightRootForbidden = right.operations.noRoot?.includes(operation) || false;
160
+ const leftPermissions = left.operations[operation];
161
+ const rightPermissions = right.operations[operation];
162
+ const rootForbidden = leftRootForbidden && rightRootForbidden || leftRootForbidden && !rightPermissions || rightRootForbidden && !leftPermissions;
163
+ const resolvedLeftPermissions = !rootForbidden && leftRootForbidden ? void 0 : leftPermissions;
164
+ const resolvedRightPermissions = !rootForbidden && rightRootForbidden ? void 0 : rightPermissions;
165
+ return {
166
+ noRoot: rootForbidden,
167
+ leftPermissions: resolvedLeftPermissions,
168
+ rightPermissions: resolvedRightPermissions
169
+ };
170
+ }
171
+ mergeFieldPermissions(leftPredicates, leftFieldPermissions = {}, rightPredicates, rightFieldPermissions = {}) {
172
+ const permissions = {};
147
173
  const predicates = {};
148
174
  for (let field in { ...leftFieldPermissions, ...rightFieldPermissions }) {
149
- const [predicateDefinition, predicate] = this.mergePredicates(
175
+ const { predicateDefinition, predicate } = this.mergePredicates(
150
176
  leftPredicates,
151
177
  leftFieldPermissions[field] || false,
152
178
  rightPredicates,
153
179
  rightFieldPermissions[field] || false
154
180
  );
155
181
  if (predicate === true) {
156
- fields[field] = true;
182
+ permissions[field] = true;
157
183
  } else if (predicateDefinition !== void 0 && typeof predicate === "string") {
158
- fields[field] = predicate;
184
+ permissions[field] = predicate;
159
185
  predicates[predicate] = predicateDefinition;
160
186
  }
161
187
  }
162
- return [predicates, fields];
188
+ return { predicates, permissions };
163
189
  }
164
- mergePredicates(leftPredicates, leftReference, rightPredicates, rightReference) {
190
+ mergePredicates(leftPredicates, leftReference = false, rightPredicates, rightReference = false) {
165
191
  if (leftReference === true || rightReference === true) {
166
- return [void 0, true];
192
+ return {
193
+ predicate: true,
194
+ predicateDefinition: void 0
195
+ };
167
196
  }
168
197
  if (leftReference !== false && rightReference !== false) {
169
198
  const leftPredicate = leftPredicates[leftReference];
170
199
  const rightPredicate = rightPredicates[rightReference];
171
200
  if (leftPredicate === rightPredicate) {
172
- return [leftPredicate, leftReference];
201
+ return {
202
+ predicate: leftReference,
203
+ predicateDefinition: leftPredicate
204
+ };
173
205
  }
174
206
  let predicateName = "__merge__" + leftReference + "__" + rightReference;
175
207
  while (leftPredicates[predicateName]) {
176
208
  predicateName += "_";
177
209
  }
178
- return [
179
- {
210
+ return {
211
+ predicate: predicateName,
212
+ predicateDefinition: {
180
213
  or: [leftPredicate, rightPredicate]
181
- },
182
- predicateName
183
- ];
214
+ }
215
+ };
184
216
  } else if (leftReference !== false) {
185
- return [leftPredicates[leftReference], leftReference];
217
+ return {
218
+ predicate: leftReference,
219
+ predicateDefinition: leftPredicates[leftReference]
220
+ };
186
221
  } else if (rightReference !== false) {
187
222
  let predicateName = rightReference;
188
223
  if (rightPredicates !== leftPredicates) {
@@ -190,9 +225,15 @@ class PermissionFactory {
190
225
  predicateName += "_";
191
226
  }
192
227
  }
193
- return [rightPredicates[rightReference], predicateName];
228
+ return {
229
+ predicate: predicateName,
230
+ predicateDefinition: rightPredicates[rightReference]
231
+ };
194
232
  } else {
195
- return [void 0, false];
233
+ return {
234
+ predicate: false,
235
+ predicateDefinition: void 0
236
+ };
196
237
  }
197
238
  }
198
239
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PermissionFactory.js","sources":["../../../../../packages/engine-content-api/src/acl/PermissionFactory.ts"],"sourcesContent":["import { Acl, Model, Schema, Writable } from '@contember/schema'\nimport { getEntity, PredicateDefinitionProcessor } from '@contember/schema-utils'\nimport { mapObject } from '../utils'\nimport { prefixVariable } from './VariableUtils'\n\nexport interface Identity {\n\tprojectRoles: readonly string[]\n}\n\nexport class PermissionFactory {\n\tpublic create(schema: Schema, roles: readonly string[], prefix?: string): Acl.Permissions {\n\t\tlet result: Acl.Permissions = {}\n\t\tfor (let role of roles) {\n\t\t\tconst roleDefinition = schema.acl.roles[role] || { entities: {} }\n\t\t\tlet rolePermissions: Acl.Permissions = this.prefixPredicatesWithRole(schema.model, roleDefinition.entities, prefix || role)\n\t\t\tif (roleDefinition.inherits) {\n\t\t\t\tconst inheritedPermissions = this.create(schema, roleDefinition.inherits, prefix || role)\n\t\t\t\trolePermissions = this.mergePermissions(inheritedPermissions, rolePermissions)\n\t\t\t}\n\t\t\tresult = this.mergePermissions(result, rolePermissions)\n\t\t}\n\t\tresult = this.makePrimaryPredicatesUnionOfAllFields(schema.model, result)\n\n\t\treturn result\n\t}\n\n\tprivate prefixPredicatesWithRole(model: Model.Schema, permissions: Acl.Permissions, role: string): Acl.Permissions {\n\t\treturn mapObject(permissions, ({ operations, predicates }, entityName) => ({\n\t\t\toperations,\n\t\t\tpredicates: mapObject(predicates, predicate => {\n\t\t\t\tconst predicateDefinitionProcessor = new PredicateDefinitionProcessor(model)\n\t\t\t\treturn predicateDefinitionProcessor.process(getEntity(model, entityName), predicate, {\n\t\t\t\t\thandleColumn: ({ value }) => {\n\t\t\t\t\t\tif (typeof value === 'string') {\n\t\t\t\t\t\t\treturn prefixVariable(role, value)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn value\n\t\t\t\t\t},\n\t\t\t\t\thandleRelation: ({ value }) => {\n\t\t\t\t\t\tif (typeof value === 'string') {\n\t\t\t\t\t\t\treturn prefixVariable(role, value)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn value\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t}),\n\t\t}))\n\t}\n\n\tprivate makePrimaryPredicatesUnionOfAllFields(model: Model.Schema, permissions: Acl.Permissions): Acl.Permissions {\n\t\treturn mapObject(permissions, (permission, entityName): Acl.EntityPermissions => {\n\t\t\tconst entity = getEntity(model, entityName)\n\t\t\tconst entityPredicates: Writable<Acl.PredicateMap> = { ...permission.predicates }\n\t\t\tconst entityOperations: Writable<Acl.EntityOperations> = { ...permission.operations }\n\n\t\t\tconst operationNames = ['read', 'create', 'update'] as const\n\t\t\tfor (let operation of operationNames) {\n\t\t\t\tif (!entityOperations[operation]) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst fieldPermissions: Writable<Acl.FieldPermissions> = { ...entityOperations[operation] }\n\t\t\t\tentityOperations[operation] = fieldPermissions\n\n\t\t\t\tif (Object.values(fieldPermissions).some(it => it === true)) {\n\t\t\t\t\tfieldPermissions[entity.primary] = true\n\t\t\t\t}\n\t\t\t\tif (fieldPermissions[entity.primary] === true) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst predicateReferences: string[] = Object.entries(fieldPermissions)\n\t\t\t\t\t.filter(([key]) => key !== entity.primary)\n\t\t\t\t\t.map(([key, value]) => value)\n\t\t\t\t\t.filter(value => value !== false)\n\t\t\t\t\t.filter((value, index, array): value is string => array.indexOf(value) === index)\n\n\t\t\t\tlet idPermissions: Acl.Predicate = fieldPermissions[entity.primary] || false\n\n\t\t\t\tfor (let predicateReference of predicateReferences) {\n\t\t\t\t\tconst [predicateDefinition, predicate] = this.mergePredicates(\n\t\t\t\t\t\tentityPredicates,\n\t\t\t\t\t\tidPermissions,\n\t\t\t\t\t\tentityPredicates,\n\t\t\t\t\t\tpredicateReference,\n\t\t\t\t\t)\n\t\t\t\t\tif (typeof predicate !== 'string' || predicateDefinition === undefined) {\n\t\t\t\t\t\tthrow new Error('should not happen')\n\t\t\t\t\t}\n\t\t\t\t\tidPermissions = predicate\n\t\t\t\t\tentityPredicates[predicate] = predicateDefinition\n\t\t\t\t}\n\t\t\t\tfieldPermissions[entity.primary] = idPermissions\n\t\t\t\tentityPredicates[idPermissions as Acl.PredicateReference] = entityPredicates[idPermissions as Acl.PredicateReference]\n\t\t\t}\n\t\t\treturn {\n\t\t\t\toperations: entityOperations,\n\t\t\t\tpredicates: entityPredicates,\n\t\t\t}\n\t\t})\n\t}\n\n\tprivate mergePermissions(left: Acl.Permissions, right: Acl.Permissions): Acl.Permissions {\n\t\tconst result = { ...left }\n\t\tfor (let entityName in right) {\n\t\t\tif (result[entityName] !== undefined) {\n\t\t\t\tresult[entityName] = this.mergeEntityPermissions(result[entityName], right[entityName])\n\t\t\t} else {\n\t\t\t\tresult[entityName] = right[entityName]\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n\n\tprivate mergeEntityPermissions(left: Acl.EntityPermissions, right: Acl.EntityPermissions): Acl.EntityPermissions {\n\t\tlet predicates: Writable<Acl.PredicateMap> = {}\n\t\tconst operations: Writable<Acl.EntityOperations> = {}\n\t\tif (left.operations.customPrimary || right.operations.customPrimary) {\n\t\t\toperations.customPrimary = true\n\t\t}\n\t\tconst noRoot: `${Acl.Operation}`[] = []\n\n\t\tconst operationNames: (keyof Pick<Acl.EntityOperations, 'create' | 'read' | 'update'>)[] = [\n\t\t\t'create',\n\t\t\t'read',\n\t\t\t'update',\n\t\t]\n\n\t\tfor (let operation of operationNames) {\n\t\t\tconst leftNoRoot = left.operations.noRoot?.includes(operation) || false\n\t\t\tconst rightNoRoot = right.operations.noRoot?.includes(operation) || false\n\t\t\tif (leftNoRoot && rightNoRoot) {\n\t\t\t\tnoRoot.push(operation)\n\t\t\t}\n\n\t\t\tconst leftFieldPermissions: Acl.FieldPermissions = leftNoRoot && !rightNoRoot ? {} : (left.operations[operation] || {})\n\t\t\tconst rightFieldPermissions: Acl.FieldPermissions = rightNoRoot && !leftNoRoot ? {} : (right.operations[operation] || {})\n\t\t\tconst [operationPredicates, fieldPermissions] = this.mergeFieldPermissions(\n\t\t\t\tleft.predicates,\n\t\t\t\tleftFieldPermissions,\n\t\t\t\tright.predicates,\n\t\t\t\trightFieldPermissions,\n\t\t\t)\n\t\t\tpredicates = { ...predicates, ...operationPredicates }\n\t\t\tif (Object.keys(fieldPermissions).length > 0) {\n\t\t\t\toperations[operation] = fieldPermissions\n\t\t\t}\n\t\t}\n\n\t\tconst [predicateDefinition, predicate] = this.mergePredicates(\n\t\t\tleft.predicates,\n\t\t\tleft.operations.delete || false,\n\t\t\tright.predicates,\n\t\t\tright.operations.delete || false,\n\t\t)\n\t\tif (predicate === true) {\n\t\t\toperations.delete = true\n\t\t} else if (predicateDefinition !== undefined && typeof predicate === 'string') {\n\t\t\tpredicates[predicate] = predicateDefinition\n\t\t\toperations.delete = predicate\n\t\t}\n\t\tif (noRoot.length > 0) {\n\t\t\toperations.noRoot = noRoot\n\t\t}\n\n\t\treturn {\n\t\t\tpredicates: predicates,\n\t\t\toperations: operations,\n\t\t}\n\t}\n\n\tprivate mergeFieldPermissions(\n\t\tleftPredicates: Acl.PredicateMap,\n\t\tleftFieldPermissions: Acl.FieldPermissions,\n\t\trightPredicates: Acl.PredicateMap,\n\t\trightFieldPermissions: Acl.FieldPermissions,\n\t): [Acl.PredicateMap, Acl.FieldPermissions] {\n\t\tconst fields: Writable<Acl.FieldPermissions> = {}\n\t\tconst predicates: Writable<Acl.PredicateMap> = {}\n\n\t\tfor (let field in { ...leftFieldPermissions, ...rightFieldPermissions }) {\n\t\t\tconst [predicateDefinition, predicate] = this.mergePredicates(\n\t\t\t\tleftPredicates,\n\t\t\t\tleftFieldPermissions[field] || false,\n\t\t\t\trightPredicates,\n\t\t\t\trightFieldPermissions[field] || false,\n\t\t\t)\n\t\t\tif (predicate === true) {\n\t\t\t\tfields[field] = true\n\t\t\t} else if (predicateDefinition !== undefined && typeof predicate === 'string') {\n\t\t\t\tfields[field] = predicate\n\t\t\t\tpredicates[predicate] = predicateDefinition\n\t\t\t}\n\t\t}\n\n\t\treturn [predicates, fields]\n\t}\n\n\tprivate mergePredicates(\n\t\tleftPredicates: Acl.PredicateMap,\n\t\tleftReference: Acl.Predicate,\n\t\trightPredicates: Acl.PredicateMap,\n\t\trightReference: Acl.Predicate,\n\t): [Acl.PredicateDefinition, Acl.PredicateReference] | [undefined, boolean] {\n\t\tif (leftReference === true || rightReference === true) {\n\t\t\treturn [undefined, true]\n\t\t}\n\n\t\tif (leftReference !== false && rightReference !== false) {\n\t\t\tconst leftPredicate: Acl.PredicateDefinition = leftPredicates[leftReference]\n\t\t\tconst rightPredicate: Acl.PredicateDefinition = rightPredicates[rightReference]\n\t\t\tif (leftPredicate === rightPredicate) {\n\t\t\t\treturn [leftPredicate, leftReference]\n\t\t\t}\n\n\t\t\tlet predicateName = '__merge__' + leftReference + '__' + rightReference\n\t\t\twhile (leftPredicates[predicateName]) {\n\t\t\t\tpredicateName += '_'\n\t\t\t}\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tor: [leftPredicate, rightPredicate],\n\t\t\t\t} as Acl.PredicateDefinition,\n\t\t\t\tpredicateName,\n\t\t\t]\n\t\t} else if (leftReference !== false) {\n\t\t\treturn [leftPredicates[leftReference], leftReference]\n\t\t} else if (rightReference !== false) {\n\t\t\tlet predicateName = rightReference\n\t\t\tif (rightPredicates !== leftPredicates) {\n\t\t\t\twhile (leftPredicates[predicateName]) {\n\t\t\t\t\tpredicateName += '_'\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn [rightPredicates[rightReference], predicateName]\n\t\t} else {\n\t\t\treturn [undefined, false]\n\t\t}\n\t}\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PermissionFactory.js","sources":["../../../../../packages/engine-content-api/src/acl/PermissionFactory.ts"],"sourcesContent":["import { Acl, Model, Schema, Writable } from '@contember/schema'\nimport { getEntity, PredicateDefinitionProcessor } from '@contember/schema-utils'\nimport { mapObject } from '../utils'\nimport { prefixVariable } from './VariableUtils'\n\nexport interface Identity {\n\tprojectRoles: readonly string[]\n}\n\nexport class PermissionFactory {\n\tpublic create(schema: Schema, roles: readonly string[], prefix?: string): Acl.Permissions {\n\t\tlet result: Acl.Permissions = {}\n\t\tfor (let role of roles) {\n\t\t\tconst roleDefinition = schema.acl.roles[role] || { entities: {} }\n\t\t\tlet rolePermissions: Acl.Permissions = this.prefixPredicatesWithRole(schema.model, roleDefinition.entities, prefix || role)\n\t\t\tif (roleDefinition.inherits) {\n\t\t\t\tconst inheritedPermissions = this.create(schema, roleDefinition.inherits, prefix || role)\n\t\t\t\trolePermissions = this.mergePermissions(inheritedPermissions, rolePermissions)\n\t\t\t}\n\t\t\tresult = this.mergePermissions(result, rolePermissions)\n\t\t}\n\t\tresult = this.makePrimaryPredicatesUnionOfAllFields(schema.model, result)\n\n\t\treturn result\n\t}\n\n\tprivate prefixPredicatesWithRole(model: Model.Schema, permissions: Acl.Permissions, role: string): Acl.Permissions {\n\t\treturn mapObject(permissions, ({ operations, predicates }, entityName) => ({\n\t\t\toperations,\n\t\t\tpredicates: mapObject(predicates, predicate => {\n\t\t\t\tconst predicateDefinitionProcessor = new PredicateDefinitionProcessor(model)\n\t\t\t\treturn predicateDefinitionProcessor.process(getEntity(model, entityName), predicate, {\n\t\t\t\t\thandleColumn: ({ value }) => {\n\t\t\t\t\t\tif (typeof value === 'string') {\n\t\t\t\t\t\t\treturn prefixVariable(role, value)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn value\n\t\t\t\t\t},\n\t\t\t\t\thandleRelation: ({ value }) => {\n\t\t\t\t\t\tif (typeof value === 'string') {\n\t\t\t\t\t\t\treturn prefixVariable(role, value)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn value\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t}),\n\t\t}))\n\t}\n\n\tprivate makePrimaryPredicatesUnionOfAllFields(model: Model.Schema, permissions: Acl.Permissions): Acl.Permissions {\n\t\treturn mapObject(permissions, (permission, entityName): Acl.EntityPermissions => {\n\t\t\tconst entity = getEntity(model, entityName)\n\t\t\tconst entityPredicates: Writable<Acl.PredicateMap> = { ...permission.predicates }\n\t\t\tconst entityOperations: Writable<Acl.EntityOperations> = { ...permission.operations }\n\n\t\t\tconst operationNames = ['read', 'create', 'update'] as const\n\t\t\tfor (let operation of operationNames) {\n\t\t\t\tif (!entityOperations[operation]) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst fieldPermissions: Writable<Acl.FieldPermissions> = { ...entityOperations[operation] }\n\t\t\t\tentityOperations[operation] = fieldPermissions\n\n\t\t\t\tif (Object.values(fieldPermissions).some(it => it === true)) {\n\t\t\t\t\tfieldPermissions[entity.primary] = true\n\t\t\t\t}\n\t\t\t\tif (fieldPermissions[entity.primary] === true) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst predicateReferences: string[] = Object.entries(fieldPermissions)\n\t\t\t\t\t.filter(([key]) => key !== entity.primary)\n\t\t\t\t\t.map(([key, value]) => value)\n\t\t\t\t\t.filter(value => value !== false)\n\t\t\t\t\t.filter((value, index, array): value is string => array.indexOf(value) === index)\n\n\t\t\t\tlet idPermissions: Acl.Predicate = fieldPermissions[entity.primary] || false\n\n\t\t\t\tfor (let predicateReference of predicateReferences) {\n\t\t\t\t\tconst { predicateDefinition, predicate } = this.mergePredicates(\n\t\t\t\t\t\tentityPredicates,\n\t\t\t\t\t\tidPermissions,\n\t\t\t\t\t\tentityPredicates,\n\t\t\t\t\t\tpredicateReference,\n\t\t\t\t\t)\n\t\t\t\t\tif (typeof predicate !== 'string' || predicateDefinition === undefined) {\n\t\t\t\t\t\tthrow new Error('should not happen')\n\t\t\t\t\t}\n\t\t\t\t\tidPermissions = predicate\n\t\t\t\t\tentityPredicates[predicate] = predicateDefinition\n\t\t\t\t}\n\t\t\t\tfieldPermissions[entity.primary] = idPermissions\n\t\t\t\tentityPredicates[idPermissions as Acl.PredicateReference] = entityPredicates[idPermissions as Acl.PredicateReference]\n\t\t\t}\n\t\t\treturn {\n\t\t\t\toperations: entityOperations,\n\t\t\t\tpredicates: entityPredicates,\n\t\t\t}\n\t\t})\n\t}\n\n\tprivate mergePermissions(left: Acl.Permissions, right: Acl.Permissions): Acl.Permissions {\n\t\tconst result = { ...left }\n\t\tfor (let entityName in right) {\n\t\t\tif (result[entityName] !== undefined) {\n\t\t\t\tresult[entityName] = this.mergeEntityPermissions(result[entityName], right[entityName])\n\t\t\t} else {\n\t\t\t\tresult[entityName] = right[entityName]\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n\n\tprivate mergeEntityPermissions(left: Acl.EntityPermissions, right: Acl.EntityPermissions): Acl.EntityPermissions {\n\t\tlet predicates: Writable<Acl.PredicateMap> = {}\n\t\tconst operations: Writable<Acl.EntityOperations> = {}\n\t\tif (left.operations.customPrimary || right.operations.customPrimary) {\n\t\t\toperations.customPrimary = true\n\t\t}\n\t\tconst noRoot: `${Acl.Operation}`[] = []\n\n\t\tfor (let operation of [\n\t\t\t'create',\n\t\t\t'read',\n\t\t\t'update',\n\t\t] as const) {\n\n\t\t\tconst { predicates: opPredicates, permissions: fieldPermissions, noRoot: opNoRoot } = this.mergeOperationPermissions(left, right, operation)\n\n\t\t\tif (opNoRoot) {\n\t\t\t\tnoRoot.push(operation)\n\t\t\t}\n\n\t\t\tpredicates = { ...predicates, ...opPredicates }\n\t\t\tif (Object.keys(fieldPermissions).length > 0) {\n\t\t\t\toperations[operation] = fieldPermissions\n\t\t\t}\n\t\t}\n\n\t\tconst { predicateDefinition, predicate, noRoot: opNoRoot } = this.mergeDeletePermissions(left, right)\n\t\tif (opNoRoot) {\n\t\t\tnoRoot.push('delete')\n\t\t}\n\t\tif (predicate === true) {\n\t\t\toperations.delete = true\n\t\t} else if (predicateDefinition !== undefined && typeof predicate === 'string') {\n\t\t\tpredicates[predicate] = predicateDefinition\n\t\t\toperations.delete = predicate\n\t\t}\n\n\n\t\tif (noRoot.length > 0) {\n\t\t\toperations.noRoot = noRoot\n\t\t}\n\n\t\treturn {\n\t\t\tpredicates: predicates,\n\t\t\toperations: operations,\n\t\t}\n\t}\n\n\n\tprivate mergeOperationPermissions(left: Acl.EntityPermissions, right: Acl.EntityPermissions, operation: 'create' | 'read' | 'update'): {\n\t\tnoRoot: boolean\n\t\tpredicates: Acl.PredicateMap\n\t\tpermissions: Acl.FieldPermissions\n\t} {\n\t\tconst { noRoot, leftPermissions, rightPermissions } = this.resolveNoRoot(left, right, operation)\n\t\treturn {\n\t\t\tnoRoot,\n\t\t\t...this.mergeFieldPermissions(\n\t\t\t\tleft.predicates,\n\t\t\t\tleftPermissions,\n\t\t\t\tright.predicates,\n\t\t\t\trightPermissions,\n\t\t\t),\n\t\t}\n\t}\n\n\tprivate mergeDeletePermissions(left: Acl.EntityPermissions, right: Acl.EntityPermissions): {\n\t\tnoRoot: boolean\n\t\tpredicate: Acl.PredicateReference | boolean\n\t\tpredicateDefinition: Acl.PredicateDefinition | undefined\n\t} {\n\t\tconst { noRoot, leftPermissions, rightPermissions } = this.resolveNoRoot(left, right, 'delete')\n\n\t\treturn {\n\t\t\tnoRoot,\n\t\t\t...this.mergePredicates(\n\t\t\t\tleft.predicates,\n\t\t\t\tleftPermissions,\n\t\t\t\tright.predicates,\n\t\t\t\trightPermissions,\n\t\t\t),\n\t\t}\n\t}\n\n\tprivate resolveNoRoot<const Op extends`${Acl.Operation}`>(left: Acl.EntityPermissions, right: Acl.EntityPermissions, operation: Op): {\n\t\tnoRoot: boolean\n\t\tleftPermissions: Acl.EntityPermissions['operations'][Op] | undefined\n\t\trightPermissions: Acl.EntityPermissions['operations'][Op] | undefined\n\t} {\n\t\tconst leftRootForbidden = left.operations.noRoot?.includes(operation) || false\n\t\tconst rightRootForbidden = right.operations.noRoot?.includes(operation) || false\n\t\tconst leftPermissions = left.operations[operation]\n\t\tconst rightPermissions = right.operations[operation]\n\n\t\tconst rootForbidden = (leftRootForbidden && rightRootForbidden)\n\t\t\t|| (leftRootForbidden && !rightPermissions)\n\t\t\t|| (rightRootForbidden && !leftPermissions)\n\n\t\tconst resolvedLeftPermissions = !rootForbidden && leftRootForbidden ? undefined : leftPermissions\n\t\tconst resolvedRightPermissions = !rootForbidden && rightRootForbidden ? undefined : rightPermissions\n\n\t\treturn {\n\t\t\tnoRoot: rootForbidden,\n\t\t\tleftPermissions: resolvedLeftPermissions,\n\t\t\trightPermissions: resolvedRightPermissions,\n\t\t}\n\t}\n\n\tprivate mergeFieldPermissions(\n\t\tleftPredicates: Acl.PredicateMap,\n\t\tleftFieldPermissions: Acl.FieldPermissions | undefined = {},\n\t\trightPredicates: Acl.PredicateMap,\n\t\trightFieldPermissions: Acl.FieldPermissions | undefined = {},\n\t): {predicates: Acl.PredicateMap; permissions: Acl.FieldPermissions} {\n\t\tconst permissions: Writable<Acl.FieldPermissions> = {}\n\t\tconst predicates: Writable<Acl.PredicateMap> = {}\n\n\t\tfor (let field in { ...leftFieldPermissions, ...rightFieldPermissions }) {\n\t\t\tconst { predicateDefinition, predicate } = this.mergePredicates(\n\t\t\t\tleftPredicates,\n\t\t\t\tleftFieldPermissions[field] || false,\n\t\t\t\trightPredicates,\n\t\t\t\trightFieldPermissions[field] || false,\n\t\t\t)\n\t\t\tif (predicate === true) {\n\t\t\t\tpermissions[field] = true\n\t\t\t} else if (predicateDefinition !== undefined && typeof predicate === 'string') {\n\t\t\t\tpermissions[field] = predicate\n\t\t\t\tpredicates[predicate] = predicateDefinition\n\t\t\t}\n\t\t}\n\n\t\treturn { predicates, permissions }\n\t}\n\n\tprivate mergePredicates(\n\t\tleftPredicates: Acl.PredicateMap,\n\t\tleftReference: Acl.Predicate | undefined = false,\n\t\trightPredicates: Acl.PredicateMap,\n\t\trightReference: Acl.Predicate | undefined = false,\n\t): {\n\t\tpredicate: Acl.PredicateReference | boolean\n\t\tpredicateDefinition: Acl.PredicateDefinition | undefined\n\t} {\n\t\tif (leftReference === true || rightReference === true) {\n\t\t\treturn {\n\t\t\t\tpredicate: true,\n\t\t\t\tpredicateDefinition: undefined,\n\t\t\t}\n\t\t}\n\n\t\tif (leftReference !== false && rightReference !== false) {\n\t\t\tconst leftPredicate: Acl.PredicateDefinition = leftPredicates[leftReference]\n\t\t\tconst rightPredicate: Acl.PredicateDefinition = rightPredicates[rightReference]\n\t\t\tif (leftPredicate === rightPredicate) {\n\t\t\t\treturn {\n\t\t\t\t\tpredicate: leftReference,\n\t\t\t\t\tpredicateDefinition: leftPredicate,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet predicateName = '__merge__' + leftReference + '__' + rightReference\n\t\t\twhile (leftPredicates[predicateName]) {\n\t\t\t\tpredicateName += '_'\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tpredicate: predicateName,\n\t\t\t\tpredicateDefinition: {\n\t\t\t\t\tor: [leftPredicate, rightPredicate],\n\t\t\t\t} as Acl.PredicateDefinition,\n\t\t\t}\n\t\t} else if (leftReference !== false) {\n\t\t\treturn {\n\t\t\t\tpredicate: leftReference,\n\t\t\t\tpredicateDefinition: leftPredicates[leftReference],\n\t\t\t}\n\t\t} else if (rightReference !== false) {\n\t\t\tlet predicateName = rightReference\n\t\t\tif (rightPredicates !== leftPredicates) {\n\t\t\t\twhile (leftPredicates[predicateName]) {\n\t\t\t\t\tpredicateName += '_'\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tpredicate: predicateName,\n\t\t\t\tpredicateDefinition: rightPredicates[rightReference],\n\t\t\t}\n\t\t} else {\n\t\t\treturn {\n\t\t\t\tpredicate: false,\n\t\t\t\tpredicateDefinition: undefined,\n\t\t\t}\n\t\t}\n\t}\n}\n"],"names":["opNoRoot"],"mappings":"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"}