From b8012c8698781659b60c909961392c037afe41b8 Mon Sep 17 00:00:00 2001 From: Zaid Abdulla Date: Tue, 23 Aug 2016 20:59:12 -0700 Subject: [PATCH] Generic function to sanitize value types in Mongo query --- lib/nbi.coffee | 12 ++++++++++-- lib/query.coffee | 49 +++++++++++++++++++++++------------------------- 2 files changed, 33 insertions(+), 28 deletions(-) diff --git a/lib/nbi.coffee b/lib/nbi.coffee index c57f955..d38f7e1 100644 --- a/lib/nbi.coffee +++ b/lib/nbi.coffee @@ -443,8 +443,16 @@ listener = (request, response) -> return else q = {} - q = query.expand(q, aliases) if collectionName is 'devices' - q = query.substituteObjectId(q) if collectionName is 'tasks' + + switch collectionName + when 'devices' + q = query.expand(q, aliases) + when 'tasks' + q = query.sanitizeQueryTypes(q, { + _id: ((v) -> return new mongodb.ObjectID(v)) + timestamp: ((v) -> return new Date(v)) + retries: Number + }) if urlParts.query.projection? projection = {} diff --git a/lib/query.coffee b/lib/query.coffee index 5e91654..9d77adb 100644 --- a/lib/query.coffee +++ b/lib/query.coffee @@ -125,31 +125,6 @@ expand = (query, aliases) -> return new_query -# Replace _id string values with ObjectID type -substituteObjectId = (query) -> - for k, v of query - if k[0] == '$' # logical operator - for i in [0...v.length] - substituteObjectId(v[i]) - else if k == '_id' - if common.typeOf(v) is common.STRING_TYPE - query[k] = mongodb.ObjectID(v) if v.length == 24 - else if common.typeOf(v) is common.OBJECT_TYPE - for kk, vv of v - switch kk # operator - when '$in', '$nin' - for i in [0...vv.length] - vv[i] = mongodb.ObjectID(vv[i]) if vv[i].length == 24 - when '$eq', '$gt', '$gte', '$lt', '$lte', '$ne' - v[kk] = mongodb.ObjectID(vv) if vv.length == 24 - when '$exists', '$type' then - # ignore - else - throw new Error('Operator not supported') - - return query - - # Generate parameter projection from a query # If second arg is given, it's edited and returned queryProjection = (query, proj) -> @@ -233,7 +208,29 @@ test = (params, query) -> return true +sanitizeQueryTypes = (query, types) -> + for k, v of query + if k[0] == '$' # logical operator + sanitizeQueryTypes(vv, types) for vv in v + else if k of types + if common.typeOf(v) is common.OBJECT_TYPE + for kk, vv of v + switch kk # operator + when '$in', '$nin' + vv[i] = types[k](vv[i]) for i in [0...vv.length] + when '$eq', '$gt', '$gte', '$lt', '$lte', '$ne' + v[kk] = types[k](vv) + when '$exists', '$type' then + # ignore + else + throw new Error('Operator not supported') + else + query[k] = types[k](query[k]) + + return query + + exports.expand = expand -exports.substituteObjectId = substituteObjectId exports.queryProjection = queryProjection exports.test = test +exports.sanitizeQueryTypes = sanitizeQueryTypes