View Issue Details

IDProjectCategoryView StatusLast Update
0032787mantisbtadministrationpublic2023-10-31 16:32
Reporterdregad Assigned Todregad  
PrioritynormalSeverityfeatureReproducibilityN/A
Status closedResolutionfixed 
Target Version2.26.0Fixed in Version2.26.0 
Summary0032787: Facilitate identification of user accounts sharing the same email
Description

When email_ensure_unique = ON, it is an error to have multiple user accounts with the same email address in the database, which is something that can happen when this config's value is changed from OFF to ON or when upgrading from MantisBT < 1.3.0-rc.2 (see 0009093).

As discussed in 0020647:0052620, we should make it easier for the admin to identify these accounts having duplicate emails so they can be fixed.

TagsNo tags attached.

Relationships

related to 0009093 closedvboctor Add a configuration option to enforce email uniqueness 
related to 0020647 closedvboctor Not able to update existing user accounts if $g_email_ensure_unique == ON 
related to 0032451 closeddregad Email uniqueness is not enforced on case-sensitive databases 
related to 0033012 assigneddregad Don't abort Admin Checks after first failure unless it's critical 
related to 0032940 closeddregad Add admin check to detect users without e-mail address when allow_empty_email = OFF 

Activities

dregad

dregad

2023-07-29 05:27

developer   ~0067921

PR https://github.com/mantisbt/mantisbt/pull/1898

atrol

atrol

2023-09-09 09:38

developer   ~0068077

@dregad I noticed that our "Manage User" page is slow.
I suspect it's caused by the user_is_email_unique calls you introduced to show the icon for non-unique emails.
You might want to remove it again, as there is not much benefit for installations with thousands of users.

dregad

dregad

2023-09-10 04:23

developer   ~0068078

I'll have a look if it can be optimized and will revert if not.

dregad

dregad

2023-09-10 08:03

developer   ~0068079

I ran quick local test with a dump of mantisbt.org tracker's user table (44423 rows):

  • master (0553a42): Page execution time: 0.6156 seconds Memory usage: 3,999 KiB Total queries executed: 66 Total query execution time: 0.3678 seconds
  • commit d6681928: Page execution time: 0.6105 seconds Memory usage: 4,081 KiB Total queries executed: 16 Total query execution time: 0.3592 seconds

So it does execute 50 additional queries (as expected for the uniqueness check), but the overall performance is nearly the same.

On mantisbt.org on the other hand, the same page executes in approx. 3 seconds, vs 0.2 seconds with commit d66819280.

So it seems environment specific, maybe a missing or corrupt index on the DB ?

dregad

dregad

2023-09-10 08:15

developer   ~0068080

Git bisect identifies MantisBT master bf7a3c22 as the offending commit (no surprise).

dregad

dregad

2023-09-10 08:21

developer   ~0068081

I tried optimizing and repairing the table, but that did not change anything. I don't understand why I'm not seeing the performance degradation locally. Any ideas ?

atrol

atrol

2023-09-10 08:34

developer   ~0068082

Last edited: 2023-09-10 09:56

I don't understand why I'm not seeing the performance degradation locally

I remember you are using some script to change the original email addresses for local testing purposes.
Maybe you change all addresses to the same one or clear them?

[EDIT] Forget about that, the script adds the user name to the addresses.
https://github.com/mantisbt/mantisbt-tools/blob/master/db-anonymize.sql

atrol

atrol

2023-09-10 09:11

developer   ~0068083

Maybe replacing the ILIKE by comparing with UPPER(email) works better for some databases.

dregad

dregad

2023-09-10 13:12

developer   ~0068084

I remember you are using some script to change the original email addresses for local testing purposes.

I did not use it in this specific case, to make sure I had a test case as close as possible to the original. My local database is an exact copy.

Maybe replacing the ILIKE by comparing with UPPER(email) works better for some databases

It could be, but in this specific case I don't think that's the issue as both environments are running MySQL (8.0 on the server, 8.1 on my laptop).

dregad

dregad

2023-09-16 10:25

developer   ~0068111

Last edited: 2023-09-28 08:27

PR https://github.com/mantisbt/mantisbt/pull/1919 improves the performance issue with manage_user_page.php reported by @atrol in 0032787:0068077.

With this, the page loads under 0.5 seconds on this tracker, vs approx. 3 seconds before this change. This is still about twice as slow as before MantisBT master d6681928, but I believe that's acceptable for an admin page.

atrol

atrol

2023-10-03 06:31

