[P-1] Separate the account information from the user entity.

Created on 18 October 2012, almost 12 years ago
Updated 10 November 2023, 11 months ago

Prerequisites

This is a follow-up to Unify anonymous and registered users Active .

Problem/Motivation

Currently the user 'account' is a hard-wired part of what we call a 'user' in Drupal. This is an annoying and unnecessary interdependency because the account itself is something that should be optional.

Proposed resolution

Create a new, separate account entity with a primary key 'uid' for a unique relation between user and account. The account entity consists of the password and the initial e-mail address only.

Every visitor of a site can potentially be a user. By registering on the website a user would get an 'account' attached to his user entity through which he can identify himself as that user. Until then, this happens exclusively through the session.

We would end up with two distinct objects in core:

User - Any visitor, registered or not, can become a 'user'. That means that, whenever something that should be available to anonymous users but somehow requires a user entity (or would be better of if it had one) happens on the website we generate a user entity. Thus, a 'user' is any type of person that we want to be able to store information for. This could be anything from anonymous commenters (core) or voters (contrib) through to contacts in a complex, contributed CRM system as well as registered users with an account or other means to identify themselves on the site.

Account - Accounts would be the default way for Drupal to identify users. Users can create accounts and once an account is attached to a user entity that user is a 'registered user'. Accounts are somewhat optional and could be replaced with other authentication mechanisms that would also lead to 'registered users'.

Benefits

With the account being optional and replacable by other, alternative authentication mechanisms we would ease the adoption of Drupal for niche use-cases where accounts are not actually required and cumbersome or only partly required (@see this comment for an example of such a case).

Also, the implementation of an anonymous user API according to Unify anonymous and registered users Active would be much cleaner in general because there would be no stale account data on user entities of non-registered users.

Related issues

Unify anonymous and registered users Active

📌 Task
Status

Active

Component

Idea

Created by

🇦🇹Austria fubhy

Live updates comments and jobs are added and updated live.

Missing content requested by

🇦🇺Australia dpi
10 months ago
Sign in to follow issues

