Add a configuration entity access controller with some extra super-duper amazing access control features that are available only to those entities who can call themselves configuration.

Initially, add support for enable and disable operations, as those are a combination of an access check for the update permission, and a check to see whether the entity can technically be enabled or disabled at all.

Later we may add support for a duplicate operation in combination with a specific link template key and an entity list controller operation.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Xano’s picture

Status: Active » Needs review
FileSize
3.02 KB
Xano’s picture

To do: make any config entity type's access controller extend ConfigAccessController.

Status: Needs review » Needs work

The last submitted patch, 1: drupal_2200183_1.patch, failed testing.

Xano’s picture

Status: Needs work » Needs review
FileSize
12.49 KB
9.33 KB

Status: Needs review » Needs work

The last submitted patch, 4: drupal_2200183_4.patch, failed testing.

Xano’s picture

Status: Needs work » Needs review
FileSize
1.68 KB
14.03 KB

Status: Needs review » Needs work

The last submitted patch, 6: drupal_2200183_6.patch, failed testing.

Xano’s picture

Status: Needs work » Needs review
FileSize
2.66 KB
14.55 KB
tim.plunkett’s picture

Title: Add ConfigAccessController » Add ConfigEntityAccessController
  1. +++ b/core/lib/Drupal/Core/Config/Entity/ConfigAccessController.php
    @@ -0,0 +1,34 @@
    +class ConfigAccessController extends EntityAccessController {
    

    Let's rename this ConfigEntityAccessController, its a bit clearer (we should have another for ConfigStorageController too)

  2. +++ b/core/lib/Drupal/Core/Config/Entity/ConfigAccessController.php
    @@ -0,0 +1,34 @@
    +      $status_is_toggleable = $operation == 'disable' ? $entity->status() : !$entity->status();
    

    This line is the only part of the patch that is confusing. 'toggleable' is not really a word, and it needs a code comment, and the $entity->status() : !$entity->status() is really odd looking...

  3. +++ b/core/modules/views_ui/views_ui.routing.yml
    @@ -52,7 +52,7 @@ views_ui.enable:
    -    _permission: 'administer views'
    +    _entity_access: view.enable
    
    @@ -61,7 +61,7 @@ views_ui.disable:
    -    _permission: 'administer views'
    +    _entity_access: view.disable
    

    Nice!

damiankloip’s picture

So what happens if you want to check if someone has access to enable an entity that is currently already enabled? This patch means it will always deny access. Yeah, that is what we want when building operation links, but that seems like the only time we want that behaviour?

Xano’s picture

FileSize
25.98 KB
21.31 KB

Status: Needs review » Needs work

The last submitted patch, 11: drupal_2200183_11.patch, failed testing.

The last submitted patch, 11: drupal_2200183_11.patch, failed testing.

tim.plunkett’s picture

I just meant the ConfigEntityAccessController class itself, not sandwiching 'Entity' in after the entity type name.

Love the commit message though :)

Xano’s picture

Status: Needs work » Needs review
Related issues: +#2201137: Introduce a "duplicate" entity operation
FileSize
14.72 KB
11.92 KB

#11 was faulty. Refactoring went wrong in PhpStorm. Because of that, the attached interdiff is against #8.

On a related note: #2201137: Introduce a "duplicate" entity operation.

Xano’s picture

15: drupal_2200183_14.patch queued for re-testing.

Xano’s picture

15: drupal_2200183_14.patch queued for re-testing.

Status: Needs review » Needs work

The last submitted patch, 15: drupal_2200183_14.patch, failed testing.

Xano’s picture

Status: Needs work » Needs review
FileSize
14.71 KB
yanniboi’s picture

Status: Needs review » Needs work

I've had a look at this:

  • Patch applies fine
  • Installs
  • No error messages in log
  • Code looks clean

Only thing I could spot is you haven't fixed the terminology of 'toggleable' as @tim.plunkett pointed out.

If you fix that I would say this is RTBC.

Xano’s picture

Status: Needs work » Needs review
FileSize
14.71 KB
1.09 KB

Cool! I changed the variable name now. Forgot to do that last time.

