diff options
author | David Svantesson <davidsvantesson@gmail.com> | 2019-10-25 16:46:37 +0200 |
---|---|---|
committer | Lunny Xiao <xiaolunwen@gmail.com> | 2019-10-25 22:46:37 +0800 |
commit | 6aa3f8bc29cb1ed3a1b165cbf526079a751c8c71 (patch) | |
tree | d18aafe7855f9d21fb0d8d7104e7ac7b4aba72b2 /services/issue | |
parent | c34e58fc008d53a5ec92cadadab2b13fb4e0ae94 (diff) | |
download | gitea-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.go | 106 |
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 +} |