Skip to content

Latest commit

 

History

History
169 lines (133 loc) · 5.62 KB

Accessing-related-models.md

File metadata and controls

169 lines (133 loc) · 5.62 KB
title lang layout navgroup keywords tags sidebar permalink summary
Accessing related models
en
navgroup
access-control
LoopBack
models
lb3_sidebar
/doc/en/lb3/Accessing-related-models.html
For related models, LoopBack automatically <i>related model methods</i> corresponding to the API routes defined for the relationship.

{% include important.html content="When accessing a related model, the effective ACL (the one considered to resolve access permission) is the one for the model you are primarily calling. So if a given model has no ACL, then all the endpoints accessible through the model relations will be open, even if a related model has DENY ALL permissions set.

This can be a security risk since, for example, GET /OpenModel/{id}/ACLSecuredModel will allow full access to ACLSecuredModel through the OpenModel relations. " %}

Restricting access to related models

When two models have a relationship between them (see Creating model relations), LoopBack automatically creates a set of related model methods corresponding to the API routes defined for the relationship.

In the following list, modelName is the name of the related model and modelNamePlural is the plural form of the related model name. 

{% include note.html content=" In the method names below, the separators are double underscores, __. " %}

belongsTo:

  • __get__relatedModelName

hasOne:

  • __create__relatedModelName
  • __get__relatedModelName
  • __update__relatedModelName
  • __destroy__relatedModelName

hasMany:

  • __count__relatedModelNamePlural
  • __create__relatedModelNamePlural
  • __delete__relatedModelNamePlural
  • __destroyById__relatedModelNamePlural
  • __findById__relatedModelNamePlural
  • __get__relatedModelNamePlural
  • __updateById__relatedModelNamePlural

hasManyThrough:

  • __count__relatedModelNamePlural
  • __create__relatedModelNamePlural
  • __delete__relatedModelNamePlural
  • __destroyById__relatedModelNamePlural
  • __exists__relatedModelNamePlural (through only)
  • __findById__relatedModelNamePlural
  • __get__relatedModelNamePlural
  • __link__relatedModelNamePlural (through only)
  • __updateById__relatedModelNamePlural
  • __unlink__relatedModelNamePlural (through only)

hasAndBelongsToMany:

  • __link__relatedModelNamePlural
  • __unlink__relatedModelNamePlural

You can use these related model methods to control access to the related routes.

For example, if a User hasMany projects, LoopBack creates these routes (among others) and the corresponding related model methods:

  • /api/users/count - standard method is count
  • /api/users/:id/projects - related model method is __get__projects
  • /api/users/:id/projects/count - related model method is __count__projects

{% include important.html content=" If a model has a DENY ALL permission (for example a built-in model such as the User model), but related models have no ACLs,the related models will still not be accessible through the User model. So, for example, even if the books model's default ACL is ALLOW $authenticated for GET /books, the route GET /user/{id}/books default will still be DENY ALL. " %}

To configure access control to such routes, set the permission on the related model methods in the model definition JSON file. For example, the ACL for the User model definition JSON file (user.json) for these routes might look like this, for example:

{% include code-caption.html content="/common/models/user.json" %}

"acls": [{
  "principalType": "ROLE",
  "principalId": "$authenticated",
  "permission": "ALLOW",
  "property": "count"
}, {
  "principalType": "ROLE",
  "principalId": "$owner",
  "permission": "ALLOW",
  "property": "__get__projects"
}, {
  "principalType": "ROLE",
  "principalId": "$authenticated",
  "permission": "ALLOW",
  "property": "__count__projects"
}]

Querying related models

{% include important.html content=" This feature requires LoopBack 2.16.0 or later. " %}

When querying a model, you may also want to return data from its related models.

For example, suppose you have three models: UserReport, and LineItem, where:

  • A user can have many reports; that is, there is a HasMany relation  between User and Report (User hasMany Report).
  • A report can have many line items; that is, there is a HasMany relation  between Report and Lineitem (Report hasMany LineItem).

Additionally, the ReportModel is configured with the following ACLs so that authenticated users can create new records and users can update their own records:

[{
    "principalType": "ROLE",
    "principalId": "$everyone",
    "permission": "DENY"
  }, {
    "principalType": "ROLE",
    "principalId": "$owner",
    "permission": "ALLOW",
    "property": "findById"
  },
  ...
]

Assume the LineItem model has the same ACL defined.

Now, suppose you want to fetch a model owned by your user and also get at its related models. Here is how you do it with findById() using the Node API:

Report.findById(1, {include: 'lineitems'});

Using the REST API:

GET /api/Reports/110?filter={"include":["lineItems"]}

Example results:

{
  "name": "january report - bob",
  "id": 110,
  "userId": 100,
  "lineItemModels": [{
    "name": "lunch",
    "id": 111,
    "reportModelId": 110
  }, {
    "name": "dinner",
    "id": 112,
    "reportModelId": 110
  }]
}