Auth: Fix email verification bypass when using basic authentication (#82914)

This commit is contained in:
Xavi Lacasa
2024-02-16 18:54:59 +01:00
committed by GitHub
parent fabaff9a24
commit 46c26bbd0b
27 changed files with 1403 additions and 22 deletions
+24 -4
View File
@@ -2,13 +2,17 @@ package notifications
import (
"context"
"github.com/grafana/grafana/pkg/services/user"
)
type NotificationServiceMock struct {
Webhook SendWebhookSync
EmailSync SendEmailCommandSync
Email SendEmailCommand
ShouldError error
Webhook SendWebhookSync
EmailSync SendEmailCommandSync
Email SendEmailCommand
EmailVerified bool
EmailVerification SendVerifyEmailCommand
ShouldError error
WebhookHandler func(context.Context, *SendWebhookSync) error
EmailHandlerSync func(context.Context, *SendEmailCommandSync) error
@@ -39,4 +43,20 @@ func (ns *NotificationServiceMock) SendEmailCommandHandler(ctx context.Context,
return ns.ShouldError
}
func (ns *NotificationServiceMock) SendResetPasswordEmail(ctx context.Context, cmd *SendResetPasswordEmailCommand) error {
// TODO: Implement if needed
return ns.ShouldError
}
func (ns *NotificationServiceMock) ValidateResetPasswordCode(ctx context.Context, query *ValidateResetPasswordCodeQuery, userByLogin GetUserByLoginFunc) (*user.User, error) {
// TODO: Implement if needed
return nil, ns.ShouldError
}
func (ns *NotificationServiceMock) SendVerificationEmail(ctx context.Context, cmd *SendVerifyEmailCommand) error {
ns.EmailVerified = true
ns.EmailVerification = *cmd
return ns.ShouldError
}
func MockNotificationService() *NotificationServiceMock { return &NotificationServiceMock{} }
+6
View File
@@ -51,3 +51,9 @@ type SendResetPasswordEmailCommand struct {
type ValidateResetPasswordCodeQuery struct {
Code string
}
type SendVerifyEmailCommand struct {
User *user.User
Code string
Email string
}
@@ -28,15 +28,25 @@ type EmailSender interface {
SendEmailCommandHandlerSync(ctx context.Context, cmd *SendEmailCommandSync) error
SendEmailCommandHandler(ctx context.Context, cmd *SendEmailCommand) error
}
type PasswordResetMailer interface {
SendResetPasswordEmail(ctx context.Context, cmd *SendResetPasswordEmailCommand) error
ValidateResetPasswordCode(ctx context.Context, query *ValidateResetPasswordCodeQuery, userByLogin GetUserByLoginFunc) (*user.User, error)
}
type EmailVerificationMailer interface {
SendVerificationEmail(ctx context.Context, cmd *SendVerifyEmailCommand) error
}
type Service interface {
WebhookSender
EmailSender
PasswordResetMailer
EmailVerificationMailer
}
var mailTemplates *template.Template
var tmplResetPassword = "reset_password"
var tmplSignUpStarted = "signup_started"
var tmplWelcomeOnSignUp = "welcome_on_signup"
var tmplVerifyEmail = "verify_email_update"
func ProvideService(bus bus.Bus, cfg *setting.Cfg, mailer Mailer, store TempUserStore) (*NotificationService, error) {
ns := &NotificationService{
@@ -257,6 +267,20 @@ func (ns *NotificationService) ValidateResetPasswordCode(ctx context.Context, qu
return user, nil
}
func (ns *NotificationService) SendVerificationEmail(ctx context.Context, cmd *SendVerifyEmailCommand) error {
return ns.SendEmailCommandHandlerSync(ctx, &SendEmailCommandSync{
SendEmailCommand: SendEmailCommand{
To: []string{cmd.Email},
Template: tmplVerifyEmail,
Data: map[string]any{
"Code": url.QueryEscape(cmd.Code),
"Name": cmd.User.Name,
"VerificationEmailLifetimeHours": int(ns.Cfg.VerificationEmailMaxLifetime.Hours()),
},
},
})
}
func (ns *NotificationService) signUpStartedHandler(ctx context.Context, evt *events.SignUpStarted) error {
if !ns.Cfg.VerifyEmailEnabled {
return nil