Skip to content

Commit cc55fed

Browse files
committed
Added extra test cases and fixed issue found with them.
1 parent af9f91c commit cc55fed

File tree

2 files changed

+99
-26
lines changed

2 files changed

+99
-26
lines changed

spec/DatabaseController.spec.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,65 @@ describe('DatabaseController', function () {
236236
done();
237237
});
238238

239+
it('should not return a $or operation if the query involves one of the two fields also used as array/pointer permissions', done => {
240+
const clp = buildCLP(['users', 'user']);
241+
const query = { a: 'b', user: createUserPointer(USER_ID) };
242+
243+
schemaController.testPermissionsForClassName
244+
.withArgs(CLASS_NAME, ACL_GROUP, OPERATION)
245+
.and.returnValue(false);
246+
schemaController.getClassLevelPermissions.withArgs(CLASS_NAME).and.returnValue(clp);
247+
schemaController.getExpectedType
248+
.withArgs(CLASS_NAME, 'user')
249+
.and.returnValue({ type: 'Pointer' });
250+
schemaController.getExpectedType
251+
.withArgs(CLASS_NAME, 'users')
252+
.and.returnValue({ type: 'Array' });
253+
254+
const output = databaseController.addPointerPermissions(
255+
schemaController,
256+
CLASS_NAME,
257+
OPERATION,
258+
query,
259+
ACL_GROUP
260+
);
261+
262+
expect(output).toEqual({ ...query, user: createUserPointer(USER_ID) });
263+
264+
done();
265+
});
266+
267+
it('should not return a $or operation if the query involves one of the fields also used as array/pointer permissions', done => {
268+
const clp = buildCLP(['user', 'users', 'userObject']);
269+
const query = { a: 'b', user: createUserPointer(USER_ID) };
270+
271+
schemaController.testPermissionsForClassName
272+
.withArgs(CLASS_NAME, ACL_GROUP, OPERATION)
273+
.and.returnValue(false);
274+
schemaController.getClassLevelPermissions.withArgs(CLASS_NAME).and.returnValue(clp);
275+
schemaController.getExpectedType
276+
.withArgs(CLASS_NAME, 'user')
277+
.and.returnValue({ type: 'Pointer' });
278+
schemaController.getExpectedType
279+
.withArgs(CLASS_NAME, 'users')
280+
.and.returnValue({ type: 'Array' });
281+
schemaController.getExpectedType
282+
.withArgs(CLASS_NAME, 'userObject')
283+
.and.returnValue({ type: 'Object' });
284+
285+
const output = databaseController.addPointerPermissions(
286+
schemaController,
287+
CLASS_NAME,
288+
OPERATION,
289+
query,
290+
ACL_GROUP
291+
);
292+
293+
expect(output).toEqual({ ...query, user: createUserPointer(USER_ID) });
294+
295+
done();
296+
});
297+
239298
it('should throw an error if for some unexpected reason the property specified in the CLP is neither a pointer nor an array', done => {
240299
const clp = buildCLP(['user']);
241300
const query = { a: 'b' };

src/Controllers/DatabaseController.js

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,21 +1378,28 @@ class DatabaseController {
13781378
return query;
13791379
}
13801380
const queries = query.$or.map(q => this.objectToEntriesStrings(q));
1381-
for (let i = 0; i < queries.length - 1; i++) {
1382-
for (let j = i + 1; j < queries.length; j++) {
1383-
const [shorter, longer] = queries[i].length > queries[j].length ? [j, i] : [i, j];
1384-
const foundEntries = queries[shorter].reduce(
1385-
(acc, entry) => acc + (queries[longer].includes(entry) ? 1 : 0),
1386-
0
1387-
);
1388-
if (foundEntries === queries[shorter].length) {
1389-
// If the shorter query is completely contained in the longer one, we can strike
1390-
// out the longer query.
1391-
query.$or.splice(longer, 1);
1392-
queries.splice(longer, 1);
1381+
let repeat = false;
1382+
do {
1383+
repeat = false;
1384+
for (let i = 0; i < queries.length - 1; i++) {
1385+
for (let j = i + 1; j < queries.length; j++) {
1386+
const [shorter, longer] = queries[i].length > queries[j].length ? [j, i] : [i, j];
1387+
const foundEntries = queries[shorter].reduce(
1388+
(acc, entry) => acc + (queries[longer].includes(entry) ? 1 : 0),
1389+
0
1390+
);
1391+
const shorterEntries = queries[shorter].length;
1392+
if (foundEntries === shorterEntries) {
1393+
// If the shorter query is completely contained in the longer one, we can strike
1394+
// out the longer query.
1395+
query.$or.splice(longer, 1);
1396+
queries.splice(longer, 1);
1397+
repeat = true;
1398+
break;
1399+
}
13931400
}
13941401
}
1395-
}
1402+
} while (repeat);
13961403
if (query.$or.length === 1) {
13971404
query = { ...query, ...query.$or[0] };
13981405
delete query.$or;
@@ -1406,21 +1413,28 @@ class DatabaseController {
14061413
return query;
14071414
}
14081415
const queries = query.$and.map(q => this.objectToEntriesStrings(q));
1409-
for (let i = 0; i < queries.length - 1; i++) {
1410-
for (let j = i + 1; j < queries.length; j++) {
1411-
const [shorter, longer] = queries[i].length > queries[j].length ? [j, i] : [i, j];
1412-
const foundEntries = queries[shorter].reduce(
1413-
(acc, entry) => acc + (queries[longer].includes(entry) ? 1 : 0),
1414-
0
1415-
);
1416-
if (foundEntries === queries[shorter].length) {
1417-
// If the shorter query is completely contained in the longer one, we can strike
1418-
// out the shorter query.
1419-
query.$and.splice(shorter, 1);
1420-
queries.splice(shorter, 1);
1416+
let repeat = false;
1417+
do {
1418+
repeat = false;
1419+
for (let i = 0; i < queries.length - 1; i++) {
1420+
for (let j = i + 1; j < queries.length; j++) {
1421+
const [shorter, longer] = queries[i].length > queries[j].length ? [j, i] : [i, j];
1422+
const foundEntries = queries[shorter].reduce(
1423+
(acc, entry) => acc + (queries[longer].includes(entry) ? 1 : 0),
1424+
0
1425+
);
1426+
const shorterEntries = queries[shorter].length;
1427+
if (foundEntries === shorterEntries) {
1428+
// If the shorter query is completely contained in the longer one, we can strike
1429+
// out the shorter query.
1430+
query.$and.splice(shorter, 1);
1431+
queries.splice(shorter, 1);
1432+
repeat = true;
1433+
break;
1434+
}
14211435
}
14221436
}
1423-
}
1437+
} while (repeat);
14241438
if (query.$and.length === 1) {
14251439
query = { ...query, ...query.$and[0] };
14261440
delete query.$and;

0 commit comments

Comments
 (0)