-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Fix OWNER role to handle multiple relations #3140
Fix OWNER role to handle multiple relations #3140
Conversation
Can one of the admins verify this patch? To accept patch and trigger a build add comment ".ok\W+to\W+test." |
Can one of the admins verify this patch? |
3 similar comments
Can one of the admins verify this patch? |
Can one of the admins verify this patch? |
Can one of the admins verify this patch? |
@slnode ok to test |
test/role.test.js
Outdated
|
||
app.model(Message, {dataSource: 'db'}); | ||
|
||
const password = 'pass'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am afraid we cannot use ES6 in this repository yet because of #3003 :(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 719945d
common/models/role.js
Outdated
* Here is the new way to resolve owner relations | ||
* First, fetches `belongsTo` relation (User) | ||
* Then, fallback looking for userId / owner | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand the code correctly, then you are proposing to ignore hard-coded property names like userId
and ownerId
when ownerRelations
is configured. I guess it makes sense, we must describe this difference in our documentation.
Please add unit-test(s) to verify that when ownerRelations
is set, and there is no relation associated with userId
/ownerId
, then these two properties are ignored.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 199fa03
test/role.test.js
Outdated
}; | ||
|
||
return Promise.all([ | ||
new Promise((resolve, reject) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please promise-ify Role.isInRole
and other related APIs you call from new tests. See #418 for background and https://github.com/strongloop/loopback/pull/1493/files for an example how to implement such change.
Would you mind to add Promise support in a new pull request first, before working on this feature? It will help us to keep the git history clean.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you mind to add Promise support in a new pull request first, before working on this feature?
What do you mean by this ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We try to keep pull request small and have each request focused on a single thing. Adding Promise support AND allowing multi-owner Role resolution in the same pull request would go against that.
So I see two options how to move this pull request forward:
- Rewrite your new tests to use callbacks instead of promises. This seems like a step back to me.
- Start a new feature branch & a new pull request that will only add support for Promise style invocation to
Role
methods (and possibly other models you are going to invoke the tests you are adding here). When this other pull request is landed, you can simplify the code in this pull request by using the newly added Promise API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, you're definitely right. I find it uggly anyway ... However, do I need to add tests on the promisify support for role related things ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, at least basic smoke tests are needed when adding support for Promises to our API.
I went ahead and implemented the improvement myself - see #3146.
@bajtos i updated my tests with your promisify role lib ! However we need to merge this once ES6 polyfill and promisify role lib will be merged. Feel free to modify what you want and erase my commits history to keep the only added code. Thank you |
@pierreclr @bajtos please see #3180 Also the PR's name is not good: it's not about supporting multiple (different) owners, it's about being able the resolve the owner through multiple belongsTo relations. This should not be an option (referring to this) but the default behavior : from the moment the instance belongsTo the user by any of the possible existing relations, then the $owner role should be resolved truthy. thoughts gentlemen? |
Hi @ebarault ! That's what I thought first. However adding the capability to have multiple user models imply breaking changes on the way to resolve owner role (expect nosql connectors since the id's are uniques cross dbs / collections). I think the best way to handle this problem is the following :
However, IMO this feature becomes crucial integrating multiple user models. (Think about an |
Hi @pierreclr : could you detail the breaking change you're referring that would not be covered with the implementation i proposed in #3180 ? (similar to yours when there's a single user model) all existing tests pass, and I don't have in mind a new test that could fail |
@ebarault As already discuss and even if it was not very good for security, we used to resolve owner role on userId / owner property. In your PR you just (and only) fetch belongsTo relation (My initial PR did the exact same thing). But the braking change is the following. Considering a loopback app with model without any belongsTo relation BUT a https://github.com/strongloop/loopback/pull/3140/files#diff-b7e36d904fe1d290934c235affb649ecR609 |
@pierreclr: hmm right, but this implementation is so limited, ... for example it does not allow someone to use different foreign keys name than userId or owner. I'd advocate that loopback 3 should not support this owner resolving mechanism and follows only belongsTo relations. loopback 2 would remain unchanged. Thoughts? |
@ebarault thank you for joining the discussion here! Please read also our previous discussion in #3106 to better understand the context. In particular, #3106 (comment) describes my concerns related to backwards compatibility.
IMO, changing the auth layer to follow only Feature flags are the solution we are using in situations like this.
However, in this particular case, I think it's important to allow users to decide whether they want all "belongsTo" relations to be treated as ownership (
Good point. Perhaps we should fix the code handling |
@bajtos @pierreclr : a shame I missed the discussion from #3106 I am not using the $owner role because the behavior is not consistent to me, so I had to implement my own resolver to handle more complex logics. When required to refactor the isOwner method for the sake of the multiple user model PR, i understood then why I could not use this role resolver as I was expecting it to work and considered it more a bug than a feature : so I proposed that fix. But... okay, let's keep full backward compatibility. I'll keep focussed in the other PR to the fix required for multiple users. It should be merged before the present one. About iterating through belongsTo relations: here is why i consider the way
(ps. i considered here that for (var i in object) returns keys in lexicographical order, it's might not be the case, but anyway this does not change the nature of the problem) About the security concern I mentioned : there are certainly others, that one came to me just because my knowledge of the underlying logic, we should tinker this more. |
@ebarault I don't understand that ... in case of a non owner relation to a user (that means relation type |
I have a suggestion: we can use |
@raymondfeng I feel not comfortable with what you propose for the following reasons :
and everything will work as expected :) However, let me know what can I do to accelerate the merge :) |
@pierreclr: a model could have any number of belongsTo relation with other users. [invitation](fk: senderId=id1) --belongsTo--> user(id1) both users have hasMany relations with invitations, none of users them can "belongsTo" an invitation sender has rights on invitation to display it, revoke it isOwner is a good starting point, complemented by logic inside the methods definitions, to enable such logic |
@bajtos, @raymondfeng, @pierreclr |
But I don't understand what is the bug you describe, I don't see any bug ! Before we stop the |
Well that's my point @pierreclr : the current implementation does not behave consistently and gives fluctuant results according to the relation name when there are multiple belongsTo relation: this should not be the case at all (meaning: not a by default behavior) |
any updates on when this feature will be merged to the master?? |
That's a good question, indeed. IIRC, this pull request is being blocked by #3265. @ebarault you used to have a much better understanding of the work being done here and in #3265 (which you authored). What's the status of these to pull requests? Do you have any bandwidth to finish them? If not, could you perhaps advise us if there is a way how to finish this pull request without waiting for #3265? |
Hi @bajtos,
yes i still plan to have those addressed. but i'm currently short on bandwidth. I may have a little more time to cover those in august. Actually, #3265 was blocked by the deficient merge algorithm on models inheritance. Now that it's fixed #3265 can be resumed. while I believe #3140 could be merged as-is, It's maybe preferable to wait for #3265 to land as it will help cleaning the code in #3140. |
can we just do something like this in the boot folder ?
|
Let's move this pull request forward. I have rebased the changes on top of the latest master and addressed the most important comments that were also easy to fix - see 44db862. I'll wait few days to allow you (@pierreclr and @ebarault) to review my changes and the patch in whole, if you like to. If there are no objections raised, then I'll go ahead and land this pull request early next week. |
Fix the code resolving OWNER role to correctly handle the situation where the target model has multiple "belongsTo" relations to the User model. Introduce a new model setting "ownerRelations" that enables the new behavior. When "ownerRelations" is set to true, then all "belongsTo" relations are considered as granting ownership. Alternatively, "ownerRelations" can be set to an array of the relations which are granting ownership. For example, a document can "belongTo" an author and a reviewer, but only the author is an owner, the reviewer is not. In this case, "ownerRelations" should be set to "['author']".
Can one of the admins verify this patch? |
2 similar comments
Can one of the admins verify this patch? |
Can one of the admins verify this patch? |
Landed, thank you @pierreclr for the contribution 🎉 and sorry that it took so long to get it merged. Thanks @ebarault for your help along the way! |
+1 Could you please create the issue yourself, @lehni, to speed things up? |
Description
Fix the code resolving OWNER role to correctly handle the situation
where the target model has multiple "belongsTo" relations to the User
model.
Introduce a new model setting "ownerRelations" that enables the new
behavior. When "ownerRelations" is set to true, then all "belongsTo"
relations are considered as granting ownership. Alternatively,
"ownerRelations" can be set to an array of the relations which
are granting ownership.
For example, a document can "belongTo" an
author
and areviewer
,but only the author is an owner, the reviewer is not. In this case,
ownerRelations
should be set to['author']
.Related issues