developer   ~0068167

@dregad your changes to add admin check to detect duplicate e-mails introduces a side effect.
If $g_email_ensure_unique is enabled and duplicate emails are found (e. g. about 1000 in our own tracker), the check fails (check_print_test_row), so that the complete check process stops and you can't run the rest of the checks.

As a quick solution, you might want to change from check_print_test_row to check_print_test_warn_row.

The mid-term solution would be to enhance the concept of $g_failed_test (stop running tests after the first one failed).
Of course, some failing tests are blocking and must be fixed to run further tests, but not all of them.

dregad

dregad

2023-10-03 06:53

developer   ~0068169

It's not really a side-effect, it's totally by design...

The rationale is that if you configured the system for unique e-mail addresses and your system does not comply then you have a real error condition and you need to fix the problem as it could cause problems. I don't agree that this should be downgraded to a warning.

We do have a specific problem in this tracker due to the large number of non-compliant of legacy accounts and the effort it would take to fix them.

So indeed the real problem is the way our admin test handle the failures. Maybe we should introduce a concept of "blocking" errors that cause the checks to abort, vs non-critical failures that lets them continue.

atrol

atrol

2023-10-03 13:23

developer   ~0068172

I don't agree that this should be downgraded to a warning.

Right, I should have written "temporary workaround" instead of "temporary solution".

We do have a specific problem in this tracker due to the large number of non-compliant of legacy accounts and the effort it would take to fix them.

I suspect we are not alone.
Be aware that option $g_email_ensure_unique was introduced with questionable default settng ON in version 1.3, so that installations that started before 1.3 are also affected.

dregad

dregad

2023-10-04 04:11

developer   ~0068173

Yes I know, this is exactly why I added the warning in the Admin Guide (see MantisBT master 18ea9a43).

