Now that user roles are configurables (#1479454: Convert user roles to configurables) we should incorporate the permissions that have been assigned to a role into the UserRole entity.
For example the default anonymous role config entity
id: anonymous
label: Anonymous user
weight: 0
permissions:
- 'access content'
langcode: en
Stale permission assignment on module uninstallation will temporarly be removed until #2003966: Helper issue for #1199946 : Disabled modules are broken beyond repair is resolved which will allow us to cleanup permissions in hook_module_preuninstall().
Follow-up issues:
#2025089: Deprecate user_role_grant_permissions() and user_role_revoke_permissions()
#2026983: [regression] Grants for permissions defined by a module are not revoked / removed from Role config entities when that module is uninstalled
| Comment | File | Size | Author |
|---|---|---|---|
| #128 | 124-127-interdiff.txt | 1006 bytes | alexpott |
| #128 | 1872876-127.patch | 73.71 KB | alexpott |
| #127 | 1872876_127.patch | 73.7 KB | chx |
| #127 | interdiff.txt | 1006 bytes | chx |
| #124 | 1872876-124.patch | 73.71 KB | fubhy |
Comments
Comment #1
fubhy commented#1872874: Remove the module name property from the role permission table still blocks this issue from moving forward and didn't get any reviews yet. Anyone got a few minutes to take a look?
Comment #2
chx commentedThat doesn't block this. I've seen Drupal install and the Field UI upgrade test pass. If that test passes... note: I have made some cleanups that could've been done otherwise, mostly to use API functions where they weren't. Also, I brutally simplified a Views filter, left a message to Daniel to verify it is indeed unnecessary code.
Comment #4
chx commentedWhile it doesn't quite block, it is quite tedious :)
Comment #5
chx commentedComment #7
chx commentedAfter a discussion with dawehner: a) we need a filter for enabled permissions cos only uninstalled permissions are removed -- but the list of permissions retrieved by module_invoke_all includes only the permissions by enabled modules so we don't need to consult the other config file which is slated for removal anyways b) we will want to move $rid to the config object name from the top key so that we have one object per rid. Next revision will include a) and once that's passed I will get to b).
Comment #8
dawehnerStarted to work on tests for the filter and field, which clearly shows how many issues we have with the filter.
Comment #9
chx commentedComment #11
chx commentedThis splits the config objects per role id because -- config('foo')->get() is always an array but config('foo')->get('something') can be NULL and PHP doesnt like a NULL when it expects an array. Huge props to dawehner for making the Views user test coverage more solid.
Comment #12
chx commentedOne more roll, the modules-permissions is moved out of the user.permission. namespace to avoid confusion. The commented out Views tests have a todo , dawehner will file a followup and get 'em fixed. This should be ready.
Comment #13
fubhy commentedMostly nitpicky review. There are some ugly things which are caused by the module name that we currently store along with the permission assignments but that can be solved later as chx pointed out. So, thanks for solving this issue despite that uglyness.
Not sure about the name of that function given what it does. I had to read the function 3 times before I saw what was going on. The feature set (rename, replace with multiple, delete) is basically caused by the array_merge(). It's okay to have all that in this one function but it's rather a replace then. So can we name it 'update_replace_permissions'?
double quotes! (not that it matters)
Two line breaks.
Missing empty line between @param and @return.
Do we really need a helper function for that? We are only using that in two places :). Well, I guess it doesn't hurt.
Missing empty line after function.
----
Is there a follow-up for solving the views tests as mentioned in the @todos?
Comment #14
chx commentedTwo line breaks! Oh dear. Quick, let's fix it before the universe unravels in the face of such a horror.
I am grateful for the review but I couldn't resist.
Comment #15
fubhy commentedOkay. RTBC once this comes back green (which it will) :)
Comment #16
chx commentedKeeping up with HEAD. As interdiff is not possible, I attached a direct diff of the two patches.
Comment #17
chx commentedfubhy points out that while update_rename_permissions is now update_replace_permissions the variable and the doxygen didnt'f wolow. As you can see, replacing letters is easy and cheap :)
Comment #18
fubhy commentedEspecially with PhpStorm, eh? +1 RTBC for the HEAD chasing.
Comment #20
chx commentedGrr!
Comment #22
chx commentedTo clarify the last few rerolls: during the commitfest another installSchema call got added. I needed to remove that. But, that installSchema does not get a list of tables to install but the name of the module and then either a string or an array is a DrupalWTF. And, has absolutely nothing to do with the substrance of this patch and so the RTBC is correct.
Comment #23
xjm#22: 1872876_22.patch queued for re-testing.
Comment #24
alexpottIt seems like the HandlerFilterPermissionTest is unfinished
Comment #25
dawehnerOpened another issue for the @todo in the test: #1959296: Fix the not operation in the many to one handling.
That's just a rerole.
Comment #26
dawehnerAdded tests for the UI part.
Comment #28
tim.plunkettRerolled.
Comment #30
dawehnerIt's actually good to see that we got more and more tests over time.
Comment #31
dawehnerI don't really understand the todo here:
I hope that chx can enlighten us.
This is just a list of small cleanups/adaptions to new things in drupal.
Comment #32
chx commentedThat whole permissions-by-module stuff is just for uninstall. Die, die, die! I hope we can remove it at one point. So that's what the todo is: remove if we can.
Comment #33
tim.plunkettAnother one bites the dust!
@dawehner++ @chx++
Comment #34
dawehnerWe agree that this @todo is not helpful there, so let's drop it.
Comment #35
andypostThis requires follow-up to be filed.
Maybe better to implement helper in follow-up. Seems hook execution for for each field is too expensive without caching
Is there a reason to not make a follow up and add link here for @todo
Comment #36
dawehnerThanks for your comment.
This just happens once for the full result. I don't think that this is a performance issue we have to tackle.
There is already a follow up for that: #1959296: Fix the not operation in the many to one handling.
Comment #37
alexpottFrom a conversation on IRC.
alexpott:
just wondering why the info contained in user.permission.anonymous.yml is not just an array on user.role.anonymous.yml. If I want to deploy a role - to me that's always going to include its permissions… and the relationship between these files will always be 1 to 1
dawehner:
that is a good point. as far as I know one goal to the current approach is to avoid using the user roles config entity
alexpott:
gotta ask… why?
dawehner:
i'm not 100% sure, but I think it's considered as a bad practice to load the config files directly for config entities... then loading the entity might be too much overhead
alexpott:
hmmm... it seems a shame
There doesn't seem to be be any explanation on the issue as to why adding a permission property to the role config entity was not considered.
Putting the issue at needs review cause I want to know why we're making it more difficult to deploy a role we have move three files instead of just two... (remember the manifest :) )
Comment #38
alexpottTagging
Comment #39
chx commentedComment #41
chx commentedComment #43
chx commentedThe interdiff is against #34 because that's the last reviewed patch. The fix wasn't too hard.
Comment #45
chx commentedComment #47
chx commentedHopefully this is the last. Still interdiff against #34.
Comment #48
chx commentedOpsie. I suspect this doesn't have test coverage.
Comment #49
andypostLooks awesome! +1 to RTBC
Comment #50
andypostNW for user.schema and let's not commit dead code
/user/config/schema/user/schema.yml needs update too
do we really need this code without @todo and link?
Comment #51
chx commentedViews tests are by dawehner and I have nothing to do with them so I just removed them so this can get in. Added schema.
Comment #52
andypostshould be green!
Comment #53
Anonymous (not verified) commentedso, marking as NW as chx suggests.
Comment #54
chx commentedThanks.
Comment #55
chx commentedMaybe easier to understand this way.
Comment #56
Anonymous (not verified) commentednice work chx, i think that is RTBC if green.
Comment #58
chx commentedSigh.
Comment #59
andypostBack to RTBC
Comment #60
alexpottWe're nearly there...
I think we can do something different in
user_modules_uninstalled(). We should either move the info inuser.module.permissionto state OR (and I like preferably)... just get all the permissions by invoking hook_perm and then removing all the ones that don't exist from each role. What's really nice is that the snippet fromsystem_update_8020()becomes completely unnecessary... as this is the only place where we've actually taken care of this information during upgrade.This code is unnecessary now that permissions are stored in the role configuration entity.
Comment #61
fubhy commentedThere is a issue with that due to hook_modules_uninstalled() being fired when the affected modules are already disabled which obviously causes their hook_permission() implementation (and therefore also the information about provided permissions) to disappear.
That doesn't work with the current situation with disabled/enabled modules either as that would cause permissions for (potentially only temporarly) disabled modules to be removed as well which is definitely unwanted.
The only viable solution currently (while we still have the stupid 'disabled' state for modules) would be to write them to state() which is what I tried in the patch over at #1872874: Remove the module name property from the role permission table. I think we spoke about that on IRC before. However, I also remember speaking to @chx about this on IRC one or two months ago and we agreed to move forward with this patch with the solution he implemented here as seen above. It's a workaround, yes, but it should not hinder this from getting committed. We can solve it afterwards imho.
Comment #62
chx commentedAgreed, right now we do not have a better choice so this revision only changes RoleStorageController
Comment #64
chx commented#62: 1872876_62.patch queued for re-testing.
Comment #66
chx commentedSigh. bot flukes.
Comment #67
alexpottCame up with a solution that does not use an additionally config file (which is not config) and does not use state :)...
Basically in the role entity permissions are stored as an array keyed by the permission name and with a value of the implementing module...
This patch also fixes a bug on admin/people where in #62 and before you'll get an sql error is you select a permission no one has...
Comment #68
alexpottRemoved @todo I introduced... and removed some british optimisation :)
Also some performance testing...
Without patch
With patch
Comment #70
alexpottFixed comments indexing perms...
Comment #71
fubhy commentedHmm... I am not really sure about the benefit of that change. I don't think that it is any better than what we had in patch #62. You are basically just moving the information about the providing module from A to B but it stays in config. And we don't want it there. I think what we really need is a custom, temporary keyvalue store as tried in #1872874: Remove the module name property from the role permission table. But that's really a follow-up. Let's get #62 in and then fix this properly in #1872874: Remove the module name property from the role permission table.
Comment #72
alexpottOkay so here is what's better about #70...
isset()rather thanin_array()for all of our lookups on the permissions array http://stackoverflow.com/questions/13483219/what-is-faster-in-array-or-i... (apart from when uninstalling modules but who cares about the performance there)...So in summary: #70 is complete, has upgrade path (because there is no additional storage of info), better tested (less new stuff), and more performant.
Comment #73
fubhy commentedOkay, so we are adding lot's of array juggling code now (and invest time in writing that code) just to remove it again once that other key.value store issue is done. Yes it has to be done before release but it's far from critical. It doesn't break anything right now. It's just upgrade-path stuff. And the patch is already there, probably just needs a re-roll and some discussion/fixes. Don't get me wrong, I am not against #70 in any way. I just don't see the point of refactoring this patch with temporary solutions as those benefits you described in #72 are just temporary either until we fix this properly. Let's just move on quickly.
Comment #74
alexpottNoticed a bug... obviously we're missing some views test coverage :)
Comment #75
alexpottMore british optimisation replaced with true Drupal optimization!
Comment #76
fubhy commentedOkay then, let's get this in!
Comment #77
alexpottAssigning to catch for commit/review
Comment #78
catchCould we maybe add a @code example here?
The last sentence is very long, "and so.." onwards could be a new sentence maybe.
I'm not sure about these retrospective updates, mainly due to the horrors of the Drupal 7 upgrade path, but in this case it's a tiny amount of data, we're still pretty far off supporting head to head updates, and saves doing the work twice, so it's probably fine.
Both the existing code and the new could use user_role_permissions() (or whatever that changes to if this patch removes it).
The module key shouldn't be necessary in the yml. This originally got added because of disabled modules which there's a critical issue to remove. module/permission relationships if they have to be kept for now could go in state or somewhere but there's no way this is config much less for individual assignments.
If this is for updates only shouldn't it be in user.install? We shouldn't be using the config API in update situations either but there's already an issue for that and it's not introduced here.
Comment #79
fubhy commentedYes, it's not config. But it was not introduced here either and we still have the disabled module state. There is a follow-up issue to use a key-value store to temporarily store the permissions of disabled modules until they are either re-enabled or uninstalled. #1872874: Remove the module name property from the role permission table
Comment #80
catchuser_role_grant_permissions() doesn't require a module name so it's a regression to have to specify that.
Comment #81
alexpottI've moved the module - permissions info into state :)
Also implemented a has() method on the role to make the in_array nicer.
Comment #83
fubhy commentedOkay, if I read the interdiff correctly it only writes permissions to state upon installation of new modules. What about dynamically added permissions based on things like node types, etc.? If those get added later they never make it into state().
Also, has() is maybe a bit too unspecific. What about hasPermission()?
Comment #84
fubhy commentedI am sorry, but there are even more problems with this... Imho, #62 or #75 are still the way to go until #1199946: Disabled modules are broken beyond repair so the "disable" functionality needs to be removed is fixed. As I realize now, not even the patch from #1872874: Remove the module name property from the role permission table is going to help us as we can't couple key/value and config like this... It's simply going to leave us in an awkward and dirty state upon deployment of the permission config too. Sorry, but we have to keep the module name in the configuration. We really don't want to have config depending on key/value. In any case, as mentioned previously, the situation we have now in D7 is very very dirty as well anyways. Also, I am not aware of any module that properly cleans up it's permission unless uninstalled. E.g. currently, if you create a node type, then assign node-type specific permissions, then remove that node type again, the permission assignments are going to stay in config forever unless the node module gets uninstalled. This whole thing is really sub-optimal atm. and I can't think of a proper solution to the problem atm.
Hence, the best thing we can do atm. is to retain the same functionality we had in D7 so we at least don't introduce any regressions. That means: Keep the module name in the config for now.
Comment #85
fubhy commentedRe-uploading patch from #75 by @alexpott
Comment #87
gddNote that as of #1199946-148: Disabled modules are broken beyond repair so the "disable" functionality needs to be removed Dries has stated he is OK with removing the disabled module state. This work is progressing at #2003966: Helper issue for #1199946 : Disabled modules are broken beyond repair. So it appears we can remove all the disable-specific code from this patch and move on.
Comment #88
fubhy commentedWill do.
Comment #89
fubhy commentedProbably missed a few parts... Anyways, this basically blindly removes any of the module keys from the config and anywhere else. Hence, cleaning up permissions is _NOT_ supported atm as we do not have a pre-uninstalled hook in which we could fire hook_permissions().
Comment #90
fubhy commentedComment #92
fubhy commented#89: 1872876-89.patch queued for re-testing.
Comment #94
fubhy commented@catch / @alexpott Can we get this committed even with the "regression" of not cleaning up stale permissions on uninstall for now? This issue blocks #1966334: Convert user_access to User::hasPermission() (more or less)
Comment #95
fubhy commentedRelated: #607238: Permissions are assumed to be unique among modules, but uniqueness is not enforced
Comment #96
fubhy commentedre-roll
Comment #99
fubhy commentedI'd like to get this in the shape of #96. No cleanup code. We won't need that once the disabled module patch is in. And I am close to finishing it. I can get back to this today and upload a green patch that does not incorporate any cleanup for now. I'd hardly consider that a regression. And it's really something we absolutely need for D8. Pretty please?
Comment #100
chx commentedMoving to catch so we can get an opinion on how to continue with this.
Comment #101
fubhy commentedLet's see if I missed any permissions.
Comment #102
fubhy commentedI opened a follow-up issue to clean up user.module and remove the redundant procedural wrappers.
#2025089: Deprecate user_role_grant_permissions() and user_role_revoke_permissions()
Comment #102.0
fubhy commentedUpdated issue summary.
Comment #104
chx commentedwe discussed this on irc and we will go ahead w/o cleanup for now
Comment #105
fubhy commentedComment #107
fubhy commented#105: 1872876-105.patch queued for re-testing.
Comment #108
dawehnerFixed the code/tests
Comment #110
dawehner#108: user_permissions_config-1872876-106.patch queued for re-testing.
Comment #112
fubhy commentedFixing views filter plugin static factory, upgrade_replace_permissions() and ViewsExecutableTest.
Comment #114
fubhy commented#112: 1872876-111.patch queued for re-testing.
Comment #116
fubhy commentedComment #118
fubhy commentedComment #120
fubhy commentedComment #121
andypostWalked through patch and found no problems. RTBC?
Great!
Comment #122
alexpottThis would be even sweeter if it looked like this...
Even if you don't change hasPermission() to can() and implement cannot() I think we separate the if's as above as it makes it easier to correlate with the big comment above!
Comment #123
fubhy commentedComment #124
fubhy commentedAgreed about the if() statement. I disagree with ->can() and ->cannot() though as I simply feel that hasPermission() is more verbose and also in-line with ->grantPermission() and ->revokePermission().
Also, ->can() could be mistaken has "is this user a container?" :D /jk
EDIT: Sorry, doublepost.
Comment #125
andypostNow it much more readable.
Comment #126
catchanonmyous
Can we open a critical, postponed, follow-up for the uninstall cleanup? Otherwise this looks ready.
Comment #126.0
catchUpdated issue summary.
Comment #127
chx commentedComment #128
alexpottAdded followup to issue summary add rerolled for
Actually a bug...
Comment #129
catchCommitted/pushed to 8.x, thanks!
Comment #130
larowlanCan we get a change notice here.
Comment #131
fubhy commentedVery simple change record: https://drupal.org/node/2027241
Not sure if that's enough?
Comment #132
scor commentedupdate tags (normalize to "Needs change notification")
Comment #133
chx commentedComment #135
xjmLooks like the change notice was posted.
Comment #135.0
xjmUpdate