Problem/Motivation

  • In Drupal, we have a concept of "administrative route", expressed via the _admin_route route option.
  • Certain things happen for administrative routes, such as AdminPathConfigEntityConverter and LanguageNegotiationUserAdmin.
  • Caching is also affected, though see #2877528: Change Dynamic Page Cache's response policy from "deny admin routes" to "deny html admin routes" about possibly changing that.
  • AdminRouteSubscriber automatically marks routes with a path that starts with /admin as administrative.
  • As a result, some REST module routes get marked as administrative, such as GET requests to MenuLinkContent and Shortcut entities, though it's not at all clear why we'd want any of the administrative route behaviors happening for those requests.
  • Outside of core's REST module, who knows what use cases contrib has for non-HTML routes and whether it's clear what "administrative"
    means for those use cases.

Proposed resolution

  1. Option 1: Keep core's current behavior of marking /admin/* routes as administrative, regardless of format. If it's undesirable for the canonical URL of an entity to be administrative, then move that URL out of /admin. See,
    for example, #2873529: BlockContent, MenuLinkContent, and Shortcut define incorrect canonical links.
  2. Option 2: Change AdminRouteSubscriber to only mark /admin/* routes as administrative if they're HTML routes. For non-HTML routes, require explicit opt-in to _admin_route, not magic based on URL path. This would be a potential BC break for contrib that was relying on the existing magic.
  3. Option 3: Change REST module to mark all its routes as non-administrative by default. That's implemented in the patch in comment #2.
  4. Option 4: Change REST module to only mark entity resources as non-administrative. This could be accomplished via EntityResource::getBaseRoute().
  5. Option 5: Change REST module to only mark GET requests of entity resources as non-administrative. This could be accomplished via EntityResource::getBaseRoute() and its $method parameter.

Remaining tasks

  • Decide on which option makes the most sense. Option 2 was chosen, per routing system maintainer @tim.plunkett in #9.
  • Implement that option and create a change record to communicate the corresponding BC break.

User interface changes

None.

API changes

Routes that don't serve HTML, but for example JSON, and have a path that starts with /admin are no longer automatically marked as admin routes.

Data model changes

None.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Wim Leers created an issue. See original summary.

Wim Leers’s picture

Status: Active » Needs review
FileSize
690 bytes

So we do mind limiting AdminRouteSubscriber to HTML routes, but we don't mind making the REST module's routing aware of concepts only relevant to HTML? This makes little sense to me.

Anyway, here's a patch.

effulgentsia’s picture

Title: Stop marking REST routes as administrative » Decide which, if any, non-HTML routes should be administrative
Category: Bug report » Task
Issue summary: View changes
Status: Needs review » Active

So we do mind limiting AdminRouteSubscriber to HTML routes, but we don't mind making the REST module's routing aware of concepts only relevant to HTML? This makes little sense to me.

Is "administrative route" a concept that is only relevant to HTML? That's the question. I rewrote the issue summary, and am setting this issue to Active in order to have a discussion on which direction to take.

Wim Leers’s picture

Is "administrative route" a concept that is only relevant to HTML? That's the question.

I think "administrative route" is only relevant to HTML, yes.

The whole reason it's called "administrative" in the first place is because of the "admin" or "back end" of a site, which uses the "admin theme".

That is the entire purpose/goal/semantic/origin of _admin_route: to determine which HTML pages should use the admin theme. That is: all HTML pages that have a URL starting with the /admin prefix, as well as the few exceptions that don't have that path prefix, but want to use the admin theme anyway, depending on configuration: the /node/add/* HTML pages.
_admin_route is the abstraction for that: so that that is the sole factor in determining whether a route should use the admin theme during theme negotiation (see \Drupal\user\Theme\AdminNegotiator). Then the /node/add/* routes can just set that _admin_route route option, and other exceptional cases are then also possible.
IOW: if we didn't have _admin_route, then we'd be forced to stick to just /admin path prefixes or also hardcode whatever crazy logic to deal with the exceptions.

Wim Leers’s picture

Wim Leers’s picture

Issue tags: +blocker

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

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now 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.

Wim Leers’s picture

Component: rest.module » routing system

Come to think of it, this is actually more of a routing system issue probably! At the very least, it's a question where we'd want a routing system maintainer to weigh in.

tim.plunkett’s picture

Core has only had two reasons to care about whether a path is "admin" or not:

  1. What theme should be used
  2. Should we check the $user->preferred_admin_langcode when determining the language

I honestly don't know if the langcode portion affects non-HTML routes.

Upon first reading, I like option #2.
However, how will you know if the route explicitly opted in or not? The check for /admin/ actually goes and sets the route option...

Wim Leers’s picture

Status: Active » Needs review
FileSize
1.71 KB

Thanks, Tim!

I also like option 2. Patch attached that implements it.

However, how will you know if the route explicitly opted in or not? The check for /admin/ actually goes and sets the route option...

For option 2, the IS says that non-HTML routes would have to explicitly opt in. Since \Drupal\system\EventSubscriber\AdminRouteSubscriber sets the _admin_route route option only for HTML routes, that means that non-HTML routes would have to set that route option themselves in their route definition. So it's a non-issue. Unless I'm misunderstanding you.

Status: Needs review » Needs work

The last submitted patch, 10: 2874938-10.patch, failed testing. View results

tim.plunkett’s picture

You misunderstood me, but my point also didn't make any sense in light of that patch. I originally envisioned Yet Another Subscriber having trouble introspecting this, but of course it can live inside the existing subscriber.

Wim Leers’s picture

Okay!

So what do you think about #10? :)

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
3.02 KB
3.91 KB

Yes, but with one small change. Formats are specified as pipe-delimited, so this needs some extra finesse.
Added a unit test, of which the last case covers my change.

Status: Needs review » Needs work

The last submitted patch, 14: 2874938-admin-14.patch, failed testing. View results

Wim Leers’s picture

Status: Needs work » Needs review
FileSize
6.06 KB
9.83 KB

D'oh, of course! Thanks for the fix, and the test! ❤️👌

The failures aren't in your new test, but in the existing REST test coverage, which is now failing only because the work-around is no longer relevant :) I can simply resolve the two @todos, and tests then pass! (#2765959: Make 4xx REST responses cacheable by (Dynamic) Page Cache + comprehensive cacheability test coverage would have to add even more of those work-arounds until this is fixed.)

borisson_’s picture

I think we should retitle this issue - it's been decided that only those non-html routes that also have a html as alllowed format should be marked as administrative.

The code looks solid as do the tests, should we also upload a test-only patch?

Wim Leers’s picture

Title: Decide which, if any, non-HTML routes should be administrative » AdminRouteSubscriber must only mark HTML as administrative
FileSize
8.08 KB
9.83 KB

#17++

Done!

Wim Leers’s picture

Title: AdminRouteSubscriber must only mark HTML as administrative » AdminRouteSubscriber must only mark HTML routes as administrative

The last submitted patch, 18: 2874938-16-test-only.patch, failed testing. View results

borisson_’s picture

Status: Needs review » Reviewed & tested by the community

Awesome, thanks!

xjm’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs change record

I was going to ask for a routing subsystem maintainer review -- turns out that's @tim.plunkett and he's agreed on the solution above.

Probably we should add a change record? Thanks!

Wim Leers’s picture

Issue summary: View changes
Status: Needs work » Reviewed & tested by the community
Issue tags: -Needs change record
xjm’s picture

Status: Reviewed & tested by the community » Fixed

Committed to 8.5.x and published the change record. Thanks!

Wim Leers’s picture

This allowed me to close #2877528: Change Dynamic Page Cache's response policy from "deny admin routes" to "deny html admin routes" since it's now obsolete. And it allowed me to rebase #2765959's patch, the new one is 5 KB smaller because it doesn't need to handle the edge cases that HEAD (before this patch went in) was causing for lots of scenarios: #2765959-231: Make 4xx REST responses cacheable by (Dynamic) Page Cache + comprehensive cacheability test coverage — yay!

  • xjm committed 3af361c on 8.5.x
    Issue #2874938 by Wim Leers, tim.plunkett, borisson_, effulgentsia:...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.