yanniboi’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +drupaldevdays

Great, this looks good to me!

damiankloip’s picture

S0, regarding my comment in #10, we are happy that when a config entity is enabled, access for ENTITY_TYPE:enable will always be false, regardless of the usage?

Xano’s picture

I think we do, as it makes no sense to have access to enable a particular entity in its current state if you cannot enable it anyway. Access control depends on the entity's state.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 21: drupal_2200183_21.patch, failed testing.

Xano’s picture

Status: Needs work » Needs review
FileSize
14.74 KB

Re-roll.

Status: Needs review » Needs work

The last submitted patch, 26: drupal_2200183_26.patch, failed testing.

Xano’s picture

Status: Needs work » Needs review
FileSize
14.63 KB
894 bytes
Xano’s picture

Status: Needs review » Reviewed & tested by the community

RTBC per #22.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

#10 does seem like a problem - and the logic is wrong with the current patch. A user who has access to enable a config entity should have that access regardless of the state of that entity.

Xano’s picture

When would that be a problem? Entity access control is bound to an entity's state anyway. That's how the entire system currently works.

tstoeckler’s picture

Yeah, I'm with Xano on this one. Why would you want to allow enabling an already enabled entity? Can you elaborate @alexpott or @damiankloip?

Xano’s picture

@tim.plunkett did a similar thing in #2235347: Field instance operations are out of order for deleting field instance configs.

Tim obviously did no such thing. My sleepy other me must have posted this.

tim.plunkett’s picture

What I did in the other issue is not related, because it's about delete.
It's not as much about the state of the entity, IMO.

If the entity is enabled, and we allow you to enable it, it's a no-op.
Do we want to deny access for no-op cases?
That's the question we need to answer here.

I don't have a strong opinion either way.

Berdir’s picture

The last patch in #2084323: EntityForm::actions() adds 'delete' without checking access is about the same, that is about delete there but it's exactly the same pattern for deciding that access is not allowed if the entity is in a given state (new).

tstoeckler’s picture

So in theory - from an API design perspective - I don't have a strong preference either. However due to the fact that we bind the visibility of the operation links to the access of the operation itself already I see no reason to loosen that binding here just for the sake of allowing people to enable already enabled entities on an API level. That's the reason why I'm in favor of that approach.

Berdir’s picture

Yeah, we obviously do not want to show enable for a config entity that is already enabled, the only question I think is who is responsible for preventing that, is it the list builder that shouldn't even try to show that operation or should the operation exist but you wouldn't have access?

Given that we eventually ( in 9.x or contrib) want to move toward separately defined entity operations as plugins or whatever and tie them even more to the entity access control system, it makes more sense for me as well to handle visibility of operations in the access class.

Xano’s picture

Are there any concrete arguments against doing this? To me, this is about asking access controllers Can this user perform this operation on this entity, yes or no?. We so far do not and probably should not not care about the internals, and since entity access control returns computed values, the possible use cases are limited to deciding whether a user can or cannot do something anyway.

Regardless, this patch does make writing secure and sensible code a little easier, and we can more easily change the internals after release, because calling code will no longer have to check multiple requirements when it comes to operations.

tstoeckler’s picture

Status: Needs work » Needs review

Well, this is needs review at least.

Xano’s picture

28: drupal_2200183_28.patch queued for re-testing.

Status: Needs review » Needs work

The last submitted patch, 28: drupal_2200183_28.patch, failed testing.

Xano’s picture

Status: Needs work » Needs review
FileSize
13.54 KB

Re-roll.

Xano’s picture

42: drupal_2200183_42.patch queued for re-testing.

Xano’s picture

42: drupal_2200183_42.patch queued for re-testing.

tstoeckler’s picture

Assigned: Xano » alexpott

Assigning to @alexpott as apparently there's no further progress here.

So @tim.plunkett doesn't really have a strong preference and it seems @Berdir seems to be leaning slightly towards going with the current approach. @Xano and I also favor the current approach.

@alexpott Do you feel strongly that the current approach is incorrect? And if so, can you explain why? Thanks a lot.

Xano’s picture

42: drupal_2200183_42.patch queued for re-testing.