Comments & Activities

  • 🇺🇸United States michelle Wisconsin, USA

    I think this might help my use case as well. I run the website for the camera club I am in and we maintain the "roster" via user accounts. This works great except for those who don't have email addresses (mostly the older ones). I currently put in a fake email for them but having them be users without accounts would be much cleaner, I think.

    Michelle

  • 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 .

  • 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 .

  • 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 .

  • 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 .

  • 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 .

  • 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 .

  • 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 .

  • 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 .

  • 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 .

  • 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 .

  • 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 .

  • 🇬🇧United Kingdom yautja_cetanu

    Updated issue summary.

  • 🇬🇧United Kingdom yautja_cetanu

    Summary

    In this thread Unify anonymous and registered users Active Sun proposed a potentially simpler method of only achieving an anonymous user API that helps with the comment module situation described in this issue #355513: Create an anonymous user API . We have invested how both ideas could be achieved. Sun’s is in theory and our idea can be found both in the Party module and fubhy’s sandbox: http://drupal.org/sandbox/sumsi/1806794

    After further analysis we think that Sun’s proposal could work but is a little more complicated than it appears at first. Our idea appears complicated but think it is actually simpler then initially appears and has more scope at assisting many contrib cases. Both proposals would be helpful and so we have gone into detail here.

    Sun/ Damien Tournoud’s Idea

    We keep users as they are but put a flag on the user of whether it is anonymous or authenticated. We then move all systems that deal with anonymous users to deal with users + anonymous flag. For example when a comment is input with some information such as name, website and e-mail it is saved on a user that is flagged as anonymous. This user will be treated in almost the same way bar some exceptions.

    Dealing with Names and Passwords requires some extra code.

    • You will have to force comment names to be unique. OR have to enable non-unique usernames at the database level for all users and enforce unique usernames at a higher level like with e-mail.
    • You will have to set a random hidden password for anonymous users OR enable NULL passwords at the database level for all users and enforce that it is non-null at a higher level like with e-mails.
    • In order for this to happen there are a number of situations where the anonymous flag on a user needs to be checked before something can happen.
      • Every form that changes that edits or creates a user has to first check the flag before it can change the username or password to implement the restrictions that were previously at the database level.
      • This code is shown below but it feels unpleasant

    Change the Database scheme or not?

    We think that changing the database schema seems to be the reasonable conclusion as making it completely impossible even in contrib to allow anonymous users to have non-unique names does not make sense. However due to #845774: Regression: Anonymous users can post comments in the name of registered users this is arguably a good thing.

    However if we want to allow anonymous users to be non-unique (And we definitely want them to not have a password) we need something like below

    Example of how we would make an anonymous user API that deals with saving and updating usernames and passwords.

    Wordy Code

    Comment Module says I want to save a name on the user 
    Thing - Takes this information and looks at the user, it it anyonmous or authenticated
    Thing - Finds its anonymous
    Things - Passes it to anonymous save
    Anonymous Save - I will allow non-unique usersname
    Saves the username
    

    Code Snippet

    // Comment module gets information about a comment from a form. In CommentStorageController
    
    $user = user_create();
    $user->name = “Cheese”
    $user->save();
    
    // $user->save() eventuall calls UserStorageController->save()
    
    if ($user->isAnonymous()) {
      hook_presave	
      save normally, calling parent::save();
      hook_insert/update
    }
    else {
      db_select() // find if another user has the same name
      if (other user exists) {
        // reject username change
      } 
      if (user with same email) {
     	 //reject email
      }
      if (password is empty) {
      	 // reject password save.
      }
      // save entity after bad changes have been rejected.
    }
    

    Our Proposal
    Our idea completely separates the user information from the information required to authenticate that user. Our idea puts the username as a unique property on the account entity and deals with the name of a user with our “nice name concept”.

    Potential Performance Worries and our solution

    Loading a user and an account from the from the database will be slower and more memory intensive than loading one record from one table.

    So instead we have found a way of not needing to load both tables in the vast majority of cases. For example, using the concept of a name on the user entity (nice_name), our patch in the issue only loads the account on 2 occasions.

    We add a ‘name’ field onto the user table that is essentially free text and non-unique so that it can take any value. When comments are saved they can create a user and write directly to the name field. When accounts are created they will write to both the account name (which is unique) and the user name which is not unique.

    This allows us to maintain unique account names, but allow for non-unique comment-poster names. We think this is no worse than sun’s proposal, especially regarding performance but allows for contrib to much more easily take control of the display name of a user entity.

    This has a bunch of further benefits

    • The nice name is free to have duplicates, simplifying the problem of allowing multiple anonymous comments with the same name.
    • The nice name can be used like a cache. This means name alteration using hook_user_format_name only happens on write => faster rendering of a user name => faster load times for pages with lots of user represented
      • Accounts can set the name as the username to start off with.
    • A Full name module can easily use fields from the profile module
    • In Party we have built a tool that uses ctools plugins to set the entity label on our “Party” (which is essentially like the user). On every save it looks for suitable name in a variety of places and chooses the most appropriate.
      • This allows fields that are not required (such as full name on a profile) to be used for the label
      • This allows for labels to be constructed from multiple fields such as Name + Town.
    • Saving the name allows name calculation to be fairly intensive without effecting the performance of a load operation.

    It also opens up the potential for contrib to some really interesting things in the future

  • 🇺🇸United States smustgrave

    Postponing Unify anonymous and registered users Active

    From the linked issue
    While taking a look at #1816218: Separate the account information from the user entity. @catch found this issue and mentioned they both could be moved to the ideas queue.

  • 🇬🇧United Kingdom AaronMcHale Edinburgh, Scotland

    Already commented on Unify anonymous and registered users Active expressing my support. Definitely +1 to this.l

    A few thoughts (some of which I've thought for a long time but never got around to expressing them):

    1. We shouldn't assume that passwords will be the only method of authenticating, pass keys are gaining momentum, and the latest WCAG standards Accessible Authentication (Enhanced) (Level AAA) states:

      A cognitive function test (such as remembering a password or solving a puzzle) is not required for any step in an authentication process unless that step provides at least one of the following:
      Alternative
      Another authentication method that does not rely on a cognitive function test.
      Mechanism
      A mechanism is available to assist the user in completing the cognitive function test.

      So we may want to take the opportunity to consider this as part of what we think of as the base fields and data structures for the account entity type.

    2. As the user entity could then be used for more than just site users, should we consider renaming it to something more generic like "identity", and "user" is actually the bundle.
    3. Building on that, to facilitate different types of users (ie users with accounts, a simple person record like in a CRM, newsletter subscribers who don't have accounts, etc), is it worth fully supporting user bundles in core, see https://www.drupal.org/project/user_bundle for example of what I mean. That way we benefit from each "user type" being able to have different and shared fields. However, that thought might be out of scope and maybe a separate idea, because both types I just mentioned could have accounts.
Production build 0.71.5 2024