From 4c6be5cf543c1c28a2e9f61497c24623c6a589b1 Mon Sep 17 00:00:00 2001 From: kekskurse Date: Thu, 13 Mar 2025 23:01:59 +0100 Subject: [PATCH] chore: add mail check --- pkg/miniauth/error.go | 1 + pkg/miniauth/miniauth.go | 17 ++++++++++++++- pkg/miniauth/miniauth_test.go | 28 ++++++++++++++++++++++++- pkg/smtpclient/smtpclient.go | 12 +++++++++++ pkg/userstore/mail.go | 17 +++++++++++++++ pkg/userstore/mail_test.go | 39 +++++++++++++++++++++++++++++++++++ 6 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 pkg/smtpclient/smtpclient.go diff --git a/pkg/miniauth/error.go b/pkg/miniauth/error.go index 0a79738..e3b8aaf 100644 --- a/pkg/miniauth/error.go +++ b/pkg/miniauth/error.go @@ -8,4 +8,5 @@ var ( ErrPasswordNotComplexEnough = errors.New("password not complex enough") ErrMailAddressInvalide = errors.New("email address invalide") ErrCantCreateUser = errors.New("cant create user") + ErrCantSendMail = errors.New("cant send mail") ) diff --git a/pkg/miniauth/miniauth.go b/pkg/miniauth/miniauth.go index c4b915f..7879701 100644 --- a/pkg/miniauth/miniauth.go +++ b/pkg/miniauth/miniauth.go @@ -1,9 +1,11 @@ package miniauth import ( + "errors" "net/mail" "regexp" + "git.keks.cloud/kekskurse/miniauth/pkg/smtpclient" "git.keks.cloud/kekskurse/miniauth/pkg/userstore" "git.keks.cloud/kekskurse/miniauth/pkg/utils" "github.com/go-passwd/validator" @@ -13,6 +15,7 @@ import ( type Miniauth struct { store userstore.Store log zerolog.Logger + smtp smtpclient.SMTPClient } func NewMiniauth(us userstore.Store) Miniauth { @@ -38,6 +41,15 @@ func (m Miniauth) RegisterUser(username string, email string, password string) e return utils.WrapError(ErrMailAddressInvalide, err, log) } + used, err := m.store.MailCheckExists(email) + if err != nil { + return utils.WrapError(ErrMailAddressInvalide, err, log) + } + + if used { + return utils.WrapError(ErrMailAddressInvalide, errors.New("email alreadys used"), log) + } + id, err := m.store.UserWrite(username, password) if err != nil { return utils.WrapError(ErrCantCreateUser, err, log) @@ -50,7 +62,10 @@ func (m Miniauth) RegisterUser(username string, email string, password string) e return utils.WrapError(ErrCantCreateUser, err, log) } - // TODO Send mail + err = m.smtp.SendMail("register", email, map[string]any{"hash": "abc"}) + if err != nil { + return utils.WrapError(ErrCantSendMail, err, log) + } return nil } diff --git a/pkg/miniauth/miniauth_test.go b/pkg/miniauth/miniauth_test.go index 8e9af07..04eb054 100644 --- a/pkg/miniauth/miniauth_test.go +++ b/pkg/miniauth/miniauth_test.go @@ -40,6 +40,30 @@ func TestRegistration(t *testing.T) { exptErr: ErrMailAddressInvalide, exptErrString: "email address invalide: mail: missing '@' or angle-addr", }, + { + name: "invaloid password", + username: "kekskurse", + password: "abc123d,.,jfhfh", + mail: "error@error.error", + exptErr: ErrCantSendMail, + exptErrString: "cant send mail: error mail send", + }, + { + name: "success", + username: "someuser", + password: "abc123d,.,jfhfh", + mail: "hello@example.com", + exptErr: nil, + exptErrString: "", + }, + { + name: "mail already used", + username: "someuser2", + password: "abc123d,.,jfhfh", + mail: "hello@example.com", + exptErr: ErrMailAddressInvalide, + exptErrString: "email address invalide: email alreadys used", + }, } ma := getMiniAuth(t) @@ -47,7 +71,9 @@ func TestRegistration(t *testing.T) { t.Run(tt.name, func(t *testing.T) { err := ma.RegisterUser(tt.username, tt.mail, tt.password) assert.ErrorIs(t, err, tt.exptErr) - assert.Equal(t, tt.exptErrString, err.Error()) + if tt.exptErrString != "" { + assert.Equal(t, tt.exptErrString, err.Error()) + } }) } } diff --git a/pkg/smtpclient/smtpclient.go b/pkg/smtpclient/smtpclient.go new file mode 100644 index 0000000..dadb63c --- /dev/null +++ b/pkg/smtpclient/smtpclient.go @@ -0,0 +1,12 @@ +package smtpclient + +import "errors" + +type SMTPClient struct{} + +func (s SMTPClient) SendMail(templateName string, to string, data any) error { + if to == "error@error.error" { + return errors.New("error mail send") + } + return nil +} diff --git a/pkg/userstore/mail.go b/pkg/userstore/mail.go index d95dea5..6d5db3b 100644 --- a/pkg/userstore/mail.go +++ b/pkg/userstore/mail.go @@ -17,3 +17,20 @@ func (s Store) MailAdd(mail string, userID int64, primary bool) error { return nil } + +func (s Store) MailCheckExists(email string) (bool, error) { + query := "SELECT COUNT(*) FROM mail WHERE mail = ?" + log := s.log.With().Str("func", "MailCheckExists").Str("email", email).Str("query", query).Logger() + + var count int + err := s.db.QueryRow(query, email).Scan(&count) + if err != nil { + return true, utils.WrapError(ErrCantExecuteQuery, err, log) + } + + if count > 0 { + return true, nil + } + + return false, nil +} diff --git a/pkg/userstore/mail_test.go b/pkg/userstore/mail_test.go index b5377de..000b1ac 100644 --- a/pkg/userstore/mail_test.go +++ b/pkg/userstore/mail_test.go @@ -6,6 +6,45 @@ import ( "github.com/stretchr/testify/assert" ) +func TestCheckMailExist(t *testing.T) { + store, err := NewDummyStore() + assert.Nil(t, err, "[setup] should be abel to create dummystore") + + id, err := store.UserWrite("foo", "foo") + assert.Nil(t, err, "[setup] should be abel to create user") + + err = store.MailAdd("mail@kekskurse.de", id, false) + assert.Nil(t, err, "[setup] should be abel to add mail") + + _, err = store.db.Exec("UPDATE mail SET is_validated = 1 WHERE mail = ?", "mail@kekskurse.de") + assert.Nil(t, err) + + tts := []struct { + name string + mail string + used bool + }{ + { + name: "mail addresse unused", + mail: "foo@bar.de", + used: false, + }, + { + name: "mail address used", + mail: "mail@kekskurse.de", + used: true, + }, + } + + for _, tt := range tts { + t.Run(tt.name, func(t *testing.T) { + used, err := store.MailCheckExists(tt.mail) + assert.Nil(t, err) + assert.Equal(t, tt.used, used) + }) + } +} + func TestAddMail(t *testing.T) { store, err := NewDummyStore() assert.Nil(t, err, "[setup] should be abel to create dummystore")