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

CommentFileSizeAuthor
#137 2274433-137.patch4.47 KBsmustgrave
#137 2274433-137-tests-only.patch1.07 KBsmustgrave
#137 interdiff-123-137.txt2.14 KBsmustgrave
#123 interdiff_121-123.txt606 bytesvsujeetkumar
#123 2274433_123.patch3.42 KBvsujeetkumar
#121 2274433_121.patch3.42 KBvsujeetkumar
#114 2274433-field-config-access-fix.patch2.97 KBAnonymous (not verified)
#91 2274433-field-locked-91.patch13.47 KBandypost
#91 interdiff.txt7.21 KBandypost
#85 2274433-field-locked-84.patch11.84 KBandypost
#85 interdiff.txt2.4 KBandypost
#83 2274433-field-locked-83.patch9.7 KBandypost
#83 interdiff.txt3.45 KBandypost
#74 locked_field_can_be-2274433-74-complete.patch6.51 KBgeertvd
#74 locked_field_can_be-2274433-74-test.patch3.04 KBgeertvd
#74 interdiff-2274433-71-74.txt3.2 KBgeertvd
#71 locked_field_can_be-2274433-71-complete.patch5.69 KBgeertvd
#71 locked_field_can_be-2274433-71-test.patch2.21 KBgeertvd
#71 interdiff-2274433-62-71.txt4.27 KBgeertvd
#62 locked_field_can_be-2274433-62-complete.patch4.2 KBgeertvd
#60 locked_field_can_be-2274433-60-complete.patch4.14 KBgeertvd
#60 interdiff-2274433-57-60.txt746 bytesgeertvd
#57 locked_field_can_be-2274433-57-complete.patch4.2 KBgeertvd
#57 interdiff-2274433-55-57.txt798 bytesgeertvd
#55 locked_field_can_be-2274433-55-complete.patch4.19 KBgeertvd
#55 locked_field_can_be-2274433-55-test.patch1.5 KBgeertvd
#55 interdiff-2274433-50-55.txt794 bytesgeertvd
#50 locked_field_can_be-2274433-50-complete.patch4.19 KBgeertvd
#50 locked_field_can_be-2274433-50-test.patch1.5 KBgeertvd
#50 interdiff-2274433-42-50.txt2.32 KBgeertvd
#42 locked_field_can_be-2274433-42-complete.patch3.71 KBgeertvd
#42 locked_field_can_be-2274433-42-test.patch1.04 KBgeertvd
#42 interdiff-2274433-39-42.txt960 bytesgeertvd
#39 locked_field_can_be-2274433-39-complete.patch3.57 KBgeertvd
#39 locked_field_can_be-2274433-39-test.patch915 bytesgeertvd
#31 locked_field_can_be-2274433-31.patch2.67 KBsiva_epari
#31 interdiff.txt1.64 KBsiva_epari
#29 locked_field_can_be-2274433-29.patch10.79 KBsiva_epari
#29 interdiff.txt1.13 KBsiva_epari
#23 2274433-restructured-the-locked-field-conditions.patch2.88 KBlittleindian
#22 fieldlockedui.png32.23 KBlittleindian
#14 2274433-field-locked-14.patch3.19 KBandypost
#14 interdiff.txt2.29 KBandypost
#11 interdiff-2274433-9-10.txt1.27 KBKars-T
#10 2274433-field-locked-10.patch1.78 KBKars-T
#9 2274433-field-locked-9.patch1.37 KBandypost
#8 field_locked_edit.png24.05 KBandypost
#8 field_locked.png6.28 KBandypost
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

swentel’s picture

Version: 8.0-alpha11 » 8.x-dev
Priority: Major » Normal

That's weird, that would mean #2150179: Delete confirm form for locked fields is hotlinkable did not fix this.

Anonymous’s picture

I'll try the Alpha 12 tomorrow.

Anonymous’s picture

I am still able to change the cardinality in Alpha 12.
This is example of one of my fields:

id: myentity.body
uuid: ace72462-7e4c-47b6-a710-1661ff68732a
status: true
langcode: en
name: body
entity_type: myentity
type: text_with_summary
settings: {  }
module: text
locked: true
cardinality: 1
translatable: true
indexes: {  }

This is how I create instance(s):

$instance = FieldInstanceConfig::loadByName($entity_type, $bundle, 'body');
  if (empty($instance)) {
    entity_create('field_instance_config', array(
      'field_name' => 'body',
      'entity_type' => $entity_type,
      'bundle' => $bundle,
      'label' => 'Description',
      'description' => 'Describe this.',
      'settings' => array('display_summary' => TRUE, 'text_processing' => 1),
    ))->save();
    entity_get_form_display($entity_type, $bundle, 'default')
      ->setComponent('body', array('type' => 'text_textarea_with_summary'))
      ->save();
    entity_get_display($entity_type, $bundle, 'default')
      ->setComponent('body', array('label' => 'hidden', 'type' => 'text_default', 'weight' => 0))
      ->save();
swentel’s picture

Oh, 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.

Anonymous’s picture

@swentel - what I'm talking about is UI, what you are proposing is DX.

longwave’s picture

Your 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().

Anonymous’s picture

@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 ridiculous bad idea that contradicts the whole concept of Field API.

andypost’s picture

Priority: Normal » Major
Issue summary: View changes
FileSize
6.28 KB
24.05 KB

"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 to locked: true
3) at admin/structure/types/manage/article/fields click "Term Reference" link

4) You can change cardinality and vocabulary

added to summary

andypost’s picture

Status: Active » Needs review
FileSize
1.37 KB

A quick fix - disable a whole form so settings could be viewed but no way to change them.

Kars-T’s picture

Patch 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.

Kars-T’s picture

FileSize
1.27 KB

Adding an interdiff

andypost’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests
andypost’s picture

Issue tags: +Field API

Tagged

andypost’s picture

Status: Needs work » Needs review
FileSize
2.29 KB
3.19 KB

Fixed access for edit, still needs tests

Shivam Agarwal’s picture

@andypost I am trying to reproduce this bug but I am confused in step #2 of reproduce. Can you please elaborate? Thanks

andypost’s picture

@Shuvam this is drush way to change config directly (set property to locked)

Shivam Agarwal’s picture

Status: Needs review » Needs work

@ Andypost This patch is still not working. I can still access delete from UI which should be banned once patch is applied.

andypost’s picture

Yes, 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

littleindian’s picture

Assigned: Unassigned » littleindian
littleindian’s picture

Assigned: littleindian » Unassigned
littleindian’s picture

Assigned: Unassigned » littleindian
littleindian’s picture

Issue summary: View changes
Status: Needs work » Needs review
FileSize
32.23 KB

It 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.

littleindian’s picture

@andy I have restructured the locked field condition.
working on writing test for same!

littleindian’s picture

The test is already written Drupal\field_ui\Tests\ManageFieldsTest for

function testLockedField()
$edit_link = $this->xpath('//tr[@id=:field_name]/td[4]', array(':field_name' => $field_name));
 $this->assertFalse(in_array('edit', $edit_link), 'Edit option for locked field is not present the UI');

This will solve our purpose.

littleindian’s picture

Assigned: littleindian » Unassigned
andypost’s picture

Status: Needs review » Needs work

Patch looks great, just needs tests and fix nits

  1. +++ b/core/modules/field/src/FieldConfigAccessControlHandler.php
    @@ -23,8 +23,8 @@ class FieldConfigAccessControlHandler extends EntityAccessControlHandler {
    -    if ($operation == 'delete') {
    -      $field_storage_entity = $entity->getFieldStorageDefinition();
    +    $field_storage_entity = $entity->getFieldStorageDefinition();
    +    if (in_array($operation , array('update', 'delete'))) {
    

    getFSD() should stay within if

  2. +++ b/core/modules/field/src/FieldConfigAccessControlHandler.php
    @@ -34,5 +34,4 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
    -
     }
    

    needs revert

littleindian’s picture

Assigned: Unassigned » littleindian
iMiksu’s picture

Assigned: littleindian » Unassigned
Issue tags: +Needs reroll
siva_epari’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
FileSize
1.13 KB
10.79 KB

Patch rerolled and changes from [#26] implemented.

Status: Needs review » Needs work

The last submitted patch, 29: locked_field_can_be-2274433-29.patch, failed testing.

siva_epari’s picture

Status: Needs work » Needs review
FileSize
1.64 KB
2.67 KB

Accidentally added the original of the renamed file. Removed it.

Trying to fix the errors. Hope this works!

Status: Needs review » Needs work

The last submitted patch, 31: locked_field_can_be-2274433-31.patch, failed testing.

Status: Needs work » Needs review
Anonymous’s picture

Ok so we have a patch. Can this be commited?

dawehner’s picture

@ivanjaros
You know how core development works, we need reviews: https://www.drupal.org/patch/review

Anonymous’s picture

bump

longwave’s picture

Status: Needs review » Needs work

Needs tests.

geertvd’s picture

Assigned: Unassigned » geertvd

Writing tests for this one

geertvd’s picture

Added tests for this.

The last submitted patch, 39: locked_field_can_be-2274433-39-test.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 39: locked_field_can_be-2274433-39-complete.patch, failed testing.

geertvd’s picture

geertvd’s picture

Status: Needs work » Needs review

The last submitted patch, 42: locked_field_can_be-2274433-42-test.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 42: locked_field_can_be-2274433-42-complete.patch, failed testing.

Status: Needs work » Needs review
koence’s picture

Status: Needs review » Reviewed & tested by the community

Test looks ok to me.

alexpott’s picture

Status: Reviewed & tested by the community » Needs review
Issue tags: -Needs tests +Needs subsystem maintainer review

I'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.

swentel’s picture

Status: Needs review » Needs work
Issue tags: -Needs subsystem maintainer review

Looks good to me, two small nitpicks in current patch.

  1. +++ b/core/modules/field_ui/src/Tests/ManageFieldsTest.php
    @@ -532,6 +532,11 @@ function testLockedField() {
    +    $this->assertText('The field ' . $field_name . ' is locked and cannot be edited.');
    

    Should use format_string() for replacing $field_name

    </li>
    <li>
    <code>
    +++ b/core/modules/field/src/Entity/FieldStorageConfig.php
    @@ -137,7 +137,8 @@ class FieldStorageConfig extends ConfigEntityBase implements FieldStorageConfigI
        * - field settings cannot be changed,
    -   * - new fields cannot be created
    +   * - new fields cannot be created,
    +   * - storage settings cannot be changed,
    

    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.

geertvd’s picture

geertvd’s picture

Fixed feedback from #49

alexpott’s picture

Status: Needs review » Needs work
+++ b/core/modules/field_ui/src/Tests/ManageFieldsTest.php
@@ -530,8 +530,15 @@ function testLockedField() {
+    $this->assertText(format_string('The field !field_name is locked and cannot be edited.', array('!field_name' => $field_name)));

Probably better to use SafeMarkup::format() and it needs to use the placeholder %<code> indicator and not <code>!.

alexpott’s picture

And assertRaw() instead of assertText()

The last submitted patch, 50: locked_field_can_be-2274433-50-test.patch, failed testing.

geertvd’s picture

geertvd’s picture

Probably better to use SafeMarkup::format()

Missed this, fixing that now

geertvd’s picture

The last submitted patch, 55: locked_field_can_be-2274433-55-test.patch, failed testing.

swentel’s picture

Status: Needs review » Reviewed & tested by the community

Alright, looks good now.

geertvd’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
746 bytes
4.14 KB
alexpott’s picture

@geertvd hold fire with that - we're exploring the issue haven't made minds up about the overall direction.

geertvd’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
4.2 KB

Ok, re-uploaded the patch from #57 and setting back to RTBC

The last submitted patch, 60: locked_field_can_be-2274433-60-complete.patch, failed testing.

yched’s picture

Locked 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 ?

geertvd’s picture

I 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?

yched’s picture

this patch only covers field storage settings

Well, 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 ?

geertvd’s picture

Oh yeah you are right, nevermind my previous comment then :)

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

Is there a way we could leave the label editable ?

This 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

Anonymous’s picture

Se 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.

yched’s picture

Se we want to lock the storage but keep the instance editable

That 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.

geertvd’s picture

The last submitted patch, 71: locked_field_can_be-2274433-71-test.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 71: locked_field_can_be-2274433-71-complete.patch, failed testing.

geertvd’s picture

Seems 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.

The last submitted patch, 74: locked_field_can_be-2274433-74-test.patch, failed testing.

geertvd’s picture

bump

Anonymous’s picture

bump

andypost’s picture

looks good to go
@yched any more suggestions?

swentel’s picture

Status: Needs review » Reviewed & tested by the community

Hmm, the UI might be confusing to users.

  • The Storage tab is visible and linkable, but there's no link on the manage fields page
  • When the field is locked, there's still a 'Save field settings' button - which works, but won't do much if there's any other element available there.

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.

swentel’s picture

Status: Reviewed & tested by the community » Needs review

Woops, didn't want to RTBC it yet after testing.

yched’s picture

Status: Needs review » Needs work

Yep, 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.

geertvd’s picture

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.

I tried this, I added a EntityAccessControlHandler for FieldStorageConfig 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?

andypost’s picture

Status: Needs work » Needs review
Issue tags: +Entity Field API
FileSize
3.45 KB
9.7 KB

Let's see how it works with tests (tabs somehow broken in my install)

@yched I think isDeletable() should care about locked status

also discovered that field module uses permissions defined in field_ui module!

Status: Needs review » Needs work

The last submitted patch, 83: 2274433-field-locked-83.patch, failed testing.

andypost’s picture

Status: Needs work » Needs review
FileSize
2.4 KB
11.84 KB

Fix access for links and bring a bit sanity to building

Status: Needs review » Needs work

The last submitted patch, 85: 2274433-field-locked-84.patch, failed testing.

geertvd’s picture

@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

    // Split the entity type and the operation.
    $requirement = $route->getRequirement('_entity_access');
    list($entity_type, $operation) = explode('.', $requirement);
    // If there is valid entity of the given entity type, check its access.
    $parameters = $route_match->getParameters();
    if ($parameters->has($entity_type)) {
      $entity = $parameters->get($entity_type);
      if ($entity instanceof EntityInterface) {
        return $entity->access($operation, $account, TRUE);
      }
    }
    // No opinion, so other access checks should decide if access should be
    // allowed or not.
    return AccessResult::neutral();
andypost’s picture

Filed child issue #2562855: Fields cannot be administered without Field UI module

@geertvd entity is there, otherwise entityform will not work

+++ b/core/modules/field_ui/src/Routing/RouteSubscriber.php
@@ -79,7 +79,7 @@ protected function alterRoutes(RouteCollection $collection) {
           array('_entity_form' => 'field_storage_config.edit') + $defaults,
-          array('_permission' => 'administer ' . $entity_type_id . ' fields'),
+          array('_entity_access' => 'field_storage_config.update'),

The entity is here exists, see \Drupal\field_ui\Routing\FieldUiRouteEnhancer

geertvd’s picture

I think the field_config entity is there, the field_storage_config entity is not.

Entityform is working because of this

 /**
   * {@inheritdoc}
   */
  public function getEntityFromRouteMatch(RouteMatchInterface $route_match, $entity_type_id) {
    // The URL of this entity form contains only the ID of the field_config
    // but we are actually editing a field_storage_config entity.
    $field_config = FieldConfig::load($route_match->getRawParameter('field_config'));

    return $field_config->getFieldStorageDefinition();
  }
yched’s picture

  1. +++ b/core/modules/field_ui/src/Tests/ManageFieldsTest.php
    @@ -525,16 +525,32 @@ function testLockedField() {
    +    // Check that the links for delete and storage settings are not present.
    +    $delete_link_path = $edit_link_path . '/delete';
    +    $delete_link = $this->xpath('//ul[contains(@class, dropbutton)]/li/a[contains(@href, :path)]', array(':path' => $delete_link_path));
    +    $this->assertEqual(count($delete_link), 0, 'Delete option for locked field is not present in the UI');
    +    $storage_link_path = $edit_link_path . '/storage';
    +    $storage_link = $this->xpath('//ul[contains(@class, dropbutton)]/li/a[contains(@href, :path)]', array(':path' => $storage_link_path));
    +    $this->assertEqual(count($storage_link), 0, 'Storage option for locked field is not present in the UI');
    +
    +    $this->drupalGet($edit_link_path);
    +    $this->assertResponse(200);
    +    // Make sure the label field is available even when the field is locked.
    +    $this->assertField('label', 'The label field is available for the locked field.');
    +    $this->drupalGet($delete_link_path);
         $this->assertResponse(403);
    +    $this->drupalGet($storage_link_path);
    +    $this->assertResponse(200);
    +    // Make sure the cardinality field is not available once the field is
    +    // locked.
    +    $this->assertNoField('cardinality', 'The cardinality field is not available for the locked field.');
    +    $this->assertRaw(SafeMarkup::format('The field %field_name is locked and cannot be edited.', array('%field_name' => $field_name)));
    

    The 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 ?

  2. +++ b/core/modules/field_ui/src/FieldConfigListBuilder.php
    @@ -168,6 +172,7 @@ public function getDefaultOperations(EntityInterface $entity) {
    +      $operations['edit']['attributes']['title'] = $this->t('Edit field settings.');
    
    @@ -175,16 +180,17 @@ public function getDefaultOperations(EntityInterface $entity) {
    +      $operations['delete']['attributes']['title'] = $this->t('Delete field.');
    ...
    +        'title' => $this->t('Storage settings'),
    

    Labels should be consistent (verb + complement ?)

  3. +++ b/core/modules/field_ui/src/Form/FieldStorageConfigEditForm.php
    @@ -62,6 +62,17 @@ public function form(array $form, FormStateInterface $form_state) {
    +    // Forbid access to the form if the field is locked.
    +    $field_storage = $form_state->get('field_config')->getFieldStorageDefinition();
    +    if ($field_storage->isLocked()) {
    +      $form['locked'] = array(
    +        '#markup' => $this->t('The field %field is locked and cannot be edited.', array('%field' => $field_label)),
    +      );
    +
    +      return $form;
    +    }
    

    Do we still need this now that the route is not accessible ?

andypost’s picture

Fixed #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 uses isLocked() method of storage?

The remaining issue that no tabs displayed for field settings forms

Status: Needs review » Needs work

The last submitted patch, 91: 2274433-field-locked-91.patch, failed testing.

andypost’s picture

@geertvd finally get you point about entity!

  1. +++ b/core/modules/field_ui/src/Routing/RouteSubscriber.php
    @@ -79,7 +79,7 @@ protected function alterRoutes(RouteCollection $collection) {
             $route = new Route(
               "$path/fields/{field_config}/storage",
               array('_entity_form' => 'field_storage_config.edit') + $defaults,
    -          array('_permission' => 'administer ' . $entity_type_id . ' fields'),
    +          array('_entity_access' => 'field_storage_config.update'),
    

    really interesting how form is found here, there's only "field_config" entity on route

  2. +++ b/core/modules/field_ui/src/Form/FieldStorageConfigEditForm.php
    @@ -62,6 +62,7 @@ public function form(array $form, FormStateInterface $form_state) {
    +
    

    todo: remove

geertvd’s picture

Perhaps we can add the field_storage_config entity in \Drupal\field_ui\Routing\FieldUiRouteEnhancer?

Anonymous’s picture

Also 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.

andrewbelcher’s picture

This 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.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

cilefen’s picture

Issue summary: View changes

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

andypost’s picture

Version: 8.3.x-dev » 8.4.x-dev
andypost’s picture

andypost’s picture

This will be very useful for domain access module and domain_entity (access) modules to disallow changes on automatically assigned domains to entities

Berdir’s picture

Priority: Major » Normal

Discussed 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.

Boobaa’s picture

You 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:

  1. create an entityreference field as 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);
  2. make sure field_ui.module is enabled (but hey, it's impossible to create fields manually without this anyway);
  3. visit the "Manage fields" page of the entity you've added this entityreference field to (eg. http://example.com/admin/structure/types/manage/page/fields);
  4. the third column (titled "Field type") contains an "Entity reference" link for this field (regardless the fact that the fourth column titled "Operations" says "Locked" for this field).

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?

vijaycs85’s picture

Title: Locked field can be altered via UI » Do not allow to alter Locked field via UI

Updating title as per proposed solution/problem statement as it's causing confusion in #2831936: Add "File" MediaSource plugin

Anonymous’s picture

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?

Sounds 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....?

Boobaa’s picture

Hmm, that sounds like a flexible solution, but would result in a HUGE permission maze pretty quickly.

Anonymous’s picture

For 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.

andypost’s picture

what Locked exactly means,

The related issue

IMO this property should be renamed to field_ui_locked

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Anonymous’s picture

I'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.

Anonymous’s picture

This is causing the misbehaving of entity access control:

\Drupal\field\FieldConfigAccessControlHandler::checkAccess

/**
   * {@inheritdoc}
   */
  protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
    // Delegate access control to the underlying field storage config entity:
    // the field config entity merely handles configuration for a particular
    // bundle of an entity type, the bulk of the logic and configuration is with
    // the field storage config entity. Therefore, if an operation is allowed on
    // a certain field storage config entity, it should also be allowed for all
    // associated field config entities.
    // @see \Drupal\Core\Field\FieldDefinitionInterface
    /** \Drupal\field\FieldConfigInterface $entity */
    $field_storage_entity = $entity->getFieldStorageDefinition();
    return $field_storage_entity->access($operation, $account, TRUE);
  }

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.

/**
   * {@inheritdoc}
   */
  protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
    /** @var \Drupal\field\Entity\FieldConfig $entity */
    $storage = $entity->getFieldStorageDefinition();
    if ($operation === 'delete') {
      if ($storage->isLocked()) {
        return AccessResult::forbidden()->addCacheableDependency($storage);
      } else {
        return AccessResult::allowedIfHasPermission($account, 'administer ' . $entity->getTargetEntityTypeId() . ' fields')->addCacheableDependency($entity);
      }
    }
    return AccessResult::allowedIfHasPermission($account, 'administer ' . $entity->getTargetEntityTypeId() . ' fields');
  }

Additionally, the \Drupal\field_ui\FieldConfigListBuilder::buildRow should check update 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 the storage-settings operation so we don't have to implement hook_entity_operation_alter().

Anonymous’s picture

Status: Needs work » Needs review
FileSize
2.97 KB

Status: Needs review » Needs work

The last submitted patch, 114: 2274433-field-config-access-fix.patch, failed testing. View results

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

vsujeetkumar’s picture

Status: Needs work » Needs review
FileSize
3.42 KB

Re-roll patch created for 9.1.x, Please review.

Status: Needs review » Needs work

The last submitted patch, 121: 2274433_121.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

vsujeetkumar’s picture

Status: Needs work » Needs review
FileSize
3.42 KB
606 bytes

Fixed tests, Please review.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Closed https://www.drupal.org/node/806102 as a duplicate of this. Please move over credit for
RoSk0
mdm
chr.fritsch

quietone credited mdm.

quietone credited qoop.

quietone credited RoSk0.

quietone credited rszrama.

quietone credited sja1.

quietone’s picture

@smustgrave, thank you. I have reviewed the now closed duplicate and moved credit.

smustgrave’s picture

So 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.

The last submitted patch, 137: 2274433-137-tests-only.patch, failed testing. View results

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Anybody’s picture

@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 instance

  • label
  • description
  • default values

which 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.

lauriii’s picture

lauriii’s picture

Status: Needs review » Needs work

I 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.

Anybody’s picture

@lauriii:

I can't think of a use case where users would actually want to customize permissions for these two forms separately.

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.

I think it might make sense to hold off making this change because we are looking into combining these two forms in #3347291: [PP-1] Combine field storage and field instance forms.

Agree, would be nice, if the points from about could be taken into account.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.