-
-
Notifications
You must be signed in to change notification settings - Fork 835
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
Convention for permissions #2202
Comments
For reference, this discussion was initially brought up in #2113 (comment) and later in an internal meeting. |
Personally I'm a huge fan of dot notated permissions, it gives a easy way to break permission down if you need to (such as was done in #2113). The attribute names sent via JSON will have to be camelCase since JSON attribute names can't have dots in them. But in the backend the dot notated makes the most sense for easy break down. Further some core extension and even core itself requires dot notated namespaces in order to function properly. |
I would prefer dot notated as well, as it would open up possibilities for more robust namespacing of permissions |
Related to #2092 |
If we go with dots, the following changes need to be made: CORE:
Also, for the changes in #2212:
Approve:
Tags:
Likes:
Flags
ScopesIn addition to the permission itself (dot-separated), we also have per-scope permissions, such as per-tag. I have 2 proposals for doing this:
|
Is "throttled" a typo here? |
I'm okay with this proposal (#2202 (comment)), but I'd rather see dash-es than camelCasing where permissions are combined into one string, for instance:
What do you think? |
I do like the idea of having an additional column for the extension ID that's separated from the permission name in the database, and they could be combined into a single value at run time. That column could be used to clear permissions when an extension is uninstalled permanently, just like how migrations work. |
That's a good idea. Do you mean this in addition to the scope column / prefix for which tag to use? |
This would be my proposed solution. Split the permission into 3 big parts:
And have permission split into two parts:
If possible, I would actually suggest to have those 4 items as separate columns/parameters/attrs, so we wouldn't need to choose an actual separator.
Possibly allow nullable namespace for global permissions. This would however not work well with Or if we go with separator, my preference would be column for scope, then dots between the others. Which would be stored very similarly to what we do now I believe. like As to namespace and ability casing, I would be in favor of camelCase |
I don't think we should move away from I would be in favor of storing extension ID as a database column, but I don't think it should actually be provided or used when checking the permission, since its biggest use case is being able to clear out permission settings for an old extension. In general, I would prefer if we can store permission data separated in the database, because that makes changing it with SQL much easier. That doesn't in any way affect the APIs for For global namespaces, we'd need to choose between null (empty string) or some constant. Empty string is probably more intuitive. And that brings us to the ability itself. I think there's consensus that the namespace should at least be dot-separated out. But do we want to have dot-separation within the ability itself to separate out sub-abilities (e.g. #2202 (comment)). This is the convention used in #2113, and it could make policy evaluation more powerful. For instance, we could try the following implementation: Policies are tied to a namespace (e.g.
When evaluating We could use either camel case or dashes for separating words, but sub-permissions would be separated by dots. Implementation-aside, a whole other issue is how we can provide migration from one system to the other, or a backwards compatibility layer. |
I don't feel like we need to add more complexity to policies/AbstractPolicy. I have never felt limited by the current solution. The permission namespacing by extension somehow has to be part of the call, because an extension might want to access/set permissions for another extension as well. We can't assume all calls will be for permissions from that very extension. If the extension ID is only added in the database, then this means we need some kind of permission registration function. Which might be a good idea, but I also like the current solution of having flexible permissions. One aspect of free-name permissions is that extension can dynamically create permissions as well. It's something I plan to use in Formulaire to have form-specific permissions, which might be in addition to the existing tag-scoping. How are we going to decide on this? There are many good proposals. Do we want to make some kind of vote? |
Even without adding logic to run through "layers" of permissions, I feel like denoting subpermissions with dots would be clearer to understand and work with. Also, decoupling permission names from method names (and having each policy specify that relationship) would make the structure of policies a lot more intuitive. I don't think permissions should be "namespaced" by extension ID, I would prefer if the extension ID was considered metadata. It could be used for clearing out DB tables on uninstall and deciding which extension page to display those permissions on with #2409. I don't think it should be considered at all in the get/set process for extensions, other than to add that tag / label. Actually we might not even need to store it in the DB, we could just use an extender to tie permissions to extensions. For proceeding, I think we should have a tiny bit more discussion on options, and when we settle on the exact differences between the proposal, we can vote. Would also be good to get input from the other developers @luceos @tankerkiller125 @datitisev @SychO9 |
Not sure I understand why we'd need to namespace by extension, isn't it to avoid possible problems with extensions using already used permission names ? If so, then perhaps we can find a different solution to that since this feels like adding more complexity. And I also agree it'd be best not to move away from using
I feel like the current system is simple and powerful enough, so I don't think we need to go for sub-abilities unless really necessary. While it could be very useful, I don't really see a benefit right now apart from maybe nicer permission names. Could be wrong depending on how implementation actually goes.
I'd go for empty string. |
I think the discussion kind of deviated a bit with many suggestions for radical changes. I'm also very happy with the current solution. I don't have much to say regarding the suggestions for core, I think all the proposals make sense and would work. My only concern are extension prefixes and magic namespaces. Those were not covered in the comments higher up. The main example for this is the My usual standard is to start the permission name with the extension ID. But I need to switch things to benefit from the magic namespaces, example:
The fix could be:
Something like
We could then know that the part after This still creates a problem, because now we need to patch the permission name back together. Would Or should we choose to put the extension ID as a suffix in extensions (?) Whatever we decide, I think permission namespacing by extension ID needs to be part of what we choose as standard. Core extensions might not use them, but we need this to be standardized across community extensions. |
One of my goals in the policy refactor is to eliminate the magicness of this namespacing, and explicitly have policies assigned to Now, another important feature of the permission is the I'm still not sure about the extension ID. What's its purpose, really? It doesn't factor in deciding which policy to use, and is unlikely to matter TO a policy. It's metadata that can be used for cleaning up permissions from the DB, but that isn't actually used in evaluation. So I think we might as well chuck it in the front or the end of policies:
|
I think the need for an extension ID/prefix/suffix is to prevent conflict. Many extensions will do similar things, and some permission names would clash. For example two extensions could allow reacting to posts in different ways, and both shouldn't just call their permission Even if two extensions with identical permission naming are technically incompatible, uninstalling one to install another could pick up leftover permissions and cause all sort of problems. Because of this, I think rigorous namespacing is a must. Using the extension ID as prefix or suffix is a nice way to have something consistent across extensions. The alternative would be to have the prefix part of the ability name, but it's not always easy to find something that writes well with the established casing. I'm not a big fan of this syntax, but it's also a valid option:
EDIT: something I didn't mention. Having the namespace in front is incredibly useful when editing permissions in the database since they get grouped with the default ordering |
I think having extension namespaces in front makes sense as well, I also think using the |
What if when registering a policy through the extender, we set the extension ID in the policy class, once the policy class is aware of its extension ID we could use that to properly determine a permission of the form: |
Since extension IDs are currently "optional", I don't think it should be dot separated: |
I agree with the majority that not changing too much is the best way forward. I also think that the last proposal makes the most sense Having said that, I do think that this issue should impact the logic of tags and simplify it. It sounds "nice", but the fact that the discussion prefix is used to scope permission by tag doesn't make a lot of sense. So, looking at the proposal how would tags be modified to register an ability and core understand it needs to horizontally scale the permission grid? Because if we understand that, we can also understand how an alternative tags extension (eg categories which is standalone from tags) should create permissions... I hope this makes sense :) |
What if we did The biggest issue that came up wasn't tags and scopability (we could provide that as a separate parameter to the grid). Instead, it's the rather the "magic" logic in policies, where calling For the actual permission naming, I still prefer dots over camel case, as it's a more versatile format. That being said, I definitely understand the downsides, so if most of @flarum/core prefer camel case, I'd be alright with that. Pros:
Downsides:
One last thing that came up was potentially adding another layer of logic in |
Our entrypoint for permission checks is currently the
And of course, the actor is implicitly available. I suppose some of these could be split out into other params, but which exactly? Permission name would be good to keep together. Scope (e.g. with tags) is non-standard (and might make sense as a separate column tbh, but that breaks some existing things. Vendor is part of the permission, would be odd detaching that. |
I dislike the idea of a helper. That would introduce a class to fix something that currently isn't clear? I think it's not wrong or bad to require abilities to be prefixed and it should be no issue that devs have to take that into consideration themselves. To me, this sounds like something that needs to be doc-driven in terms of education of best practices. |
@flarum/core |
It's probably a bit late to change the scopable prefix/suffix thing for the next release now. For the |
The obvious fix is a migration to rename all permission values containing "viewForum" and "viewUserList". However, I'm concerned about the potential impact to extensions: we can introduce a global policy for the old ability names (and do the same in tags), but any cases using |
I think it's a little late to make that change as well tbh. |
Which one? Scoping or permision renaming? |
both |
For now, we could change the translations to be a bit clearer? |
Yes, that would be harmless |
For reference. This is a text search on the latest version of all Packagist Flarum extensions in files ending in For
For
So if we exclude forks and abandoned extensions from this list we're left with almost nothing, with almost all extensions controlled by Flarum core members. Of course there are all the private extensions out there to keep in mind as well. EDIT: and for the javascript side, there's no usage of
|
@clarkwinkelmann based on that data it would seem that it would be safe to change these then? |
That's my thought as well. Very limited and manageable impact. Also whether we make it backward compatible or not, we could create a good error message if anyone tries to use the old ability name so that it doesn't silently fails if someone did manage to use it in a private extension or local extender. I believe I have two private extensions that use the ability name but those will be very simple changes, they only change client-side display of the permission dropdown. |
I believe that this is now mostly a documentation issue? |
Yup |
* Document `help` field in admin settings * Document additional attrs in admin page settings * Document some helpers and utils. * Document convention with the container in register/bind methods * Document that all lifecycle stubs should call super * Document scheduled commands * Document permission tag scopability * Document magic permission model namespaces Closes flarum/framework#2202 * Document testing `config` method * Document assets:publish command * Document filesystem extensibility Closes #172 * Update i18n docs for stable. Complete the lang pack docs. * 1.0 update guide * Document extension assets * Remove beta references * Revert "Remove beta references" This reverts commit e15ed85. * Update docs/extend/filesystem.md Co-authored-by: Sami Mazouz <sychocouldy@gmail.com> * Update docs/extend/i18n.md Co-authored-by: Clark Winkelmann <clark.winkelmann@gmail.com> * Update docs/extend/i18n.md Co-authored-by: Sami Mazouz <sychocouldy@gmail.com> * Update docs/extend/i18n.md Co-authored-by: Sami Mazouz <sychocouldy@gmail.com> * Update docs/extend/permissions.md Co-authored-by: Sami Mazouz <sychocouldy@gmail.com> * Update docs/extend/update-1.0.md Co-authored-by: Sami Mazouz <sychocouldy@gmail.com> * Update docs/extend/update-1.0.md Co-authored-by: Sami Mazouz <sychocouldy@gmail.com> * Update docs/extend/update-1.0.md Co-authored-by: Sami Mazouz <sychocouldy@gmail.com> * Update docs/extend/i18n.md Co-authored-by: Sami Mazouz <sychocouldy@gmail.com> * Update docs/extend/i18n.md Co-authored-by: Sami Mazouz <sychocouldy@gmail.com> * Spacing fix * DOn't assume local storage driver * Adjust tag scoped comment * Finish sentences (and sandwiches) * Mention translations * Fix octane link docs * Clarify pluralization variable convention Co-authored-by: Sami Mazouz <sychocouldy@gmail.com> Co-authored-by: Clark Winkelmann <clark.winkelmann@gmail.com>
* Document `help` field in admin settings * Document additional attrs in admin page settings * Document some helpers and utils. * Document convention with the container in register/bind methods * Document that all lifecycle stubs should call super * Document scheduled commands * Document permission tag scopability * Document magic permission model namespaces Closes flarum/framework#2202 * Document testing `config` method * Document assets:publish command * Document filesystem extensibility Closes #172 * Update i18n docs for stable. Complete the lang pack docs. * 1.0 update guide * Document extension assets * Remove beta references * Revert "Remove beta references" This reverts commit e15ed85. * Remove beta references * Update docs/extend/filesystem.md Co-authored-by: Sami Mazouz <sychocouldy@gmail.com> * Update docs/extend/i18n.md Co-authored-by: Clark Winkelmann <clark.winkelmann@gmail.com> * Update docs/extend/i18n.md Co-authored-by: Sami Mazouz <sychocouldy@gmail.com> * Update docs/extend/i18n.md Co-authored-by: Sami Mazouz <sychocouldy@gmail.com> * Update docs/extend/permissions.md Co-authored-by: Sami Mazouz <sychocouldy@gmail.com> * Update docs/extend/update-1.0.md Co-authored-by: Sami Mazouz <sychocouldy@gmail.com> * Update docs/extend/update-1.0.md Co-authored-by: Sami Mazouz <sychocouldy@gmail.com> * Update docs/extend/update-1.0.md Co-authored-by: Sami Mazouz <sychocouldy@gmail.com> * Update docs/extend/i18n.md Co-authored-by: Sami Mazouz <sychocouldy@gmail.com> * Update docs/extend/i18n.md Co-authored-by: Sami Mazouz <sychocouldy@gmail.com> * Spacing fix * DOn't assume local storage driver * Adjust tag scoped comment * Finish sentences (and sandwiches) * Mention translations * Fix octane link docs * Clarify update steps * Clarify pluralization variable convention * Revert "Clarify pluralization variable convention" This reverts commit 52ac219. * Clarify pluralization variable convention * Update update.md * Update docs/update.md Co-authored-by: Alexander Skvortsov <sasha.skvortsov109@gmail.com> Co-authored-by: Alexander Skvortsov <38059171+askvortsov1@users.noreply.github.com> Co-authored-by: Sami Mazouz <sychocouldy@gmail.com> Co-authored-by: Clark Winkelmann <clark.winkelmann@gmail.com>
Before stable we need to:
Some options in the conventions:
user.edit
userEdit
What we have to consider is that permissions are usually made an attribute on a model. So it's pretty confusing if different conventions are used for model attributes, permissions and permission grid keys, for instance:
camelCase used in core for
viewDiscussions
: https://github.com/flarum/core/blob/88366fe8af3baa566ad625743016acb85a0cf345/js/src/admin/components/PermissionGrid.js#L104-L113camelCase and dot mixed
viewLastSeenAt
anduser.viewLastSeenAt
: https://github.com/flarum/core/blob/88366fe8af3baa566ad625743016acb85a0cf345/js/src/admin/components/PermissionGrid.js#L153-L157The text was updated successfully, but these errors were encountered: