Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Always store primary email address into email_address table and also …
…the state
  • Loading branch information
lunny committed Jun 8, 2021
commit 2180ed11f62db6dbfa7f95b27b0a7e4c5a54b564
15 changes: 15 additions & 0 deletions models/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,21 @@ func (err ErrEmailAddressNotExist) Error() string {
return fmt.Sprintf("Email address does not exist [email: %s]", err.Email)
}

// ErrPrimaryEmailCannotDelete primary email address cannot be deleted
type ErrPrimaryEmailCannotDelete struct {
Email string
}

// IsErrPrimaryEmailCannotDelete checks if an error is an ErrPrimaryEmailCannotDelete
func IsErrPrimaryEmailCannotDelete(err error) bool {
_, ok := err.(ErrPrimaryEmailCannotDelete)
return ok
}

func (err ErrPrimaryEmailCannotDelete) Error() string {
return fmt.Sprintf("Primary email address cannot be deleted [email: %s]", err.Email)
}

// ErrOpenIDAlreadyUsed represents a "OpenIDAlreadyUsed" kind of error.
type ErrOpenIDAlreadyUsed struct {
OpenID string
Expand Down
2 changes: 2 additions & 0 deletions models/migrations/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,8 @@ var migrations = []Migration{
NewMigration("Convert avatar url to text", convertAvatarURLToText),
// v180 -> v181
NewMigration("Delete credentials from past migrations", deleteMigrationCredentials),
// v181 -> v182
NewMigration("Always save primary email on email address table", addPrimaryEmail2EmailAddress),
}

// GetCurrentDBVersion returns the current db version
Expand Down
74 changes: 74 additions & 0 deletions models/migrations/v181.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package migrations

import (
"xorm.io/xorm"
)

func addPrimaryEmail2EmailAddress(x *xorm.Engine) (err error) {
type User struct {
ID int64 `xorm:"pk autoincr"`
Email string `xorm:"NOT NULL"`
IsActive bool `xorm:"INDEX"` // Activate primary email
}

type EmailAddress struct {
ID int64 `xorm:"pk autoincr"`
UID int64 `xorm:"INDEX NOT NULL"`
Email string `xorm:"UNIQUE NOT NULL"`
IsActivated bool
IsPrimary bool `xorm:"DEFAULT(false) NOT NULL"`
}

// Add is_primary column
if err = x.Sync2(new(EmailAddress)); err != nil {
return
}

if _, err = x.Exec("UPDATE email_address SET is_primary=? WHERE is_primary IS NULL", false); err != nil {
return
}

sess := x.NewSession()
defer sess.Close()

const batchSize = 100

for start := 0; ; start += batchSize {
users := make([]*User, 0, batchSize)
if err = sess.Limit(batchSize, start).Find(&users); err != nil {
return
}
if len(users) == 0 {
break
}

for _, user := range users {
var exist bool
exist, err = sess.Where("email=?", user.Email).Table("email_address").Exist()
if err != nil {
return
}
if !exist {
if _, err = sess.Insert(&EmailAddress{
UID: user.ID,
Email: user.Email,
IsActivated: user.IsActive,
IsPrimary: true,
}); err != nil {
return
}
} else {
if _, err = sess.Where("email=?", user.Email).Cols("is_primary").Update(&EmailAddress{
IsPrimary: true,
}); err != nil {
return
}
}
}
}
return nil
}
20 changes: 8 additions & 12 deletions models/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,6 @@ const (
)

var (
// ErrEmailNotExist e-mail does not exist error
ErrEmailNotExist = errors.New("E-mail does not exist")

// ErrEmailNotActivated e-mail address has not been activated error
ErrEmailNotActivated = errors.New("E-mail address has not been activated")

Expand Down Expand Up @@ -876,15 +873,6 @@ func CreateUser(u *User) (err error) {
}

u.Email = strings.ToLower(u.Email)
isExist, err = sess.
Where("email=?", u.Email).
Get(new(User))
if err != nil {
return err
} else if isExist {
return ErrEmailAlreadyUsed{u.Email}
}

if err = ValidateEmail(u.Email); err != nil {
return err
}
Expand Down Expand Up @@ -915,6 +903,14 @@ func CreateUser(u *User) (err error) {
return err
}

// insert email address
if _, err := sess.Insert(&EmailAddress{
UID: u.ID,
Email: u.Email,
}); err != nil {
return err
}

return sess.Commit()
}

Expand Down
Loading