summaryrefslogtreecommitdiffstats
path: root/services/issue
diff options
context:
space:
mode:
authorDavid Svantesson <davidsvantesson@gmail.com>2019-10-25 16:46:37 +0200
committerLunny Xiao <xiaolunwen@gmail.com>2019-10-25 22:46:37 +0800
commit6aa3f8bc29cb1ed3a1b165cbf526079a751c8c71 (patch)
treed18aafe7855f9d21fb0d8d7104e7ac7b4aba72b2 /services/issue
parentc34e58fc008d53a5ec92cadadab2b13fb4e0ae94 (diff)
downloadgitea-6aa3f8bc29cb1ed3a1b165cbf526079a751c8c71.tar.gz
gitea-6aa3f8bc29cb1ed3a1b165cbf526079a751c8c71.zip
Mail assignee when issue/pull request is assigned (#8546)
* Send email to assigned user * Only send mail if enabled * Mail also when assigned through API * Need to refactor functions from models to issue service * Refer to issue index rather than ID * Disable email notifications completly at initalization if global disable * Check of user enbled mail shall be in mail notification function only * Initialize notifications from routers init function. * Use the assigned comment when sending assigned mail * Refactor so that assignees always added as separate step when new issue/pr. * Check error from AddAssignees * Check if user can be assiged to issue or pull request * Missing return * Refactor of CanBeAssigned check. CanBeAssigned shall have same check as UI. * Clarify function names (toggle rather than update/change), and clean up. * Fix review comments. * Flash error if assignees was not added when creating issue/pr * Generate error if assignee users doesn't exist
Diffstat (limited to 'services/issue')
-rw-r--r--services/issue/issue.go106
1 files changed, 104 insertions, 2 deletions
diff --git a/services/issue/issue.go b/services/issue/issue.go
index a28916a7f9..a5f725ab70 100644
--- a/services/issue/issue.go
+++ b/services/issue/issue.go
@@ -9,12 +9,13 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/notification"
api "code.gitea.io/gitea/modules/structs"
)
// NewIssue creates new issue with labels for repository.
-func NewIssue(repo *models.Repository, issue *models.Issue, labelIDs []int64, assigneeIDs []int64, uuids []string) error {
- if err := models.NewIssue(repo, issue, labelIDs, assigneeIDs, uuids); err != nil {
+func NewIssue(repo *models.Repository, issue *models.Issue, labelIDs []int64, uuids []string) error {
+ if err := models.NewIssue(repo, issue, labelIDs, uuids); err != nil {
return err
}
@@ -96,3 +97,104 @@ func ChangeTitle(issue *models.Issue, doer *models.User, title string) (err erro
return nil
}
+
+// UpdateAssignees is a helper function to add or delete one or multiple issue assignee(s)
+// Deleting is done the GitHub way (quote from their api documentation):
+// https://developer.github.com/v3/issues/#edit-an-issue
+// "assignees" (array): Logins for Users to assign to this issue.
+// Pass one or more user logins to replace the set of assignees on this Issue.
+// Send an empty array ([]) to clear all assignees from the Issue.
+func UpdateAssignees(issue *models.Issue, oneAssignee string, multipleAssignees []string, doer *models.User) (err error) {
+ var allNewAssignees []*models.User
+
+ // Keep the old assignee thingy for compatibility reasons
+ if oneAssignee != "" {
+ // Prevent double adding assignees
+ var isDouble bool
+ for _, assignee := range multipleAssignees {
+ if assignee == oneAssignee {
+ isDouble = true
+ break
+ }
+ }
+
+ if !isDouble {
+ multipleAssignees = append(multipleAssignees, oneAssignee)
+ }
+ }
+
+ // Loop through all assignees to add them
+ for _, assigneeName := range multipleAssignees {
+ assignee, err := models.GetUserByName(assigneeName)
+ if err != nil {
+ return err
+ }
+
+ allNewAssignees = append(allNewAssignees, assignee)
+ }
+
+ // Delete all old assignees not passed
+ if err = models.DeleteNotPassedAssignee(issue, doer, allNewAssignees); err != nil {
+ return err
+ }
+
+ // Add all new assignees
+ // Update the assignee. The function will check if the user exists, is already
+ // assigned (which he shouldn't as we deleted all assignees before) and
+ // has access to the repo.
+ for _, assignee := range allNewAssignees {
+ // Extra method to prevent double adding (which would result in removing)
+ err = AddAssigneeIfNotAssigned(issue, doer, assignee.ID)
+ if err != nil {
+ return err
+ }
+ }
+
+ return
+}
+
+// AddAssigneeIfNotAssigned adds an assignee only if he isn't already assigned to the issue.
+// Also checks for access of assigned user
+func AddAssigneeIfNotAssigned(issue *models.Issue, doer *models.User, assigneeID int64) (err error) {
+ assignee, err := models.GetUserByID(assigneeID)
+ if err != nil {
+ return err
+ }
+
+ // Check if the user is already assigned
+ isAssigned, err := models.IsUserAssignedToIssue(issue, assignee)
+ if err != nil {
+ return err
+ }
+ if isAssigned {
+ // nothing to to
+ return nil
+ }
+
+ valid, err := models.CanBeAssigned(assignee, issue.Repo, issue.IsPull)
+ if err != nil {
+ return err
+ }
+ if !valid {
+ return models.ErrUserDoesNotHaveAccessToRepo{UserID: assigneeID, RepoName: issue.Repo.Name}
+ }
+
+ removed, comment, err := issue.ToggleAssignee(doer, assigneeID)
+ if err != nil {
+ return err
+ }
+
+ notification.NotifyIssueChangeAssignee(doer, issue, assignee, removed, comment)
+
+ return nil
+}
+
+// AddAssignees adds a list of assignes (from IDs) to an issue
+func AddAssignees(issue *models.Issue, doer *models.User, assigneeIDs []int64) (err error) {
+ for _, assigneeID := range assigneeIDs {
+ if err = AddAssigneeIfNotAssigned(issue, doer, assigneeID); err != nil {
+ return err
+ }
+ }
+ return nil
+}