The Task
Convert the current permissions system to use the new configuration system.
Current implementation
- Individual permissions are defined by modules in hook_permission().
- Roles are defined in the admin area at admin/people/permissions/roles and stored in the {role} table (with the exception of the anonymous and authenticated user roles, which are added at install time and locked.)
- Users are assigned roles on the user edit page, and this is stored in the {users_roles} table
- Roles have permissions added or removed at admin/people/permissions, and this data is stored in the role {role_permission}.
- The data in the {role_permission} and {user_role} tables are the central way to determine whether or not a user has permission to do something.
Proposed implementation
This is going to need some discussion about, and I have not done any real thoughtwork behind it other than five minutes of dicussion on irc with xjm and msonnabaum. An interesting thing to think about here is that the permissions themselves are defined in code by modules, but the actual USE of those permissions (aka what permissions are available for what roles) is very much a config issue. If we follow our current trend, we would want to get rid of hook_permission() and have modules define permissions in config files (system.permission.administer_foo.xml). Then there would be a separate file that essentially implements {role_permission} and another for {user_role}. Oh and what are roles anyways? Do roles belong in the config system? If so then how do we attach them to users? One suggestion is that roles are a property on user entities, and this list of available roles is in config.
We are going to see a lot of systems where these kinds of questions come up (think blocks for instance) and these systems that bridge config and content (aka entities) are going to be among some of the most difficult to deal with.
Looking for feedback and ideas to form some consensus around a solution at this point.
Other considerations
This is central to Drupal's entire security model, we want to make sure we get it right.
This issue is related #935062: Change role id to machine name. In that issue, roles are treated as pure config which I think is the right approach as well. So if that patch lands, it may just become a matter of converting roles to CMI and we're done with that part of it.
Follow-up
#1872870: Implement a RoleListController and RoleFormController
#1751274: Do not query user_roles directly
#1872876: Turn role permission assignments into configuration.
Comment | File | Size | Author |
---|---|---|---|
#160 | drupal-1479454-159.patch | 52.31 KB | dawehner |
#152 | user.config.151.patch | 52.31 KB | sun |
#152 | interdiff.txt | 5.37 KB | sun |
#151 | 149-151.interdiff.txt | 656 bytes | fubhy |
#151 | 1479454-151.patch | 53.04 KB | fubhy |
Comments
Comment #0.0
gddAdding to pointers to related issue
Comment #1
neclimdulI guess I see it as 3 things. I have to admit a bit of grey area in how the listed features actually fall depending on the site. We do basically allow anything to happen so there's a special case for everything.
Right now we don't have a robust solution to 1) and we generally do things like stuff the information in a cache table or some serialized field in a random database table. I personally think the lack of user interaction makes this separate from CMI as it now and had high hopes for the different K/V threads. 2) is clearly CMI and 3) is clearly everything else. db tables, entities, etc.
Comment #2
Anonymous (not verified) CreditAttribution: Anonymous commentedi started writing a script to generate XML config files for core modules (and we should provide this tool for contrib too).
then i hit the obvious point - many module's permissions are dependent on which other modules/filters/etc... are enabled at the time their hook_permission() implementation is run. so - how do i ship this as a module?
Comment #3
Anonymous (not verified) CreditAttribution: Anonymous commentedi'll post the script to generate the XML files anyway once i finish it...
Comment #4
Anonymous (not verified) CreditAttribution: Anonymous commentedhere's the Gist to generate XML files for permissions:
https://gist.github.com/2139409
Comment #5
johnbarclay CreditAttribution: johnbarclay commentedThis sounds like a good starting point for me to do some cmi work. If no one else is doing this can I assign it to myself?
Comment #6
gddI talked to several people about this in Denver, and I think everyone agrees that the list of roles that are available should be configuration, so converting that could be a first step. Then I (personally) feel that a user's assigned roles should be a field on the user entity.
@beejeebus can you provide an example of where permissions are dynamically created based on other modules' info?
Comment #7
Anonymous (not verified) CreditAttribution: Anonymous commentedhttp://api.drupal.org/api/drupal/core%21modules%21node%21node.module/fun...
http://api.drupal.org/api/drupal/core%21modules%21filter%21filter.module...
Comment #8
Hugo Wetterberg CreditAttribution: Hugo Wetterberg commentedFirst draft for getting roles into cmi.
Comment #10
Hugo Wetterberg CreditAttribution: Hugo Wetterberg commentedTests should be passing now
Comment #12
Hugo Wetterberg CreditAttribution: Hugo Wetterberg commentedWell, that was a spectacular failure, amazing how many errors you can get from one error in block visibility settings. Long live testing :)
This should put everything back in order.
Comment #13
Hugo Wetterberg CreditAttribution: Hugo Wetterberg commentedComment #15
Hugo Wetterberg CreditAttribution: Hugo Wetterberg commentedApparently I had some unsaved files. The the filter & comment module has now been updated to use the new user_role_names method.
Comment #16
Hugo Wetterberg CreditAttribution: Hugo Wetterberg commentedOh yeah! Tests passed, so it's time to describe the changes a bit:
Only the roles have been migrated to cmi, permissions have been left alone. The default config contains the "anonymous" and "authenticated" roles, the "administrator" role is added programatically by the standard install profile.
There's been one API change for the user module. The `user_roles` function which previously returned "An associative array with the role id as the key and the role name as [...] value" now has been changed to return "An associative array with the role id as the key and the role object as [...] value". The function `user_role_names`has been added and it has the exact same characteristics as the `user_roles` function previously had. This is what's brought on the changes in the comment, block and filter modules.
Comment #17
gddI think the API change for user_roles() vs user_role_names() makes sense, the new function name is more clear and they better reflect what they actually do.
This is probably a bit of a performance hit, but I'm not sure what else to do when we need to link SQL stuff to config data. If we removed the need to have the role names in the $user object, and just stored the rid, we could get this down to one query again. Now that rids are machine names and have some meaning, this might be worthwhile to do as a followup.
Typo (backend)
Assuming we eventually bring {role_permission} into CMI, this is all going to change too eventually.
Other than the typo, most of this is just commentary. It also needed a reroll against head because new update hooks were added. I've done this reroll including the typo but now someone else will have to RTBC.
Nice patch, thanks for the help!
Comment #18
gddI actually opened the followup about removing role names - #1768576: Remove role names from the $user->roles array
Comment #19
Dries CreditAttribution: Dries commentedCommitted #1768576: Remove role names from the $user->roles array, which this issue depends on.
Comment #20
gddThis needs a reroll now
Comment #21
Anonymous (not verified) CreditAttribution: Anonymous commentedcould just be:
or whatever dbtng method returns things keyed by id...
Comment #22
galooph CreditAttribution: galooph commentedHere's the rerolled patch from #17.
I looked at bejeebus' comment in #21, but we need to step through the roles to add the human readable role name anyway, now that the names come from config('user.roles').
Comment #23
gddThis entire hunk can be removed now, the whole point of #1768576: Remove role names from the $user->roles array was to be able to remove this code.
Comment #24
gddAlso, before anyone asks, it is quite possible that this will be better represented as ConfigEntity, however there is another patch waiting behind this one that needs to get done before feature freeze, so I'd just as soon get this in and then do the conversion later.
Comment #25
fubhy CreditAttribution: fubhy commentedWorking on this now as well as on #1751274: Do not query user_roles directly
Comment #26
fubhy CreditAttribution: fubhy commentedOkay. This patch is the first step... It converts user roles into config entities. The next step would be to convert permissions to CMI.
Next up: Convert permissions to CMI.
Comment #27
fubhy CreditAttribution: fubhy commentedLooks like VDC added some more stuff that I didn't fix with the previous patch. Converting permissions to CMI turns out to be a bit more tricky than I initially thought. Need to chat with Greg first to find out how we want to solve that. Will fall back to fixing the Views stuff and probably converting some parts of the Roles UI to entity controllers (follow-up issues).
Comment #28
fubhy CreditAttribution: fubhy commentedOkay.. Since we can easily work on permissions and roles in separate issues I am splitting this up. Since the previous patch already does the Roles => ConfigEntity conversion (except for Views, @timplunkett will bring that issue up in a VDC meeting shortly) let's make this the "Convert roles to configurables" issue.
Also tagging with VDC and Configurables as requested by Tim.
Also uploading a new patch with some minor fixes. I think the update path is not fully working yet either. Will need some more testing.
Edit: I am going to create the 'Convert permissions to CMI' issue after I was able to get ahold of Greg. Currently, I am not entirely sure how we would implement that in a way that would not completely ruin the DX for permissions.
Comment #29
dawehnerJust adding a tag
Comment #31
dawehnerOne problem i have with this patch
when you for example go to the people management you get
Comment #33
fubhy CreditAttribution: fubhy commentedThanks Daniel, Will fix those failing tests tomorrow and also convert the role assignment / permission assignment tables to CMI. I might need a hand for the VDC integration with those as well :)
Comment #34
fubhy CreditAttribution: fubhy commentedSo... This should pass now (at least it passes all previously failed tests locally). I had a quick chat with Greg on IRC yesterday and we agreed that we will skip the hook_permission() conversion for now. Instead the next steps will be to convert the user<->role & role<->permission assignments to CMI. I will open follow-up issues for that. We will have to investigate how this should be tackled because we will loose the ability to join on permissions if we do a straight conversion. So it might be an option to keep a sort of 'cache' in the database with which we would still be able to join while the 'real' assignments reside in config. But I am not even sure yet if we actually need those joins.
EDIT: The conversion of the permission assignments went rather smooth and is not as much -/+ as I thought so I am uploading the patch here.
Comment #35
fubhy CreditAttribution: fubhy commentedAttached patch also include the conversion of {role_permissions}. Will do the same with {user_roles} in the next step.
Note: I think we should open a follow-up for refactoring the whole user_roles / user_permissions API. Some of the functions have very poor DX forcing us to do a lot of array magic for our use-cases.
@dawehner I added a few @todo's for you to solve. I hope you don't mind :).
Comment #37
fubhy CreditAttribution: fubhy commentedComment #39
dawehnerThis just fixes the views integration part, i'm not sure about the failing test.
Comment #41
dawehnerUps, this has been the wrong patch. Here is the actual patch.
Comment #43
gddThis kind of made my brain melt the first couple times I read it. I think
'user.permissions.' . $role->rid
would be more readable, in fact I'd rather that all instances of double-quote-embedded-variables be changed to concatenation. It's faster and more consistent with the other ConfigEntity implementations.Couldn't this and other methods in here just as easily be handled in hook_role_()? I'm wondering if there is a benefit to subclassing ConfigStorageController. I had this argument with myself when doing ImageStyles and ended up implementing the hooks instead.
Every time I see one of these I want to cry with joy.
Can we change this to just 'role'? It would be clearer and reduce confusion with the existing 'user_roles' table.
Looks like something weird happened here.
I didn't review the Views parts because I'm really not up on that stuff, but given that dawehner wrote it, I'm not particularly concerned.
Thanks for working on this!
Comment #44
gddComment #45
fubhy CreditAttribution: fubhy commentedAll the core module currently have their module name as prefix for entity types. @see taxonomy_vocabulary / taxonomy_term. However, I changed the naming of the entity class to just Role as well as the label. But the 'plugin id' (== entity type) should stay "user_role", no?
I am not a big fan of self-implemented hooks. This stuff is core functionality of the role entity and should be baked in to the controller. Actually, we should maybe open an issue to remove those from all other core entities as well and move them into the controllers instead. But that's just me :)
I have no strong opinion about single- vs. doublequotes. I usually tend to use double quotes if the assembled string would get really long otherwise... Which is not the case here. So... Changed it to single quotes!
Yeah, looks like cat->keyboard... Except, I don't have a cat :(
The attached patch also converts the user role entity into a plugin now that we got that in core.
Comment #47
fubhy CreditAttribution: fubhy commentedFixing upgrade path.
Comment #48
klausiuser_update_8002() needs to be updated. I guess you could just rewrite it?
Comment #49
fubhy CreditAttribution: fubhy commentedOops, now I know why we are storing the name of the providing module in {role_permissions}. We can work around that anyhow.
Comment #51
fubhy CreditAttribution: fubhy commentedOkay. Let's have this tested: I tried something else and moved the permissions into the role entity. So now we got $role->permissions instead. That also comes with quite some more code that we can remove and also allows us to clean up related code quite a bit more.
Comment #52
gddI talked about this with timplunkett and some others last night. Ultimately we didn't have any consensus about which is better or worse, but we do agree that we should standardize on something. One other thing we realized is that we should benchmark each approach, because this is something that is going to run on every page load including cached pages (I think.) So even a slight performance improvement would be worthwhile.
Will review the new patch later but I like the idea of putting permissions into the role object.
Comment #54
moshe weitzman CreditAttribution: moshe weitzman commentedSeems like we have some test fails here. Would be nice to fix and reroll.
Comment #55
gddI don't have time to get into the test failures but here is a reroll to current head.
Comment #57
andypostThis was broken
Comment #59
fubhy CreditAttribution: fubhy commentedSome parts of this patch produce early dependency issues on the entity system. That's what's causing most of the test failures. Will look into solving those on monday. I hope we can solve them nicely. Don't feel like adding more workaround hacks to install.core.inc, et all.
Comment #60
andypostFixed administration screens and update hook order
Comment #62
andypostThere was 3 calls to removed user_permission_roles()
Comment #64
marcingy CreditAttribution: marcingy commentedHopefully this fixes the upgrade tests
Comment #66
marcingy CreditAttribution: marcingy commentedNot sure why it is failing but translation.install also needs a dependency.
Comment #67
andypostSuppose this should fix broken tests
Comment #68
andypostLet's see how dependencies are related to failures
Comment #70
marcingy CreditAttribution: marcingy commentedThe dependency in 68 is backwards for node and user installs. I'll try and roll a patch later.
Comment #71
marcingy CreditAttribution: marcingy commentedLets see how this goes
Comment #73
BerdirLooks like this causes the user picture update function to run before system.module adds the uuid column to the file_managed table.
Comment #74
andypostThe problem here no in update functions itself #67 and local install-update works, but in simpletest update.php and authorize.php throws entity_load_multiple() function not found
@marcingy please provide a interdiff of changes
Comment #75
fubhy CreditAttribution: fubhy commentedIt's an early entity system dependency issue triggered by user_access(). We now require an entity_load() there due to the role<->permission relation now lying in the role entity directly. I didn't look at the latest patches yet but that's what drove my last patch against the wall.
Comment #76
fubhy CreditAttribution: fubhy commentedOkay... I really don't want to add more hacks to update.php, install.core.inc or authorize.php. Considering that the entity system simply isn't yet capable of handling early bootstrap situations yet we should move forward with a simplified version for now and fix the permissions assignments via a $role->permissions property (instead of a separate CMI namespace for that) later.
This patch is pretty much what we already had in #49. Should be green or nearly green.
I will open a follow-up for converting to $role->permissions.
Comment #77
fubhy CreditAttribution: fubhy commentedLet's re-factor towards a $role->permissions property in #1857210: Move permission assignments into a $role->permissions property on the UserRole entity.
Comment #79
fubhy CreditAttribution: fubhy commentedLooks like I forgot a tiny little piece. Should be fairly simple to fix that, though.
Comment #80
fubhy CreditAttribution: fubhy commentedComment #81
fubhy CreditAttribution: fubhy commentedMinor improvements.
Comment #82
gddI'm fine with the solution for permissions presented here and taking that topic to the followup issue.
I'm still wondering whether it is better to extend the storage controller or self-implement hooks. Lacking a standard I suppose I don't care, we can change it in a followup if we want. We should choose one or the other for consistency though.
I wonder if this is worth putting in the base class? Or maybe even as a part of #1701014: Validate config object names.
I was talking to fubhy in IRC earlier, and one thing we talked about is how do modules change or override permissions with config? For instance, if Foo module wants to force anonymous users to have 'access content'. In this patch, you could not provide default configuration to do this, you would need to manage it in foo_install(). The only way around this would be to have a separate config file for every combination of role and permission (right now the files with permissions are user.permissions.[role].yml, this would have to change to user.permissions.[role].[permission].yml.) I'm not a fan of that change and I'm fine with the hook_install() solution, but it is worth talking about.
Overall I feel like we're really close.
Comment #83
fubhy CreditAttribution: fubhy commentedYes and yes. I am actually 100% pro extending the controller in favor of self-implemented hooks as communicated before but we can of course discuss that in a follow-up issue. And yes, we should have a consistent solution for that for all entity types... whatever we decide is right.
That line existed beforehand as well (@see user_role_save()). Though, making that a part of #1701014: Validate config object names sounds good to me. Other places in core where we do that:
TermFormController::submit(), VocabularyFormController::save()
Currently, in D7, we don't allow modules to provide default role->permission assignments other than by simply going the hook_install() route too. I think that would be a new feature, and a rarely used one too. I am actually in favor of still going for the $role->permissions property in which case we would only be able to provide default config for role->permission assignments in the actual role .yml file (which is fine if you ask me). Modules would then have to assign permissions in hook_install(). Export/Import would still work as expected.
That solution is also much cleaner and might reduce the amount of array magic and helper functions that we currently have in user.module (which we should clean up anyways).
If you ask me, all these things should be handled in follow-ups. Let's leave this at NR for a few more days for others to take a look. There might still be bugs :)
Comment #84
BerdirGeneral remarks:
- A bit worried about performance here, mostly about the permissions list. I think we need to do some benchmarks here, with an actual useful and real permission set. I just checked a bigger site that I worked on and "select count(*) from role_permission;
" returns 2115. Suggestion: Install all the modules, create 10+ roles, assign all the permissions and see how many config() calls we have.
- Upgrade path tests, we already have UserRoleUpgradePathTest from the role machine name change, does this cover everything that we're doing here? Maybe add a few additional permission checks?
Right now, this code does count($roles) * count($perms) config() calls, which means config storage loads, which means as much cache queries. #1187726: Add caching for configuration / rework config object loading (Was: Memory usage and i/o from config objects) is working on changing that, but then it's still count($roles). Hm...
This code seems to be repeated quite a few times, maybe add a helper function to update.inc or so?
Should be Contains.., also in other files.
Comment #85
gddGoing to look into the performance impact today, in the meantime here's a reroll to current head.
Comment #86
gddComment #88
gddI ran this test and the results weren't that different. This is on a fresh D8 install, all core modules installed + all devel modules, 10 roles, all roles given all permissions (1251 entries in {role_permission}.) The pages were visited as a non-admin user, since I know there are places in core where we bypass user access checks for admin. I just chose four pages at semi-random. For each visit, I give the number of times config() is called, as well as how many times the config is actually loaded from files (since the first patches in #1187726: Add caching for configuration / rework config object loading (Was: Memory usage and i/o from config objects) have gone in.)
So we're not really adding that many extra config calls with this patch. config() is 0.1% to 0.2% of wall time consistently.
There's no doubt this takes longer. With the same setup as above, we're looking at 6.3ms without the patch and 75.6 with it. However with the new caching in place, at least that hit only happens once per cron run, which shouldn't be too bad.
Comment #89
gddThis patch changes 'Definition of' to 'Contains' where necessary. I didn't really see much to be gained by creating a helper function for the update functions, so I just left that code. The language upgrade tests are passing for me locally so giving the bot another chance here.
Comment #90
gddComment #91
fubhy CreditAttribution: fubhy commentedYeah.. I think at this point I would be +1 for not adding such an update function too... If we find more places in core where we want to rename permissions we can think about it again.
Regarding the performance... It looks like the decrease in performance is rather minor with this patch. Plus, you have to consider that we should still think about going for $role->permissions in a follow-up which would remove quite a few config() calls.
I would be okay with RTBC...
Comment #92
sunThanks for working on this — looks pretty good already.
This update is changed to rely on the migrated roles and permissions in config.
A) We either need to leave this update alone.
B) Or we need to define a proper dependency via
hook_update_dependencies()
.The backtick is the shell execution operator in PHP. Let's use simple single quotes here, please.
Is there any reason for why we cannot rename 'rid' to 'id' and 'name' to 'label' directly within this patch?
Hm. Also, should we do #1831928: Support a 'locked' property on ConfigEntities first?
Unless we rename 'name' to 'label' in this patch, we also need an override for the label() method.
Let's use the ->id() and ->label() methods everywhere instead of directly accessing those properties.
We can safely remove this, as it doesn't state anything that wouldn't be obvious.
Hm. This looks pretty heavy for something that probably shouldn't exist in the first place. I don't see what we gain from this enforced "put it last" sorting.
Can't we set a default weight of -20 and -10 for the anonymous and authenticated roles, and just default the weight for new roles to 0?
Hm. Can we provide a helper function à la
user_role_cache_reset()
for these?Minor: This query could be simplified now as the table aliases are no longer needed; i.e., just
SELECT rid, uid FROM {user_roles} WHERE uid IN (:uids)
It's not clear to me why the form submission handler for the user role form creates a new role entity from scratch. Normally this happens in the form constructor or through the entity form controller already?
Given that, I also don't understand how the SAVED_UPDATED condition could ever be reached?
Overall, I'm a bit skeptical about doing the role_permission conversion in the same patch. I didn't really understand why we're using separate config files for each role's permissions instead of a single user.permissions config file that holds all the mappings. I wonder whether we should perform that conversion in a separate follow-up issue?
We're no longer dropping tables in config conversion updates, and instead leave that for #1860986: Drop left-over tables from 8.x.
Unless I'm mistaken, then the new config factory cache essentially works the same as a static cache performance-wise, so the additional static cache in
user_role_permissions()
, which essentially just copies over the values may not be needed?But again, perhaps it would be better to leave the role-permissions part for a separate issue.
Hm. The module name that defines a permission is not really configuration, but instead state information. By now, it's pretty obvious that it was wrong to add that data to the role_permission table in first place.
I think we'll have to split that permission owner tracking functionality out into a separate state storage first.
Note that other conversion issues interestingly started to convert default configuration in install profiles directly into actual default config files in the profile's ./config directory. We might want to check whether that works here, too.
Comment #93
fubhy CreditAttribution: fubhy commentedAwesome review, thanks! I think I know what we gotta do now and will roll another patch + follow ups later today!
Comment #94
tim.plunkettNote, you don't need to override Entity::label(), since it uses the entity keys. Otherwise, review points are valid.
Comment #95
fubhy CreditAttribution: fubhy commentedYes, I was hoping that we can do that eventually, too.
Yes, but we don't use a entity form controller yet because it is also used by the list overview which I was planning to do a generic solution for for config entities (same as with tabledrag/weighting functionality) once I get a chance. Will open a follow-up issue to move his stuff into a form controller. This has to be considered a temporary solution. I added a @todo and opened a follow-up issue for this: #1872870: Implement a RoleListController and RoleFormController
Agreed... I opened an issue for that: #1872874: Remove the module name property from the role permission table
Agreed.... I opened an issue for that too: #1872876: Turn role permission assignments into configuration.
Okay... So regarding the attached patch:
I applied most of what was pointed out by #93... Except for the stuff that got removed entirely due to the fresh follow-up issue for the permission assignments.
I started converted ->rid to id() (with an 'id' property) and ->name to ->label() (with a 'label' property).
This was there before... I guess it has something to do with the javascript for the permission overview? Maybe?
Comment #96
fubhy CreditAttribution: fubhy commentedOh, sorry... I accidentally put my early work for the Form and List controller conversion into this patch too. Pardon me.
Comment #98
fubhy CreditAttribution: fubhy commentedFixing the failing tests... Once this is RTBC I also want to open a pure cleanup issue for all that ancient user role touching code.
Comment #99
fubhy CreditAttribution: fubhy commentedI continued work over at #1872874: Remove the module name property from the role permission table and started with a small patch for that. I would like to fix #1872870: Implement a RoleListController and RoleFormController next but it's currently blocked by #80855: Add element #type table and merge tableselect/tabledrag into it and it's followup #1855402: Add generic weighting (tabledrag) support for config entities (DraggableListController).
Comment #100
gddI gave this another lookthrough, and it appears to address all the existing concerns. I agree with moving most of the open permission questions into followups. Putting this to rtbc. Thanks for all the hrd work.
Comment #101
alexpottWe need to use the new update_config_manifest_add() here to create a manifest.user.role file during upgrade. Additionally since roles are such a key part of the system I think we need upgrade tests as well.
Comment #102
larowlanPatch adds update_config_manifest_add() call to create the manifest.user.role file and a simple upgrade test that we can load the new user_role entities. Much of the role upgrade process is already tested in Drupal\system\Tests\Upgrade\UserRoleUpgradePathTest::testRoleUpgrade() which is testing the change from serial rids to machine names, but covers much of the role functionality (other than the (config) entity system integration). New tests just make sure we can load the sample user roles by rid using entity_load().
Comment #103
fubhy CreditAttribution: fubhy commentedLet's not use loops or if/else statements in the test itself. It should be enough to simply check for 'authenticated' and 'anonymous' after the upgrade has been performed.
Comment #104
fubhy CreditAttribution: fubhy commentedEDIT: Oh, I made the interdiff the wrong way round... - == + of course :)
Comment #105
alexpottSorry also missed the fact that we need to create a UUID and add langcode to the config entity during the 7 to 8 upgrade.
The update should look something like:
So that the created config files are the same as if they'd been created by entity->save()
Comment #106
fubhy CreditAttribution: fubhy commentedComment #107
alexpottDiscovered some issues with views whilst testing this patch - can not add the role field and also we've introduced the possibility for cross site scripting.
To recreate:
<script>alert('here');</script>js
The specific code that causes this is here:
We need to
$query->orderBy('r.name');
Comment #108
alexpottPatch attached fixes issues discover in #107 and adds a test view for user_roles. Unfortunately the way the user roles are added to the view is in the preRender() step which seems a little unorthodox. But fixing that is outside the scope of this patch.
Still todo: fix the ordering of the roles in the view so that is matches the SQL equivalent.
Unfortunately the interdiff is impossible to read since this is also a reroll on top of the blocks as plugins patch.
Comment #109
ParisLiakos CreditAttribution: ParisLiakos commentedComment #110
alexpottJust discovered another issue with this patch... (at least it's an issue in #108)
Changing the order of the roles on admin/people/roles and press "save order" does not work.
Comment #111
damiankloip CreditAttribution: damiankloip commentedInstead of setting the uuid here, should this create a new config entity from this data (which will then generate this anyway) and save, al la importCreate type thing? If there is a reason not to do this, apologies!
Comment #112
alexpottYep there is a reason to not use entity_create() - entity_get_info() uses the hook system which should not be invoked during hook_update_N
Comment #113
damiankloip CreditAttribution: damiankloip commentedGood point, sorry for the noise. Proceed :)
Comment #114
fubhy CreditAttribution: fubhy commentedHey alex, thanks for the continued stream of good reviews! Are you working on a patch for what you pointed out in #110 or should I get my hands dirty?
Comment #115
alexpottThe attached patch fixes the role ordering issue for on admin/people/roles
Basically the issue was is fixed by doing this:
I've added a test for this too...
Interdiff impossible to read due to the fact this is a reroll too :)
Comment #116
alexpottReviewing the Role storage controller lead me to find some code that will never be fired since entity_create will always generate an object with a weight property.
Patch attached moves this logic to RoleStorageController::create() which means we can remove some business logic from the user_admin_roles() form FTW!
Comment #117
gddGiven that this has undergone review from all the CMI maintainers and it appears all the concerns have been addressed, I'm going to RTBC. Also removing the "Needs benchmarks" tag since I did that in #1479454-88: Convert user roles to configurables
Comment #118
Berdir#116: 1479454-116-user-roles.patch queued for re-testing.
Comment #120
alexpottI've got a fix for the "Drupal\views\Tests\AnalyzeTest" - could not reproduce the other failures. Just working on the role ordering in views.
Comment #121
alexpottThe patch attached fixes "Drupal\views\Tests\AnalyzeTest" and sorts roles listed in the view according to role weight which I think makes the most logical sense. In pre-CMI roles on the view where sorted according to name which meant that a site admin could never change the order without change names. This way they can order the roles in the admin screen and hey presto! A test for this has been added to.
The views test and Drupal\user\Plugin\views\field\Roles code could do with a review from the VDC team in any of them has time - cheers!
Comment #122
fubhy CreditAttribution: fubhy commentedThanks for keeping the patches coming, Alex. Switching to weight sorting instead of name makes sense and is consistent. The test also looks good. I am not a VDC person though... :)
Comment #123
dawehnerAlex, thank you for fixing these parts! +1 in general
ups
I really love to not use constants anymore.
Is it just me that a weight as string feels wrong?
Feels like a comment inspired by some unix commands :)
Just as a todo: We should adapt these rolenames later as they refer to the PRE-psr0 filenames.
Comment #124
andypostThis issue also requires 2 follow-ups to convert List/Form controllers
Comment #125
fubhy CreditAttribution: fubhy commentedI already created a follow-up for that. #1872870: Implement a RoleListController and RoleFormController
Comment #126
alexpottimho this is now good to go as VDC people have had look - many thanks!
Comment #127
fubhy CreditAttribution: fubhy commentedAlright then!
Comment #128
webchickHm. The benchmarks in #88 seems like it could use catch's feedback prior to commit.
Comment #129
tim.plunkett#126: 1479454-126-user-roles.patch queued for re-testing.
Comment #131
fubhy CreditAttribution: fubhy commentedComment #132
fubhy CreditAttribution: fubhy commentedComment #133
webchickAaaaand back to catch. :)
Comment #135
fubhy CreditAttribution: fubhy commented#132: 1479454-132.patch queued for re-testing.
Comment #137
alexpottDrupal\system\Tests\Entity\EntityTranslationTest
norDrupal\translation\Tests\TranslationTest
fail locally :(Will retest...
Comment #138
alexpott#132: 1479454-132.patch queued for re-testing.
Comment #139
fubhy CreditAttribution: fubhy commentedYeah, doesn't fail locally for me either.
Comment #141
alexpottLast test only failed
Drupal\translation\Tests\TranslationTest
- which does not fail locally :( ... retesting.Comment #142
alexpott#132: 1479454-132.patch queued for re-testing.
Comment #144
alexpottThis is annoying ran
Drupal\translation\Tests\TranslationTest
30 times locally - no fail...Adding debug to try and find out what's going on... this will probably go green :(
Comment #145
catchCould we add one non-magic role to the test? I realise the default ones get saved to the db too so maybe that's excessive, but I wasn't expecting to see these two tested.
This is a bit weird in the controller, is it just because we were doing it before?
Why in the API CRUD function and not in validate/submit? (again presumably it was like this before).
All of these could be follow-ups I think.
On the performance information. First of all thanks for checking! heyrocker's number didn't say what we skip - presumably a query against the users_roles table? Also they look OK to me - it's going to be something that we should focus efforts on optimizing CMI vs. this particular case so fine with that.
Unassigning me - if this was green I'd probably commit it but see what happens with the bot :(
Comment #146
tim.plunkettYes, everything in #145 is there because that's where it was before. Follow-up-fodder.
Rerolled for #1779026: Convert Text Formats to Configuration System
Comment #147
alexpottFYI both #144 and #146 contain debug code in
core/modules/translation/lib/Drupal/translation/Tests/TranslationTest.php
to try to work out whyDrupal\translation\Tests\TranslationTest
is failing.Comment #148
sunLooks like we're almost done here! :)
Gave this another final review spin:
This potentially fails, because the node is created via the UI, and the web user might not have permissions to create or translate the node.
Also, hm, apparently ::createPage() verifies that $node is an object already.
I wonder whether we could skip most of the custom weight-futzing, by changing the weights of these built-in roles to -10 and -9 respectively?
I.e., so that any new role gets a default weight of 0 and everyone's happy. ;)
This should normally happen in one of these instead:
1) preSave()
2) Form validation handler of the user role form.
This particular issue of
trim()
apparently repeats itself across all Configurable conversion issues. We should definitely create a dedicated follow-up issue to discuss what the "proper" place is/should be.Can't we use array_keys($entities) here and execute a single delete query?
Apparently, that's even prepared in $rid already... ;)
I'm not sure whether it is legit to put this sorting into
attachLoad()
.In all other conversions thus far, we're selectively performing the sorting where it is actually needed only. This typically means the admin listing page only.
Is there a technical reason for having to perform it on all loads?
This should be moved into a config file of the Standard profile.
Comment #149
fubhy CreditAttribution: fubhy commentedMaybe, but let's do that in a follow-up (if it's even necessary).
Granted... Moved it to the form validation handler. Will move it to the Form controller in the follow-up and then consider if we should have a base ConfigEntityFormController. Oki?
Ahrm... Yes, good catch... D'oh
We required weighting in multiple other places too (e.g. Views UI, etc.). I believe that's why we moved it there.
Agreed.
Comment #151
fubhy CreditAttribution: fubhy commentedWow, I am blind!
Comment #152
sunFixed that test.
Cleaned up the code.
Also changed the ::create() into a ::preSave(), and slightly corrected its logic to exactly match what it did before.
Comment #153
sun@fubhy confirmed the final tweaks in #152 and asked me to re-assign to @catch...
However, @catch already checked this in #145, so instead of doing so, rtbc'ing.
Comment #154
webchickThis is a lovely patch of loveliness. Nice to see this becoming more consistent everywhere.
Committed and pushed to 8.x. Thanks!
This'll need a change notice.
Comment #155
webchick:(
Anyone around by chance to debug this? Else I'll need to roll this back temporarily before bed.
Comment #156
xjmI confirmed the fail locally; the error is:
Comment #157
webchickOk, sorry folks. Reverted 2ae1597227b96 for now. :(
Comment #158
webchickComment #159
xjm#152: user.config.151.patch queued for re-testing.
Comment #160
dawehnerRerolled for the change in views.
Comment #161
fubhy CreditAttribution: fubhy commentedJust had a quick chat with @dawehner about his patch since there was no interdiff. Setting back to RTBC now that we got this fixed again.
Comment #162
andypostNeeds @todo for #1872870: Implement a RoleListController and RoleFormController
Comment #162.0
andypostClarifying wording
Comment #163
tim.plunkettWe don't need to add an in-code todo for something that isn't changed by this patch, we have that issue.
Comment #164
webchickOk! Take two! :)
Committed and pushed to 8.x.
Back to change notice.
Comment #165
sunFYI: #67769: Add trim to all text field submissions puts an end to the question of "Who performs a
trim()
on certain property values?" — by removing all trimming from API code and leaving it to the form handling code only. Even better! It's even automated for you for all text-related form input elements, which in turn automatically triggers the regular #required validation for required fields (but you can always opt-out via'#trim' => FALSE
).Comment #166
fubhy CreditAttribution: fubhy commentedOh god, we never did the change notice for this. On it in a minute.
Comment #167
fubhy CreditAttribution: fubhy commentedhttp://drupal.org/node/1907430
Comment #168
fubhy CreditAttribution: fubhy commentedComment #169
tstoecklerMade some minor adjustments (http://drupal.org/node/1907430/revisions/view/2548596/2548840) but looked very good and extensive already. Going back to fixed. If someone disagrees with my changes there's always the next revision, but that shouldn't hold up the critical count.
Comment #170
pcambraI think we should add also to the change notice the way to generate roles "programatically"
Comment #171
fubhy CreditAttribution: fubhy commented@pcambra: You don't want that normally. Either you define them in the UI or through .yml. There are rare cases where you will want to define them in code like that.
Comment #172.0
(not verified) CreditAttribution: commentedUpdated issue summary.
Comment #172.1
chx CreditAttribution: chx commentedUpdated issue summary.
Comment #173
xjmUntagging. Please remove the "Needs change notification" tag when the change notice task is complete.
Comment #173.0
xjmUpdated issue summary.