Closed nocko closed 8 years ago
I recently ran into a use case (permissions checking in an API); where it was convenient to let the database filter results based on permissions subquery. I doubt it's a common pattern, but it's helpful for me...
Hey @nocko - just to be clear - you know what the unique key id
is for the query but you'd like to add additional criteria (that won't affect the query results)?
It could effect the query results, instead of returning the unique key'd item, a failed where clause would return no results. This is the desired behaviour.
Example:
Zone.find(1, where=['owner_id = ANY ((select ARRAY(select org_id from users_orgs where user_id = ?) || ?)::int[])', 1, 1])
generates:
SELECT * FROM zones WHERE owner_id = ANY ((select ARRAY(select org_id from users_orgs where user_id = 1) || 1)::int[]) AND id = 1;
Explanation: Return zone row with unique id = 1, if the user or one of the user's organizations owns the zone, otherwise return no results.
This works well for filtering a collection of rows, but I'd like the same decorator to enforce access control on collections of rows (already working) and specific rows (failed because where clause is overwritten by InteractionBase.select() without falling back to adbapi.ConnectionPool methods.
OK - makes sense. I'll merge if you make the one change I suggest in the comments. Thanks for the PR!
I've never noticed twistar.utils, those are handy. I've implemented at least two of those functions in my own code. Should spend more time reading the code. Thanks.
Thanks @nocko! I bumped the minor version on pypi as well. Let me know if anything is missing from utils.py
.
This works as expected when an id is not provided to DBObject.find(where=...), but failed to work when using specifying an id DBObject.find(id, where=...). InteractionBase.select() discards the clause if an id is provided. This patch retains any provided where clause.