-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
Ensure user email is always in email address table #13296
Changes from 11 commits
e9d0455
111e507
e259244
77cd657
d2d2479
bdd4bc2
c220b5e
38901cf
4de7015
d2cc31c
cf397c2
987a843
daa11e6
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 |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// Copyright 2020 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 ( | ||
"code.gitea.io/gitea/modules/log" | ||
|
||
"xorm.io/xorm" | ||
) | ||
|
||
func addUserPrimaryEmailToUserMails(x *xorm.Engine) error { | ||
type User struct { | ||
ID int64 `xorm:"pk autoincr"` | ||
Email string `xorm:"NOT NULL"` | ||
IsActive bool `xorm:"INDEX"` | ||
} | ||
type EmailAddress struct { | ||
ID int64 `xorm:"pk autoincr"` | ||
UID int64 `xorm:"INDEX NOT NULL"` | ||
Email string `xorm:"UNIQUE NOT NULL"` | ||
IsActivated bool | ||
} | ||
|
||
if err := x.Sync2(new(User), new(EmailAddress)); err != nil { | ||
return err | ||
} | ||
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 it's necessary, because you haven't changeed the struct of them. 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. Got it, my bad, just read some other migrations and I thought it was required. |
||
|
||
updateUsers := func(users []*User) error { | ||
sess := x.NewSession() | ||
defer sess.Close() | ||
if err := sess.Begin(); err != nil { | ||
return err | ||
} | ||
for _, user := range users { | ||
email := new(EmailAddress) | ||
if isExist, err := sess.Where("email=?", user.Email).Get(email); err != nil { | ||
return err | ||
} else if isExist { | ||
if email.UID != user.ID { | ||
log.Warn("Email (%s) from user with ID %d is taken by user with ID %d", email.Email, user.ID, email.UID) | ||
log.Warn("Skipping to avoid conflicts, should be manually fixed") | ||
} | ||
continue | ||
} | ||
email = &EmailAddress{ | ||
Email: user.Email, | ||
UID: user.ID, | ||
IsActivated: user.IsActive, | ||
} | ||
if _, err := sess.Insert(email); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
return sess.Commit() | ||
} | ||
|
||
var start = 0 | ||
var batchSize = 100 | ||
for { | ||
var users = make([]*User, 0, batchSize) | ||
if err := x.Limit(batchSize, start).Find(&users); err != nil { | ||
return err | ||
} | ||
|
||
if err := updateUsers(users); err != nil { | ||
return err | ||
} | ||
|
||
start += len(users) | ||
|
||
if len(users) < batchSize { | ||
break | ||
} | ||
} | ||
|
||
return nil | ||
} |
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.
why change ?
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.
Because in the
email_1ddress.yml
fixtures, theuser11@example.com
is registered touser1
, and changing that file rather than this, brings more issues and places where it should be updated (I initially went through that route with commits bdd4bc2 and 77cd657), and decided later that the minimal impact would be to update the email address here.