User can create multiple profiles while profile type disallows multiple

Created on 6 December 2022, almost 2 years ago
Updated 22 May 2024, 6 months ago

Problem/Motivation

Hi!

I've applied Content Moderation + Workflow to my Member profile type.
This to allow reviewing and approval by an admin of the said profile.

The issue is that when I visit the profile.user_page.single page (/user/{user}/{profile_type}), it let me create another profile, while another one is still pending review.

Steps to reproduce

  • Create a profile type, don't allow multiple profiles per user
  • Go to /user/{user}/{profile_type} and create a profile, don't publish it
  • Go back to /user/{user}/{profile_type} and create a profile

You now have 2 profiles.

Proposed resolution

Alter the ProfileStorage to allow loading all profiles and not only the published ones.

πŸ› Bug report
Status

Needs work

Version

1.0

Component

Code

Created by

πŸ‡§πŸ‡ͺBelgium ludo.r Brussels

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

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡§πŸ‡¬Bulgaria pfrenssen Sofia

    Great find! I also discovered some duplicates in our database. However we are not using content moderation, so there must be another mechanism that allows duplicates to be created. In our case all duplicates are published.

    We have a decoupled administration section, so it is possible the duplicates have been created through JSON:API. Maybe we should implement ProfileStorage::create() and throw an InvalidArgumentException when trying to create a profile for a user that already has one?

    Regardless of the approach, this also needs an update path to remove the duplicates. Marking as Needs Work for that.

  • πŸ‡§πŸ‡¬Bulgaria pfrenssen Sofia

    I started looking into preventing duplicates on entity level. Some things to consider:

    • The uid field is not required, and it is revisioned. This means the linked user can change in the lifetime of the profile entity.
    • Probably having historic duplicates is not a problem, but when saving a new revision we should avoid switching to a user which already has a profile.
  • @pfrenssen opened merge request.
  • Status changed to Needs review over 1 year ago
  • πŸ‡§πŸ‡¬Bulgaria pfrenssen Sofia

    This is ready for review. Note that the MR just adds entity validation. Probably we can also update the form like was done in the patch from #2.

    Even with this entity validation in place it is still possible to programmatically create duplicate profiles by bypassing entity validation and manually creating entities (e.g. by doing Profile::create()->save()), but this is similar to how other entity types operate. For example a node can also be saved manually with invalid data.

    Content entities have an optional flag validationRequired that prevent any entities from being saved which do not pass validation. Setting this flag would make it impossible to create duplicate profiles, but this option is used only very rarely.

    That said, this is probably a good enough solution since it will effectively stop accidental creation of duplicates through forms and REST APIs. We can never stop the creation of invalid data through bad code. It is the developer's responsibility to properly validate entities before saving them.

  • I have reviewed the merge request of @pfrenssen, and it looks good to me. However, because I am new to the Drupal and PHP ecosystem, I refrained from actually signing something off. I'd appreciate if someone with more experience would chime in and review the changes.

  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 9.5.x + Environment: PHP 7.3 & MySQL 5.7
    last update over 1 year ago
    Patch Failed to Apply
  • πŸ‡΅πŸ‡­Philippines bryanmanalo

    #2 patch works! Thanks @Ludo.R!

    But I have to modify slightly to make it compatible with another patch from https://www.drupal.org/project/profile/issues/3232335 πŸ› User Profile form does not load latest revision when it is not the default one Needs review .

  • Status changed to Needs work 6 months ago
  • πŸ‡ΊπŸ‡ΈUnited States glassb

    I tested MR !17 on a site running 10.1.8 with content moderation, but I found that duplicate profiles were still being created. After some debugging, it looks like it is making it to

    if ($profile_exists) {
          $this->context->buildViolation($constraint->errorMessage)
            ->atPath('uid')
            ->addViolation();
        }

    and $profile_exists does evaluate as true when expected. I'm not familiar with Symfony constraints, but it seems like once the violation is raised it should prevent the submission. I tried looking into it, but it looks correct as far as I can tell.

    For now, #2 patch does seem to work for me.

  • πŸ‡·πŸ‡΄Romania alex.stanciu

    Here's a re-roll of patch #2 on the latest 8.x-1.x as the previous one no longer applies.

Production build 0.71.5 2024