diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index d43711e362c64..b63e7ab662c5c 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -709,7 +709,7 @@ func CreateIssue(ctx *context.APIContext) { form.Labels = make([]int64, 0) } - if err := issue_service.NewIssue(ctx, ctx.Repo.Repository, issue, form.Labels, nil, assigneeIDs); err != nil { + if err := issue_service.NewIssue(ctx, ctx.Repo.Repository, issue, form.Labels, nil, assigneeIDs, 0); err != nil { if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) { ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err) } else if errors.Is(err, user_model.ErrBlockedUser) { diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index 45fd01f4da530..83a5b76bf15bc 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -1224,6 +1224,14 @@ func NewIssuePost(ctx *context.Context) { return } + if projectID > 0 { + if !ctx.Repo.CanRead(unit.TypeProjects) { + // User must also be able to see the project. + ctx.Error(http.StatusBadRequest, "user hasn't permissions to read projects") + return + } + } + if setting.Attachment.Enabled { attachments = form.Files } @@ -1256,7 +1264,7 @@ func NewIssuePost(ctx *context.Context) { Ref: form.Ref, } - if err := issue_service.NewIssue(ctx, repo, issue, labelIDs, attachments, assigneeIDs); err != nil { + if err := issue_service.NewIssue(ctx, repo, issue, labelIDs, attachments, assigneeIDs, projectID); err != nil { if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) { ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err.Error()) } else if errors.Is(err, user_model.ErrBlockedUser) { @@ -1267,18 +1275,6 @@ func NewIssuePost(ctx *context.Context) { return } - if projectID > 0 { - if !ctx.Repo.CanRead(unit.TypeProjects) { - // User must also be able to see the project. - ctx.Error(http.StatusBadRequest, "user hasn't permissions to read projects") - return - } - if err := issues_model.ChangeProjectAssign(ctx, issue, ctx.Doer, projectID); err != nil { - ctx.ServerError("ChangeProjectAssign", err) - return - } - } - log.Trace("Issue created: %d/%d", repo.ID, issue.ID) if ctx.FormString("redirect_after_creation") == "project" && projectID > 0 { ctx.JSONRedirect(ctx.Repo.RepoLink + "/projects/" + strconv.FormatInt(projectID, 10)) diff --git a/services/issue/issue.go b/services/issue/issue.go index 27a106009c899..0753813b646f9 100644 --- a/services/issue/issue.go +++ b/services/issue/issue.go @@ -22,7 +22,7 @@ import ( ) // NewIssue creates new issue with labels for repository. -func NewIssue(ctx context.Context, repo *repo_model.Repository, issue *issues_model.Issue, labelIDs []int64, uuids []string, assigneeIDs []int64) error { +func NewIssue(ctx context.Context, repo *repo_model.Repository, issue *issues_model.Issue, labelIDs []int64, uuids []string, assigneeIDs []int64, projectID int64) error { if err := issue.LoadPoster(ctx); err != nil { return err } @@ -31,14 +31,23 @@ func NewIssue(ctx context.Context, repo *repo_model.Repository, issue *issues_mo return user_model.ErrBlockedUser } - if err := issues_model.NewIssue(ctx, repo, issue, labelIDs, uuids); err != nil { - return err - } - - for _, assigneeID := range assigneeIDs { - if _, err := AddAssigneeIfNotAssigned(ctx, issue, issue.Poster, assigneeID, true); err != nil { + if err := db.WithTx(ctx, func(ctx context.Context) error { + if err := issues_model.NewIssue(ctx, repo, issue, labelIDs, uuids); err != nil { return err } + for _, assigneeID := range assigneeIDs { + if _, err := AddAssigneeIfNotAssigned(ctx, issue, issue.Poster, assigneeID, true); err != nil { + return err + } + } + if projectID > 0 { + if err := issues_model.ChangeProjectAssign(ctx, issue, issue.Poster, projectID); err != nil { + return err + } + } + return nil + }); err != nil { + return err } mentions, err := issues_model.FindAndUpdateIssueMentions(ctx, issue, issue.Poster, issue.Content)