Use AccountInterface instead of UserInterface in authentication

Created on 30 October 2023, 8 months ago
Updated 18 April 2024, 2 months ago

Problem/Motivation

Currently JwtAuthValidEvent::setUser() typehints UserInterface so that full user objects must be used as part of JWT authentication.

Core's authentication only requires the result of the authentication to implement AccountInterface, however. As far as I can tell, there is no reason for the additional requirement. Lifting that would allow integrating the JWT authentication with a non-user-entity-based authentication, which is currently not possible.

Steps to reproduce

Proposed resolution

Change the typehint in JwtAuthValidEvent::setUser() and related code to AccountInterface instead of UserInterface.

Remaining tasks

User interface changes

API changes

Data model changes

πŸ“Œ Task
Status

Fixed

Version

2.0

Component

Code

Created by

πŸ‡©πŸ‡ͺGermany tstoeckler Essen, Germany

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @tstoeckler
  • Status changed to Needs review 8 months ago
  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 10.1.x + Environment: PHP 8.1 & MySQL 8
    last update 8 months ago
    12 pass
  • πŸ‡©πŸ‡ͺGermany tstoeckler Essen, Germany

    Here we go.

    This does a little more than strictly necessary:

    • Removes the fallback to the anonymous user. Not sure why that was there, it was (arguably?) not necessary even before this change, but it has even less justification now.
    • Removes the fallback in the authentication provider. Previously it was already unnecessary because there was always a fallback user that would be returned (see previous point), but it's still unnecessary now
    • Renamed methods to getAccount/setAccount vs. getUser/setUser. Not sure what the BC-policy is, that could be reverted of course, or we could leave in the old ones for BC.

    Tests are green locally with this.

  • Status changed to Needs work 5 months ago
  • πŸ‡ΊπŸ‡ΈUnited States pwolanin

    Changing the method names seems overkill and likely to break other people's integrations.

    If you really want to do that, just add the new methods and call them from the old methods and mark the old ones as deprecated. Maybe we need to do that in any case if you are changing the type hinting.

    This should probably have some test coverage added?

  • πŸ‡©πŸ‡ͺGermany tstoeckler Essen, Germany

    Thanks for taking a look.

    Fine with deprecating the methods instead, sure. Just one question: If someone actually sets an AccountInterface that is not a UserInterface then getUser() would not return a UserInterface with the current code. Not sure how would like that handled, I would see the following options:

    1. That's fine, just document that that can happen, since getUser() is deprecated then, all is good (my preference)
    2. Actually track a separate $user and $account object (which would be very confusing IMO)
    3. In that case return the account from getAccount() but return NULL from getUser() (also confusing IMO, albeit less so)
    4. Try to load a user from the account and return NULL otherwise (not much better than the previous one in my book)

    Since there are currently no typehints we are pretty much free to do whatever without risking any PHP breakage, but, yeah, would be good to know what the API should be in your opinion with this change.

    In terms of test coverage: An actually meaningful test would only be possible with a custom AccountInterface implementation, which this patch enables, but does not exist in core itself. Is that what you had in mind, or would you be happy with unit(-y) test coverage, as well?

  • πŸ‡ΊπŸ‡ΈUnited States pwolanin

    Sounds like we should add typehints in the 3.x branch if we do that any time soon.

    Option #1 is maybe fine... you can change the @return param comment even and document that it just returns what was added in setUser() / setAccount() ?

    As far as tests... well maybe you are right that there is not much to test. You could have a Kernel test or something that sets a \Drupal\Core\Session\UserSession as the user in a test module event subscriber? Why do you need a non-core implementation?

  • πŸ‡©πŸ‡ͺGermany tstoeckler Essen, Germany

    Thanks for the follow-up. Meant to reply with an updated patch "in hand", but that never materialized, sorry about that...

    Sounds good regarding the getAccount()//setAccount() methods. πŸ‘

    And yes, makes sense regarding the test, as well, I was a bit in a mental rabbit hole when I wrote that thinking about the use-case in our project of having a custom AccountInterface implementation. Just setting a UserSession in a test is absolutely the sensible thing to do. πŸ‘

    Not sure when I will get around to updating the patch, but wanted to reply at least, for now.

  • First commit to issue fork.
  • Merge request !10Use AccountInterface and not UserInterface β†’ (Merged) created by alexpott
  • Status changed to Needs review 3 months ago
  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    Created an MR based on @tstoeckler's code.

    I've added back the old methods and deprecated them.

    I'm not convinced that we need test coverage beyond the existing code coverage - this is more a underlying refactor where we're broadening the interface to allow what Drupal's user authentication allows.

  • Pipeline finished with Failed
    3 months ago
    Total: 190s
    #122652
  • Pipeline finished with Failed
    3 months ago
    Total: 155s
    #122658
  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    Hiding the patch now we have an MR.

  • Pipeline finished with Success
    3 months ago
    Total: 157s
    #122667
  • πŸ‡ΊπŸ‡ΈUnited States pwolanin
  • Pipeline finished with Skipped
    3 months ago
    #136947
  • Status changed to RTBC 3 months ago
  • Status changed to Fixed 3 months ago
  • πŸ‡ΊπŸ‡ΈUnited States pwolanin

    merged to 2.x and will cherry-pick to 3.x

    Please make a 3.x issue to remove the old methods.

  • πŸ‡©πŸ‡ͺGermany tstoeckler Essen, Germany

    Wow, that's awesome, thanks a lot!

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

Production build 0.69.0 2024