Here's my use case: I want to disable certain endpoints by using an environment specific settings file and config overrides. Here's what I tried:
$config['rest.resource.delete_account']['status'] = FALSE;
However it doesn't look like this is going to work. Based on the alterRoutes method, the resource routes don't seem to care whether status is on or not. I used the REST module to disable the endpoint and it seems to just delete the config from the config table. I copied alterRoutes below for reference.
protected function alterRoutes(RouteCollection $collection) {
// Iterate over all enabled REST resource configs.
/** @var \Drupal\rest\RestResourceConfigInterface[] $resource_configs */
$resource_configs = $this->resourceConfigStorage->loadMultiple();
// Iterate over all enabled resource plugins.
foreach ($resource_configs as $resource_config) {
$resource_routes = $this->getRoutesForResourceConfig($resource_config);
$collection->addCollection($resource_routes);
}
}
My proposed solution is to add something in the alterRoutes method that looks at whether the resource has an active status. Let me know if there are problems with this approach.
| Comment | File | Size | Author |
|---|---|---|---|
| #38 | 2844046-38.patch | 6.7 KB | wim leers |
| #30 | 2844046-30.patch | 6.7 KB | wim leers |
Comments
Comment #2
dpolant commentedComment #3
damienmckennaShould this be looked at from the greater config entity perspective? Should all config entities be disable-able?
Comment #5
wim leersConfirmed. Great catch!
That's already the case:
\Drupal\Core\Config\Entity\ConfigEntityInterface::enable().But of course the REST module long predates config entities. This was overlooked in #2308745: Remove rest.settings.yml, use rest_resource config entities.
Comment #6
wim leersIt already had a comment
// Iterate over all enabled REST resource configs.… but that didn't reflect reality sadly. It also still had// Iterate over all enabled resource plugins., which should have been removed in #2308745: Remove rest.settings.yml, use rest_resource config entities.Comment #7
wim leersComment #8
wim leersOnce #2815845: Importing (deploying) REST resource config entities should automatically do the necessary route rebuilding we'll be able to easily test this: we will be able to change
EntityResourceTestBase::deprovisionResource()to no longer delete the REST Resource config entity, but instead disable it. And inprovisionResource()we can then create it if it does not exist, but if it already exists, just callenable(). That's exactly what we need to test here!Comment #9
wim leersComment #10
dawehnerI just tried to write some tests, no idea whether they fail or pass.
IMHO we need to both disable and delete.
Comment #11
wim leersThis blocks #2851126: The UI says "disable", but it's really "delete".
Comment #12
wim leers#2815845: Importing (deploying) REST resource config entities should automatically do the necessary route rebuilding landed, this is now unblocked!
Comment #13
wim leersRebased @dawehner's proposal of #10. (#10 no longer applies.)
Comment #16
wim leersShould be 'configuration'.
Should be
$resource_config->save().Those explain the key failures.
Also, I think it doesn't make sense we allow modifying all those configuration details when we just need to be able to disable a resource. It'd be more logical to add a method to be able to retrieve the REST Resource Config entity then, so then you can call
disable(),enable()anddelete()on it. The complication is that you must always callrefreshTestStateAfterRestConfigChange()after any of those, to keep the test environment in sync. But that's okay.So, in this patch, I am:
ResourceTestBase::provisionResource()andprovisionEntityResource()to their original signatures$resource_typeparameter fromResourceTestBase::provisionResource(), and instead moving that tostatic $resourceConfigId$this->resourceConfigStorage->load(static::$resourceConfigId)->disable()->save();to disable,$this->resourceConfigStorage->load(static::$resourceConfigId)->enable()->save();to re-enable and $this->resourceConfigStorage->load(static::$resourceConfigId)->delete(); to savethis->deprovisionResource()Comment #17
wim leersThis is what @dawehner proposed in #10. It's well-intended, but it's not testing what we want to test.
We want to first verify that the provisioned resource has a 200 response. THEN we want to disable it and verify that we get a 404. Then if we re-enable again, we want a 200. And then if we delete it, we again want a 404.
It's important that we verify those 200 responses in between, because only then we're actually testing that routes are working (200 response) vs not working (404 response) at the expected times!
So, keeping this exact same test code, but moving it after our first successfully verified 200 response!
Comment #18
wim leersWe now have:
We still need to add an assertion of a 200 response between "enable" and "delete". This does that. Test coverage is now complete.
Comment #19
wim leersNow the test coverage (and its failing tests) make it clear that the bug reported in the IS is not yet fixed.
So, time to fix that. This interdiff is identical to my patch in #6.
Comment #20
wim leersFinally, there were some small flaws in the assertions that check the behavior after disabling. We should just copy/paste the assertions we already had for a deleted resource.
Also make the comments consistent.
This should be green :) And hopefully RTBC'able! :)
Comment #21
wim leersClearer.
Comment #26
tedbowVery clear that we aren't adding routes for disabled resources!
Removal of deprovisionEntityResource makes things simpler!
We have this code block now twice.
Could we refactor to
protected function assertRouteNotAvailable($url, $request_options)No need to pass $has_canonical_url has that can be figured out.
Other than the refactor suggestion I think this could be RTBC.
Tests just passed yay!
Comment #27
wim leersYay! :) Done.
Didn't go with
assertRouteNotAvailablebut withassertResourceNotAvailable, because it's about the resource, not the route (a single resource has many routes).Comment #28
tedbowExtra line that can be removed on commit.
Great! RTBC!
Comment #29
wim leersForgot a bit.
Comment #30
wim leersAnd fixing the nit in #28.
Comment #32
tedbow@Wim Leers sorry I missed the missing arguments in #27. I guess that is why we have tests ;)
Checked the test failures and were caused by this. Tests passed in #29 after fix. and #30
Still RTBC!
Comment #33
alexpottI've stared at this for a bit and thought is this change really necessary. Cause at the moment this fix is eligible for 8.3.1 cause 8.3.x is frozen till the release of 8.3.0. This means there will be a time when the cascade of classes involved in entity resource REST testing are out of sync between 8.3.x and 8.4.x if I commit this now. Which might prove costly for writing patches during this time.
I'm not sure what to do here. If @Wim Leers or @tedbow feel that they want to get this in to 8.4.x now and are happy to live with the out-of-syncness I'm happy to go along with that. Since they are working on most of the issues that touch this area.
Comment #34
wim leersThat shouldn't hurt us much. We're rarely touching the "provision resource" code. This is likely the last time.
If this can still land in 8.3.1, that means that this problem is also very temporary. If this could never land in 8.3, this wouldn't even be that big of a problem.
Comment #35
alexpottCommitted b739f56 and pushed to 8.4.x. Thanks!
Thanks @Wim Leers for addressing #33.
Comment #37
wim leersPorting to 8.3.
Comment #38
wim leersWell, actually a simple
git cherry-pick 6d2c634ea1baf081c2092b757ae54ccf908c2a54seems to work fine :)Comment #39
wim leersI just realized alexpott probably only set it to "Patch (to be ported)" so that he can cherry-pick it into 8.3.x once 8.3.0 is out. Oops :)
Comment #41
alexpott@catch, @cilefen and @xjm and I just decided that patch rules will apply to the RC up until RC2 so backporting this to 8.3.x
Committed 8b622f8 and pushed to 8.3.x. Thanks!
Comment #42
wim leersEven better, thanks!