Updated: Comment #33
Inand , @pounard voiced strong concerns that not taking global overrides in case of an override-free context poses security issues. He proposed that would be a security issue. In Drupal 7, if you put something in global $conf, whatever you put in the forms to edit those values, it never took hold, the global $conf set value was trumping everything. In Drupal 8 that is not the case, and we should discuss if this is good or not.
1. Global $conf values were used for different purposes. For example, variable module used them to override values with translations with early versions creeping in translations into original config. That was resolved with workarounds, and Drupal 8 has a native override system that can differentiate between original values and overrides (thanks to variable module experience by Jose :), so this use case might not apply anymore. However, it is easy to imagine people use global $conf values to include dynamic overrides as well. Such as values depending on session information or outside data sources, etc. Dynamic conditions are possible to put into settings.php and we really don't know if certain global $conf values were used as strongarm to avoid certain settings from being modified or were dynamically generated. These are two use cases for global $conf.
2. When different overrides are available, they have different priorities and the stronger one will prevail. As per the current setup inand prior to that in , global overrides were lower priority compared to language overrides. So if you overrode your site name in your global overrides, if you also had translations for your site name, then the translations prevailed. That make sense for the site name use case at least. Again there are likely use cases when you want some global overrides to apply if there are no translations and others to just strongarm on the site and not let people change or override in any other way. The language overrides now prevail for two reasons: (a) their weight in event listener priority is higher compared to global overrides [not actually relevant] (b) they listen to an event fired later (config.load vs. config.init), so they set their overrides later and therefore trump global overrides.
The position that @pounard explained is where global $conf is used as a security enforcement system, and working around it either by making higher priority overrides or making it sometimes not apply in forms is a hazard. We should figure out if we want to make global overrides trump everything (take higher priority) and even apply in override free environments, keep their current lower priority or separate this to two override system, one where you can put your enforced overrides that would always apply even in "override free" contexts and one where you put your soft global overrides. There can be arguments for both.
It should be noted it is already possible to do global overrides that would trump language overrides, it is admittedly not currently possible to do global overrides that would sure-fire apply even in "override free" mode, that is prohibited right now.
Make global overrides stick:
- Keep the override-free context, since it is used in internal config operations to access the original values for import & staging.
- Add the capability to force overrides. The default override handler will take any override either forced or not. The free context will not take any override, even if forced and there is a forced-only context, which only takes forced values.
- Add a config.context.only.forced on the DIC to expose this and make the admin forms use it. Made global overrides forced.
- Re-roll patch
- Agree that the global $conf set value should trump everything
User interface changes
|FAILED: [[SimpleTest]]: [MySQL] 58,897 pass(es), 7 fail(s), and 0 exception(s).|
|FAILED: [[SimpleTest]]: [MySQL] Setup environment: Test cancelled by admin prior to completion.|
|PASSED: [[SimpleTest]]: [MySQL] 57,913 pass(es).|
|#24||interdiff.txt||622 bytes||Gábor Hojtsy|
|#24||global-overrides-forced-24.patch||11.51 KB||Gábor Hojtsy|
|PASSED: [[SimpleTest]]: [MySQL] 53,240 pass(es).|