rethinkdb-websocket-server icon indicating copy to clipboard operation
rethinkdb-websocket-server copied to clipboard

Query validation of array data

Open coffenbacher opened this issue 8 years ago • 5 comments

What's the best way to validate a query like this? For example, to ensure id > 0

r.table('test').insert([{id: 1}, {id: -1}]) // Query

r.table('test').insert(RP.check(arr => arr.every(e => e.id > 0))) // Whitelist entry

Whitelisting like this fails, I think because arr is a parsed query as opposed to a js array. I'm not sure how to loop through it.

coffenbacher avatar Feb 29 '16 22:02 coffenbacher

Also, related, but I'm not sure how to validate queries of the form:

r.table('test').getAll('id1', 'id2', 'id3')

For example, comparing the id's in the getAll against a valid list.

coffenbacher avatar Feb 29 '16 23:02 coffenbacher

For your first query, you're right that its not working because the arr is still in ReQL AST instead of a vanilla JS array. A workaround for now would be:

const MAKE_ARRAY = 2;
const checkArr = checkFn => term => (
  Array.isArray(term)
  && term.length === 2
  && term[0] === MAKE_ARRAY
  && Array.isArray(term[1])
  && checkFn(term[1])
);

// whitelist entry
r.table('test').insert(
  checkArr(arr => arr.every(e => e.id > 0))
)

But this should ideally be addressed at the library level. I think it'll probably be safest to make something like RP.checkArr and RP.refArr, even though it might feel nicer to just seamlessly convert arrays to vanilla JS in RP.check and RP.ref, since it might be hard to do securely without leaving out edge cases.

mikemintz avatar Mar 01 '16 05:03 mikemintz

I don't think there's an easy way to do validate variable number of arguments like getAll. I'll need to think more about that one.

mikemintz avatar Mar 01 '16 05:03 mikemintz

Great, thanks! This helps a lot for now.

Regarding variable number of arguments, I'm thinking a workaround for now is to pass an array wrapped in r.args instead of spreading the array into multiple arguments? Not 100% sure where to go from there, but I imagine it becomes a lot more similar to the example you provided of dealing with the AST.

coffenbacher avatar Mar 01 '16 05:03 coffenbacher

Great idea using r.args, that should work for getAll, and then yes you can use the same RP.checkArr workaround above. You can do:

r.table('test').getAll(
  r.args(checkArr(arr => arr.every(e => e.id > 0)))
)

Assuming the rethinkdb backend supports r.args anywhere, then there should be no need to implement a special case for whitelisting functions with variable number of arguments.

mikemintz avatar Mar 02 '16 04:03 mikemintz