From ffa12bdb71d1e708ff782fb681895aea9b83766b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=B5=B5=E6=99=BA=E8=B6=85?= <1012112796@qq.com>
Date: Thu, 10 Sep 2020 03:08:55 +0800
Subject: [PATCH] Fix "only mail on mention" bug (#12775)

* fix mail mention bug

fix #12774

Signed-off-by: a1012112796 <1012112796@qq.com>

* fix test

Co-authored-by: techknowlogick <techknowlogick@gitea.io>
---
 models/user.go                  | 12 +++++++++++-
 models/user_test.go             | 17 +++++++++++++++++
 services/mailer/mail_issue.go   |  2 +-
 services/mailer/mail_release.go |  2 +-
 4 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/models/user.go b/models/user.go
index 2e5d6473bb..c7b3f0981e 100644
--- a/models/user.go
+++ b/models/user.go
@@ -1419,11 +1419,21 @@ func getUserEmailsByNames(e Engine, names []string) []string {
 }
 
 // GetMaileableUsersByIDs gets users from ids, but only if they can receive mails
-func GetMaileableUsersByIDs(ids []int64) ([]*User, error) {
+func GetMaileableUsersByIDs(ids []int64, isMention bool) ([]*User, error) {
 	if len(ids) == 0 {
 		return nil, nil
 	}
 	ous := make([]*User, 0, len(ids))
+
+	if isMention {
+		return ous, x.In("id", ids).
+			Where("`type` = ?", UserTypeIndividual).
+			And("`prohibit_login` = ?", false).
+			And("`is_active` = ?", true).
+			And("`email_notifications_preference` IN ( ?, ?)", EmailNotificationsEnabled, EmailNotificationsOnMention).
+			Find(&ous)
+	}
+
 	return ous, x.In("id", ids).
 		Where("`type` = ?", UserTypeIndividual).
 		And("`prohibit_login` = ?", false).
diff --git a/models/user_test.go b/models/user_test.go
index 220823ee02..d03ef4fad4 100644
--- a/models/user_test.go
+++ b/models/user_test.go
@@ -389,3 +389,20 @@ func TestGetUserIDsByNames(t *testing.T) {
 	assert.Error(t, err)
 	assert.Equal(t, []int64(nil), IDs)
 }
+
+func TestGetMaileableUsersByIDs(t *testing.T) {
+	results, err := GetMaileableUsersByIDs([]int64{1, 4}, false)
+	assert.NoError(t, err)
+	assert.Equal(t, 1, len(results))
+	if len(results) > 1 {
+		assert.Equal(t, results[0].ID, 1)
+	}
+
+	results, err = GetMaileableUsersByIDs([]int64{1, 4}, true)
+	assert.NoError(t, err)
+	assert.Equal(t, 2, len(results))
+	if len(results) > 2 {
+		assert.Equal(t, results[0].ID, 1)
+		assert.Equal(t, results[1].ID, 4)
+	}
+}
diff --git a/services/mailer/mail_issue.go b/services/mailer/mail_issue.go
index 1030a9548e..01c198984b 100644
--- a/services/mailer/mail_issue.go
+++ b/services/mailer/mail_issue.go
@@ -118,7 +118,7 @@ func mailIssueCommentBatch(ctx *mailCommentContext, ids []int64, visited map[int
 				visited[id] = true
 			}
 		}
-		recipients, err := models.GetMaileableUsersByIDs(unique)
+		recipients, err := models.GetMaileableUsersByIDs(unique, fromMention)
 		if err != nil {
 			return err
 		}
diff --git a/services/mailer/mail_release.go b/services/mailer/mail_release.go
index 55182f55cf..f278c853ae 100644
--- a/services/mailer/mail_release.go
+++ b/services/mailer/mail_release.go
@@ -27,7 +27,7 @@ func MailNewRelease(rel *models.Release) {
 		return
 	}
 
-	recipients, err := models.GetMaileableUsersByIDs(watcherIDList)
+	recipients, err := models.GetMaileableUsersByIDs(watcherIDList, false)
 	if err != nil {
 		log.Error("models.GetMaileableUsersByIDs: %v", err)
 		return