Updated: Comment #N
Problem/Motivation
We still have (and would like to convert) usages of drupal_get_hash_salt() in our OO code. This is not ideal, as tests have to do the if(!function_exists('ffdfdf')) hack etc.. We cannot just use the setting directly as we need to keep the logic that throws an exception if it is empty.
Proposed resolution
Find a new home for this. We could just check for this when we get the hash_salt setting. I think it makes more sense to just have this living somewhere though.
Remaining tasks
Find a place, patch. Convert remaining usages.
User interface changes
None
API changes
Hopefully no more drupal_get_hash_salt(), just the new thing.
https://drupal.org/node/2197037 will need to be updated.
| Comment | File | Size | Author |
|---|---|---|---|
| #32 | interdiff-2207585-32.txt | 527 bytes | damiankloip |
| #32 | 2207585-32.patch | 7.14 KB | damiankloip |
| #22 | 2207585-22.patch | 7.59 KB | damiankloip |
| #2 | drupal_2207585_2.patch | 3.48 KB | xano |
Comments
Comment #1
damiankloip commentedAfter briefly speaking to sun on IRC, he suggested adding a method to Settings itself. The thought had crossed my mind, so this is some good validation.
So, how about this? Haven't converted the remaining usages, or marked drupal_get_hash_salt() as deprecated yet.
Comment #2
xanoI fixed some docs in the test.
I also think this may not be the right place, or at least not for the code in its current form, as
Settingsis a component and should therefore be useful and make sense outside the context of Drupal. Adding a method for a very specific setting is questionable, but referring to Drupal-specific use cases (settings.php) is not helpful to outsiders at all.Wasn't @sun working on a
siteservice? Maybe this would fit in there.Comment #3
dawehnerMoar changes.
Comment #4
tstoecklerSorry, but I don't really see how we can add that code given that Settings currently lives in Component. What we could do is pass a list of required properties in __construct() and have Settings::get() throw an exception in case a required property is missing. That would make it generic enough for people to re-use outside of Drupal.
Comment #5
tstoecklerActually that would be kind of pointless as well, as you obviously know all of the settings' keys when calling Settings::__construct(), so making Settings throw an exception on a missing key would be weird.
Instead we should throw an exception as soon as we initialize Settings if 'hash_salt' is missing.
Comment #6
sunSettingsis completely misplaced in Component — it's a 100% Drupalism and we need to move that into Core ASAP. My plan was to move it intoDrupal\Core\Site\Settings, which is also where the newSitesingleton will be located, becauseSettingsare always loaded from a particular site directory.Adding dedicated methods for settings that are required to exist makes perfect sense to me. We should consider to add more of them later on. This approach would allow us to "namespace" settings in settings.php and provide dedicated methods to retrieve them, automatically applying defaults; e.g.,
Settings::getTwig(), etc.In short, the proposed patch looks good and makes sense to me.
The only part that I don't like is that the method is not static — but to change that, we first have to convert
Settingsinto a proper singleton, because the current code and usage is a total mess. Pretty much following the code of the new Site singleton in #1757536: Move settings.php to /settings directory, fold sites.php into settings.php → this may or may not happen in #2199795: Make the Settings class prevent serialization of actual settingsSo for now, the approach of the patch is in line with the current "architecture" of the
Settingsclass, and thus fine.I'd like to see a few replacements as part of this patch though... At minimum,
drupal_get_hash_salt()itself should call the method. :)Comment #7
damiankloip commentedYeah, this was a quick initial patch tbh :) So yes, it should definitely call the new method!
I agree with you on this, I think this change makes sense, as well as moving Settings into the Core namespace (which I guess is the same reason we agreed when talking about this in IRC yesterday).
Comment #8
dawehnerI really wonder whether we could special case the logic to initialize the APC classloader.
For all the other usecases it could be worth to try out container parameters for that.
Comment #9
sunCreated #2208475: Move Settings into Drupal\Core\Site\Settings
Comment #10
damiankloip commentedI don't think hashSalt() would be suited to a container param tbh - you would then need to inject the container when you needed this. Which seems like it would get pretty strange.
I think we should move on with this patch as-is, now we have the issue sun created in #9 to move Settings into the Core namespace - which I totally agree with.
Comment #11
damiankloip commentedHere we go, converted the function body to use the new method.
Comment #12
sunThanks — looks great to me! :)
Comment #13
ParisLiakos commentedi feel that this should be postponed to #2208475: Move Settings into Drupal\Core\Site\Settings
if we end up moving it to core, we should actually move it first, and then add this method.
if not, well there are some alternatives posted in #2208475: Move Settings into Drupal\Core\Site\Settings
Comment #14
damiankloip commentedThis does not make any difference to things in reality (adding this before we move it), as likely this will be so short lived it will be negligible.
We discussed a bit before; people are caught up on Settings actually being a useful component that people might re use...it's not really.
Comment #15
ianthomas_ukThis approach would still allow people to call settings()->get('hash_salt') without triggering the exception and is confusing DX: How do people know when to call ->getSettingName() and when to call get('setting_name')?
Erroring on construction is an interesting idea, but it assumes that the setting is required for the site to work at all. That's probably true for hash_salt, as it's required for fundamental things such as form handling, but might not be true in all cases. If we go down this route, we should ensure that it's possible to add an 'error on use' option if we need it in the future.
Comment #16
ianthomas_ukComment #17
ParisLiakos commentedwe can move on here now
Comment #18
damiankloip commentedReroll, and made new method static instead. Also, what happened to the Settings class. We seem to have methods doing the same thing that maybe aren't needed? I'm looking at you #2219009: Improve DX of Settings class.
Comment #19
ParisLiakos commentedyes indeed we have duplicate methods..the only difference is the fact of being static..
so there are two paths
Settings::get()and
$this->settings->getSetting()I find it very confusing tbh..I believe that (i didnt test it)
$this->settings->get()would be the exact same thing of calling$this->settings->getSetting()hmm the whole other class uses self:: and i think it makes sense because this class is final ( :( )
But anyway lets keep the consistency and use self here too
Comment #20
sunJust a silly thought: (to be ignored)
One potential way to address that concern would be:
Dunno why I'm posting this, but yeah, the idea is flawed, so please ignore this, unless you can make something more fruitful out of it :-)
Comment #21
damiankloip commented@ParisLiakos, yes, I mean this: #2250491: Remove duplicate methods from Settings class. Seems we could clean that class up considerably. Not sure why #2219009: Improve DX of Settings class got committed with those changes tbh. Is adding duplicate methods better DX? No :)
@sun, I see where you're coming from. I think this could be worth more discussion. However, I think how we have the current patch is sufficient for our needs. The most important thing is our code in core uses this so the exception is thrown. If a developer uses get('hash_salt') or getAll() (could need to dynamically get values etc.. ?) then why not?
Comment #22
damiankloip commentedNow with conversion to use this in CsrfTokenGenerator too.
Comment #24
damiankloip commentedWhoops.
Comment #25
ParisLiakos commentedlooks good to good, besides one thing which i also mentioned in #19
Comment #26
damiankloip commentedSorry Paris, I thought I changed that in the last patch but obv. forgot!
Comment #27
ParisLiakos commentedno problem:) thanks for your patience!
Comment #28
sunHm. I assume/fear that the injected Settings will be serialized much more often with this change, since the CsrfTokenManager gets injected into every form...
#2199795: Make the Settings class prevent serialization of actual settings
It looks like #2201919: Replace drupal_get_hash_salt() with direct Settings call in CsrfTokenGenerator was merged into this issue?
Wondering whether it is necessary to perform that change here? Can we make the constructor call
Settings::getHashSalt()instead?The problem with serialized settings is that they are typically unserialized in a completely different request/context. settings.php might have been changed, but the unserialized
Settingsclass still holds the former settings.Comment #29
damiankloip commentedYes, this is a good point. Let's go with the simplest solution for now like this? Also, yes, I was going to close #2201919: Replace drupal_get_hash_salt() with direct Settings call in CsrfTokenGenerator. Most of that patch is obsolete now anyway.
Comment #30
sunThanks.
That appears to be the only safe/secure approach for now. We'll have to study and investigate this whole situation of serialized settings some more - which could use a critical release-blocking issue, because unserialization and usage of possibly stale/outdated settings is a security issue.
Comment #31
catchNo longer applies.
Also shouldn't we mark drupal_get_hash_salt() deprecated here?
Comment #32
damiankloip commentedYep, I think that's a good shout. Rerolled and added deprecated in doc.
Comment #33
ParisLiakos commentedComment #35
catchPart of me thinks twice about this because it further cements that anything with a dependency on Settings has to stay in \Drupal\Core and can't be a component, however:
1. OOP code should not be calling out to procedural code. If we'd stuck to that rule I think we'd have saved ourselves quite a lot of pain this release cycle with hidden dependencies.
2. Like the Cache system, the settings dependency can always be restricted to a factory, then only the factory has to be in \Drupal\Core not the entire subsystem.
Committed/pushed to 8.x, thanks!