From 6aa3f8bc29cb1ed3a1b165cbf526079a751c8c71 Mon Sep 17 00:00:00 2001 From: David Svantesson Date: Fri, 25 Oct 2019 16:46:37 +0200 Subject: 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 --- services/issue/issue.go | 106 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 2 deletions(-) (limited to 'services/issue') 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 +} -- cgit v1.2.3