Prevent NPE when cache service is disabled (#19703) (#19783)

Backport #19703

The cache service can be disabled - at which point ctx.Cache will be nil
and the use of it will cause an NPE.

The main part of this PR is that the cache is used for restricting
resending of activation mails and without this we cache we cannot
restrict this. Whilst this code could be re-considered to use the db and
probably should be, I think we can simply disable this code in the case
that the cache is disabled.

Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: Lauris BH <lauris@nix.lv>
This commit is contained in:
zeripath 2022-05-25 12:49:59 +01:00 committed by GitHub
parent 336e1ac779
commit ccc11c1e77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 18 deletions

View File

@ -417,7 +417,7 @@ func SignUp(ctx *context.Context) {
ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey
ctx.Data["PageIsSignUp"] = true ctx.Data["PageIsSignUp"] = true
//Show Disabled Registration message if DisableRegistration or AllowOnlyExternalRegistration options are true // Show Disabled Registration message if DisableRegistration or AllowOnlyExternalRegistration options are true
ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration || setting.Service.AllowOnlyExternalRegistration ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration || setting.Service.AllowOnlyExternalRegistration
ctx.HTML(http.StatusOK, tplSignUp) ctx.HTML(http.StatusOK, tplSignUp)
@ -438,7 +438,7 @@ func SignUpPost(ctx *context.Context) {
ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey
ctx.Data["PageIsSignUp"] = true ctx.Data["PageIsSignUp"] = true
//Permission denied if DisableRegistration or AllowOnlyExternalRegistration options are true // Permission denied if DisableRegistration or AllowOnlyExternalRegistration options are true
if setting.Service.DisableRegistration || setting.Service.AllowOnlyExternalRegistration { if setting.Service.DisableRegistration || setting.Service.AllowOnlyExternalRegistration {
ctx.Error(http.StatusForbidden) ctx.Error(http.StatusForbidden)
return return
@ -632,8 +632,10 @@ func handleUserCreated(ctx *context.Context, u *user_model.User, gothUser *goth.
ctx.Data["ActiveCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language()) ctx.Data["ActiveCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language())
ctx.HTML(http.StatusOK, TplActivate) ctx.HTML(http.StatusOK, TplActivate)
if err := ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil { if setting.CacheService.Enabled {
log.Error("Set cache(MailResendLimit) fail: %v", err) if err := ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil {
log.Error("Set cache(MailResendLimit) fail: %v", err)
}
} }
return return
} }
@ -653,14 +655,15 @@ func Activate(ctx *context.Context) {
} }
// Resend confirmation email. // Resend confirmation email.
if setting.Service.RegisterEmailConfirm { if setting.Service.RegisterEmailConfirm {
if ctx.Cache.IsExist("MailResendLimit_" + ctx.User.LowerName) { if setting.CacheService.Enabled && ctx.Cache.IsExist("MailResendLimit_"+ctx.User.LowerName) {
ctx.Data["ResendLimited"] = true ctx.Data["ResendLimited"] = true
} else { } else {
ctx.Data["ActiveCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language()) ctx.Data["ActiveCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language())
mailer.SendActivateAccountMail(ctx.Locale, ctx.User) mailer.SendActivateAccountMail(ctx.Locale, ctx.User)
if setting.CacheService.Enabled {
if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil { if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil {
log.Error("Set cache(MailResendLimit) fail: %v", err) log.Error("Set cache(MailResendLimit) fail: %v", err)
}
} }
} }
} else { } else {
@ -789,7 +792,7 @@ func ActivateEmail(ctx *context.Context) {
if u, err := user_model.GetUserByID(email.UID); err != nil { if u, err := user_model.GetUserByID(email.UID); err != nil {
log.Warn("GetUserByID: %d", email.UID) log.Warn("GetUserByID: %d", email.UID)
} else { } else if setting.CacheService.Enabled {
// Allow user to validate more emails // Allow user to validate more emails
_ = ctx.Cache.Delete("MailResendLimit_" + u.LowerName) _ = ctx.Cache.Delete("MailResendLimit_" + u.LowerName)
} }

View File

@ -80,7 +80,7 @@ func ForgotPasswdPost(ctx *context.Context) {
return return
} }
if ctx.Cache.IsExist("MailResendLimit_" + u.LowerName) { if setting.CacheService.Enabled && ctx.Cache.IsExist("MailResendLimit_"+u.LowerName) {
ctx.Data["ResendLimited"] = true ctx.Data["ResendLimited"] = true
ctx.HTML(http.StatusOK, tplForgotPassword) ctx.HTML(http.StatusOK, tplForgotPassword)
return return
@ -88,8 +88,10 @@ func ForgotPasswdPost(ctx *context.Context) {
mailer.SendResetPasswordMail(u) mailer.SendResetPasswordMail(u)
if err = ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil { if setting.CacheService.Enabled {
log.Error("Set cache(MailResendLimit) fail: %v", err) if err = ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil {
log.Error("Set cache(MailResendLimit) fail: %v", err)
}
} }
ctx.Data["ResetPwdCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ResetPwdCodeLives, ctx.Locale.Language()) ctx.Data["ResetPwdCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ResetPwdCodeLives, ctx.Locale.Language())

View File

@ -106,7 +106,7 @@ func EmailPost(ctx *context.Context) {
// Send activation Email // Send activation Email
if ctx.FormString("_method") == "SENDACTIVATION" { if ctx.FormString("_method") == "SENDACTIVATION" {
var address string var address string
if ctx.Cache.IsExist("MailResendLimit_" + ctx.User.LowerName) { if setting.CacheService.Enabled && ctx.Cache.IsExist("MailResendLimit_"+ctx.User.LowerName) {
log.Error("Send activation: activation still pending") log.Error("Send activation: activation still pending")
ctx.Redirect(setting.AppSubURL + "/user/settings/account") ctx.Redirect(setting.AppSubURL + "/user/settings/account")
return return
@ -142,8 +142,10 @@ func EmailPost(ctx *context.Context) {
} }
address = email.Email address = email.Email
if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil { if setting.CacheService.Enabled {
log.Error("Set cache(MailResendLimit) fail: %v", err) if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil {
log.Error("Set cache(MailResendLimit) fail: %v", err)
}
} }
ctx.Flash.Info(ctx.Tr("settings.add_email_confirmation_sent", address, timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language()))) ctx.Flash.Info(ctx.Tr("settings.add_email_confirmation_sent", address, timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language())))
ctx.Redirect(setting.AppSubURL + "/user/settings/account") ctx.Redirect(setting.AppSubURL + "/user/settings/account")
@ -202,8 +204,10 @@ func EmailPost(ctx *context.Context) {
// Send confirmation email // Send confirmation email
if setting.Service.RegisterEmailConfirm { if setting.Service.RegisterEmailConfirm {
mailer.SendActivateEmailMail(ctx.User, email) mailer.SendActivateEmailMail(ctx.User, email)
if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil { if setting.CacheService.Enabled {
log.Error("Set cache(MailResendLimit) fail: %v", err) if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil {
log.Error("Set cache(MailResendLimit) fail: %v", err)
}
} }
ctx.Flash.Info(ctx.Tr("settings.add_email_confirmation_sent", email.Email, timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language()))) ctx.Flash.Info(ctx.Tr("settings.add_email_confirmation_sent", email.Email, timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language())))
} else { } else {
@ -271,7 +275,7 @@ func loadAccountData(ctx *context.Context) {
user_model.EmailAddress user_model.EmailAddress
CanBePrimary bool CanBePrimary bool
} }
pendingActivation := ctx.Cache.IsExist("MailResendLimit_" + ctx.User.LowerName) pendingActivation := setting.CacheService.Enabled && ctx.Cache.IsExist("MailResendLimit_"+ctx.User.LowerName)
emails := make([]*UserEmail, len(emlist)) emails := make([]*UserEmail, len(emlist))
for i, em := range emlist { for i, em := range emlist {
var email UserEmail var email UserEmail