-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
new: DefaultACL options for server config #7111
Conversation
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.
Here I ask myself one thing:
If we have a defaultACL config by Class, why not use a new field into Parse.Schema. To allow further remote control (via Parse Dashboard) and keep one source of truth.
The current string/object system seems to not support the use case:
- User wants to apply same defaultACL on all classes but wants also to apply a specific default ACL config on one class
Here I would suggest to support only the object version in parse options. Less doc variation, more consistency over parse ecosystem. The ACL defined into the defaultAcl
parse server options, will be used as a fallback if no defaultACL
is found on the Class Schema
.
Then support a new field defaultACL
on Parse.Schema
(like the clp
field)
Additional note: Having a new defaultACL field on Class could work nicely with the new defined schema system.
Then the developer will have in one place: className, field, indexes, CLP, defaultACL.
What do you think about this ?
PS: Here i know that it need more work, but i think it's one of the best ways to achieve this feature, also we can after update the JS SD. (currently i don't know if other SDKs are actively used to manage schemas)
I like the suggestion @Moumouls, so I also think this PR requires extensive review to make sure no ACL is being overriden, which could obviously be a security concern if |
Codecov Report
@@ Coverage Diff @@
## master #7111 +/- ##
==========================================
+ Coverage 93.64% 93.69% +0.05%
==========================================
Files 169 169
Lines 12508 12537 +29
==========================================
+ Hits 11713 11747 +34
+ Misses 795 790 -5
Continue to review full report at Codecov.
|
Here i think we should keep a consistent usage of ACL and avoid a new string ACL feature. So let's just use a the current ACL spec (follow Rest spec): https://docs.parseplatform.org/rest/guide/#user-security defaultACL: {
"*": {
read: true
write: false
}
"role:Admin":{ read: true, write: true}
...
} I understand that this structure do not support your I think that the Current user feature could be achieved by simply transforming on the fly on parse server side the currentUser: {
read: true,
write: false
} Also in graphql this feature would be very interesting: mutation createObject {
createComment(input: { fields: { ACL: { currentUser: { read: true, write: false} } } }) {
comment {
id
ACL {
users {
# Current user is now listed here
userId
}
}
}
}
} |
You should only trigger default ACL on object creation, never on object update :) it's too hard to manage ACL on update and avoid conflicts, if a developer need more control on this part, he should use the beforeSave trigger to introduce his business logic. Note on creation if the user provide ACL you can merge the ACL this way to ensure default and custom one.
This way we let the user add additional ACL and ensure that default ACL correctly overwrite ACL provided by the user. (for example if malicious user try to disable the write of the |
@Moumouls how would you feel about evolving this feature in the future as part of the WIP for schema? Schema evolution: -Validator (#7013) So in the future, you'll be able to set class specific data validation and class specific defaultACL via the dashboard. Or would you prefer the defaultACL schema to be part of this PR? |
Yes to keep the current PR scope small as possible, here we just need to support defaultACL for all classes via ParseServer Options Then another PR could cover the |
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.
Add an explicit test in ACL.spec, check if currentUser
works correctly via the create/update REST API
if (reqUser && aclOptions.currentUser) { | ||
aclOptions[reqUser] = aclOptions.currentUser; | ||
} |
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.
this code is not used at the right place.
You need to add an explicit test create/update ACL with the Rest API into spec/ParseACL.spec.js
Then the rest / graphql API could use this new field for better DX.
Here you only trigger the ACL transformation at creation time and if user do not provided ACL.
May be create a new restwrite fn handleACL
to perform the operation after buildDefaultACL
.
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 have added a test case for REST API and it works fine with currentUser
write: true, | ||
}, | ||
}; | ||
const aclOptions = Object.assign({}, this.config.defaultACL || defaultACL); |
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.
const aclOptions = Object.assign({}, this.config.defaultACL || defaultACL); | |
const aclOptions = this.config.defaultACL || defaultACL; |
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 do that, tests fail and this.config.defaultACL gets mutated and then other tests fail.
RestWrite.prototype.buildDefaultACL = function () { | ||
if ((this.query && this.query.objectId) || this.data.ACL) { | ||
return; | ||
} |
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 user provide ACL on new object you need to combine the default and provided ones like this:
finalAcl = {...this.data.ACL, ...defaultACL}
Here we need to ensure that defaultACL at creation time is always merged and may be overwrite some unwanted ACL (user provide: role:Admin: { read: true, write: false}
, but we want role:Admin: { read: true, write: true}
)
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 think for this PR we should only affect objects with intrinsic no ACL, otherwise if a user wants to use the legacy option of defaultACL: {'*': { read: true, write: true }}
, they have no option to make objects private.
E.g:
defaultACL: {'*': { read: true, write: true }}
Create object with new Parse.ACL(user);
The object ACL will 'merge' to be:
{
h8qM6TzGqA: { read: true, write: true },
'*': { read: true, write: true }
}
TODO: check how this functions for |
|
Closing as probably best handled in CLPs |
New Pull Request Checklist
Issue Description
Closes: #7068
Approach
Adds a "defaultACL" option to Parse Server config.
This sets the ACL on Parse.Objects if they are unset. It does not override ACL.
Default ACL is a JSON representation of Parse.ACL, except you can set
currentUser
, which overrides to the user who saves the object.TODOs before merging