Patch allowRemoveAll flaw
This commit is contained in:
parent
e1b85092d5
commit
2c15ae9464
5 changed files with 39 additions and 23 deletions
|
@ -1,3 +1,6 @@
|
||||||
|
# 2.0.2
|
||||||
|
* Fix flaw where clients could remove all records, even if `allowRemoveAll` were `false`.
|
||||||
|
|
||||||
# 2.0.1
|
# 2.0.1
|
||||||
* Override `readMany` and `findOne`.
|
* Override `readMany` and `findOne`.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
include: package:pedantic/analysis_options.yaml
|
||||||
analyzer:
|
analyzer:
|
||||||
strong-mode:
|
strong-mode:
|
||||||
implicit-casts: false
|
implicit-casts: false
|
|
@ -12,10 +12,12 @@ class MongoService extends Service<String, Map<String, dynamic>> {
|
||||||
/// If set to `true`, parameters in `req.query` are applied to the database query.
|
/// If set to `true`, parameters in `req.query` are applied to the database query.
|
||||||
final bool allowQuery;
|
final bool allowQuery;
|
||||||
|
|
||||||
|
/// No longer used. Will be removed by `2.1.0`.
|
||||||
|
@deprecated
|
||||||
final bool debug;
|
final bool debug;
|
||||||
|
|
||||||
MongoService(DbCollection this.collection,
|
MongoService(DbCollection this.collection,
|
||||||
{this.allowRemoveAll: false, this.allowQuery: true, this.debug: true})
|
{this.allowRemoveAll = false, this.allowQuery = true, this.debug = true})
|
||||||
: super();
|
: super();
|
||||||
|
|
||||||
SelectorBuilder _makeQuery([Map<String, dynamic> params_]) {
|
SelectorBuilder _makeQuery([Map<String, dynamic> params_]) {
|
||||||
|
@ -51,7 +53,7 @@ class MongoService extends Service<String, Map<String, dynamic>> {
|
||||||
}
|
}
|
||||||
} else if (key == 'query' &&
|
} else if (key == 'query' &&
|
||||||
(allowQuery == true || !params.containsKey('provider'))) {
|
(allowQuery == true || !params.containsKey('provider'))) {
|
||||||
Map query = params[key];
|
var query = params[key] as Map;
|
||||||
query.forEach((key, v) {
|
query.forEach((key, v) {
|
||||||
var value = v is Map<String, dynamic> ? _filterNoQuery(v) : v;
|
var value = v is Map<String, dynamic> ? _filterNoQuery(v) : v;
|
||||||
|
|
||||||
|
@ -99,7 +101,7 @@ class MongoService extends Service<String, Map<String, dynamic>> {
|
||||||
var item = _removeSensitive(data);
|
var item = _removeSensitive(data);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String nonce = (await collection.db.getNonce())['nonce'];
|
var nonce = (await collection.db.getNonce())['nonce'] as String;
|
||||||
var result = await collection.findAndModify(
|
var result = await collection.findAndModify(
|
||||||
query: where.eq(_NONCE_KEY, nonce),
|
query: where.eq(_NONCE_KEY, nonce),
|
||||||
update: item,
|
update: item,
|
||||||
|
@ -209,12 +211,16 @@ class MongoService extends Service<String, Map<String, dynamic>> {
|
||||||
@override
|
@override
|
||||||
Future<Map<String, dynamic>> remove(String id,
|
Future<Map<String, dynamic>> remove(String id,
|
||||||
[Map<String, dynamic> params]) async {
|
[Map<String, dynamic> params]) async {
|
||||||
if (id == null ||
|
if (id == null || id == 'null') {
|
||||||
id == 'null' &&
|
// Remove everything...
|
||||||
(allowRemoveAll == true ||
|
if (!(allowRemoveAll == true ||
|
||||||
params?.containsKey('provider') != true)) {
|
params?.containsKey('provider') != true)) {
|
||||||
await collection.remove(null);
|
throw AngelHttpException.forbidden(
|
||||||
return {};
|
message: 'Clients are not allowed to delete all items.');
|
||||||
|
} else {
|
||||||
|
await collection.remove(null);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// var result = await read(id, params);
|
// var result = await read(id, params);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name: angel_mongo
|
name: angel_mongo
|
||||||
version: 2.0.1
|
version: 2.0.2
|
||||||
description: MongoDB-enabled services for the Angel framework. Well-tested.
|
description: MongoDB-enabled services for the Angel framework. Well-tested.
|
||||||
author: Tobe O <thosakwe@gmail.com>
|
author: Tobe O <thosakwe@gmail.com>
|
||||||
homepage: https://github.com/angel-dart/angel_mongo
|
homepage: https://github.com/angel-dart/angel_mongo
|
||||||
|
@ -12,4 +12,5 @@ dependencies:
|
||||||
mongo_dart: ">= 0.2.7 < 1.0.0"
|
mongo_dart: ">= 0.2.7 < 1.0.0"
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
http: ">= 0.11.3 < 0.12.0"
|
http: ">= 0.11.3 < 0.12.0"
|
||||||
|
pedantic: ^1.0.0
|
||||||
test: ^1.0.0
|
test: ^1.0.0
|
||||||
|
|
|
@ -80,8 +80,8 @@ main() {
|
||||||
|
|
||||||
response = await client.get("$url/api");
|
response = await client.get("$url/api");
|
||||||
expect(response.statusCode, isIn([200, 201]));
|
expect(response.statusCode, isIn([200, 201]));
|
||||||
List<Map> users =
|
var users = god.deserialize(response.body,
|
||||||
god.deserialize(response.body, outputType: <Map>[].runtimeType);
|
outputType: <Map>[].runtimeType) as List<Map>;
|
||||||
expect(users.length, equals(1));
|
expect(users.length, equals(1));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -89,11 +89,11 @@ main() {
|
||||||
var response = await client.post("$url/api",
|
var response = await client.post("$url/api",
|
||||||
body: god.serialize(testGreeting), headers: headers);
|
body: god.serialize(testGreeting), headers: headers);
|
||||||
expect(response.statusCode, isIn([200, 201]));
|
expect(response.statusCode, isIn([200, 201]));
|
||||||
Map created = god.deserialize(response.body);
|
var created = god.deserialize(response.body) as Map;
|
||||||
|
|
||||||
response = await client.get("$url/api/${created['id']}");
|
response = await client.get("$url/api/${created['id']}");
|
||||||
expect(response.statusCode, isIn([200, 201]));
|
expect(response.statusCode, isIn([200, 201]));
|
||||||
Map read = god.deserialize(response.body);
|
var read = god.deserialize(response.body) as Map;
|
||||||
expect(read['id'], equals(created['id']));
|
expect(read['id'], equals(created['id']));
|
||||||
expect(read['to'], equals('world'));
|
expect(read['to'], equals('world'));
|
||||||
//expect(read['createdAt'], isNot(null));
|
//expect(read['createdAt'], isNot(null));
|
||||||
|
@ -103,7 +103,7 @@ main() {
|
||||||
var response = await client.post("$url/api",
|
var response = await client.post("$url/api",
|
||||||
body: god.serialize(testGreeting), headers: headers);
|
body: god.serialize(testGreeting), headers: headers);
|
||||||
expect(response.statusCode, isIn([200, 201]));
|
expect(response.statusCode, isIn([200, 201]));
|
||||||
Map created = god.deserialize(response.body);
|
var created = god.deserialize(response.body) as Map;
|
||||||
|
|
||||||
var id = new ObjectId.fromHexString(created['id'] as String);
|
var id = new ObjectId.fromHexString(created['id'] as String);
|
||||||
var read = await greetingService.findOne({'query': where.id(id)});
|
var read = await greetingService.findOne({'query': where.id(id)});
|
||||||
|
@ -116,7 +116,7 @@ main() {
|
||||||
var response = await client.post("$url/api",
|
var response = await client.post("$url/api",
|
||||||
body: god.serialize(testGreeting), headers: headers);
|
body: god.serialize(testGreeting), headers: headers);
|
||||||
expect(response.statusCode, isIn([200, 201]));
|
expect(response.statusCode, isIn([200, 201]));
|
||||||
Map created = god.deserialize(response.body);
|
var created = god.deserialize(response.body) as Map;
|
||||||
|
|
||||||
var id = new ObjectId.fromHexString(created['id'] as String);
|
var id = new ObjectId.fromHexString(created['id'] as String);
|
||||||
var read = await greetingService.readMany([id.toHexString()]);
|
var read = await greetingService.readMany([id.toHexString()]);
|
||||||
|
@ -128,11 +128,11 @@ main() {
|
||||||
var response = await client.post("$url/api",
|
var response = await client.post("$url/api",
|
||||||
body: god.serialize(testGreeting), headers: headers);
|
body: god.serialize(testGreeting), headers: headers);
|
||||||
expect(response.statusCode, isIn([200, 201]));
|
expect(response.statusCode, isIn([200, 201]));
|
||||||
Map created = god.deserialize(response.body);
|
var created = god.deserialize(response.body) as Map;
|
||||||
|
|
||||||
response = await client.patch("$url/api/${created['id']}",
|
response = await client.patch("$url/api/${created['id']}",
|
||||||
body: god.serialize({"to": "Mom"}), headers: headers);
|
body: god.serialize({"to": "Mom"}), headers: headers);
|
||||||
Map modified = god.deserialize(response.body);
|
var modified = god.deserialize(response.body) as Map;
|
||||||
expect(response.statusCode, isIn([200, 201]));
|
expect(response.statusCode, isIn([200, 201]));
|
||||||
expect(modified['id'], equals(created['id']));
|
expect(modified['id'], equals(created['id']));
|
||||||
expect(modified['to'], equals('Mom'));
|
expect(modified['to'], equals('Mom'));
|
||||||
|
@ -143,11 +143,11 @@ main() {
|
||||||
var response = await client.post("$url/api",
|
var response = await client.post("$url/api",
|
||||||
body: god.serialize(testGreeting), headers: headers);
|
body: god.serialize(testGreeting), headers: headers);
|
||||||
expect(response.statusCode, isIn([200, 201]));
|
expect(response.statusCode, isIn([200, 201]));
|
||||||
Map created = god.deserialize(response.body);
|
var created = god.deserialize(response.body) as Map;
|
||||||
|
|
||||||
response = await client.post("$url/api/${created['id']}",
|
response = await client.post("$url/api/${created['id']}",
|
||||||
body: god.serialize({"to": "Updated"}), headers: headers);
|
body: god.serialize({"to": "Updated"}), headers: headers);
|
||||||
Map modified = god.deserialize(response.body);
|
var modified = god.deserialize(response.body) as Map;
|
||||||
expect(response.statusCode, isIn([200, 201]));
|
expect(response.statusCode, isIn([200, 201]));
|
||||||
expect(modified['id'], equals(created['id']));
|
expect(modified['id'], equals(created['id']));
|
||||||
expect(modified['to'], equals('Updated'));
|
expect(modified['to'], equals('Updated'));
|
||||||
|
@ -157,7 +157,7 @@ main() {
|
||||||
test('remove item', () async {
|
test('remove item', () async {
|
||||||
var response = await client.post("$url/api",
|
var response = await client.post("$url/api",
|
||||||
body: god.serialize(testGreeting), headers: headers);
|
body: god.serialize(testGreeting), headers: headers);
|
||||||
Map created = god.deserialize(response.body);
|
var created = god.deserialize(response.body) as Map;
|
||||||
|
|
||||||
int lastCount = (await greetingService.index()).length;
|
int lastCount = (await greetingService.index()).length;
|
||||||
|
|
||||||
|
@ -165,6 +165,11 @@ main() {
|
||||||
expect((await greetingService.index()).length, equals(lastCount - 1));
|
expect((await greetingService.index()).length, equals(lastCount - 1));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('cannot remove all unless explicitly set', () async {
|
||||||
|
var response = await client.delete('$url/api/null');
|
||||||
|
expect(response.statusCode, 403);
|
||||||
|
});
|
||||||
|
|
||||||
test('\$sort and query parameters', () async {
|
test('\$sort and query parameters', () async {
|
||||||
// Search by where.eq
|
// Search by where.eq
|
||||||
Map world = await greetingService.create({"to": "world"});
|
Map world = await greetingService.create({"to": "world"});
|
||||||
|
@ -173,8 +178,8 @@ main() {
|
||||||
|
|
||||||
var response = await client.get("$url/api?to=world");
|
var response = await client.get("$url/api?to=world");
|
||||||
print(response.body);
|
print(response.body);
|
||||||
List<Map> queried =
|
var queried = god.deserialize(response.body,
|
||||||
god.deserialize(response.body, outputType: <Map>[].runtimeType);
|
outputType: <Map>[].runtimeType) as List<Map>;
|
||||||
expect(queried.length, equals(1));
|
expect(queried.length, equals(1));
|
||||||
expect(queried[0].keys.length, equals(2));
|
expect(queried[0].keys.length, equals(2));
|
||||||
expect(queried[0]["id"], equals(world["id"]));
|
expect(queried[0]["id"], equals(world["id"]));
|
||||||
|
|
Loading…
Reference in a new issue