*: add migration to convert all emails to lowercase

Fixes #338
This commit is contained in:
Eric Chiang 2016-03-01 10:51:50 -08:00
parent 118bbb6d18
commit 9bc68edae7
3 changed files with 23 additions and 3 deletions

View file

@ -0,0 +1,18 @@
-- +migrate Up
CREATE OR REPLACE FUNCTION raise_exp() RETURNS VOID AS $$
BEGIN
RAISE EXCEPTION 'Found duplicate emails when using case insensitive comparision, cannot perform migration.';
END;
$$ LANGUAGE plpgsql;
SELECT LOWER(email),
COUNT(email),
CASE
WHEN COUNT(email) > 1 THEN raise_exp()
ELSE NULL
END
FROM authd_user
GROUP BY LOWER(email);
UPDATE authd_user SET email = LOWER(email);

View file

@ -5,6 +5,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"reflect" "reflect"
"strings"
"time" "time"
"github.com/go-gorp/gorp" "github.com/go-gorp/gorp"
@ -400,7 +401,7 @@ func (r *userRepo) getByEmail(tx repo.Transaction, email string) (user.User, err
qt := r.quote(userTableName) qt := r.quote(userTableName)
ex := r.executor(tx) ex := r.executor(tx)
var um userModel var um userModel
err := ex.SelectOne(&um, fmt.Sprintf("select * from %s where email = $1", qt), email) err := ex.SelectOne(&um, fmt.Sprintf("select * from %s where email = $1", qt), strings.ToLower(email))
if err != nil { if err != nil {
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
@ -424,7 +425,7 @@ func (r *userRepo) insertRemoteIdentity(tx repo.Transaction, userID string, ri u
type userModel struct { type userModel struct {
ID string `db:"id"` ID string `db:"id"`
Email string `db:"email"` Email string `db:"email"` // NOTE(ericchiang): When making comparisions emails are case insensitive.
EmailVerified bool `db:"email_verified"` EmailVerified bool `db:"email_verified"`
DisplayName string `db:"display_name"` DisplayName string `db:"display_name"`
Disabled bool `db:"disabled"` Disabled bool `db:"disabled"`
@ -453,7 +454,7 @@ func newUserModel(u *user.User) (*userModel, error) {
um := userModel{ um := userModel{
ID: u.ID, ID: u.ID,
DisplayName: u.DisplayName, DisplayName: u.DisplayName,
Email: u.Email, Email: strings.ToLower(u.Email),
EmailVerified: u.EmailVerified, EmailVerified: u.EmailVerified,
Admin: u.Admin, Admin: u.Admin,
Disabled: u.Disabled, Disabled: u.Disabled,

View file

@ -105,6 +105,7 @@ func (u *User) AddToClaims(claims jose.Claims) {
// UserRepo implementations maintain a persistent set of users. // UserRepo implementations maintain a persistent set of users.
// The following invariants must be maintained: // The following invariants must be maintained:
// * Users must have a unique Email and ID // * Users must have a unique Email and ID
// * Emails are case insensitive.
// * No other Users may have the same RemoteIdentity as one of the // * No other Users may have the same RemoteIdentity as one of the
// users. (This constraint may be relaxed in the future) // users. (This constraint may be relaxed in the future)
type UserRepo interface { type UserRepo interface {