feat: change email, export my data, delete account (with data anonymization)
This commit is contained in:
1 parent
bb191c389a
commit
10a66cd979
123 files changed
+10789
-76
No files matched your search
@@ -6,6 +6,8 @@ import (
|
||||
"RenewCMS/internal/infrastructure/useCases"
|
||||
"errors"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@@ -58,6 +60,7 @@ type mockUserRepo struct {
|
||||
beforeTransfer func()
|
||||
beforeClearVerification func()
|
||||
knownRoles *mockRoleRepo
|
||||
confirmLock sync.Mutex
|
||||
}
|
||||
|
||||
func newMockUserRepo() *mockUserRepo {
|
||||
@@ -80,6 +83,8 @@ func (m *mockUserRepo) sortedIds() []uint32 {
|
||||
}
|
||||
|
||||
func (m *mockUserRepo) Get(id uint32) (user.User, error) {
|
||||
m.confirmLock.Lock()
|
||||
defer m.confirmLock.Unlock()
|
||||
m.getCalls++
|
||||
if err := m.fail.trigger("Get"); err != nil {
|
||||
return user.User{}, err
|
||||
@@ -117,6 +122,81 @@ func (m *mockUserRepo) GetByEmail(email string) (user.User, error) {
|
||||
return user.User{}, user.ErrUserNotFound
|
||||
}
|
||||
|
||||
func (m *mockUserRepo) IsEmailInUse(email string, exceptUserId uint32) (bool, error) {
|
||||
m.confirmLock.Lock()
|
||||
defer m.confirmLock.Unlock()
|
||||
return m.emailInUse(email, exceptUserId)
|
||||
}
|
||||
|
||||
func (m *mockUserRepo) emailInUse(email string, exceptUserId uint32) (bool, error) {
|
||||
if err := m.fail.trigger("IsEmailInUse"); err != nil {
|
||||
return false, err
|
||||
}
|
||||
for id, stored := range m.users {
|
||||
if id != exceptUserId && strings.EqualFold(stored.Email, email) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (m *mockUserRepo) SetPendingEmailChange(userId uint32, pendingEmail string, code string, expiration time.Time) (user.User, error) {
|
||||
if err := m.fail.trigger("SetPendingEmailChange"); err != nil {
|
||||
return user.User{}, err
|
||||
}
|
||||
stored, ok := m.users[userId]
|
||||
if !ok {
|
||||
return user.User{}, user.ErrUserNotFound
|
||||
}
|
||||
stored.PendingEmail = pendingEmail
|
||||
stored.EmailChangeCode = code
|
||||
stored.EmailChangeExpiration = expiration
|
||||
m.users[userId] = stored
|
||||
return stored, nil
|
||||
}
|
||||
|
||||
func (m *mockUserRepo) ClearPendingEmailChange(userId uint32) (user.User, error) {
|
||||
if err := m.fail.trigger("ClearPendingEmailChange"); err != nil {
|
||||
return user.User{}, err
|
||||
}
|
||||
stored, ok := m.users[userId]
|
||||
if !ok {
|
||||
return user.User{}, user.ErrUserNotFound
|
||||
}
|
||||
stored.PendingEmail = ""
|
||||
stored.EmailChangeCode = ""
|
||||
stored.EmailChangeExpiration = time.Time{}
|
||||
m.users[userId] = stored
|
||||
return stored, nil
|
||||
}
|
||||
|
||||
func (m *mockUserRepo) ConfirmEmailChange(userId uint32, pendingEmail string, code string, now time.Time) (user.User, error) {
|
||||
m.confirmLock.Lock()
|
||||
defer m.confirmLock.Unlock()
|
||||
if err := m.fail.trigger("ConfirmEmailChange"); err != nil {
|
||||
return user.User{}, err
|
||||
}
|
||||
stored, ok := m.users[userId]
|
||||
if !ok {
|
||||
return user.User{}, user.ErrUserNotFound
|
||||
}
|
||||
if stored.PendingEmail != pendingEmail || stored.EmailChangeCode != code || !now.Before(stored.EmailChangeExpiration) {
|
||||
return user.User{}, user.ErrInvalidEmailChangeCode
|
||||
}
|
||||
taken, _ := m.emailInUse(pendingEmail, userId)
|
||||
if !taken {
|
||||
stored.Email = pendingEmail
|
||||
}
|
||||
stored.PendingEmail = ""
|
||||
stored.EmailChangeCode = ""
|
||||
stored.EmailChangeExpiration = time.Time{}
|
||||
m.users[userId] = stored
|
||||
if taken {
|
||||
return user.User{}, user.ErrEmailUnavailable
|
||||
}
|
||||
return stored, nil
|
||||
}
|
||||
|
||||
func (m *mockUserRepo) GetAll() ([]user.User, error) {
|
||||
m.getAllCalls++
|
||||
if err := m.fail.trigger("GetAll"); err != nil {
|
||||
|
||||
Reference in new issue
Block a user