Skip to content

Commit 7669ff8

Browse files
committed
fix: primary email cannot be activated
* Primary email should be activated together with user account when 'RegisterEmailConfirm' is enabled. * To fix the existing error state. When 'RegisterEmailConfirm' is enabled, the admin should have permission to modify the activations status of user email. And the user should be allowed to send activation to primary email. * Only judge whether email is primary from email_address table. Signed-off-by: Meano <[email protected]>
1 parent 522b720 commit 7669ff8

File tree

5 files changed

+42
-38
lines changed

5 files changed

+42
-38
lines changed

models/user_mail.go

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -366,8 +366,8 @@ func SearchEmails(opts *SearchEmailOptions) ([]*SearchEmailResult, int64, error)
366366
}
367367

368368
// ActivateUserEmail will change the activated state of an email address,
369-
// either primary (in the user table) or secondary (in the email_address table)
370-
func ActivateUserEmail(userID int64, email string, primary, activate bool) (err error) {
369+
// either primary or secondary (all in the email_address table)
370+
func ActivateUserEmail(userID int64, email string, activate bool) (err error) {
371371
sess := x.NewSession()
372372
defer sess.Close()
373373
if err = sess.Begin(); err != nil {
@@ -397,24 +397,23 @@ func ActivateUserEmail(userID int64, email string, primary, activate bool) (err
397397
return fmt.Errorf("updateActivation(): %v", err)
398398
}
399399

400-
if primary {
401-
// Activate/deactivate a user's primary email address
400+
// Activate/deactivate a user's primary email address and account
401+
if addr.IsPrimary {
402402
user := User{ID: userID, Email: email}
403403
if has, err := sess.Get(&user); err != nil {
404404
return err
405405
} else if !has {
406406
return fmt.Errorf("no such user: %d (%s)", userID, email)
407407
}
408-
if user.IsActive == activate {
409-
// Already in the desired state; no action
410-
return nil
411-
}
412-
user.IsActive = activate
413-
if user.Rands, err = GetUserSalt(); err != nil {
414-
return fmt.Errorf("generate salt: %v", err)
415-
}
416-
if err = updateUserCols(sess, &user, "is_active", "rands"); err != nil {
417-
return fmt.Errorf("updateUserCols(): %v", err)
408+
// The user's activation state should synchronized with the primary email
409+
if user.IsActive != activate {
410+
user.IsActive = activate
411+
if user.Rands, err = GetUserSalt(); err != nil {
412+
return fmt.Errorf("generate salt: %v", err)
413+
}
414+
if err = updateUserCols(sess, &user, "is_active", "rands"); err != nil {
415+
return fmt.Errorf("updateUserCols(): %v", err)
416+
}
418417
}
419418
}
420419

routers/web/admin/emails.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,8 @@ func ActivateEmail(ctx *context.Context) {
125125

126126
log.Info("Changing activation for User ID: %d, email: %s, primary: %v to %v", uid, email, primary, activate)
127127

128-
if err := models.ActivateUserEmail(uid, email, primary, activate); err != nil {
129-
log.Error("ActivateUserEmail(%v,%v,%v,%v): %v", uid, email, primary, activate, err)
128+
if err := models.ActivateUserEmail(uid, email, activate); err != nil {
129+
log.Error("ActivateUserEmail(%v,%v,%v): %v", uid, email, activate, err)
130130
if models.IsErrEmailAlreadyUsed(err) {
131131
ctx.Flash.Error(ctx.Tr("admin.emails.duplicate_active"))
132132
} else {

routers/web/user/auth.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1429,6 +1429,10 @@ func handleAccountActivation(ctx *context.Context, user *models.User) {
14291429
return
14301430
}
14311431

1432+
if err := models.ActivateUserEmail(user.ID, user.Email, true); err != nil {
1433+
log.Error(fmt.Sprintf("Error active user mail: %v", err))
1434+
}
1435+
14321436
log.Trace("User activated: %s", user.Name)
14331437

14341438
if err := ctx.Session.Set("uid", user.ID); err != nil {

routers/web/user/setting/account.go

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -107,35 +107,36 @@ func EmailPost(ctx *context.Context) {
107107
ctx.Redirect(setting.AppSubURL + "/user/settings/account")
108108
return
109109
}
110-
if ctx.Query("id") == "PRIMARY" {
111-
if ctx.User.IsActive {
110+
111+
id := ctx.QueryInt64("id")
112+
email, err := models.GetEmailAddressByID(ctx.User.ID, id)
113+
if err != nil {
114+
log.Error("GetEmailAddressByID(%d,%d) error: %v", ctx.User.ID, id, err)
115+
ctx.Redirect(setting.AppSubURL + "/user/settings/account")
116+
return
117+
}
118+
if email == nil {
119+
log.Error("Send activation: EmailAddress not found; user:%d, id: %d", ctx.User.ID, id)
120+
ctx.Redirect(setting.AppSubURL + "/user/settings/account")
121+
return
122+
}
123+
if email.IsActivated {
124+
log.Error("Send activation: email not set for activation")
125+
ctx.Redirect(setting.AppSubURL + "/user/settings/account")
126+
return
127+
}
128+
if email.IsPrimary {
129+
if ctx.User.IsActive && !setting.Service.RegisterEmailConfirm {
112130
log.Error("Send activation: email not set for activation")
113131
ctx.Redirect(setting.AppSubURL + "/user/settings/account")
114132
return
115133
}
134+
// Only fired when the primary email is inactive (Wrong state)
116135
mailer.SendActivateAccountMail(ctx.Locale, ctx.User)
117-
address = ctx.User.Email
118136
} else {
119-
id := ctx.QueryInt64("id")
120-
email, err := models.GetEmailAddressByID(ctx.User.ID, id)
121-
if err != nil {
122-
log.Error("GetEmailAddressByID(%d,%d) error: %v", ctx.User.ID, id, err)
123-
ctx.Redirect(setting.AppSubURL + "/user/settings/account")
124-
return
125-
}
126-
if email == nil {
127-
log.Error("Send activation: EmailAddress not found; user:%d, id: %d", ctx.User.ID, id)
128-
ctx.Redirect(setting.AppSubURL + "/user/settings/account")
129-
return
130-
}
131-
if email.IsActivated {
132-
log.Error("Send activation: email not set for activation")
133-
ctx.Redirect(setting.AppSubURL + "/user/settings/account")
134-
return
135-
}
136137
mailer.SendActivateEmailMail(ctx.User, email)
137-
address = email.Email
138138
}
139+
address = email.Email
139140

140141
if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil {
141142
log.Error("Set cache(MailResendLimit) fail: %v", err)

templates/user/settings/account.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@
9292
<form action="{{AppSubUrl}}/user/settings/account/email" method="post">
9393
{{$.CsrfTokenHtml}}
9494
<input name="_method" type="hidden" value="SENDACTIVATION">
95-
<input name="id" type="hidden" value="{{if .IsPrimary}}PRIMARY{{else}}{{.ID}}{{end}}">
95+
<input name="id" type="hidden" value="{{.ID}}">
9696
{{if $.ActivationsPending}}
9797
<button disabled class="ui blue tiny button">{{$.i18n.Tr "settings.activations_pending"}}</button>
9898
{{else}}

0 commit comments

Comments
 (0)