Skip to content

Commit a181f25

Browse files
authored
Validate near parameter (#694)
* Change near param to predef and validate passed value * Update documentation * Update paramValidatorAndParser function * Add tests for near parameter * Update tests
1 parent 1d8f797 commit a181f25

File tree

5 files changed

+34
-5
lines changed

5 files changed

+34
-5
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Make sure you have the following tools installed:
1414

1515
- Docker
1616
- Docker Compose
17-
- Node.Js v14
17+
- Node.Js v16
1818
- Yarn package manager
1919

2020
Fork, then clone the repo:

packages/api/lib/controllers/boxesController.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ const geoJsonStringifyReplacer = function geoJsonStringifyReplacer (key, box) {
203203
* @apiParam {Boolean="true","false"} [classify=false] if specified, the api will classify the boxes accordingly to their last measurements.
204204
* @apiParam {Boolean="true","false"} [minimal=false] if specified, the api will only return a minimal set of box metadata consisting of [_id, updatedAt, currentLocation, exposure, name] for a fast response.
205205
* @apiParam {Boolean="true","false"} [full=false] if true the API will return populated lastMeasurements (use this with caution for now, expensive on the database)
206-
* @apiParam {String} [near] A comma separated coordinate, if specified, the api will only return senseBoxes within maxDistance (in m) of this location
206+
* @apiParam {Number} [near] A comma separated coordinate, if specified, the api will only return senseBoxes within maxDistance (in m) of this location
207207
* @apiParam {Number} [maxDistance=1000] the amount of meters around the near Parameter that the api will search for senseBoxes
208208
* @apiUse ExposureFilterParam
209209
* @apiUse BBoxParam
@@ -819,7 +819,7 @@ module.exports = {
819819
allowedValues: ['true', 'false'],
820820
},
821821
{ name: 'full', defaultValue: 'false', allowedValues: ['true', 'false'] },
822-
{ name: 'near' },
822+
{ predef: 'near' },
823823
{ name: 'maxDistance' },
824824
{ predef: 'bbox' },
825825
]),

packages/api/lib/helpers/userParamHelpers.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,27 @@ const retrieveLocationParameter = function ({ value }) {
348348
}
349349
};
350350

351+
const retrieveNearParameter = function ({ value, dataType, dataTypeIsArray }) {
352+
try {
353+
// wrap dataType in array for calling of casting function
354+
dataType = dataTypeIsArray ? dataType[0] : dataType;
355+
if (!dataTypeIsArray && Array.isArray(value)) {
356+
return { error: ARRAY_NOT_ALLOWED };
357+
}
358+
359+
// test and cast value against dataType
360+
value = castParam(value, dataType, dataTypeIsArray);
361+
362+
if (typeof value === 'undefined') {
363+
return { error: CAST_FAILED };
364+
}
365+
366+
return { castedValue: transformAndValidateCoords(value) };
367+
} catch (err) {
368+
return { error: ERROR_CUSTOM_MESSAGE, message: err.message };
369+
}
370+
};
371+
351372
const
352373
GET_DATA_MULTI_DEFAULT_COLUMNS = ['sensorId', 'createdAt', 'value', 'lat', 'lon'],
353374
GET_DATA_MULTI_ALLOWED_COLUMNS = ['createdAt', 'value', 'lat', 'lon', 'height', 'unit', 'boxId', 'sensorId', 'phenomenon', 'sensorType', 'boxName', 'exposure'];
@@ -389,7 +410,7 @@ const retrieveParametersPredefs = {
389410
return { name: 'bbox', dataType: 'bbox' };
390411
},
391412
'near' () {
392-
return { name: 'near', dataType: 'as-is' };
413+
return { name: 'near', dataType: ['Number'], paramValidatorAndParser: retrieveNearParameter };
393414
},
394415
'maxDistance' () {
395416
return { name: 'maxDistance', dataType: 'as-is' };

packages/models/src/box/box.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1005,7 +1005,7 @@ const buildFindBoxesQuery = function buildFindBoxesQuery (opts = {}) {
10051005
'$near': {
10061006
'$geometry': {
10071007
type: 'Point',
1008-
coordinates: [near.split(',')[0], near.split(',')[1]]
1008+
coordinates: [near[0], near[1]]
10091009
},
10101010
'$maxDistance': maxDistance ? maxDistance : 1000,
10111011
}

tests/tests/002-location_tests.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,14 @@ describe('openSenseMap API locations tests', function () {
284284
});
285285
});
286286

287+
it('should reject filtering boxes near a location with wrong parameter values', function () {
288+
return chakram.get(`${BASE_URL}?near=test,60`).then(function (response) {
289+
expect(response).to.have.status(422);
290+
291+
return chakram.wait();
292+
});
293+
});
294+
287295
});
288296

289297
describe('POST /boxes/:boxID/:sensorID', function () {

0 commit comments

Comments
 (0)