From 468387e9ced12367aecc8b863e20e105fbdd0c82 Mon Sep 17 00:00:00 2001 From: zeripath Date: Sat, 21 May 2022 15:29:49 +0100 Subject: [PATCH] Prevent NPE when cache service is disabled (#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. There are also several bug fixes in the /nodeinfo API endpoint. Signed-off-by: Andrew Thornton --- routers/web/auth/auth.go | 16 ++++++++++------ routers/web/auth/password.go | 8 +++++--- routers/web/user/setting/account.go | 16 ++++++++++------ 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/routers/web/auth/auth.go b/routers/web/auth/auth.go index 4d5a2c93357..ea5c7232a8a 100644 --- a/routers/web/auth/auth.go +++ b/routers/web/auth/auth.go @@ -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.HTML(http.StatusOK, TplActivate) - if err := ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil { - log.Error("Set cache(MailResendLimit) fail: %v", err) + if setting.CacheService.Enabled { + if err := ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil { + log.Error("Set cache(MailResendLimit) fail: %v", err) + } } return } @@ -653,14 +655,16 @@ func Activate(ctx *context.Context) { } // Resend confirmation email. if setting.Service.RegisterEmailConfirm { - if ctx.Cache.IsExist("MailResendLimit_" + ctx.Doer.LowerName) { + if setting.CacheService.Enabled && ctx.Cache.IsExist("MailResendLimit_"+ctx.Doer.LowerName) { ctx.Data["ResendLimited"] = true } else { ctx.Data["ActiveCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language()) mailer.SendActivateAccountMail(ctx.Locale, ctx.Doer) - if err := ctx.Cache.Put("MailResendLimit_"+ctx.Doer.LowerName, ctx.Doer.LowerName, 180); err != nil { - log.Error("Set cache(MailResendLimit) fail: %v", err) + if setting.CacheService.Enabled { + if err := ctx.Cache.Put("MailResendLimit_"+ctx.Doer.LowerName, ctx.Doer.LowerName, 180); err != nil { + log.Error("Set cache(MailResendLimit) fail: %v", err) + } } } } else { @@ -789,7 +793,7 @@ func ActivateEmail(ctx *context.Context) { if u, err := user_model.GetUserByID(email.UID); err != nil { log.Warn("GetUserByID: %d", email.UID) - } else { + } else if setting.CacheService.Enabled { // Allow user to validate more emails _ = ctx.Cache.Delete("MailResendLimit_" + u.LowerName) } diff --git a/routers/web/auth/password.go b/routers/web/auth/password.go index d7bf67cffb6..06ccd2e76f7 100644 --- a/routers/web/auth/password.go +++ b/routers/web/auth/password.go @@ -79,7 +79,7 @@ func ForgotPasswdPost(ctx *context.Context) { return } - if ctx.Cache.IsExist("MailResendLimit_" + u.LowerName) { + if setting.CacheService.Enabled && ctx.Cache.IsExist("MailResendLimit_"+u.LowerName) { ctx.Data["ResendLimited"] = true ctx.HTML(http.StatusOK, tplForgotPassword) return @@ -87,8 +87,10 @@ func ForgotPasswdPost(ctx *context.Context) { mailer.SendResetPasswordMail(u) - if err = ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil { - log.Error("Set cache(MailResendLimit) fail: %v", err) + if setting.CacheService.Enabled { + 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()) diff --git a/routers/web/user/setting/account.go b/routers/web/user/setting/account.go index 92f6c9a183d..3e96cc7c852 100644 --- a/routers/web/user/setting/account.go +++ b/routers/web/user/setting/account.go @@ -105,7 +105,7 @@ func EmailPost(ctx *context.Context) { // Send activation Email if ctx.FormString("_method") == "SENDACTIVATION" { var address string - if ctx.Cache.IsExist("MailResendLimit_" + ctx.Doer.LowerName) { + if setting.CacheService.Enabled && ctx.Cache.IsExist("MailResendLimit_"+ctx.Doer.LowerName) { log.Error("Send activation: activation still pending") ctx.Redirect(setting.AppSubURL + "/user/settings/account") return @@ -141,8 +141,10 @@ func EmailPost(ctx *context.Context) { } address = email.Email - if err := ctx.Cache.Put("MailResendLimit_"+ctx.Doer.LowerName, ctx.Doer.LowerName, 180); err != nil { - log.Error("Set cache(MailResendLimit) fail: %v", err) + if setting.CacheService.Enabled { + if err := ctx.Cache.Put("MailResendLimit_"+ctx.Doer.LowerName, ctx.Doer.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.Redirect(setting.AppSubURL + "/user/settings/account") @@ -201,8 +203,10 @@ func EmailPost(ctx *context.Context) { // Send confirmation email if setting.Service.RegisterEmailConfirm { mailer.SendActivateEmailMail(ctx.Doer, email) - if err := ctx.Cache.Put("MailResendLimit_"+ctx.Doer.LowerName, ctx.Doer.LowerName, 180); err != nil { - log.Error("Set cache(MailResendLimit) fail: %v", err) + if setting.CacheService.Enabled { + if err := ctx.Cache.Put("MailResendLimit_"+ctx.Doer.LowerName, ctx.Doer.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()))) } else { @@ -273,7 +277,7 @@ func loadAccountData(ctx *context.Context) { user_model.EmailAddress CanBePrimary bool } - pendingActivation := ctx.Cache.IsExist("MailResendLimit_" + ctx.Doer.LowerName) + pendingActivation := setting.CacheService.Enabled && ctx.Cache.IsExist("MailResendLimit_"+ctx.Doer.LowerName) emails := make([]*UserEmail, len(emlist)) for i, em := range emlist { var email UserEmail