aboutsummaryrefslogtreecommitdiff
path: root/internal/route
diff options
context:
space:
mode:
authorJoe Chen <jc@unknwon.io>2023-05-14 20:15:47 -0400
committerGitHub <noreply@github.com>2023-05-14 20:15:47 -0400
commit0721ef2399c7c0e7f01ee96530b99f883434c623 (patch)
tree8ddb3e5002ab0b7402a6339c7781d91caebd96e7 /internal/route
parent9ac93067f640ca228ff218de1686ff61e8747d05 (diff)
refactor(db): migrate off `user_email.go` to `users.go` (#7452)
Diffstat (limited to 'internal/route')
-rw-r--r--internal/route/api/v1/user/email.go60
-rw-r--r--internal/route/lfs/mocks_test.go754
-rw-r--r--internal/route/user/auth.go6
-rw-r--r--internal/route/user/setting.go37
4 files changed, 804 insertions, 53 deletions
diff --git a/internal/route/api/v1/user/email.go b/internal/route/api/v1/user/email.go
index cda2a0a4..b85d424a 100644
--- a/internal/route/api/v1/user/email.go
+++ b/internal/route/api/v1/user/email.go
@@ -17,7 +17,7 @@ import (
)
func ListEmails(c *context.APIContext) {
- emails, err := db.GetEmailAddresses(c.User.ID)
+ emails, err := db.Users.ListEmails(c.Req.Context(), c.User.ID)
if err != nil {
c.Error(err, "get email addresses")
return
@@ -35,48 +35,40 @@ func AddEmail(c *context.APIContext, form api.CreateEmailOption) {
return
}
- emails := make([]*db.EmailAddress, len(form.Emails))
- for i := range form.Emails {
- emails[i] = &db.EmailAddress{
- UserID: c.User.ID,
- Email: form.Emails[i],
- IsActivated: !conf.Auth.RequireEmailConfirmation,
+ apiEmails := make([]*api.Email, 0, len(form.Emails))
+ for _, email := range form.Emails {
+ err := db.Users.AddEmail(c.Req.Context(), c.User.ID, email, !conf.Auth.RequireEmailConfirmation)
+ if err != nil {
+ if db.IsErrEmailAlreadyUsed(err) {
+ c.ErrorStatus(http.StatusUnprocessableEntity, errors.Errorf("email address has been used: %s", err.(db.ErrEmailAlreadyUsed).Email()))
+ } else {
+ c.Error(err, "add email addresses")
+ }
+ return
}
- }
-
- if err := db.AddEmailAddresses(emails); err != nil {
- if db.IsErrEmailAlreadyUsed(err) {
- c.ErrorStatus(http.StatusUnprocessableEntity, errors.New("email address has been used: "+err.(db.ErrEmailAlreadyUsed).Email()))
- } else {
- c.Error(err, "add email addresses")
- }
- return
- }
- apiEmails := make([]*api.Email, len(emails))
- for i := range emails {
- apiEmails[i] = convert.ToEmail(emails[i])
+ apiEmails = append(apiEmails,
+ &api.Email{
+ Email: email,
+ Verified: !conf.Auth.RequireEmailConfirmation,
+ },
+ )
}
c.JSON(http.StatusCreated, &apiEmails)
}
func DeleteEmail(c *context.APIContext, form api.CreateEmailOption) {
- if len(form.Emails) == 0 {
- c.NoContent()
- return
- }
-
- emails := make([]*db.EmailAddress, len(form.Emails))
- for i := range form.Emails {
- emails[i] = &db.EmailAddress{
- UserID: c.User.ID,
- Email: form.Emails[i],
+ for _, email := range form.Emails {
+ if email == c.User.Email {
+ c.ErrorStatus(http.StatusBadRequest, errors.Errorf("cannot delete primary email %q", email))
+ return
}
- }
- if err := db.DeleteEmailAddresses(emails); err != nil {
- c.Error(err, "delete email addresses")
- return
+ err := db.Users.DeleteEmail(c.Req.Context(), c.User.ID, email)
+ if err != nil {
+ c.Error(err, "delete email addresses")
+ return
+ }
}
c.NoContent()
}
diff --git a/internal/route/lfs/mocks_test.go b/internal/route/lfs/mocks_test.go
index e4f013a6..b313ce55 100644
--- a/internal/route/lfs/mocks_test.go
+++ b/internal/route/lfs/mocks_test.go
@@ -3171,6 +3171,9 @@ func (c TwoFactorsStoreIsEnabledFuncCall) Results() []interface{} {
// MockUsersStore is a mock implementation of the UsersStore interface (from
// the package gogs.io/gogs/internal/db) used for unit testing.
type MockUsersStore struct {
+ // AddEmailFunc is an instance of a mock function object controlling the
+ // behavior of the method AddEmail.
+ AddEmailFunc *UsersStoreAddEmailFunc
// AuthenticateFunc is an instance of a mock function object controlling
// the behavior of the method Authenticate.
AuthenticateFunc *UsersStoreAuthenticateFunc
@@ -3189,6 +3192,9 @@ type MockUsersStore struct {
// DeleteCustomAvatarFunc is an instance of a mock function object
// controlling the behavior of the method DeleteCustomAvatar.
DeleteCustomAvatarFunc *UsersStoreDeleteCustomAvatarFunc
+ // DeleteEmailFunc is an instance of a mock function object controlling
+ // the behavior of the method DeleteEmail.
+ DeleteEmailFunc *UsersStoreDeleteEmailFunc
// DeleteInactivatedFunc is an instance of a mock function object
// controlling the behavior of the method DeleteInactivated.
DeleteInactivatedFunc *UsersStoreDeleteInactivatedFunc
@@ -3207,6 +3213,9 @@ type MockUsersStore struct {
// GetByUsernameFunc is an instance of a mock function object
// controlling the behavior of the method GetByUsername.
GetByUsernameFunc *UsersStoreGetByUsernameFunc
+ // GetEmailFunc is an instance of a mock function object controlling the
+ // behavior of the method GetEmail.
+ GetEmailFunc *UsersStoreGetEmailFunc
// GetMailableEmailsByUsernamesFunc is an instance of a mock function
// object controlling the behavior of the method
// GetMailableEmailsByUsernames.
@@ -3220,12 +3229,21 @@ type MockUsersStore struct {
// ListFunc is an instance of a mock function object controlling the
// behavior of the method List.
ListFunc *UsersStoreListFunc
+ // ListEmailsFunc is an instance of a mock function object controlling
+ // the behavior of the method ListEmails.
+ ListEmailsFunc *UsersStoreListEmailsFunc
// ListFollowersFunc is an instance of a mock function object
// controlling the behavior of the method ListFollowers.
ListFollowersFunc *UsersStoreListFollowersFunc
// ListFollowingsFunc is an instance of a mock function object
// controlling the behavior of the method ListFollowings.
ListFollowingsFunc *UsersStoreListFollowingsFunc
+ // MarkEmailActivatedFunc is an instance of a mock function object
+ // controlling the behavior of the method MarkEmailActivated.
+ MarkEmailActivatedFunc *UsersStoreMarkEmailActivatedFunc
+ // MarkEmailPrimaryFunc is an instance of a mock function object
+ // controlling the behavior of the method MarkEmailPrimary.
+ MarkEmailPrimaryFunc *UsersStoreMarkEmailPrimaryFunc
// SearchByNameFunc is an instance of a mock function object controlling
// the behavior of the method SearchByName.
SearchByNameFunc *UsersStoreSearchByNameFunc
@@ -3244,6 +3262,11 @@ type MockUsersStore struct {
// methods return zero values for all results, unless overwritten.
func NewMockUsersStore() *MockUsersStore {
return &MockUsersStore{
+ AddEmailFunc: &UsersStoreAddEmailFunc{
+ defaultHook: func(context.Context, int64, string, bool) (r0 error) {
+ return
+ },
+ },
AuthenticateFunc: &UsersStoreAuthenticateFunc{
defaultHook: func(context.Context, string, string, int64) (r0 *db.User, r1 error) {
return
@@ -3274,6 +3297,11 @@ func NewMockUsersStore() *MockUsersStore {
return
},
},
+ DeleteEmailFunc: &UsersStoreDeleteEmailFunc{
+ defaultHook: func(context.Context, int64, string) (r0 error) {
+ return
+ },
+ },
DeleteInactivatedFunc: &UsersStoreDeleteInactivatedFunc{
defaultHook: func() (r0 error) {
return
@@ -3304,6 +3332,11 @@ func NewMockUsersStore() *MockUsersStore {
return
},
},
+ GetEmailFunc: &UsersStoreGetEmailFunc{
+ defaultHook: func(context.Context, int64, string, bool) (r0 *db.EmailAddress, r1 error) {
+ return
+ },
+ },
GetMailableEmailsByUsernamesFunc: &UsersStoreGetMailableEmailsByUsernamesFunc{
defaultHook: func(context.Context, []string) (r0 []string, r1 error) {
return
@@ -3324,6 +3357,11 @@ func NewMockUsersStore() *MockUsersStore {
return
},
},
+ ListEmailsFunc: &UsersStoreListEmailsFunc{
+ defaultHook: func(context.Context, int64) (r0 []*db.EmailAddress, r1 error) {
+ return
+ },
+ },
ListFollowersFunc: &UsersStoreListFollowersFunc{
defaultHook: func(context.Context, int64, int, int) (r0 []*db.User, r1 error) {
return
@@ -3334,6 +3372,16 @@ func NewMockUsersStore() *MockUsersStore {
return
},
},
+ MarkEmailActivatedFunc: &UsersStoreMarkEmailActivatedFunc{
+ defaultHook: func(context.Context, int64, string) (r0 error) {
+ return
+ },
+ },
+ MarkEmailPrimaryFunc: &UsersStoreMarkEmailPrimaryFunc{
+ defaultHook: func(context.Context, int64, string) (r0 error) {
+ return
+ },
+ },
SearchByNameFunc: &UsersStoreSearchByNameFunc{
defaultHook: func(context.Context, string, int, int, string) (r0 []*db.User, r1 int64, r2 error) {
return
@@ -3361,6 +3409,11 @@ func NewMockUsersStore() *MockUsersStore {
// All methods panic on invocation, unless overwritten.
func NewStrictMockUsersStore() *MockUsersStore {
return &MockUsersStore{
+ AddEmailFunc: &UsersStoreAddEmailFunc{
+ defaultHook: func(context.Context, int64, string, bool) error {
+ panic("unexpected invocation of MockUsersStore.AddEmail")
+ },
+ },
AuthenticateFunc: &UsersStoreAuthenticateFunc{
defaultHook: func(context.Context, string, string, int64) (*db.User, error) {
panic("unexpected invocation of MockUsersStore.Authenticate")
@@ -3391,6 +3444,11 @@ func NewStrictMockUsersStore() *MockUsersStore {
panic("unexpected invocation of MockUsersStore.DeleteCustomAvatar")
},
},
+ DeleteEmailFunc: &UsersStoreDeleteEmailFunc{
+ defaultHook: func(context.Context, int64, string) error {
+ panic("unexpected invocation of MockUsersStore.DeleteEmail")
+ },
+ },
DeleteInactivatedFunc: &UsersStoreDeleteInactivatedFunc{
defaultHook: func() error {
panic("unexpected invocation of MockUsersStore.DeleteInactivated")
@@ -3421,6 +3479,11 @@ func NewStrictMockUsersStore() *MockUsersStore {
panic("unexpected invocation of MockUsersStore.GetByUsername")
},
},
+ GetEmailFunc: &UsersStoreGetEmailFunc{
+ defaultHook: func(context.Context, int64, string, bool) (*db.EmailAddress, error) {
+ panic("unexpected invocation of MockUsersStore.GetEmail")
+ },
+ },
GetMailableEmailsByUsernamesFunc: &UsersStoreGetMailableEmailsByUsernamesFunc{
defaultHook: func(context.Context, []string) ([]string, error) {
panic("unexpected invocation of MockUsersStore.GetMailableEmailsByUsernames")
@@ -3441,6 +3504,11 @@ func NewStrictMockUsersStore() *MockUsersStore {
panic("unexpected invocation of MockUsersStore.List")
},
},
+ ListEmailsFunc: &UsersStoreListEmailsFunc{
+ defaultHook: func(context.Context, int64) ([]*db.EmailAddress, error) {
+ panic("unexpected invocation of MockUsersStore.ListEmails")
+ },
+ },
ListFollowersFunc: &UsersStoreListFollowersFunc{
defaultHook: func(context.Context, int64, int, int) ([]*db.User, error) {
panic("unexpected invocation of MockUsersStore.ListFollowers")
@@ -3451,6 +3519,16 @@ func NewStrictMockUsersStore() *MockUsersStore {
panic("unexpected invocation of MockUsersStore.ListFollowings")
},
},
+ MarkEmailActivatedFunc: &UsersStoreMarkEmailActivatedFunc{
+ defaultHook: func(context.Context, int64, string) error {
+ panic("unexpected invocation of MockUsersStore.MarkEmailActivated")
+ },
+ },
+ MarkEmailPrimaryFunc: &UsersStoreMarkEmailPrimaryFunc{
+ defaultHook: func(context.Context, int64, string) error {
+ panic("unexpected invocation of MockUsersStore.MarkEmailPrimary")
+ },
+ },
SearchByNameFunc: &UsersStoreSearchByNameFunc{
defaultHook: func(context.Context, string, int, int, string) ([]*db.User, int64, error) {
panic("unexpected invocation of MockUsersStore.SearchByName")
@@ -3478,6 +3556,9 @@ func NewStrictMockUsersStore() *MockUsersStore {
// All methods delegate to the given implementation, unless overwritten.
func NewMockUsersStoreFrom(i db.UsersStore) *MockUsersStore {
return &MockUsersStore{
+ AddEmailFunc: &UsersStoreAddEmailFunc{
+ defaultHook: i.AddEmail,
+ },
AuthenticateFunc: &UsersStoreAuthenticateFunc{
defaultHook: i.Authenticate,
},
@@ -3496,6 +3577,9 @@ func NewMockUsersStoreFrom(i db.UsersStore) *MockUsersStore {
DeleteCustomAvatarFunc: &UsersStoreDeleteCustomAvatarFunc{
defaultHook: i.DeleteCustomAvatar,
},
+ DeleteEmailFunc: &UsersStoreDeleteEmailFunc{
+ defaultHook: i.DeleteEmail,
+ },
DeleteInactivatedFunc: &UsersStoreDeleteInactivatedFunc{
defaultHook: i.DeleteInactivated,
},
@@ -3514,6 +3598,9 @@ func NewMockUsersStoreFrom(i db.UsersStore) *MockUsersStore {
GetByUsernameFunc: &UsersStoreGetByUsernameFunc{
defaultHook: i.GetByUsername,
},
+ GetEmailFunc: &UsersStoreGetEmailFunc{
+ defaultHook: i.GetEmail,
+ },
GetMailableEmailsByUsernamesFunc: &UsersStoreGetMailableEmailsByUsernamesFunc{
defaultHook: i.GetMailableEmailsByUsernames,
},
@@ -3526,12 +3613,21 @@ func NewMockUsersStoreFrom(i db.UsersStore) *MockUsersStore {
ListFunc: &UsersStoreListFunc{
defaultHook: i.List,
},
+ ListEmailsFunc: &UsersStoreListEmailsFunc{
+ defaultHook: i.ListEmails,
+ },
ListFollowersFunc: &UsersStoreListFollowersFunc{
defaultHook: i.ListFollowers,
},
ListFollowingsFunc: &UsersStoreListFollowingsFunc{
defaultHook: i.ListFollowings,
},
+ MarkEmailActivatedFunc: &UsersStoreMarkEmailActivatedFunc{
+ defaultHook: i.MarkEmailActivated,
+ },
+ MarkEmailPrimaryFunc: &UsersStoreMarkEmailPrimaryFunc{
+ defaultHook: i.MarkEmailPrimary,
+ },
SearchByNameFunc: &UsersStoreSearchByNameFunc{
defaultHook: i.SearchByName,
},
@@ -3547,6 +3643,117 @@ func NewMockUsersStoreFrom(i db.UsersStore) *MockUsersStore {
}
}
+// UsersStoreAddEmailFunc describes the behavior when the AddEmail method of
+// the parent MockUsersStore instance is invoked.
+type UsersStoreAddEmailFunc struct {
+ defaultHook func(context.Context, int64, string, bool) error
+ hooks []func(context.Context, int64, string, bool) error
+ history []UsersStoreAddEmailFuncCall
+ mutex sync.Mutex
+}
+
+// AddEmail delegates to the next hook function in the queue and stores the
+// parameter and result values of this invocation.
+func (m *MockUsersStore) AddEmail(v0 context.Context, v1 int64, v2 string, v3 bool) error {
+ r0 := m.AddEmailFunc.nextHook()(v0, v1, v2, v3)
+ m.AddEmailFunc.appendCall(UsersStoreAddEmailFuncCall{v0, v1, v2, v3, r0})
+ return r0
+}
+
+// SetDefaultHook sets function that is called when the AddEmail method of
+// the parent MockUsersStore instance is invoked and the hook queue is
+// empty.
+func (f *UsersStoreAddEmailFunc) SetDefaultHook(hook func(context.Context, int64, string, bool) error) {
+ f.defaultHook = hook
+}
+
+// PushHook adds a function to the end of hook queue. Each invocation of the
+// AddEmail method of the parent MockUsersStore instance invokes the hook at
+// the front of the queue and discards it. After the queue is empty, the
+// default hook function is invoked for any future action.
+func (f *UsersStoreAddEmailFunc) PushHook(hook func(context.Context, int64, string, bool) error) {
+ f.mutex.Lock()
+ f.hooks = append(f.hooks, hook)
+ f.mutex.Unlock()
+}
+
+// SetDefaultReturn calls SetDefaultHook with a function that returns the
+// given values.
+func (f *UsersStoreAddEmailFunc) SetDefaultReturn(r0 error) {
+ f.SetDefaultHook(func(context.Context, int64, string, bool) error {
+ return r0
+ })
+}
+
+// PushReturn calls PushHook with a function that returns the given values.
+func (f *UsersStoreAddEmailFunc) PushReturn(r0 error) {
+ f.PushHook(func(context.Context, int64, string, bool) error {
+ return r0
+ })
+}
+
+func (f *UsersStoreAddEmailFunc) nextHook() func(context.Context, int64, string, bool) error {
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
+
+ if len(f.hooks) == 0 {
+ return f.defaultHook
+ }
+
+ hook := f.hooks[0]
+ f.hooks = f.hooks[1:]
+ return hook
+}
+
+func (f *UsersStoreAddEmailFunc) appendCall(r0 UsersStoreAddEmailFuncCall) {
+ f.mutex.Lock()
+ f.history = append(f.history, r0)
+ f.mutex.Unlock()
+}
+
+// History returns a sequence of UsersStoreAddEmailFuncCall objects
+// describing the invocations of this function.
+func (f *UsersStoreAddEmailFunc) History() []UsersStoreAddEmailFuncCall {
+ f.mutex.Lock()
+ history := make([]UsersStoreAddEmailFuncCall, len(f.history))
+ copy(history, f.history)
+ f.mutex.Unlock()
+
+ return history
+}
+
+// UsersStoreAddEmailFuncCall is an object that describes an invocation of
+// method AddEmail on an instance of MockUsersStore.
+type UsersStoreAddEmailFuncCall struct {
+ // Arg0 is the value of the 1st argument passed to this method
+ // invocation.
+ Arg0 context.Context
+ // Arg1 is the value of the 2nd argument passed to this method
+ // invocation.
+ Arg1 int64
+ // Arg2 is the value of the 3rd argument passed to this method
+ // invocation.
+ Arg2 string
+ // Arg3 is the value of the 4th argument passed to this method
+ // invocation.
+ Arg3 bool
+ // Result0 is the value of the 1st result returned from this method
+ // invocation.
+ Result0 error
+}
+
+// Args returns an interface slice containing the arguments of this
+// invocation.
+func (c UsersStoreAddEmailFuncCall) Args() []interface{} {
+ return []interface{}{c.Arg0, c.Arg1, c.Arg2, c.Arg3}
+}
+
+// Results returns an interface slice containing the results of this
+// invocation.
+func (c UsersStoreAddEmailFuncCall) Results() []interface{} {
+ return []interface{}{c.Result0}
+}
+
// UsersStoreAuthenticateFunc describes the behavior when the Authenticate
// method of the parent MockUsersStore instance is invoked.
type UsersStoreAuthenticateFunc struct {
@@ -4197,6 +4404,114 @@ func (c UsersStoreDeleteCustomAvatarFuncCall) Results() []interface{} {
return []interface{}{c.Result0}
}
+// UsersStoreDeleteEmailFunc describes the behavior when the DeleteEmail
+// method of the parent MockUsersStore instance is invoked.
+type UsersStoreDeleteEmailFunc struct {
+ defaultHook func(context.Context, int64, string) error
+ hooks []func(context.Context, int64, string) error
+ history []UsersStoreDeleteEmailFuncCall
+ mutex sync.Mutex
+}
+
+// DeleteEmail delegates to the next hook function in the queue and stores
+// the parameter and result values of this invocation.
+func (m *MockUsersStore) DeleteEmail(v0 context.Context, v1 int64, v2 string) error {
+ r0 := m.DeleteEmailFunc.nextHook()(v0, v1, v2)
+ m.DeleteEmailFunc.appendCall(UsersStoreDeleteEmailFuncCall{v0, v1, v2, r0})
+ return r0
+}
+
+// SetDefaultHook sets function that is called when the DeleteEmail method
+// of the parent MockUsersStore instance is invoked and the hook queue is
+// empty.
+func (f *UsersStoreDeleteEmailFunc) SetDefaultHook(hook func(context.Context, int64, string) error) {
+ f.defaultHook = hook
+}
+
+// PushHook adds a function to the end of hook queue. Each invocation of the
+// DeleteEmail method of the parent MockUsersStore instance invokes the hook
+// at the front of the queue and discards it. After the queue is empty, the
+// default hook function is invoked for any future action.
+func (f *UsersStoreDeleteEmailFunc) PushHook(hook func(context.Context, int64, string) error) {
+ f.mutex.Lock()
+ f.hooks = append(f.hooks, hook)
+ f.mutex.Unlock()
+}
+
+// SetDefaultReturn calls SetDefaultHook with a function that returns the
+// given values.
+func (f *UsersStoreDeleteEmailFunc) SetDefaultReturn(r0 error) {
+ f.SetDefaultHook(func(context.Context, int64, string) error {
+ return r0
+ })
+}
+
+// PushReturn calls PushHook with a function that returns the given values.
+func (f *UsersStoreDeleteEmailFunc) PushReturn(r0 error) {
+ f.PushHook(func(context.Context, int64, string) error {
+ return r0
+ })
+}
+
+func (f *UsersStoreDeleteEmailFunc) nextHook() func(context.Context, int64, string) error {
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
+
+ if len(f.hooks) == 0 {
+ return f.defaultHook
+ }
+
+ hook := f.hooks[0]
+ f.hooks = f.hooks[1:]
+ return hook
+}
+
+func (f *UsersStoreDeleteEmailFunc) appendCall(r0 UsersStoreDeleteEmailFuncCall) {
+ f.mutex.Lock()
+ f.history = append(f.history, r0)
+ f.mutex.Unlock()
+}
+
+// History returns a sequence of UsersStoreDeleteEmailFuncCall objects
+// describing the invocations of this function.
+func (f *UsersStoreDeleteEmailFunc) History() []UsersStoreDeleteEmailFuncCall {
+ f.mutex.Lock()
+ history := make([]UsersStoreDeleteEmailFuncCall, len(f.history))
+ copy(history, f.history)
+ f.mutex.Unlock()
+
+ return history
+}
+
+// UsersStoreDeleteEmailFuncCall is an object that describes an invocation
+// of method DeleteEmail on an instance of MockUsersStore.
+type UsersStoreDeleteEmailFuncCall struct {
+ // Arg0 is the value of the 1st argument passed to this method
+ // invocation.
+ Arg0 context.Context
+ // Arg1 is the value of the 2nd argument passed to this method
+ // invocation.
+ Arg1 int64
+ // Arg2 is the value of the 3rd argument passed to this method
+ // invocation.
+ Arg2 string
+ // Result0 is the value of the 1st result returned from this method
+ // invocation.
+ Result0 error
+}
+
+// Args returns an interface slice containing the arguments of this
+// invocation.
+func (c UsersStoreDeleteEmailFuncCall) Args() []interface{} {
+ return []interface{}{c.Arg0, c.Arg1, c.Arg2}
+}
+
+// Results returns an interface slice containing the results of this
+// invocation.
+func (c UsersStoreDeleteEmailFuncCall) Results() []interface{} {
+ return []interface{}{c.Result0}
+}
+
// UsersStoreDeleteInactivatedFunc describes the behavior when the
// DeleteInactivated method of the parent MockUsersStore instance is
// invoked.
@@ -4836,6 +5151,120 @@ func (c UsersStoreGetByUsernameFuncCall) Results() []interface{} {
return []interface{}{c.Result0, c.Result1}
}
+// UsersStoreGetEmailFunc describes the behavior when the GetEmail method of
+// the parent MockUsersStore instance is invoked.
+type UsersStoreGetEmailFunc struct {
+ defaultHook func(context.Context, int64, string, bool) (*db.EmailAddress, error)
+ hooks []func(context.Context, int64, string, bool) (*db.EmailAddress, error)
+ history []UsersStoreGetEmailFuncCall
+ mutex sync.Mutex
+}
+
+// GetEmail delegates to the next hook function in the queue and stores the
+// parameter and result values of this invocation.
+func (m *MockUsersStore) GetEmail(v0 context.Context, v1 int64, v2 string, v3 bool) (*db.EmailAddress, error) {
+ r0, r1 := m.GetEmailFunc.nextHook()(v0, v1, v2, v3)
+ m.GetEmailFunc.appendCall(UsersStoreGetEmailFuncCall{v0, v1, v2, v3, r0, r1})
+ return r0, r1
+}
+
+// SetDefaultHook sets function that is called when the GetEmail method of
+// the parent MockUsersStore instance is invoked and the hook queue is
+// empty.
+func (f *UsersStoreGetEmailFunc) SetDefaultHook(hook func(context.Context, int64, string, bool) (*db.EmailAddress, error)) {
+ f.defaultHook = hook
+}
+
+// PushHook adds a function to the end of hook queue. Each invocation of the
+// GetEmail method of the parent MockUsersStore instance invokes the hook at
+// the front of the queue and discards it. After the queue is empty, the
+// default hook function is invoked for any future action.
+func (f *UsersStoreGetEmailFunc) PushHook(hook func(context.Context, int64, string, bool) (*db.EmailAddress, error)) {
+ f.mutex.Lock()
+ f.hooks = append(f.hooks, hook)
+ f.mutex.Unlock()
+}
+
+// SetDefaultReturn calls SetDefaultHook with a function that returns the
+// given values.
+func (f *UsersStoreGetEmailFunc) SetDefaultReturn(r0 *db.EmailAddress, r1 error) {
+ f.SetDefaultHook(func(context.Context, int64, string, bool) (*db.EmailAddress, error) {
+ return r0, r1
+ })
+}
+
+// PushReturn calls PushHook with a function that returns the given values.
+func (f *UsersStoreGetEmailFunc) PushReturn(r0 *db.EmailAddress, r1 error) {
+ f.PushHook(func(context.Context, int64, string, bool) (*db.EmailAddress, error) {
+ return r0, r1
+ })
+}
+
+func (f *UsersStoreGetEmailFunc) nextHook() func(context.Context, int64, string, bool) (*db.EmailAddress, error) {
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
+
+ if len(f.hooks) == 0 {
+ return f.defaultHook
+ }
+
+ hook := f.hooks[0]
+ f.hooks = f.hooks[1:]
+ return hook
+}
+
+func (f *UsersStoreGetEmailFunc) appendCall(r0 UsersStoreGetEmailFuncCall) {
+ f.mutex.Lock()
+ f.history = append(f.history, r0)
+ f.mutex.Unlock()
+}
+
+// History returns a sequence of UsersStoreGetEmailFuncCall objects
+// describing the invocations of this function.
+func (f *UsersStoreGetEmailFunc) History() []UsersStoreGetEmailFuncCall {
+ f.mutex.Lock()
+ history := make([]UsersStoreGetEmailFuncCall, len(f.history))
+ copy(history, f.history)
+ f.mutex.Unlock()
+
+ return history
+}
+
+// UsersStoreGetEmailFuncCall is an object that describes an invocation of
+// method GetEmail on an instance of MockUsersStore.
+type UsersStoreGetEmailFuncCall struct {
+ // Arg0 is the value of the 1st argument passed to this method
+ // invocation.
+ Arg0 context.Context
+ // Arg1 is the value of the 2nd argument passed to this method
+ // invocation.
+ Arg1 int64
+ // Arg2 is the value of the 3rd argument passed to this method
+ // invocation.
+ Arg2 string
+ // Arg3 is the value of the 4th argument passed to this method
+ // invocation.
+ Arg3 bool
+ // Result0 is the value of the 1st result returned from this method
+ // invocation.
+ Result0 *db.EmailAddress
+ // Result1 is the value of the 2nd result returned from this method
+ // invocation.
+ Result1 error
+}
+
+// Args returns an interface slice containing the arguments of this
+// invocation.
+func (c UsersStoreGetEmailFuncCall) Args() []interface{} {
+ return []interface{}{c.Arg0, c.Arg1, c.Arg2, c.Arg3}
+}
+
+// Results returns an interface slice containing the results of this
+// invocation.
+func (c UsersStoreGetEmailFuncCall) Results() []interface{} {
+ return []interface{}{c.Result0, c.Result1}
+}
+
// UsersStoreGetMailableEmailsByUsernamesFunc describes the behavior when
// the GetMailableEmailsByUsernames method of the parent MockUsersStore
// instance is invoked.
@@ -5274,6 +5703,114 @@ func (c UsersStoreListFuncCall) Results() []interface{} {
return []interface{}{c.Result0, c.Result1}
}
+// UsersStoreListEmailsFunc describes the behavior when the ListEmails
+// method of the parent MockUsersStore instance is invoked.
+type UsersStoreListEmailsFunc struct {
+ defaultHook func(context.Context, int64) ([]*db.EmailAddress, error)
+ hooks []func(context.Context, int64) ([]*db.EmailAddress, error)
+ history []UsersStoreListEmailsFuncCall
+ mutex sync.Mutex
+}
+
+// ListEmails delegates to the next hook function in the queue and stores
+// the parameter and result values of this invocation.
+func (m *MockUsersStore) ListEmails(v0 context.Context, v1 int64) ([]*db.EmailAddress, error) {
+ r0, r1 := m.ListEmailsFunc.nextHook()(v0, v1)
+ m.ListEmailsFunc.appendCall(UsersStoreListEmailsFuncCall{v0, v1, r0, r1})
+ return r0, r1
+}
+
+// SetDefaultHook sets function that is called when the ListEmails method of
+// the parent MockUsersStore instance is invoked and the hook queue is
+// empty.
+func (f *UsersStoreListEmailsFunc) SetDefaultHook(hook func(context.Context, int64) ([]*db.EmailAddress, error)) {
+ f.defaultHook = hook
+}
+
+// PushHook adds a function to the end of hook queue. Each invocation of the
+// ListEmails method of the parent MockUsersStore instance invokes the hook
+// at the front of the queue and discards it. After the queue is empty, the
+// default hook function is invoked for any future action.
+func (f *UsersStoreListEmailsFunc) PushHook(hook func(context.Context, int64) ([]*db.EmailAddress, error)) {
+ f.mutex.Lock()
+ f.hooks = append(f.hooks, hook)
+ f.mutex.Unlock()
+}
+
+// SetDefaultReturn calls SetDefaultHook with a function that returns the
+// given values.
+func (f *UsersStoreListEmailsFunc) SetDefaultReturn(r0 []*db.EmailAddress, r1 error) {
+ f.SetDefaultHook(func(context.Context, int64) ([]*db.EmailAddress, error) {
+ return r0, r1
+ })
+}
+
+// PushReturn calls PushHook with a function that returns the given values.
+func (f *UsersStoreListEmailsFunc) PushReturn(r0 []*db.EmailAddress, r1 error) {
+ f.PushHook(func(context.Context, int64) ([]*db.EmailAddress, error) {
+ return r0, r1
+ })
+}
+
+func (f *UsersStoreListEmailsFunc) nextHook() func(context.Context, int64) ([]*db.EmailAddress, error) {
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
+
+ if len(f.hooks) == 0 {
+ return f.defaultHook
+ }
+
+ hook := f.hooks[0]
+ f.hooks = f.hooks[1:]
+ return hook
+}
+
+func (f *UsersStoreListEmailsFunc) appendCall(r0 UsersStoreListEmailsFuncCall) {
+ f.mutex.Lock()
+ f.history = append(f.history, r0)
+ f.mutex.Unlock()
+}
+
+// History returns a sequence of UsersStoreListEmailsFuncCall objects
+// describing the invocations of this function.
+func (f *UsersStoreListEmailsFunc) History() []UsersStoreListEmailsFuncCall {
+ f.mutex.Lock()
+ history := make([]UsersStoreListEmailsFuncCall, len(f.history))
+ copy(history, f.history)
+ f.mutex.Unlock()
+
+ return history
+}
+
+// UsersStoreListEmailsFuncCall is an object that describes an invocation of
+// method ListEmails on an instance of MockUsersStore.
+type UsersStoreListEmailsFuncCall struct {
+ // Arg0 is the value of the 1st argument passed to this method
+ // invocation.
+ Arg0 context.Context
+ // Arg1 is the value of the 2nd argument passed to this method
+ // invocation.
+ Arg1 int64
+ // Result0 is the value of the 1st result returned from this method
+ // invocation.
+ Result0 []*db.EmailAddress
+ // Result1 is the value of the 2nd result returned from this method
+ // invocation.
+ Result1 error
+}
+
+// Args returns an interface slice containing the arguments of this
+// invocation.
+func (c UsersStoreListEmailsFuncCall) Args() []interface{} {
+ return []interface{}{c.Arg0, c.Arg1}
+}
+
+// Results returns an interface slice containing the results of this
+// invocation.
+func (c UsersStoreListEmailsFuncCall) Results() []interface{} {
+ return []interface{}{c.Result0, c.Result1}
+}
+
// UsersStoreListFollowersFunc describes the behavior when the ListFollowers
// method of the parent MockUsersStore instance is invoked.
type UsersStoreListFollowersFunc struct {
@@ -5502,6 +6039,223 @@ func (c UsersStoreListFollowingsFuncCall) Results() []interface{} {
return []interface{}{c.Result0, c.Result1}
}
+// UsersStoreMarkEmailActivatedFunc describes the behavior when the
+// MarkEmailActivated method of the parent MockUsersStore instance is
+// invoked.
+type UsersStoreMarkEmailActivatedFunc struct {
+ defaultHook func(context.Context, int64, string) error
+ hooks []func(context.Context, int64, string) error
+ history []UsersStoreMarkEmailActivatedFuncCall
+ mutex sync.Mutex
+}
+
+// MarkEmailActivated delegates to the next hook function in the queue and
+// stores the parameter and result values of this invocation.
+func (m *MockUsersStore) MarkEmailActivated(v0 context.Context, v1 int64, v2 string) error {
+ r0 := m.MarkEmailActivatedFunc.nextHook()(v0, v1, v2)
+ m.MarkEmailActivatedFunc.appendCall(UsersStoreMarkEmailActivatedFuncCall{v0, v1, v2, r0})
+ return r0
+}
+
+// SetDefaultHook sets function that is called when the MarkEmailActivated
+// method of the parent MockUsersStore instance is invoked and the hook
+// queue is empty.
+func (f *UsersStoreMarkEmailActivatedFunc) SetDefaultHook(hook func(context.Context, int64, string) error) {
+ f.defaultHook = hook
+}
+
+// PushHook adds a function to the end of hook queue. Each invocation of the
+// MarkEmailActivated method of the parent MockUsersStore instance invokes
+// the hook at the front of the queue and discards it. After the queue is
+// empty, the default hook function is invoked for any future action.
+func (f *UsersStoreMarkEmailActivatedFunc) PushHook(hook func(context.Context, int64, string) error) {
+ f.mutex.Lock()
+ f.hooks = append(f.hooks, hook)
+ f.mutex.Unlock()
+}
+
+// SetDefaultReturn calls SetDefaultHook with a function that returns the
+// given values.
+func (f *UsersStoreMarkEmailActivatedFunc) SetDefaultReturn(r0 error) {
+ f.SetDefaultHook(func(context.Context, int64, string) error {
+ return r0
+ })
+}
+
+// PushReturn calls PushHook with a function that returns the given values.
+func (f *UsersStoreMarkEmailActivatedFunc) PushReturn(r0 error) {
+ f.PushHook(func(context.Context, int64, string) error {
+ return r0
+ })
+}
+
+func (f *UsersStoreMarkEmailActivatedFunc) nextHook() func(context.Context, int64, string) error {
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
+
+ if len(f.hooks) == 0 {
+ return f.defaultHook
+ }
+
+ hook := f.hooks[0]
+ f.hooks = f.hooks[1:]
+ return hook
+}
+
+func (f *UsersStoreMarkEmailActivatedFunc) appendCall(r0 UsersStoreMarkEmailActivatedFuncCall) {
+ f.mutex.Lock()
+ f.history = append(f.history, r0)
+ f.mutex.Unlock()
+}
+
+// History returns a sequence of UsersStoreMarkEmailActivatedFuncCall
+// objects describing the invocations of this function.
+func (f *UsersStoreMarkEmailActivatedFunc) History() []UsersStoreMarkEmailActivatedFuncCall {
+ f.mutex.Lock()
+ history := make([]UsersStoreMarkEmailActivatedFuncCall, len(f.history))
+ copy(history, f.history)
+ f.mutex.Unlock()
+
+ return history
+}
+
+// UsersStoreMarkEmailActivatedFuncCall is an object that describes an
+// invocation of method MarkEmailActivated on an instance of MockUsersStore.
+type UsersStoreMarkEmailActivatedFuncCall struct {
+ // Arg0 is the value of the 1st argument passed to this method
+ // invocation.
+ Arg0 context.Context
+ // Arg1 is the value of the 2nd argument passed to this method
+ // invocation.
+ Arg1 int64
+ // Arg2 is the value of the 3rd argument passed to this method
+ // invocation.
+ Arg2 string
+ // Result0 is the value of the 1st result returned from this method
+ // invocation.
+ Result0 error
+}
+
+// Args returns an interface slice containing the arguments of this
+// invocation.
+func (c UsersStoreMarkEmailActivatedFuncCall) Args() []interface{} {
+ return []interface{}{c.Arg0, c.Arg1, c.Arg2}
+}
+
+// Results returns an interface slice containing the results of this
+// invocation.
+func (c UsersStoreMarkEmailActivatedFuncCall) Results() []interface{} {
+ return []interface{}{c.Result0}
+}
+
+// UsersStoreMarkEmailPrimaryFunc describes the behavior when the
+// MarkEmailPrimary method of the parent MockUsersStore instance is invoked.
+type UsersStoreMarkEmailPrimaryFunc struct {
+ defaultHook func(context.Context, int64, string) error
+ hooks []func(context.Context, int64, string) error
+ history []UsersStoreMarkEmailPrimaryFuncCall
+ mutex sync.Mutex
+}
+
+// MarkEmailPrimary delegates to the next hook function in the queue and
+// stores the parameter and result values of this invocation.
+func (m *MockUsersStore) MarkEmailPrimary(v0 context.Context, v1 int64, v2 string) error {
+ r0 := m.MarkEmailPrimaryFunc.nextHook()(v0, v1, v2)
+ m.MarkEmailPrimaryFunc.appendCall(UsersStoreMarkEmailPrimaryFuncCall{v0, v1, v2, r0})
+ return r0
+}
+
+// SetDefaultHook sets function that is called when the MarkEmailPrimary
+// method of the parent MockUsersStore instance is invoked and the hook
+// queue is empty.
+func (f *UsersStoreMarkEmailPrimaryFunc) SetDefaultHook(hook func(context.Context, int64, string) error) {
+ f.defaultHook = hook
+}
+
+// PushHook adds a function to the end of hook queue. Each invocation of the
+// MarkEmailPrimary method of the parent MockUsersStore instance invokes the
+// hook at the front of the queue and discards it. After the queue is empty,
+// the default hook function is invoked for any future action.
+func (f *UsersStoreMarkEmailPrimaryFunc) PushHook(hook func(context.Context, int64, string) error) {
+ f.mutex.Lock()
+ f.hooks = append(f.hooks, hook)
+ f.mutex.Unlock()
+}
+
+// SetDefaultReturn calls SetDefaultHook with a function that returns the
+// given values.
+func (f *UsersStoreMarkEmailPrimaryFunc) SetDefaultReturn(r0 error) {
+ f.SetDefaultHook(func(context.Context, int64, string) error {
+ return r0
+ })
+}
+
+// PushReturn calls PushHook with a function that returns the given values.
+func (f *UsersStoreMarkEmailPrimaryFunc) PushReturn(r0 error) {
+ f.PushHook(func(context.Context, int64, string) error {
+ return r0
+ })
+}
+
+func (f *UsersStoreMarkEmailPrimaryFunc) nextHook() func(context.Context, int64, string) error {
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
+
+ if len(f.hooks) == 0 {
+ return f.defaultHook
+ }
+
+ hook := f.hooks[0]
+ f.hooks = f.hooks[1:]
+ return hook
+}
+
+func (f *UsersStoreMarkEmailPrimaryFunc) appendCall(r0 UsersStoreMarkEmailPrimaryFuncCall) {
+ f.mutex.Lock()
+ f.history = append(f.history, r0)
+ f.mutex.Unlock()
+}
+
+// History returns a sequence of UsersStoreMarkEmailPrimaryFuncCall objects
+// describing the invocations of this function.
+func (f *UsersStoreMarkEmailPrimaryFunc) History() []UsersStoreMarkEmailPrimaryFuncCall {
+ f.mutex.Lock()
+ history := make([]UsersStoreMarkEmailPrimaryFuncCall, len(f.history))
+ copy(history, f.history)
+ f.mutex.Unlock()
+
+ return history
+}
+
+// UsersStoreMarkEmailPrimaryFuncCall is an object that describes an
+// invocation of method MarkEmailPrimary on an instance of MockUsersStore.
+type UsersStoreMarkEmailPrimaryFuncCall struct {
+ // Arg0 is the value of the 1st argument passed to this method
+ // invocation.
+ Arg0 context.Context
+ // Arg1 is the value of the 2nd argument passed to this method
+ // invocation.
+ Arg1 int64
+ // Arg2 is the value of the 3rd argument passed to this method
+ // invocation.
+ Arg2 string
+ // Result0 is the value of the 1st result returned from this method
+ // invocation.
+ Result0 error
+}
+
+// Args returns an interface slice containing the arguments of this
+// invocation.
+func (c UsersStoreMarkEmailPrimaryFuncCall) Args() []interface{} {
+ return []interface{}{c.Arg0, c.Arg1, c.Arg2}
+}
+
+// Results returns an interface slice containing the results of this
+// invocation.
+func (c UsersStoreMarkEmailPrimaryFuncCall) Results() []interface{} {
+ return []interface{}{c.Result0}
+}
+
// UsersStoreSearchByNameFunc describes the behavior when the SearchByName
// method of the parent MockUsersStore instance is invoked.
type UsersStoreSearchByNameFunc struct {
diff --git a/internal/route/user/auth.go b/internal/route/user/auth.go
index ff0febb9..1e6a0589 100644
--- a/internal/route/user/auth.go
+++ b/internal/route/user/auth.go
@@ -445,7 +445,7 @@ func verifyActiveEmailCode(code, email string) *db.EmailAddress {
data := com.ToStr(user.ID) + email + user.LowerName + user.Password + user.Rands
if tool.VerifyTimeLimitCode(data, minutes, prefix) {
- emailAddress, err := db.EmailAddresses.GetByEmail(gocontext.TODO(), email, false)
+ emailAddress, err := db.Users.GetEmail(gocontext.TODO(), user.ID, email, false)
if err == nil {
return emailAddress
}
@@ -515,8 +515,10 @@ func ActivateEmail(c *context.Context) {
// Verify code.
if email := verifyActiveEmailCode(code, emailAddr); email != nil {
- if err := email.Activate(); err != nil {
+ err := db.Users.MarkEmailActivated(c.Req.Context(), email.UserID, email.Email)
+ if err != nil {
c.Error(err, "activate email")
+ return
}
log.Trace("Email activated: %s", email.Email)
diff --git a/internal/route/user/setting.go b/internal/route/user/setting.go
index 82aceaf2..6ee5fa4d 100644
--- a/internal/route/user/setting.go
+++ b/internal/route/user/setting.go
@@ -223,7 +223,7 @@ func SettingsEmails(c *context.Context) {
c.Title("settings.emails")
c.PageIs("SettingsEmails")
- emails, err := db.GetEmailAddresses(c.User.ID)
+ emails, err := db.Users.ListEmails(c.Req.Context(), c.User.ID)
if err != nil {
c.Errorf(err, "get email addresses")
return
@@ -237,9 +237,9 @@ func SettingsEmailPost(c *context.Context, f form.AddEmail) {
c.Title("settings.emails")
c.PageIs("SettingsEmails")
- // Make emailaddress primary.
if c.Query("_method") == "PRIMARY" {
- if err := db.MakeEmailPrimary(c.UserID(), &db.EmailAddress{ID: c.QueryInt64("id")}); err != nil {
+ err := db.Users.MarkEmailPrimary(c.Req.Context(), c.User.ID, c.Query("email"))
+ if err != nil {
c.Errorf(err, "make email primary")
return
}
@@ -249,7 +249,7 @@ func SettingsEmailPost(c *context.Context, f form.AddEmail) {
}
// Add Email address.
- emails, err := db.GetEmailAddresses(c.User.ID)
+ emails, err := db.Users.ListEmails(c.Req.Context(), c.User.ID)
if err != nil {
c.Errorf(err, "get email addresses")
return
@@ -261,12 +261,8 @@ func SettingsEmailPost(c *context.Context, f form.AddEmail) {
return
}
- emailAddr := &db.EmailAddress{
- UserID: c.User.ID,
- Email: f.Email,
- IsActivated: !conf.Auth.RequireEmailConfirmation,
- }
- if err := db.AddEmailAddress(emailAddr); err != nil {
+ err = db.Users.AddEmail(c.Req.Context(), c.User.ID, f.Email, !conf.Auth.RequireEmailConfirmation)
+ if err != nil {
if db.IsErrEmailAlreadyUsed(err) {
c.RenderWithErr(c.Tr("form.email_been_used"), SETTINGS_EMAILS, &f)
} else {
@@ -277,12 +273,12 @@ func SettingsEmailPost(c *context.Context, f form.AddEmail) {
// Send confirmation email
if conf.Auth.RequireEmailConfirmation {
- email.SendActivateEmailMail(c.Context, db.NewMailerUser(c.User), emailAddr.Email)
+ email.SendActivateEmailMail(c.Context, db.NewMailerUser(c.User), f.Email)
if err := c.Cache.Put("MailResendLimit_"+c.User.LowerName, c.User.LowerName, 180); err != nil {
log.Error("Set cache 'MailResendLimit' failed: %v", err)
}
- c.Flash.Info(c.Tr("settings.add_email_confirmation_sent", emailAddr.Email, conf.Auth.ActivateCodeLives/60))
+ c.Flash.Info(c.Tr("settings.add_email_confirmation_sent", f.Email, conf.Auth.ActivateCodeLives/60))
} else {
c.Flash.Success(c.Tr("settings.add_email_success"))
}
@@ -291,11 +287,18 @@ func SettingsEmailPost(c *context.Context, f form.AddEmail) {
}
func DeleteEmail(c *context.Context) {
- if err := db.DeleteEmailAddress(&db.EmailAddress{
- ID: c.QueryInt64("id"),
- UserID: c.User.ID,
- }); err != nil {
- c.Errorf(err, "delete email address")
+ email := c.Query("id") // The "id" here is the actual email address
+ if c.User.Email == email {
+ c.Flash.Error(c.Tr("settings.email_deletion_primary"))
+ c.JSONSuccess(map[string]any{
+ "redirect": conf.Server.Subpath + "/user/settings/email",
+ })
+ return
+ }
+
+ err := db.Users.DeleteEmail(c.Req.Context(), c.User.ID, email)
+ if err != nil {
+ c.Error(err, "delete email address")
return
}