If a Field API field attached to an entity is locked a privileged user can still change the cardinality, which can really mess up the website. In the case of a taxonomy term reference, the vocabulary can be changed too and in cases of other field types I, bet there are other settings that can be altered.
I think that once a field is locked, under no circumstances should it be "editable" by any means but programmatically.
This behavior us crucial for distributions and/or installation profiles and advanced modules.
Steps to reproduce:
1) standard profile Article node type has Tags
2) change field config drush @d8 cedit field.storage.node.field_tags
to locked: true
3) at admin/structure/types/manage/article/fields
click "Term Reference" link
4) You can change cardinality and vocabulary
Comment | File | Size | Author |
---|---|---|---|
#137 | 2274433-137.patch | 4.47 KB | smustgrave |
| |||
#137 | 2274433-137-tests-only.patch | 1.07 KB | smustgrave |
#137 | interdiff-123-137.txt | 2.14 KB | smustgrave |
Comments
Comment #1
swentel CreditAttribution: swentel commentedThat's weird, that would mean #2150179: Delete confirm form for locked fields is hotlinkable did not fix this.
Comment #2
Anonymous (not verified) CreditAttribution: Anonymous commentedI'll try the Alpha 12 tomorrow.
Comment #3
Anonymous (not verified) CreditAttribution: Anonymous commentedI am still able to change the cardinality in Alpha 12.
This is example of one of my fields:
This is how I create instance(s):
Comment #4
swentel CreditAttribution: swentel commentedOh, right, editable. Sorry, I misread that one completely. However, this behaviour has been there since D7 (maybe CCK as well, but I should check).
Since we support 'not deleting', we could probably support not editing too I guess, but maybe that should be split up then, because the ability to change the cardinality is valuable IMO. OTOH, the permission system could also just hide field ui fields completely for people - even per entity type.
In fact, with the configuration system now in place, the locked property on a field could probably just be removed and then using https://drupal.org/project/config_readonly you can lock your entire site completely of writing, updating or deleting any kind of config entity.
Comment #5
Anonymous (not verified) CreditAttribution: Anonymous commented@swentel - what I'm talking about is UI, what you are proposing is DX.
Comment #6
longwaveYour code sample creates a configurable field, which by design can be reconfigured by the user. You can add non-configurable fields, which cannot be edited or deleted by the user, to any entity with hook_entity_base_field_info()/_alter() or to a specific bundle with hook_entity_bundle_field_info()/_alter().
Comment #7
Anonymous (not verified) CreditAttribution: Anonymous commented@longwave: I'm not talking about a specific case here*. I'm talking about the whole concept of locking fields.
*And even if I were, it's still a
ridiculousbad idea that contradicts the whole concept of Field API.Comment #8
andypost"locked" is used only to prevent changes on field via Field UI.
But seems this broken and changing cardinality could lead to data loss! e.g. when changing vocabulary.
Steps to reproduce:
1) standard profile Article node type has Tags
2) change field config
drush @d8 cedit field.storage.node.field_tags
tolocked: true
3) at
admin/structure/types/manage/article/fields
click "Term Reference" link4) You can change cardinality and vocabulary
added to summary
Comment #9
andypostA quick fix - disable a whole form so settings could be viewed but no way to change them.
Comment #10
Kars-T CreditAttribution: Kars-T commentedPatch in #9 works but I feel that disabling the form is not as good as they did in "FieldEditForm" Class. So I made a patch in the same way as there. What I don't appreciate is that is copy & paste and by this a code stench. But everything else would explode the scope.
Comment #11
Kars-T CreditAttribution: Kars-T commentedAdding an interdiff
Comment #12
andypostComment #13
andypostTagged
Comment #14
andypostFixed access for edit, still needs tests
Comment #15
Shivam Agarwal CreditAttribution: Shivam Agarwal commented@andypost I am trying to reproduce this bug but I am confused in step #2 of reproduce. Can you please elaborate? Thanks
Comment #16
andypost@Shuvam this is drush way to change config directly (set property to locked)
Comment #17
Shivam Agarwal CreditAttribution: Shivam Agarwal commented@ Andypost This patch is still not working. I can still access delete from UI which should be banned once patch is applied.
Comment #18
andypostYes, but we need to mark this fields locked anyway.
Also we need to hide ability to delete locked fields with field ui and cover with tests
Comment #19
littleindian CreditAttribution: littleindian commentedComment #20
littleindian CreditAttribution: littleindian commentedComment #21
littleindian CreditAttribution: littleindian commentedComment #22
littleindian CreditAttribution: littleindian commentedIt worked : Tested patch #14 and followed
Steps to reproduce:
1) standard profile Article node type has Tags
2) change field config drush cedit field.storage.node.field_tags to locked: true
3) at admin/structure/types/manage/article/fields click "Term Reference" link
Attaching the screenshot for reference.
I think it's solves our purpose of hiding the ability to delete locked fields with field ui.
Working on writing the test for same.
Comment #23
littleindian CreditAttribution: littleindian commented@andy I have restructured the locked field condition.
working on writing test for same!
Comment #24
littleindian CreditAttribution: littleindian commentedThe test is already written Drupal\field_ui\Tests\ManageFieldsTest for
This will solve our purpose.
Comment #25
littleindian CreditAttribution: littleindian commentedComment #26
andypostPatch looks great, just needs tests and fix nits
getFSD() should stay within if
needs revert
Comment #27
littleindian CreditAttribution: littleindian commentedComment #28
iMiksuNeeds re-roll after #2446869: Convert the "Field storage edit" form to an actual entity form got in.
Comment #29
siva_epari CreditAttribution: siva_epari commentedPatch rerolled and changes from [#26] implemented.
Comment #31
siva_epari CreditAttribution: siva_epari commentedAccidentally added the original of the renamed file. Removed it.
Trying to fix the errors. Hope this works!
Comment #34
Anonymous (not verified) CreditAttribution: Anonymous commentedOk so we have a patch. Can this be commited?
Comment #35
dawehner@ivanjaros
You know how core development works, we need reviews: https://www.drupal.org/patch/review
Comment #36
Anonymous (not verified) CreditAttribution: Anonymous commentedbump
Comment #37
longwaveNeeds tests.
Comment #38
geertvd CreditAttribution: geertvd at XIO commentedWriting tests for this one
Comment #39
geertvd CreditAttribution: geertvd at XIO commentedAdded tests for this.
Comment #42
geertvd CreditAttribution: geertvd at XIO commentedWoops, forgot 1 line
Comment #43
geertvd CreditAttribution: geertvd at XIO commentedComment #47
koence CreditAttribution: koence at XIO commentedTest looks ok to me.
Comment #48
alexpottI'd like a sub system maintainer to chime in with a +1 since @swentel has not commented on this issue since #4. It makes sense to me but I don;t have the history with the field system that @yched and @swentel and others do.
Comment #49
swentel CreditAttribution: swentel commentedLooks good to me, two small nitpicks in current patch.
Should use format_string() for replacing $field_name
Let's merge this in one line: 'field and storage settings can not be changed'
Let's also add an assert in ManageFieldsTest::testLockedField() to make sure the 'Storage settings' link is not available, should be a simple one line.
Comment #50
geertvd CreditAttribution: geertvd at XIO commentedFixed feedback from #49
Comment #51
geertvd CreditAttribution: geertvd at XIO commentedFixed feedback from #49
Comment #52
alexpottProbably better to use SafeMarkup::format() and it needs to use the placeholder
%<code> indicator and not <code>!
.Comment #53
alexpottAnd assertRaw() instead of assertText()
Comment #55
geertvd CreditAttribution: geertvd at XIO commentedComment #56
geertvd CreditAttribution: geertvd commentedMissed this, fixing that now
Comment #57
geertvd CreditAttribution: geertvd commentedComment #59
swentel CreditAttribution: swentel commentedAlright, looks good now.
Comment #60
geertvd CreditAttribution: geertvd commentedRemoving SafeMarkup::format() again because #2549805: Remove all usage of FormattableMarkup in tests apart from explicit tests of that API
Comment #61
alexpott@geertvd hold fire with that - we're exploring the issue haven't made minds up about the overall direction.
Comment #62
geertvd CreditAttribution: geertvd commentedOk, re-uploaded the patch from #57 and setting back to RTBC
Comment #64
yched CreditAttribution: yched commentedLocked fields have always been a bit blurry :-/
The intent in D7 was to allow modules to define "programmatic fields" for their business logic, and make sure they were not removed by site admins using Field UI, but keeping more mundane aspects (mostly widget and display configuration, but also label...) adjustable.
So you could not *remove* the "field instance", but still freely edit it.
In D8, widget and display configuration are out of the field definition anyway, so that part is not an issue.
I still think it's a pain to forbid changing (or translating, for that matter) the label, since that's really only presentational preferences.
Not sure about the other stuff like field settings, default value, it's probably ok to keep them locked, so that the "semantics" of the field is locked - but then again some field types have settings that can be fairly presentational as well, there's no real way to tell generically
Ideally, we'd move from "locked TRUE / FALSE" to a more granular feature like "this and this are locked, the rest is editable", but we won't go there in D8.
Is there a way we could leave the label editable ?
Comment #65
geertvd CreditAttribution: geertvd commentedI can understand the need for #64 but this patch only covers field storage settings, which in my opinion do need to be locked if the field is locked.
Maybe we can create a follow-up for #64?
Comment #66
yched CreditAttribution: yched commentedWell, it does add a check on 'locked' to FieldConfigAccessControlHandler, so if I'm not mistaken this would block access to the "field edit form" for locked fields ?
Comment #67
geertvd CreditAttribution: geertvd commentedOh yeah you are right, nevermind my previous comment then :)
Comment #68
alexpottThis is a really good question. It should be editable. it doesn't make sense that you could change the translation but can't change the actual label.
Thanks @yched
Comment #69
Anonymous (not verified) CreditAttribution: Anonymous commentedSe we want to lock the storage but keep the instance editable.
On the other hand I think entity reference has the target bundle setting in instance and not storage so ... to me personally I am happy with more restriction, but that's just my use case.
Comment #70
yched CreditAttribution: yched commentedThat was the behavior in D7. So this might be the safest at this point ?
As I said in #64, locking all the field (instance) except label might be OK too, but that's a larger departure (and arguably less of a bugfix). No strong opinion, honestly.
Comment #71
geertvd CreditAttribution: geertvd commentedSomething like this maybe? This leaves the instance editable.
Comment #74
geertvd CreditAttribution: geertvd commentedSeems like those link asserts where false positives, fixed that.
I also added an extra check to make sure that the label field is available on the settings form.
Comment #76
geertvd CreditAttribution: geertvd commentedbump
Comment #77
Anonymous (not verified) CreditAttribution: Anonymous commentedbump
Comment #78
andypostlooks good to go
@yched any more suggestions?
Comment #79
swentel CreditAttribution: swentel commentedHmm, the UI might be confusing to users.
Not sure what the best thing is here. Bringing back the 'storage' edit link seems logical, and less hard then trying to figure out whether there's other form elements, which are accessible or not (because they might even be disabled because of stored data) to hide.
Other option might be to add a dedicated access control handler for the storage to just completely hide that tab and not care about any other storage setting.
Not sure, don't want to hold this up.
Comment #80
swentel CreditAttribution: swentel commentedWoops, didn't want to RTBC it yet after testing.
Comment #81
yched CreditAttribution: yched commentedYep, if the field storage is locked, the corresponding tab (that is misnamed "field settings" in current HEAD, there is an issue for that) should be hidden as well.
Comment #82
geertvd CreditAttribution: geertvd commentedI tried this, I added a
EntityAccessControlHandler
forFieldStorageConfig
but field_storage_config is not available in the route path for the storage settings ($path/fields/{field_config}/storage
) so this is not working.Any pointers how to do this?
Comment #83
andypostLet's see how it works with tests (tabs somehow broken in my install)
@yched I think
isDeletable()
should care about locked statusalso discovered that field module uses permissions defined in field_ui module!
Comment #85
andypostFix access for links and bring a bit sanity to building
Comment #87
geertvd CreditAttribution: geertvd commented@andypost, from what I could tell this is failing because entity_access is expecting the field_storage_config entity to be in the route.
See
\Drupal\Core\Entity\EntityAccessCheck
Comment #88
andypostFiled child issue #2562855: Fields cannot be administered without Field UI module
@geertvd entity is there, otherwise entityform will not work
The entity is here exists, see \Drupal\field_ui\Routing\FieldUiRouteEnhancer
Comment #89
geertvd CreditAttribution: geertvd commentedI think the
field_config
entity is there, thefield_storage_config
entity is not.Entityform is working because of this
Comment #90
yched CreditAttribution: yched commentedThe line spacing seems a bit random, can we keep some visual structure here ?
Also, the comments should make it clearer when we're testing the "field settings" form or the "storage settings form"
Also, the test that checks the "storage settings" form on a locked field expects a 200 ? I would have thought a 403 ?
Labels should be consistent (verb + complement ?)
Do we still need this now that the route is not accessible ?
Comment #91
andypostFixed #90.2 and #90.3, tests not touched
Cleaned-up implementation, and fixed bug in list builder
New question - is it ok that
\Drupal\field\FieldConfigAccessControlHandler
usesisLocked()
method of storage?The remaining issue that no tabs displayed for field settings forms
Comment #93
andypost@geertvd finally get you point about entity!
really interesting how form is found here, there's only "field_config" entity on route
todo: remove
Comment #94
geertvd CreditAttribution: geertvd commentedPerhaps we can add the field_storage_config entity in \Drupal\field_ui\Routing\FieldUiRouteEnhancer?
Comment #95
Anonymous (not verified) CreditAttribution: Anonymous commentedAlso I have noticed that when I click on field widget I see "edit" task and when I go there I see message about the field being locked BUT it is actually a form with submit button, not just a message. This should either be a message or the button should be hidden as well.
Comment #96
andrewbelcher CreditAttribution: andrewbelcher at FreelyGive commentedThis solves the field ui issue from #2650898: ListBuilders do not check $entity->access() for operation links. Marking as a contrib blocker, as I've got a module in development that currently ends up with lots of errors and an empty default operation due to this issue.
I couldn't quite tell what was left to be done on this. Very happy to do some work on pushing this forward if someone is able to point me at what's remaining.
Comment #99
cilefen CreditAttribution: cilefen commentedComment #101
andypostComment #102
andypostComment #103
andypostThis will be very useful for domain access module and domain_entity (access) modules to disallow changes on automatically assigned domains to entities
Comment #104
BerdirDiscussed this today with @tstoeckler, @amateescu, @plach and @xjm and agreed that this is not a major issue. You need to manually craft a URL to be able to access a page where you can change those settings. And even if we lock this down then there are always way around it, like drush cedit or config export/import in the UI.
What we need to figure out and define is what Locked exactly means, as we weren't sure what exactly should be allowed and what not.
There was also the idea to have a less strict version that only prevents from deleting a field. But that can also be done using entity access.
Another related problem that I recently noticed is that a locked field can't be re-used. I think there isn't really a reason why that shouldn't work, we can either fix that here or create a separate issue.
Comment #105
BoobaaYou don't need to manually craft a URL to be able to access a page where you can change field storage settings for
locked
fields. An example:locked
(you'll need to provide some more info like'settings' => [ 'target_type' => 'node']
, since an entityreference field MUST know what type of entities it can reference, and it's impossible to create an entityreference field manually without such information);Clicking on that link allows changing the entity type this
locked
entityreference field can reference (at least without the patch).Not sure if this warrants the major priority, tho.
I think the biggest question would be what part of the field should be
locked
? The field storage settings? The field instance settings? Both? Even something more like deletion of the field as well? Even something less like only disallowing deletion of the field? Any combination of these?Comment #106
vijaycs85Updating title as per proposed solution/problem statement as it's causing confusion in #2831936: Add "File" MediaSource plugin
Comment #107
Anonymous (not verified) CreditAttribution: Anonymous commentedSounds like there should be edit and delete permission per each field storage and instance. Therefore no locking would be needed. All allowed by default but superadmin could disable these without the need to fiddle with locking. Modules can(after field/instance creation) update permissions so all stays in config....?
Comment #108
BoobaaHmm, that sounds like a flexible solution, but would result in a HUGE permission maze pretty quickly.
Comment #109
Anonymous (not verified) CreditAttribution: Anonymous commentedFor sure, but the same thing is planned for blocks anyway so why not use the system that was built exactly for this purpose(personally I think permisisons are underused in the core in the first place)? The UX is another thing, this is about DX first and foremost.
Comment #110
andypostThe related issue
IMO this property should be renamed to
field_ui_locked
Comment #112
Anonymous (not verified) CreditAttribution: Anonymous commentedI've just noticed that hook_field_config_access() is useless as well :D
I will have to swap out the \Drupal\field_ui\FieldConfigListBuilder completely.
Comment #113
Anonymous (not verified) CreditAttribution: Anonymous commentedThis is causing the misbehaving of entity access control:
\Drupal\field\FieldConfigAccessControlHandler::checkAccess
I think the logic/reasoning described in the function is plain wrong.
The FieldConfig(field instance) delegates access to the FieldStorageConfig(field storage) which means that if I deny update operation on the storage, it will make update forbidden on the field instance as well.
I think this should be removed and isLocekd() check should be added into the access handler for field storage config for update/delete operation. That way, programmatically, one can flip the locked switch, perform change and lock it back again. Which cannot be done through the UI.
This will even allow us to "lock" field instances on specific bundles as well.
----
The method can copy most of the field storage config's implementation but this way we have separate access handlers with correct alterations working.
Additionally, the
\Drupal\field_ui\FieldConfigListBuilder::buildRow
should checkupdate
access to the storage and display only the field type as plain text instead of link. And\Drupal\field_ui\FieldConfigListBuilder::getDefaultOperations
should do the same for thestorage-settings
operation so we don't have to implementhook_entity_operation_alter()
.Comment #114
Anonymous (not verified) CreditAttribution: Anonymous commentedComment #121
vsujeetkumar CreditAttribution: vsujeetkumar at Srijan | A Material+ Company for Drupal India Association commentedRe-roll patch created for 9.1.x, Please review.
Comment #123
vsujeetkumar CreditAttribution: vsujeetkumar at Srijan | A Material+ Company for Drupal India Association commentedFixed tests, Please review.
Comment #128
smustgrave CreditAttribution: smustgrave at Mobomo commentedClosed https://www.drupal.org/node/806102 as a duplicate of this. Please move over credit for
RoSk0
mdm
chr.fritsch
Comment #136
quietone CreditAttribution: quietone at PreviousNext commented@smustgrave, thank you. I have reviewed the now closed duplicate and moved credit.
Comment #137
smustgrave CreditAttribution: smustgrave at Mobomo commentedSo patch #123 didn't work for me
I locked a field but when viewing I could still edit the widget and based on the issue summary that should not be the case. If that's no longer the proposed solution then the issue summary could use an upate.
Also added a small test assertion.
Comment #140
Anybody@smustgrave, thank you for your patch in #138! I just tested it and it works as expected! :) RTBC+1
BUT:
I disagree it's the final solution and don't think #806102: Locked fields can change the widget but not settings should have been closed as duplicate. This issue is only about disallowing to edit the field storage related configuration like cardinality. That's totally fine and a clear bug that should be fixed!
But on the other hand, and that was also an aspect of the other issue, the
locked: true
on field storage configuration currently also locks editing field instance related configuration, like field instancewhich is also an important issue. Especially not being able to edit those on reused fields with a locked field storage is a problem we run into again and again and end up editing the field instance configuration directly. That shouldn't be the case.
So I decided to create a separate issue for that: #3345006: Locking field.storage should not lock field instance settings (field.field) instead of reopening #806102: Locked fields can change the widget but not settings. I hope that's more specific.
Both should be solved.
Comment #141
lauriiiUpdating credits since I re-opened #806102: Locked fields can change the widget but not settings.
Comment #142
lauriiiI agree that the current logic is kind of wrong as argued by #113. However, the config entities being separate for field storage and field instance tends to be more of an implementation detail. I can't think of a use case where users would actually want to customize permissions for these two forms separately.
I think it might make sense to hold off making this change because we are looking into combining these two forms in #3347291: Combine field storage and field instance forms. Keeping the access controls tied together like it is currently, would be simpler from that perspective.
I'd recommend that we keep the keep the access control to two of these config entities connected, and we add additional access control to
\Drupal\field\FieldConfigAccessControlHandler::checkAccess
to prevent editing locked field configs.Comment #143
Anybody@lauriii:
That might be true. The point is, that if it's separated in the data model, it's at least possible and I'm not sure we should assume that. On the other side it is additional work. Wondering who we could ask.
One typical example that happens very often for us is, that the default value should not be locked, in contrast to all other field stuff. The default value is often very site-specific, while the fields / schema is general.
As written above, it's currently locked by the form, as it's in the wrong place. Locked by the the field storage lock in the UI, but belonging to the field instance, that should not be locked. See #140.
Agree, would be nice, if the points from about could be taken into account.