Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include related models in findById #93

Closed
bajtos opened this issue Mar 25, 2014 · 9 comments
Closed

Include related models in findById #93

bajtos opened this issue Mar 25, 2014 · 9 comments

Comments

@bajtos
Copy link
Member

bajtos commented Mar 25, 2014

Consider the use-case described in #85: a product hasAndBelongsToMany categories.

At the moment, it's possible to retrieve a category by id with all its products via findOne:

GET /api/categories/findOne?filter[where][id]=CAT-ID&filter[include]=products

We should add support for include to findById too, so that the request can be simplified to e.g.

GET /api/categories/CAT-ID?include=products
@fabien
Copy link
Contributor

fabien commented Jul 21, 2014

@bajtos would be great to have this in 2.0

@bajtos
Copy link
Member Author

bajtos commented Jul 21, 2014

would be great to have this in 2.0
/cc @raymondfeng You can probably implement this in shorter time than I would need.

@raymondfeng
Copy link
Contributor

We'll have to refine the findById() to take the options.

@doublemarked
Copy link

+1

1 similar comment
@marcopeise
Copy link

+1

@raymondfeng
Copy link
Contributor

We just added the options arg to findById. Does any of you want to create a patch?

@bajtos bajtos closed this as completed Feb 17, 2015
@bajtos bajtos reopened this Feb 17, 2015
@bajtos bajtos closed this as completed Feb 17, 2015
@maddes
Copy link

maddes commented Oct 28, 2015

Forget this, read the next comment

¿Has this been resolved in any newer version?

Notice that this prevents using the ACL resolver.

If I use find() or findOne with a where clause I get context.modelId = undefined on the resolver function.

But if I use findById() I can filter the access according to custom rules set on the resolver (because I have the id which is being requested).

This bug forces us to either:

  • Not use the the ACL resolver functions (because I'll never get the modelId when I'm including stuff), but then I have a really hard time filtering access in situations like (employee access task assigned to his team: the task is not assigned to him but to his team, therefore, he doesn't have a 'owner' relation…)
  • Do additional calls to the database filling the model needed with it's relations (which can be A LOT and it's very annoying).

Sorry the long post. I would give you a potato, but this isn't 9gag…

@maddes
Copy link

maddes commented Oct 28, 2015

This is a immensely bigger show-stopper than I expected/commented…

How could I ever limit access on the example given?

I have:

  • User
  • Team
  • Task

Relations:

  • User belongs to a Team
  • Team has many Task

ACL:

  • User has the role teamMember
  • Role teamMember has READ access granted to model Task
  • A dynamic role resolver is added then to further filter when a teamMember tries to access a Task (to check if it belongs to the Task Team)

How can I limit the access for a User not to be accessing Tasks from other teams?

If I denyAll Users to Task, nobody can access their tasks directly.

If I grant Users to Task I let them access to all tasks, which is sad.

If I use a dynamic role resolver to further limit the access of teamMember only to the Team where he is and Task from his team, I just can't get to the tasks…

why?

  • In the dynamic role resolver, if a teamMember is accessing to a Task not belonging to it's Team then the access is rejected. As a consequence, no teamMember can ever perform a Task.findOne() or Task.find() because the context.modelId received on the resolver is undefined and therefore, I can't verify the access without hideous inspection of the where clause.

Then how do I access the task? With a Task.findById({ id: taskId }).

And how do I know the taskId?

Easy, just do a Team.findById( { id: user.teamId, filter: { include: 'task' } } ) and you have a pretty list of Task for the team in the results…

Oh wait… I can't do that, because include doesn't work on findById().

But I can't use a Team.find( { filter: { include: 'task', where: { id: user.teamId } } } ) because the context.modelId will be undefined again, and I can't just grant them access to any Team they like…

So…

How do I do this simple task?

@bajtos
Copy link
Member Author

bajtos commented Nov 2, 2015

Support for filter[include] was added by #564.

@maddes please open a new issue in the loopback project to discuss the implications for custom ACL resolver.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants