Problem/Motivation

Pointed out by @tedbow at #2808217-65: To be able to view Vocabulary config entities via REST, one should not have to grant the 'administer taxonomy' permission, confirmed by @dawehner at #2808217-66: To be able to view Vocabulary config entities via REST, one should not have to grant the 'administer taxonomy' permission and by @Wim Leers at #2808217-68: To be able to view Vocabulary config entities via REST, one should not have to grant the 'administer taxonomy' permission.

#2625258: LocaleConfigManager::updateConfigTranslations() deletes translations if a config object's name happens to match that of a shipped configuration object added this _core key in January 2016, after Drupal 8 shipped, but it did not update \Drupal\serialization\Normalizer\ConfigEntityNormalizer. This was simply an oversight — it was not even discussed there at all!

All normalized config entities expose something like this:

…
"_core": {
  "default_config_hash": "lO5ziR5dVI1PpEeHZsSOfQ-Y7NWihSDKW8-MMf6uoms"
},
…

This is:

  1. weird
  2. a Drupalism
  3. useless to API consumers

Note: the reason why existing config entity GET test coverage doesn't include this _core key in the expectations defined in the getNormalizedEntity() methods is as surprising as it is simple: #2625258: LocaleConfigManager::updateConfigTranslations() deletes translations if a config object's name happens to match that of a shipped configuration object only causes _core to be added to shipped configuration, aka default configuration, aka YAML files in MODULENAME/config/install. The tests are each creating config entities in the abstract function createEntity() method that each entity type-specific test subclass must implement.

Proposed resolution

Omit the _core key from the normalization of config entities.

Remaining tasks

Do it.

User interface changes

None.

API changes

None.

Data model changes

None.

Comments

Wim Leers created an issue. See original summary.

wim leers’s picture

wim leers’s picture

Assigned: Unassigned » wim leers
Status: Active » Needs review
StatusFileSize
new3.06 KB

Let's add both functional and unit test coverage.

They should both fail.

wim leers’s picture

StatusFileSize
new745 bytes
new3.73 KB

And now with an updated normalizer, it should result in passing tests!

Note that this is testing both the json and hal_json formats in the functional test coverage!

The last submitted patch, 3: 2915414-3.patch, failed testing. View results

wim leers’s picture

Assigned: wim leers » Unassigned
wim leers’s picture

Issue summary: View changes

Note: the reason why existing config entity GET test coverage doesn't include this _core key in the expectations defined in the getNormalizedEntity() methods is as surprising as it is simple: #2625258: LocaleConfigManager::updateConfigTranslations() deletes translations if a config object's name happens to match that of a shipped configuration object only causes _core to be added to shipped configuration, aka default configuration, aka YAML files in MODULENAME/config/install. The tests are each creating config entities in the abstract function createEntity() method that each entity type-specific test subclass must implement.

Added this to the IS.

dawehner’s picture

We should ensure that once we open PATCH/POST requests that we cannot override the values. Does that mean we should exclude them in denormalization here already?

wim leers’s picture

Assigned: Unassigned » wim leers

#8: good point, that should be a blocker to #2300677: JSON:API POST/PATCH support for fully validatable config entities in theory? On it!

wim leers’s picture

StatusFileSize
new2.98 KB
new6.06 KB

Test coverage for #8, should fail.

wim leers’s picture

Assigned: wim leers » Unassigned
StatusFileSize
new838 bytes
new6.27 KB

And the fix.

wim leers’s picture

The last submitted patch, 10: 2915414-10.patch, failed testing. View results

dawehner’s picture

+++ b/core/modules/serialization/src/Normalizer/ConfigEntityNormalizer.php
@@ -18,7 +18,15 @@ class ConfigEntityNormalizer extends EntityNormalizer {
   public function normalize($object, $format = NULL, array $context = []) {
-    return $object->toArray();
+    return array_diff_key($object->toArray(), ['_core' => TRUE]);
+  }
...
+  public function denormalize($data, $class, $format = NULL, array $context = []) {
+    unset($data['_core']);
+    return parent::denormalize($data, $class, $format, $context);

Should we explain why we skip core here? Also: Why do we use once array_diff_key and once unset() ... can't we use the same approach here twice?

wim leers’s picture

Assigned: Unassigned » wim leers

You ask great questions! 😳

wim leers’s picture

Assigned: wim leers » Unassigned
StatusFileSize
new1.85 KB
new7.05 KB

Fixed.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

WFM

larowlan’s picture

Updating review credits

larowlan’s picture

+++ b/core/modules/serialization/src/Normalizer/ConfigEntityNormalizer.php
@@ -18,7 +18,33 @@ class ConfigEntityNormalizer extends EntityNormalizer {
+    return static::getDataWithoutInternals($object->toArray());
...
+    return parent::denormalize(static::getDataWithoutInternals($data), $class, $format, $context);

Any reason we went for static here?

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 16: 2915414-16.patch, failed testing. View results

wim leers’s picture

Status: Needs work » Reviewed & tested by the community

#19: because it signals it only uses the parameters it receives, it doesn't change the object. See http://drupal4hu.com/node/416.html.

alexpott’s picture

Status: Reviewed & tested by the community » Needs review
+++ b/core/modules/rest/tests/src/Functional/EntityResource/ConfigurableLanguage/ConfigurableLanguageResourceTestBase.php
@@ -74,4 +75,21 @@ protected function getNormalizedPostEntity() {
+    $normalization = $this->serializer->decode((string) $response->getBody(), static::$format);
+    $this->assertArrayNotHasKey('_core', $normalization);

This is only a negative assertion which makes me think that the test might be a bit brittle. I was wondering about why we have this test - but it is the only non-unit test case of the change. It does mean if we remove the configurable language we'd suddenly lose this test coverage.

wim leers’s picture

Status: Needs review » Reviewed & tested by the community

Exactly: there is complete and explicit unit test coverage, the hunk you quoted is about having a functional regression test. Happy to remove it if you prefer that.

larowlan’s picture

Status: Reviewed & tested by the community » Fixed

Committed as 96452be and pushed to 8.5.x.

  • larowlan committed 96452be on 8.5.x
    Issue #2915414 by Wim Leers, dawehner: Omit "_core" key from normalized...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

wim leers’s picture