forked from mystiq/dex
parent
118bbb6d18
commit
9bc68edae7
3 changed files with 23 additions and 3 deletions
18
db/migrations/0011_case_insensitive_emails.sql
Normal file
18
db/migrations/0011_case_insensitive_emails.sql
Normal 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);
|
|
@ -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,
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue