Merge pull request #8757 from kinglozzer/8754-versioned-cache-segmentation

FIX: Misconfiguration for versioned cache segmentation (fixes #8754)
This commit is contained in:
Robbie Averill 2019-01-29 09:26:57 +02:00 committed by GitHub
commit 506aa6c511
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 8 deletions

View File

@ -18,17 +18,14 @@ SilverStripe\Core\Injector\Injector:
factory: SilverStripe\Core\Cache\CacheFactory
constructor:
namespace: "VersionProvider_composerlock"
args:
disable-container: true
disable-container: true
Psr\SimpleCache\CacheInterface.RateLimiter:
factory: SilverStripe\Core\Cache\CacheFactory
constructor:
namespace: 'ratelimiter'
args:
disable-container: true
disable-container: true
Psr\SimpleCache\CacheInterface.InheritedPermissions:
factory: SilverStripe\Core\Cache\CacheFactory
constructor:
namespace: "InheritedPermissions"
args:
disable-container: true
disable-container: true

View File

@ -39,6 +39,13 @@ SilverStripe\Core\Injector\Injector:
namespace: "myCache"
```
<div class="alert" markdown="1">
Please note that if you have the `silverstripe/versioned` module installed (automatically installed by the
`silverstripe/cms` module), caches will automatically be segmented by current “stage”. This ensures that
any content written to the cache in the _draft_ reading mode isnt accidentally exposed in the _live_ reading mode.
Please read the [versioned cache segmentation](#versioned-cache-segmentation) section for more information.
</div>
Cache objects are instantiated through a [CacheFactory](SilverStripe\Core\Cache\CacheFactory),
which determines which cache adapter is used (see "Adapters" below for details).
This factory allows us you to globally define an adapter for all cache instances.
@ -209,6 +216,42 @@ SilverStripe\Core\Injector\Injector:
SilverStripe\Core\Cache\CacheFactory: '%$MemcachedCacheFactory'
```
## Versioned cache segmentation
`SilverStripe\Core\Cache\CacheFactory` now maintains separate cache pools for each versioned stage (if you have the
`silverstripe/versioned` module installed). This prevents developers from caching draft data and then
accidentally exposing it on the live stage without potentially required authorisation checks. Unless you
rely on caching across stages, you don't need to change your own code for this change to take effect. Note
that cache keys will be internally rewritten, causing any existing cache items to become invalid when this
change is deployed.
```php
// Before:
$cache = Injector::inst()->get(CacheInterface::class . '.myapp');
Versioned::set_stage(Versioned::DRAFT);
$cache->set('my_key', 'Some draft content. Not for public viewing yet.');
Versioned::set_stage(Versioned::LIVE);
$cache->get('my_key'); // 'Some draft content. Not for public viewing yet'
// After:
$cache = Injector::inst()->get(CacheInterface::class . '.myapp');
Versioned::set_stage(Versioned::DRAFT);
$cache->set('my_key', 'Some draft content. Not for public viewing yet.');
Versioned::set_stage(Versioned::LIVE);
$cache->get('my_key'); // null
```
Data that is not content sensitive can be cached across stages by simply opting out of the segmented cache
with the `disable-container` argument.
```yaml
SilverStripe\Core\Injector\Injector:
Psr\SimpleCache\CacheInterface.myapp:
factory: SilverStripe\Core\Cache\CacheFactory
constructor:
namespace: "MyInsensitiveData"
disable-container: true
```
## Additional Caches
Unfortunately not all caches are configurable via cache adapters.

View File

@ -198,8 +198,7 @@ SilverStripe\Core\Injector\Injector:
factory: SilverStripe\Core\Cache\CacheFactory
constructor:
namespace: "MyInsensitiveData"
args:
disable-container: true
disable-container: true
```
### HTTP Cache Header changes