Skip to content

Commit 984e0ce

Browse files
authored
Merge pull request #159 from Kashoo/issue156_unauthorized_delete
Issue #156 unauthorized delete
2 parents d3df4b8 + a097137 commit 984e0ce

5 files changed

Lines changed: 109 additions & 6 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
55
## [Unreleased]
66

77
### Changed
8+
- [#156](https://github.com/Kashoo/synctos/issues/156): Fix for an edge case where users assigned a replace role may gain the privilege of removing a document erroneously under certain document definition conditions
89
- [#157](https://github.com/Kashoo/synctos/issues/157): Swap in Chai as the assertion library used in specs throughout the project
910

1011
## [1.9.3] - 2017-10-23

etc/sync-function-authorization-module.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,11 @@ function() {
5757
appendToAuthorizationList(requiredAuthorizations, authorizationMap.write);
5858
}
5959

60-
if (doc._deleted && authorizationMap.remove) {
61-
writeAuthorizationFound = true;
62-
appendToAuthorizationList(requiredAuthorizations, authorizationMap.remove);
60+
if (doc._deleted) {
61+
if (authorizationMap.remove) {
62+
writeAuthorizationFound = true;
63+
appendToAuthorizationList(requiredAuthorizations, authorizationMap.remove);
64+
}
6365
} else if (!isDocumentMissingOrDeleted(oldDoc) && authorizationMap.replace) {
6466
writeAuthorizationFound = true;
6567
appendToAuthorizationList(requiredAuthorizations, authorizationMap.replace);

etc/test-helper.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -645,11 +645,11 @@ function verifyAccessDenied(doc, oldDoc, expectedAuthorization) {
645645
} else if (countAuthorizationTypes(expectedAuthorization) > 1) {
646646
assert.equal(ex.forbidden, generalAuthFailedMessage, 'Expected authorization exception not met: ' + ex.forbidden);
647647
} else if (expectedAuthorization.expectedChannels) {
648-
assert.ok(ex instanceof Error && ex.message === channelAccessDenied.message, 'Expected channel authorization error not triggered');
648+
assert.equal(ex, channelAccessDenied, 'Expected channel authorization error not triggered, got this instead: ' + ex);
649649
} else if (expectedAuthorization.expectedRoles) {
650-
assert.ok(ex instanceof Error && ex.message === roleAccessDenied.message, 'Expected role authorization error not triggered');
650+
assert.equal(ex, roleAccessDenied, 'Expected role authorization error not triggered, got this instead: ' + ex);
651651
} else if (expectedAuthorization.expectedUsers) {
652-
assert.ok(ex instanceof Error && ex.message === userAccessDenied.message, 'Expected user authorization error not triggered');
652+
assert.equal(ex, userAccessDenied, 'Expected user authorization error not triggered, got this instead: ' + ex);
653653
}
654654
}
655655

test/authorization-spec.js

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,4 +232,78 @@ describe('Authorization:', function() {
232232
testHelper.verifyAccessDenied(doc, oldDoc, { });
233233
});
234234
});
235+
236+
describe('for a document with statically-assigned replace role and nothing else', function() {
237+
it('rejects document creation', function() {
238+
var doc = {
239+
_id: 'replaceOnlyRoleDoc',
240+
stringProp: 'foobar'
241+
};
242+
243+
testHelper.verifyAccessDenied(doc, null, []);
244+
});
245+
246+
it('allows document replacement', function() {
247+
var doc = {
248+
_id: 'replaceOnlyRoleDoc',
249+
stringProp: 'foobar'
250+
};
251+
var oldDoc = {
252+
_id: 'replaceOnlyRoleDoc',
253+
stringProp: 'barfoo'
254+
};
255+
256+
testHelper.verifyDocumentReplaced(doc, oldDoc, { expectedRoles: [ 'replace' ] });
257+
});
258+
259+
it('rejects document deletion for a user with only replace role', function() {
260+
var doc = {
261+
_id: 'replaceOnlyRoleDoc',
262+
_deleted: true
263+
};
264+
var oldDoc = {
265+
_id: 'replaceOnlyRoleDoc',
266+
stringProp: 'foobar'
267+
};
268+
269+
testHelper.verifyAccessDenied(doc, oldDoc, []);
270+
});
271+
});
272+
273+
describe('for a document with statically-assigned add role and nothing else', function() {
274+
it('allows document creation', function() {
275+
var doc = {
276+
_id: 'addOnlyRoleDoc',
277+
stringProp: 'foobar'
278+
};
279+
280+
testHelper.verifyDocumentCreated(doc, { expectedRoles: [ 'add' ] });
281+
});
282+
283+
it('rejects document replacement', function() {
284+
var doc = {
285+
_id: 'addOnlyRoleDoc',
286+
stringProp: 'foobar'
287+
};
288+
var oldDoc = {
289+
_id: 'addOnlyRoleDoc',
290+
stringProp: 'barfoo'
291+
};
292+
293+
testHelper.verifyAccessDenied(doc, oldDoc, []);
294+
});
295+
296+
it('rejects document deletion for a user with only add role', function() {
297+
var doc = {
298+
_id: 'addOnlyRoleDoc',
299+
_deleted: true
300+
};
301+
var oldDoc = {
302+
_id: 'addOnlyRoleDoc',
303+
stringProp: 'foobar'
304+
};
305+
306+
testHelper.verifyAccessDenied(doc, oldDoc, []);
307+
});
308+
});
235309
});

test/resources/authorization-doc-definitions.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,5 +109,31 @@
109109
type: 'string'
110110
}
111111
}
112+
},
113+
replaceOnlyRoleDoc: {
114+
authorizedRoles: {
115+
replace: 'replace'
116+
},
117+
typeFilter: function(doc) {
118+
return doc._id === 'replaceOnlyRoleDoc';
119+
},
120+
propertyValidators: {
121+
stringProp: {
122+
type: 'string'
123+
}
124+
}
125+
},
126+
addOnlyRoleDoc: {
127+
authorizedRoles: {
128+
add: 'add'
129+
},
130+
typeFilter: function(doc) {
131+
return doc._id === 'addOnlyRoleDoc';
132+
},
133+
propertyValidators: {
134+
stringProp: {
135+
type: 'string'
136+
}
137+
}
112138
}
113139
}

0 commit comments

Comments
 (0)