strongloop / loopback-example-access-control

An example demonstrating LoopBack access control mechanisms.
Other
370 stars 168 forks source link

team model format #76

Closed TrevorPage closed 7 years ago

TrevorPage commented 8 years ago

I'm using this project to learn how model relations work, and the thing that confuses me is why a team is represented as separate objects in the database, where each team object seems to provide just one mapping of user to owner. This means that, if for example a team has three members (users), then there are three distinct team objects in the database.

It would make more sense to me if a team was represented as a single object, where the members property is an array.

Is there a specific reason why it's done like it is, perhaps because of the way relations work?

richardpringle commented 8 years ago

Hey @TrevorPage, there would only be one distinct team instance (one record in the database) that has three difference members. What bit of code (or documentation) is leading you to believe otherwise?

TrevorPage commented 8 years ago

Hi @richardpringle! The part of code that made me believe that three team records were being made is the following in boot/sample-model.js:

  // add team members
  Team.create([
    {ownerId: project.ownerId, memberId: users[0].id},
    {ownerId: project.ownerId, memberId: users[1].id}
  ], function(err, team) {
    if (err) throw err;

    console.log('Created team:', team);
  });

and:

  //add team members
  Team.create({
    ownerId: project.ownerId,
    memberId: users[1].id
  }, function(err, team) {
    if (err) throw err;

    console.log('Created team:', team);
  });

It is my understanding that the above is programmatically creating three Team objects. The documentation confirms to me that passing an array creates an array of instances (http://apidocs.strongloop.com/loopback/#persistedmodel-create).

Furthermore, if I look in common/models/team.json, it seems to me that a team model instance can only reference one member:

"memberId": {
  "type": "string",
  "required": true
}

But, further down I notice that the relation is of course hasMany:

"relations": { "members": { "type": "hasMany", "model": "user", "foreignKey": "memberId" } },

So, I see that it has a hasMany relation, but I'm struggling to grasp how the team object being created in the example is just one object, when it looks to me like several team instances are being made, where each one only references one memberId.

TrevorPage commented 8 years ago

Furthermore, if I persist the memory database to .json, I see that the one team with two members and one team with one member are represented as three separate objects:

{
  "ids": {
    "User": 1,
    "AccessToken": 1,
    "ACL": 1,
    "RoleMapping": 2,
    "Role": 2,
    "user": 4,
    "team": 4,
    "project": 3
  },
  "models": {
    "User": {},
    "AccessToken": {},
    "ACL": {},
    "RoleMapping": {
      "1": "{\"principalType\":\"USER\",\"principalId\":\"3\",\"roleId\":1,\"id\":1}"
    },
    "Role": {
      "1": "{\"name\":\"admin\",\"created\":\"2016-06-02T20:18:49.341Z\",\"modified\":\"2016-06-02T20:18:49.341Z\",\"id\":1}"
    },
    "user": {
      "1": "{\"username\":\"John\",\"password\":\"$2a$10$SIGqZ4gLjJBUVsLx7N1H/ua/nSAPH69j3DeMSNprhGAHw9CCIS51y\",\"email\":\"john@doe.com\",\"id\":1}",
      "2": "{\"username\":\"Jane\",\"password\":\"$2a$10$RFCl.psxnBbvIMhLC/sIse4X0yy.20Yy7.DOnH91YoPzXHUihHxzq\",\"email\":\"jane@doe.com\",\"id\":2}",
      "3": "{\"username\":\"Bob\",\"password\":\"$2a$10$fRX/V/aGkCDyEwIwePas1.KuYBWQqDPD/rYqNio6lvRhZvwKDE1GS\",\"email\":\"bob@projects.com\",\"id\":3}"
    },
    "team": {
      "1": "{\"ownerId\":1,\"memberId\":\"1\",\"id\":1}",
      "2": "{\"ownerId\":1,\"memberId\":\"2\",\"id\":2}",
      "3": "{\"ownerId\":2,\"memberId\":\"2\",\"id\":3}"
    },
    "project": {
      "1": "{\"name\":\"project1\",\"balance\":100,\"ownerId\":1,\"id\":1}",
      "2": "{\"name\":\"project2\",\"balance\":100,\"ownerId\":2,\"id\":2}"
    }
  }
}
richardpringle commented 8 years ago

Woah... this isn't right at all.

@TrevorPage, checkout the relations example to learn more about relations.

The team model isn't well designed here. If you ignore the fact that there are three separate team instances, I believe that the example still correctly displays the ACL logic.

Let me know if there's anything else I can help you out with. And thanks for finding the example design flaw!

FreakTheMighty commented 7 years ago

Any plans to update the example? Seems like maybe the idea was to do something like, Project has many members through Team.

richardpringle commented 7 years ago

Hey @bajtos, do you have an answer for @FreakTheMighty?

bajtos commented 7 years ago

@richardpringle hey, glad to see you are still helping :)

Any plans to update the example? Seems like maybe the idea was to do something like, Project has many members through Team.

I am not familiar with this example myself. @raymondfeng @superkhau could you PTAL?

superkhau commented 7 years ago

@FreakTheMighty No plans that I know of and with regards to priority, I don't believe it's high up there ATM -- @ritch Can you confirm?

Seems like maybe the idea was to do something like, Project has many members through Team.

No, the idea is to demonstrate a user can start many projects like they do on kickstarter, and that same user can belong to a team with various members (some with admin perms, some without etc).

Remember the goal is to demonstrate access control mechanisms, not demonstrate relations.

superkhau commented 7 years ago

I'm going to close this as won't fix -- please see https://github.com/strongloop/loopback-example-relations for examples on model relations. Please note though, this example doesn't show programmatic usage -- mostly how to query via REST -- we need an programmatic relation example too.

We do not have any examples for both access control with relations ATM.

superkhau commented 7 years ago

@FreakTheMighty @TrevorPage I added an issue you can track and upvote at https://github.com/strongloop/loopback-example-relations/issues/42 for programmatic relation examples and access control with relations at https://github.com/strongloop/loopback-example-relations/issues/43.

TrevorPage commented 7 years ago

Thanks guys. If I understand right, what we're saying is that the relations here are possibly a bit contrived, but the reason is because this is purely to demonstrate access control.

superkhau commented 7 years ago

@TrevorPage That is correct, the relations are totally contrived as the intent is to demonstrate access control. Thanks for clarifying for other users who may run into this. ;)

Feel free to submit a PR if you have time to refactor the relations to make it feel less contrived. :beer:

jackrvaughan commented 6 years ago

So in this scenario, what would be the right way to set up relations for users and teams?

Where a user can be the owner of multiple teams and teams have multiple members (which are users).

I've sort of posed this question here: https://groups.google.com/forum/#!topic/loopbackjs/Oki-1H9S6Es