alexpott’s picture

Assigned: alexpott » Unassigned

Okay let's proceed with this. I feel it might come back to bite us since access != visibility but I'm not going to argue anymore - as @Xano says it does make things more secure by default.

Xano’s picture

Status: Needs review » Reviewed & tested by the community

Alright. Putting this back to RTBC as per #22.

Xano’s picture

42: drupal_2200183_42.patch queued for re-testing.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 42: drupal_2200183_42.patch, failed testing.

Xano’s picture

Status: Needs work » Needs review
FileSize
12.93 KB

Re-roll.

Xano’s picture

Status: Needs review » Reviewed & tested by the community

RTBC as per #22 if the tests pass.

damiankloip’s picture

So say I am trying to enable some entity via a rest api I have created for my site, I would just get a 403? So I could not use entity access alone for anything like that?

Xano’s picture

You can still enable the entity. You *could* respond with a 403 by checking access, but you are not required to.

damiankloip’s picture

But how does that work generically? You cannot just have a call that enables things without access checking.

Xano’s picture

I don't know. Is denying access a problem in this case?

damiankloip’s picture

Then how do you know if the entity is already enabled or you actually don't have access? :)

Xano’s picture

You won't be able to know if the entity is already enabled without this check either. You will just get a 200 instead of a 403 regardless of the entity was enabled or disabled before the request.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 51: drupal_2200183_51.patch, failed testing.

Xano’s picture

Status: Needs work » Needs review
tstoeckler’s picture

Hmmm... that's a very interesting use-case/question @damiankloip. I suppose 404 would be a more semantic response code for an enabling an already enabled entity. Then it would be consistent with e.g. delete:

# Delete an entity
POST /node/1/delete # get back 200
# Try to delete again
POST /node/1/delete # get back 404

# Enable an entity
POST /node/1/enable # get back 200
# Try to enable again
POST /node/1/enable # get back 404

That said, enable/disable, is really a different animal that delete (especially in REST-world), so maybe the above is not really a very semantic analogy. Maybe we really do want to return 200 in that case. Hmm...

damiankloip’s picture

If I was building an API, and from past experience of its consumption, returning a 200 in the case it is already enabled usually works out best. Which kind of goes against how this patch would work? or not?

Berdir’s picture

Interesting question.

Keep in mind that...

- We have no actual integration with entity operations/links in rest.module. The links are there based on the link templates, but they are not actually useful for rest.module because it doesn't implement them nor are they how rest.module works otherwise. A delete is *not* "POST /node/1/delete", it's "DELETE /node/1".

The way to enable/disable a config entity *would* be to do a POST and change the status property. and we have no way to interact or check that, because config entity entities have no field/property level access control or validation. At least not until we have a typed data wrapper system that would work based on the config schema.

*Would* because we have no config entity integration *at all* for rest.module right now anyway ;)

So based on that, it's a problem that we currently don't have (because we have far bigger problems before we would even get to this ;)) but it's still an interesting use case why this would be the wrong approach.

damiankloip’s picture

Sure, I am saying if I was building an API though :) Not just what is provided by REST module. Yes, the examples from #61 were not correct but this is not a question about guidelines of a REST API :)

Maybe I misunderstand, but I am not reading into it as much as you are ....

I am thinking I basically cannot do this:

 // Inside my PUT/POST callback...
 if ($entity->access('enable')) {
   $entity->enable();
 }

tstoeckler’s picture

Well, that would work fine. If the entity is enabled, then the acces() call would yield FALSE, but in that case the ->enable() call would be a no-op anyway. So the code would work either way. Or am I missing something?

damiankloip’s picture

I would rather a no-op and a sensible return value than an access denied. The point is I cannot just call access() with this patch. So if I did get a 403 back, is it because I am really not allowed, or that the entity is already enabled? If I try to enable and already enabled entity, returning with access denied would not be useful IMO.

jcnventura’s picture

Issue tags: -drupaldevdays

If someone works at this in Montpellier, feel free to add it back

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Status: Needs review » Needs work

Moving to NW for some of the follow up discussion after it moved to NR

Wondering if this is still needed for 9.5?

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.