Normally a user can only set an email as preferred email if this email
is assigned to the user's account via an external ID. Before invoking
the PutPreferred REST endpoint EmailsCollection verifies that the email
belongs to the user and rejects the request with 404 Not Found if not.
Whether an email belongs to a user is decided by the Realm. By default
Realm implementations (including DefaultRealm) check the external IDs of
the user account for this. However a realm may also consider additional
emails from external sources. If email assignments in the external
sources change over time it can happen that in Gerrit we get multiple
accounts with the same preferred email. This makes the preferred email
ambiguous. Ambigouos emails are OK for Gerrit but they are at least
confusing to users that use emails as account identifiers in the REST
API because Gerrit returns 404 Not Found if an account identifier is
ambiguous.
To prevent that this leads to multiple accounts with the same preferred
email we now make sure that an external ID for the preferred email
exists. If an external ID with the email doesn't exist yet but the realm
says that the email belongs to the user we now create a MAILTO external
ID with that email automatically unless the email is already assigned to
another account via an external ID. In the latter case we reject setting
the preferred email by returning 409 Conflict.
Note that with this change newly set preferred emails will now always
exactly match an email of the external IDs of the user (case-sensitive
match). Before it was possible to set a preferred email that was only a
case-insensitive match of an external ID email. If the given email only
has an case-insensitive match with an external ID email we now
automatically choose the correct case for setting the preferred email.
Change-Id: Icb6299b7fbceadb4029a7b645ddd65d096e1fe27
Signed-off-by: Edwin Kempin <ekempin@google.com>