summaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
Diffstat (limited to 'models')
-rw-r--r--models/fixtures/user.yml9
-rw-r--r--models/issue_mail.go8
-rw-r--r--models/migrations/migrations.go2
-rw-r--r--models/migrations/v93.go16
-rw-r--r--models/user.go37
-rw-r--r--models/user_test.go33
6 files changed, 95 insertions, 10 deletions
diff --git a/models/fixtures/user.yml b/models/fixtures/user.yml
index d89dc3c126..37225f1449 100644
--- a/models/fixtures/user.yml
+++ b/models/fixtures/user.yml
@@ -6,6 +6,7 @@
name: user1
full_name: User One
email: user1@example.com
+ email_notifications_preference: enabled
passwd: 7d93daa0d1e6f2305cc8fa496847d61dc7320bb16262f9c55dd753480207234cdd96a93194e408341971742f4701772a025a # password
type: 0 # individual
salt: ZogKvWdyEx
@@ -22,6 +23,7 @@
full_name: " < U<se>r Tw<o > >< "
email: user2@example.com
keep_email_private: true
+ email_notifications_preference: enabled
passwd: 7d93daa0d1e6f2305cc8fa496847d61dc7320bb16262f9c55dd753480207234cdd96a93194e408341971742f4701772a025a # password
type: 0 # individual
salt: ZogKvWdyEx
@@ -40,6 +42,7 @@
name: user3
full_name: " <<<< >> >> > >> > >>> >> "
email: user3@example.com
+ email_notifications_preference: onmention
passwd: 7d93daa0d1e6f2305cc8fa496847d61dc7320bb16262f9c55dd753480207234cdd96a93194e408341971742f4701772a025a # password
type: 1 # organization
salt: ZogKvWdyEx
@@ -56,6 +59,7 @@
name: user4
full_name: " "
email: user4@example.com
+ email_notifications_preference: onmention
passwd: 7d93daa0d1e6f2305cc8fa496847d61dc7320bb16262f9c55dd753480207234cdd96a93194e408341971742f4701772a025a # password
type: 0 # individual
salt: ZogKvWdyEx
@@ -72,6 +76,7 @@
name: user5
full_name: User Five
email: user5@example.com
+ email_notifications_preference: enabled
passwd: 7d93daa0d1e6f2305cc8fa496847d61dc7320bb16262f9c55dd753480207234cdd96a93194e408341971742f4701772a025a # password
type: 0 # individual
salt: ZogKvWdyEx
@@ -89,6 +94,7 @@
name: user6
full_name: User Six
email: user6@example.com
+ email_notifications_preference: enabled
passwd: 7d93daa0d1e6f2305cc8fa496847d61dc7320bb16262f9c55dd753480207234cdd96a93194e408341971742f4701772a025a # password
type: 1 # organization
salt: ZogKvWdyEx
@@ -105,6 +111,7 @@
name: user7
full_name: User Seven
email: user7@example.com
+ email_notifications_preference: disabled
passwd: 7d93daa0d1e6f2305cc8fa496847d61dc7320bb16262f9c55dd753480207234cdd96a93194e408341971742f4701772a025a # password
type: 1 # organization
salt: ZogKvWdyEx
@@ -121,6 +128,7 @@
name: user8
full_name: User Eight
email: user8@example.com
+ email_notifications_preference: enabled
passwd: 7d93daa0d1e6f2305cc8fa496847d61dc7320bb16262f9c55dd753480207234cdd96a93194e408341971742f4701772a025a # password
type: 0 # individual
salt: ZogKvWdyEx
@@ -138,6 +146,7 @@
name: user9
full_name: User Nine
email: user9@example.com
+ email_notifications_preference: onmention
passwd: 7d93daa0d1e6f2305cc8fa496847d61dc7320bb16262f9c55dd753480207234cdd96a93194e408341971742f4701772a025a # password
type: 0 # individual
salt: ZogKvWdyEx
diff --git a/models/issue_mail.go b/models/issue_mail.go
index 829c4cea78..87d991e500 100644
--- a/models/issue_mail.go
+++ b/models/issue_mail.go
@@ -70,7 +70,7 @@ func mailIssueCommentToParticipants(e Engine, issue *Issue, doer *User, content
if err != nil {
return fmt.Errorf("GetUserByID [%d]: %v", watchers[i].UserID, err)
}
- if to.IsOrganization() {
+ if to.IsOrganization() || to.EmailNotifications() != EmailNotificationsEnabled {
continue
}
@@ -78,9 +78,9 @@ func mailIssueCommentToParticipants(e Engine, issue *Issue, doer *User, content
names = append(names, to.Name)
}
for i := range participants {
- if participants[i].ID == doer.ID {
- continue
- } else if com.IsSliceContainsStr(names, participants[i].Name) {
+ if participants[i].ID == doer.ID ||
+ com.IsSliceContainsStr(names, participants[i].Name) ||
+ participants[i].EmailNotifications() != EmailNotificationsEnabled {
continue
}
diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go
index 7d97741a20..15e021c05a 100644
--- a/models/migrations/migrations.go
+++ b/models/migrations/migrations.go
@@ -240,6 +240,8 @@ var migrations = []Migration{
NewMigration("add index on owner_id of repository and type, review_id of comment", addIndexOnRepositoryAndComment),
// v92 -> v93
NewMigration("remove orphaned repository index statuses", removeLingeringIndexStatus),
+ // v93 -> v94
+ NewMigration("add email notification enabled preference to user", addEmailNotificationEnabledToUser),
}
// Migrate database to current version
diff --git a/models/migrations/v93.go b/models/migrations/v93.go
new file mode 100644
index 0000000000..0b0441cd5d
--- /dev/null
+++ b/models/migrations/v93.go
@@ -0,0 +1,16 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package migrations
+
+import "github.com/go-xorm/xorm"
+
+func addEmailNotificationEnabledToUser(x *xorm.Engine) error {
+ // User see models/user.go
+ type User struct {
+ EmailNotificationsPreference string `xorm:"VARCHAR(20) NOT NULL DEFAULT 'enabled'"`
+ }
+
+ return x.Sync2(new(User))
+}
diff --git a/models/user.go b/models/user.go
index ed0fe524e4..af4ccacf6f 100644
--- a/models/user.go
+++ b/models/user.go
@@ -58,6 +58,13 @@ const (
algoScrypt = "scrypt"
algoArgon2 = "argon2"
algoPbkdf2 = "pbkdf2"
+
+ // EmailNotificationsEnabled indicates that the user would like to receive all email notifications
+ EmailNotificationsEnabled = "enabled"
+ // EmailNotificationsOnMention indicates that the user would like to be notified via email when mentioned.
+ EmailNotificationsOnMention = "onmention"
+ // EmailNotificationsDisabled indicates that the user would not like to be notified via email.
+ EmailNotificationsDisabled = "disabled"
)
var (
@@ -87,10 +94,11 @@ type User struct {
Name string `xorm:"UNIQUE NOT NULL"`
FullName string
// Email is the primary email address (to be used for communication)
- Email string `xorm:"NOT NULL"`
- KeepEmailPrivate bool
- Passwd string `xorm:"NOT NULL"`
- PasswdHashAlgo string `xorm:"NOT NULL DEFAULT 'pbkdf2'"`
+ Email string `xorm:"NOT NULL"`
+ KeepEmailPrivate bool
+ EmailNotificationsPreference string `xorm:"VARCHAR(20) NOT NULL DEFAULT 'enabled'"`
+ Passwd string `xorm:"NOT NULL"`
+ PasswdHashAlgo string `xorm:"NOT NULL DEFAULT 'pbkdf2'"`
// MustChangePassword is an attribute that determines if a user
// is to change his/her password after registration.
@@ -719,6 +727,21 @@ func (u *User) IsMailable() bool {
return u.IsActive
}
+// EmailNotifications returns the User's email notification preference
+func (u *User) EmailNotifications() string {
+ return u.EmailNotificationsPreference
+}
+
+// SetEmailNotifications sets the user's email notification preference
+func (u *User) SetEmailNotifications(set string) error {
+ u.EmailNotificationsPreference = set
+ if err := UpdateUserCols(u, "email_notifications_preference"); err != nil {
+ log.Error("SetEmailNotifications: %v", err)
+ return err
+ }
+ return nil
+}
+
func isUserExist(e Engine, uid int64, name string) (bool, error) {
if len(name) == 0 {
return false, nil
@@ -868,6 +891,7 @@ func CreateUser(u *User) (err error) {
}
u.HashPassword(u.Passwd)
u.AllowCreateOrganization = setting.Service.DefaultAllowCreateOrganization && !setting.Admin.DisableRegularOrgCreation
+ u.EmailNotificationsPreference = setting.Admin.DefaultEmailNotification
u.MaxRepoCreation = -1
u.Theme = setting.UI.DefaultTheme
@@ -1253,7 +1277,8 @@ func getUserByName(e Engine, name string) (*User, error) {
return u, nil
}
-// GetUserEmailsByNames returns a list of e-mails corresponds to names.
+// GetUserEmailsByNames returns a list of e-mails corresponds to names of users
+// that have their email notifications set to enabled or onmention.
func GetUserEmailsByNames(names []string) []string {
return getUserEmailsByNames(x, names)
}
@@ -1265,7 +1290,7 @@ func getUserEmailsByNames(e Engine, names []string) []string {
if err != nil {
continue
}
- if u.IsMailable() {
+ if u.IsMailable() && u.EmailNotifications() != EmailNotificationsDisabled {
mails = append(mails, u.Email)
}
}
diff --git a/models/user_test.go b/models/user_test.go
index 290253c4b1..d01b482ae8 100644
--- a/models/user_test.go
+++ b/models/user_test.go
@@ -74,6 +74,8 @@ func TestGetUserEmailsByNames(t *testing.T) {
// ignore none active user email
assert.Equal(t, []string{"user8@example.com"}, GetUserEmailsByNames([]string{"user8", "user9"}))
assert.Equal(t, []string{"user8@example.com", "user5@example.com"}, GetUserEmailsByNames([]string{"user8", "user5"}))
+
+ assert.Equal(t, []string{"user8@example.com"}, GetUserEmailsByNames([]string{"user8", "user7"}))
}
func TestUser_APIFormat(t *testing.T) {
@@ -196,6 +198,37 @@ func TestDeleteUser(t *testing.T) {
test(11)
}
+func TestEmailNotificationPreferences(t *testing.T) {
+ assert.NoError(t, PrepareTestDatabase())
+ for _, test := range []struct {
+ expected string
+ userID int64
+ }{
+ {EmailNotificationsEnabled, 1},
+ {EmailNotificationsEnabled, 2},
+ {EmailNotificationsOnMention, 3},
+ {EmailNotificationsOnMention, 4},
+ {EmailNotificationsEnabled, 5},
+ {EmailNotificationsEnabled, 6},
+ {EmailNotificationsDisabled, 7},
+ {EmailNotificationsEnabled, 8},
+ {EmailNotificationsOnMention, 9},
+ } {
+ user := AssertExistsAndLoadBean(t, &User{ID: test.userID}).(*User)
+ assert.Equal(t, test.expected, user.EmailNotifications())
+
+ // Try all possible settings
+ assert.NoError(t, user.SetEmailNotifications(EmailNotificationsEnabled))
+ assert.Equal(t, EmailNotificationsEnabled, user.EmailNotifications())
+
+ assert.NoError(t, user.SetEmailNotifications(EmailNotificationsOnMention))
+ assert.Equal(t, EmailNotificationsOnMention, user.EmailNotifications())
+
+ assert.NoError(t, user.SetEmailNotifications(EmailNotificationsDisabled))
+ assert.Equal(t, EmailNotificationsDisabled, user.EmailNotifications())
+ }
+}
+
func TestHashPasswordDeterministic(t *testing.T) {
b := make([]byte, 16)
rand.Read(b)