The admin must be aware that these errors must be fixed, particularly when using REST API, as the system expects the email to be unique and if it is not then user_get_id_by_email() may silently return the wrong user, leading to unpredictable and unwanted system behavior (for example: updating an issue's reporter or handler, assigning a user to a project, etc) particularly when the accounts with duplicate emails do not have the same access level.

dregad

dregad

2023-10-09 10:20

developer   ~0068194

@atrol, following up on your note 0032787:0068167 and subsequent discussion, I had a closer look yesterday

The mid-term solution would be to enhance the concept of $g_failed_test (stop running tests after the first one failed).
Of course, some failing tests are blocking and must be fixed to run further tests, but not all of them.

Indeed this is the key, and I actually believe it would not be so hard to fix this - we just need a concept of critical failure (meaning that if the test fails, then it is not possible to continue with the Checks), in addition to the existing fail, warn and info checks.

So the only difficulty is to identify those truly critical tests that should cause the Admin Checks to abort. I have not looked in detail yet, but off-hand I think only some failures in the database and paths checks would qualify.

Can you think of others ?

atrol

atrol

2023-10-09 15:59

developer   ~0068195

@dregad right, most of the blocking checks are part of check_database_inc.php
In a first step, I would add a new function check_print_test_block_row that identifies the blocking checks in addition to check_print_test_row and check_print_test_warn_row.
After that, check all current checks and change some check_print_test_row to check_print_test_block_row

To start with check_database_inc.php:
Some of the warnings should even no longer be a warning, but critical / blocking in 2.26.0

    check_print_test_warn_row(
        'PHP support for Microsoft SQL Server driver',
        'mssql' != $t_database_type,
        array( false => &quot;'mssql' driver is no longer supported in PHP >= 5.3, please use 'mssqlnative' instead&quot; )
    );

    check_print_test_warn_row(
        'PHP support for MySQL driver',
        'mysql' != $t_database_type,
        array( false => &quot;'mysql' driver is deprecated as of PHP 5.5.0, please use 'mysqli' instead&quot; )
    );

These ones must no longer block further tests, although they can be critical in terms of runtime.
So keep them like they are at the moment, but change the remaining ones to check_print_test_block_row

        check_print_test_row(
            'MySQL version is a General Availability (GA) release',
            $t_mysql_ga_release,
            array(
                true => 'You are using MySQL version ' . htmlentities( $t_db_version ) . '.',
                false => 'The version of MySQL you are using is '
                    . htmlentities( $t_db_version )
                    . '. This is a development or pre-GA version which '
                    . ( $t_versions[$t_db_major_version][0] == 'Discontinued' ? 'has been discontinued and ' : '' )
                    . 'is not recommended for Production use. You should upgrade to a supported GA release.'
            ) );

        # Within lifecycle 'Extended' support
        check_print_test_row(
            'MySQL version is within the ' . $t_support_url . ' period (GA + 8 years)',
            date_create( $t_date_extended_end ) > date_create( 'now' ),
            array(
                true => 'Extended support for MySQL ' . $t_db_major_version . ' series ends on ' . $t_date_extended_end,
                false => 'Support for the release of MySQL you are using ('
                    . htmlentities( $t_db_version )
                    . ') ended on ' . $t_date_extended_end
                    . '. It should not be used, as security flaws discovered in this version will not be fixed.'
            ) );

    check_print_test_row(
        'Version of PostgreSQL is ' . $t_support_url . '',
        date_create( $t_date_eol ) > date_create( 'now' ),
        array(
            false => 'PostgreSQL version ' . htmlentities( $t_db_version )
                . ' is no longer supported and should not be used, as security flaws discovered in this version will not be fixed.'
        ) );

    check_print_test_row(
        'Database default collation is UTF-8',
        check_is_collation_utf8( $t_collation ),
        array( false => 'Database is using '
            . htmlentities( $t_collation )
            . ' collation where UTF-8 collation is required.' )
    );

            check_print_test_row(
                'Table <em>' . htmlentities( $t_row['name'] ) . '</em> is using UTF-8 collation',
                check_is_collation_utf8( $t_row['collation'] ),
                array( false => 'Table ' . htmlentities( $t_row['name'] )
                    . ' is using ' . htmlentities( $t_row['collation'] )
                    . ' collation where UTF-8 collation is required.' )
            );

                check_print_test_row(
                    'Text column <em>' . htmlentities( $t_row['field'] )
                    . '</em> of type <em>' . $t_row['type']
                    . '</em> on table <em>' . htmlentities( $t_table )
                    . '</em> is using UTF-8 collation',
                    check_is_collation_utf8( $t_row['collation'] ),
                    array( false => 'Text column ' . htmlentities( $t_row['field'] )
                        . ' of type ' . $t_row['type']
                        . ' on table ' . htmlentities( $t_table )
                        . ' is using ' . htmlentities( $t_row['collation'] )
                        . ' collation where UTF-8 collation is required.' )
                );

If you agree with the general approach, I could go thru the other check files and identify the checks where a change is needed.

atrol

atrol

2023-10-09 16:16

developer   ~0068196

Last edited: 2023-10-09 16:50

@dregad, as 0032787:0068195 is a bit off-topic to the current issue and will introduce even more delay in getting out 2.26.0:
What about a quick workaround in 2.26.0 but implement the better check approach in 2.27.0? E. g. just move the email tests to the end of the tests?

dregad

dregad

2023-10-10 11:04

developer   ~0068198

I have opened 0033012 to track and follow-up on this so we can get it out of the way.

I'll see what's the best workaround - moving email to the end or maybe remove the if( $g_failed_test ) check.

atrol

atrol

2023-10-10 11:26

developer   ~0068199

or maybe remove the if( $g_failed_test ) check

I guess you mean remove all if( $g_failed_test ) checks, as removing one single check will not solve the issue.
Another idee for a quick workaround: set $g_failed_test = fallse after include( 'check_email_inc.php' );

dregad

dregad

2023-10-11 10:45

developer   ~0068202

Last edited: 2023-10-11 10:45

Right, it's a typo... I forgot the s, but you got the idea anyway ;-)

atrol

atrol

2023-10-14 14:51

developer   ~0068205

PR to allow failing email checks https://github.com/mantisbt/mantisbt/pull/1928

Related Changesets

MantisBT: master 3a87f5d9

2023-05-27 10:59

dregad


Details Diff
Add admin check to detect duplicate e-mails

When email_ensure_unique = ON, it is an error to have multiple user
accounts with the same email address in the database, which can happen
when this config's value is changed from OFF to ON.

This check facilitates identification of the offending accounts, helping
admins to fix them.

When email_ensure_unique = OFF, duplicates are shown as a warning, so
admins can anticipate problems when planning a switch to unique emails.

Fixes 0032787
Affected Issues
0032787
mod - admin/check/check_email_inc.php Diff File

MantisBT: master 94908539

2023-07-26 16:58

dregad


Details Diff
Fix query to find users with duplicate emails

With MySQL in only_full_group_by sql_mode, the query used in admin
checks to find users with duplicate emails (which was written and tested
with a PostgreSQL database) is throwing

ERROR 1055 (42000): Expression 0000001 of HAVING clause is not in GROUP BY
clause and contains nonaggregated column 'bugtracker.mantis_user_table.email'
which is not functionally dependent on columns in GROUP BY clause; this
is incompatible with sql_mode=only_full_group_by.

Adding a sub-query fixes the problem, and the updated query works fine
with PostgreSQL too (SQL Server and Oracle not tested).

Issue 0032787
Affected Issues
0032787
mod - admin/check/check_email_inc.php Diff File

MantisBT: master bf7a3c22

2023-07-26 17:22

dregad


Details Diff
Identify duplicated email addresses

When email_ensure_unique = ON, it is an error to have multiple user
accounts with the same email address in the database, which can happen
when this config's value is changed from OFF to ON.

This helps the admin identify offending accounts by displaying

- a warning sign next to the email address on Manage Accounts page
- warning + info message on Account Edit pages (both account_page.php
and manage_user_edit_page.php)

Fixes 0032787
Affected Issues
0032787
mod - account_page.php Diff File
mod - lang/strings_english.txt Diff File
mod - manage_user_edit_page.php Diff File
mod - manage_user_page.php Diff File

MantisBT: master 18ea9a43

2023-07-29 03:38

dregad


Details Diff
Documentation: identifying duplicate emails

Fixes 0032787
Affected Issues
0032787
mod - docbook/Admin_Guide/en-US/config/email.xml Diff File

MantisBT: master f5298f14

2023-07-29 09:47

dregad


Details Diff
Use db_get_table() in SQL for duplicated email check

Without this, the check would fail when using non-default database table
prefix/suffix.

Issue 0032787
Affected Issues
0032787
mod - admin/check/check_email_inc.php Diff File

MantisBT: master 8575f67f

2023-09-16 09:41

dregad


Details Diff
New user_get_duplicate_emails() function

Move the logic to identify duplicate e-mails used in the admin check to
user_api.php.

This allows a global approach to check for duplicate e-mail addresses,
which is more efficient than calling user_is_email_unique() many times
on a given page.

Issue 0032787
Affected Issues
0032787
mod - admin/check/check_email_inc.php Diff File
mod - core/user_api.php Diff File

MantisBT: master c1cbd1dc

2023-09-16 09:53

dregad


Details Diff
Improve output of duplicate e-mails admin check

Format as unordered list, add link to manage_user_edit_page.php.

Issue 0032787
Affected Issues
0032787
mod - admin/check/check_email_inc.php Diff File

MantisBT: master 3e93a75a

2023-09-16 10:03

dregad


Details Diff
Fix performance issue in manage_user_page.php

@atrol reported the problem in issue 0032787:68077, as the page took
approximately 3 seconds to load, vs 0.2 seconds before commit
d668192806a7457552229b1900f10d5e89ba6754.

Code now relies on user_get_duplicate_emails() to globally identify the
user accounts with duplicate e-mail addresses, instead of 50 individual
calls to user_get_duplicate_emails().

With this, the page loads under 0.5 seconds on mantisbt.org bugtracker,
vs 0000007:0000003 seconds before this change. This is still about twice as slow as
before d668192806a7457552229b1900f10d5e89ba6754, but I believe that's
acceptable for an admin page.

Fixes 0032787
Affected Issues
0032787
mod - manage_user_page.php Diff File

MantisBT: master c09dd014

2023-10-08 08:52

dregad


Details Diff
Fix incorrect case-insensitive check

Problem reported in @atrol's review
https://github.com/mantisbt/mantisbt/pull/1919#pullrequestreview-1629983973

Issue 0032787
Affected Issues
0032787
mod - core/user_api.php Diff File
mod - manage_user_page.php Diff File

MantisBT: master 7ffc863d

2023-10-14 14:38

atrol

Committer: dregad


Details Diff
Continue admin checks after failed email checks

Issue 0032787 introduces a new check for email addresses that can be hard
and time-consuming to fix when failing.

This change allows to run the remaining tests even if the email check
failed.

Signed-off-by: Damien Regad <dregad@mantisbt.org>

This is a temporary workaround that should be reverted when implementing
the fix for Issue 0033012. A @TODO comment was added in the code as a
reminder to do it when implementing a proper fix.

Initially submitted in PR https://github.com/mantisbt/mantisbt/pull/1928
(original commit message modified).
Affected Issues
0032787, 0033012
mod - admin/check/index.php Diff File