Skip to content

Commit bced3d9

Browse files
author
Dobbias Nan
committed
added pointer-permissions support
1 parent aebdf5b commit bced3d9

File tree

1 file changed

+67
-3
lines changed

1 file changed

+67
-3
lines changed

src/Controllers/DatabaseController.js

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,73 @@ const filterSensitiveData = (
195195
isMaster: boolean,
196196
aclGroup: any[],
197197
auth: any,
198+
operation: any,
199+
schema: SchemaController.SchemaController,
198200
className: string,
199201
protectedFields: null | Array<any>,
200202
object: any
201203
) => {
204+
let userId = null;
205+
if (auth && auth.user) userId = auth.user.id;
206+
207+
// replace protectedFields when using pointer-permissions
208+
const perms = schema.getClassLevelPermissions(className);
209+
if (perms) {
210+
const field =
211+
['get', 'find'].indexOf(operation) > -1
212+
? 'readUserFields'
213+
: 'writeUserFields';
214+
const fieldKeys: string[] = perms[field];
215+
216+
if (
217+
field === 'readUserFields' &&
218+
fieldKeys &&
219+
fieldKeys.length > 0 &&
220+
perms.protectedFields
221+
) {
222+
// extract protectedFields added with the pointer-permission prefix
223+
const protectedFieldsPointerPerm = Object.keys(perms.protectedFields)
224+
.filter(key => key.startsWith('readUserFields:'))
225+
.map(key => {
226+
return { key: key.substring(15), value: perms.protectedFields[key] };
227+
});
228+
229+
const newProtectedFields: Array<string> = [];
230+
let overrideProtectedFields = false;
231+
232+
// check if the object grants the current user access based on the extracted fields
233+
protectedFieldsPointerPerm.forEach(pointerPerm => {
234+
if (!fieldKeys.includes(pointerPerm.key)) return;
235+
let pointerPermIncludesUser = false;
236+
const readUserFieldValue = object[pointerPerm.key];
237+
if (readUserFieldValue) {
238+
if (Array.isArray(readUserFieldValue)) {
239+
pointerPermIncludesUser = readUserFieldValue.some(
240+
user => user.objectId && user.objectId === userId
241+
);
242+
} else {
243+
pointerPermIncludesUser =
244+
readUserFieldValue.objectId &&
245+
readUserFieldValue.objectId === userId;
246+
}
247+
}
248+
249+
if (pointerPermIncludesUser) {
250+
overrideProtectedFields = true;
251+
newProtectedFields.push(...pointerPerm.value);
252+
}
253+
});
254+
255+
// if atleast one pointer-permission affected the current user override the protectedFields
256+
if (overrideProtectedFields) protectedFields = newProtectedFields;
257+
}
258+
}
259+
202260
const isUserClass = className === '_User';
203-
if (!isUserClass || !auth || !auth.user || object.objectId !== auth.user.id)
261+
262+
/* special treat for the user class: don't filter protectedFields if currently loggedin user is
263+
the retrieved user */
264+
if (!(isUserClass && userId && object.objectId === userId))
204265
protectedFields && protectedFields.forEach(k => delete object[k]);
205266

206267
if (!isUserClass) {
@@ -1318,8 +1379,9 @@ class DatabaseController {
13181379
query,
13191380
aclGroup
13201381
);
1321-
// ProtectedFields is generated before executing the query so we
1322-
// can optimize the query using Mongo Projection at a later stage.
1382+
/* Don't use projections to optimize the protectedFields since the protectedFields
1383+
based on pointer-permissions are determined after querying. The filtering can
1384+
overwrite the protected fields. */
13231385
protectedFields = this.addProtectedFields(
13241386
schemaController,
13251387
className,
@@ -1389,6 +1451,8 @@ class DatabaseController {
13891451
isMaster,
13901452
aclGroup,
13911453
auth,
1454+
op,
1455+
schemaController,
13921456
className,
13931457
protectedFields,
13941458
object

0 commit comments

Comments
 (0)