New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix unique email address handling #27652
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,7 @@ | |
use OCP\IConfig; | ||
use OCP\ILogger; | ||
use OCP\UserInterface; | ||
use Doctrine\DBAL\Exception\UniqueConstraintViolationException; | ||
|
||
/** | ||
* Class SyncService | ||
|
@@ -97,19 +98,46 @@ public function run(\Closure $callback) { | |
|
||
// update existing and insert new users | ||
foreach ($users as $uid) { | ||
$isNew = false; | ||
try { | ||
$a = $this->mapper->getByUid($uid); | ||
if ($a->getBackend() !== $this->backendClass) { | ||
$this->logger->debug("User <$uid> already provided by another backend({$a->getBackend()} != {$this->backendClass})"); | ||
continue; | ||
} | ||
$a = $this->setupAccount($a, $uid); | ||
$this->mapper->update($a); | ||
} catch(DoesNotExistException $ex) { | ||
} catch (DoesNotExistException $ex) { | ||
$isNew = true; | ||
$a = $this->createNewAccount($uid); | ||
$this->setupAccount($a, $uid); | ||
$this->mapper->insert($a); | ||
} | ||
|
||
do { | ||
$retry = false; | ||
try { | ||
if ($isNew) { | ||
$this->mapper->insert($a); | ||
} else { | ||
$this->mapper->update($a); | ||
} | ||
} catch (UniqueConstraintViolationException $ex) { | ||
// could be due to a duplicate email | ||
$email = $a->getEmail(); | ||
if ($email === null || $email === '') { | ||
// it's a different issue, rethrow | ||
throw $ex; | ||
} | ||
// find out if there is another account with the same email address | ||
$existingAccount = $this->mapper->getByEmail($email); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd fetch the accounts, check the number of accounts, and if it's only one then verify it's the same account or another account than the one we're trying to insert. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmmm... that could be another approach, yes. |
||
if (!$existingAccount) { | ||
// it's a different issue, rethrow | ||
throw $ex; | ||
} | ||
|
||
// it's a duplicate email, so clear the field and try again | ||
$a->setEmail(null); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❗️ Note that it will set an empty email instead of null in the DB, which will likely cause trouble. I'm affraid this could lead to an infinite loop if there are 3 or more users with the same email. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, I'll replace this to an empty string. Would that prevent the infinite loop ? When testing this worked for me with null, but better be safe. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think so. You'll be setting an empty email for the first duplicate; for the next duplicate you'll set another empty email causing another duplication exception because you've already set an empty email for another user. |
||
$retry = true; | ||
} | ||
} while ($retry); | ||
// clean the user's preferences | ||
$this->cleanPreferences($uid); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not convinced about these changes: if the plan is to support duplicated emails at some point, I think it's better to keep this as it is and handle the duplication at a higher level. As long as the callers are aware that several accounts can be returned by the same email, it should be fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not, see #27626 (comment).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@DeepDiver1975 your feedback ? This will tell whether to revert the above and use the below appraoch instead.