danielrvt
danielrvt

Reputation: 10916

Loopback - $owner role with a "hasMany" relation

I've been reading the loopback docs about roles. They state the following:

To qualify a $owner, the target model needs to have a belongsTo relation to the User model (or a model extends from User) and property matching the foreign key of the target model instance. The check for $owner is only performed for a remote method that has ':id' on the path, for example, GET /api/users/:id.

However, what happens when I have a "hasMany" relation and want to perform an action on some object like this:

PUT myusers/123/news/456

This would be my user.json:

{
  "name": "MyUser",
  "plural": "myusers",
  "base": "User",
  "idInjection": true,
  "options": {
    "validateUpsert": true
  },
  "properties": {},
  "validations": [],
  "relations": {
    "news": {
      "type": "hasMany",
      "model": "News",
      "foreignKey": ""
    }
  },
  "acls": [],
  "methods": []
}

Upvotes: 3

Views: 2339

Answers (1)

mariowise
mariowise

Reputation: 2327

Based on this, this and this. I've changed the MyUser entity to Writer entity, because I like it.

As the Writer entity has many News, the News relation and ACL should be something like this (news.json).

"relations": {
  "writer": {
    "type":"belongsTo",
    "model":"Writer",
    "foreignKey":"writer_id"
  }
},
"acls": [
  { // Nobody has access to nothing
    "accessType": "*",
    "principalType": "ROLE",
    "principalId": "$everyone",
    "permission": "DENY"
  },
  { // But everyone can read everything
    "accessType": "READ",
    "principalType": "ROLE",
    "principalId": "$everyone",
    "permission": "ALLOW"
  },
  { // And authenticated users can create news
    "accessType": "EXECUTE",
    "principalType": "ROLE",
    "principalId": "$authenticated",
    "permission": "ALLOW",
    "property": "create"
  },
  { // And the owner of a news can update it
    "accessType": "WRITE",
    "principalType": "ROLE",
    "principalId": "$owner",
    "permission": "ALLOW"
  }
],

And the Writer entity has the same ACL rules but this relations (writer.json)

"relations": {
  "news": {
    "type": "hasMany",
    "model": "News",
    "foreignKey": "writer_id"
  }
}

What really happens here is that, when you create a Writer, you must specify email and password becouse he inherited from User model. So if you want to perform the

PUT writers/123/news/456

You must be logged has a Writer which can be done in this endpoint: /api/writers/login (with email+password). This endpoint is going to give you the Writer token and then you'll be able to perform the update on the News if you has the $owner token on your header, url or form.

On the other hand, you can also get the user who is doing the HTTP Request and put that user has the news owner with a hook.

Hope it helps. Regards.

Upvotes: 4

Related Questions