From 16836c2a9a0fadca6d44d4c026c91c8a6c2046ab Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Sun, 12 Feb 2023 02:11:52 +0900 Subject: [PATCH 01/69] fix edit/close/delete projects in org --- modules/context/org.go | 47 +++++++++------ routers/web/org/projects.go | 107 +++++++++++------------------------ routers/web/repo/projects.go | 2 +- services/context/user.go | 3 +- templates/projects/list.tmpl | 8 +-- templates/projects/view.tmpl | 4 +- 6 files changed, 74 insertions(+), 97 deletions(-) diff --git a/modules/context/org.go b/modules/context/org.go index 0add7f2c0c3de..982032acea8ea 100644 --- a/modules/context/org.go +++ b/modules/context/org.go @@ -56,6 +56,29 @@ func (org *Organization) UnitPermission(ctx *Context, doerID int64, unitType uni return perm.AccessModeNone } +func GetOrganizationByParams(ctx *Context) { + orgName := ctx.Params(":org") + + var err error + + ctx.Org.Organization, err = organization.GetOrgByName(ctx, orgName) + if err != nil { + if organization.IsErrOrgNotExist(err) { + redirectUserID, err := user_model.LookupUserRedirect(orgName) + if err == nil { + RedirectToUser(ctx, orgName, redirectUserID) + } else if user_model.IsErrUserRedirectNotExist(err) { + ctx.NotFound("GetUserByName", err) + } else { + ctx.ServerError("LookupUserRedirect", err) + } + } else { + ctx.ServerError("GetUserByName", err) + } + return + } +} + // HandleOrgAssignment handles organization assignment func HandleOrgAssignment(ctx *Context, args ...bool) { var ( @@ -77,25 +100,17 @@ func HandleOrgAssignment(ctx *Context, args ...bool) { requireTeamAdmin = args[3] } - orgName := ctx.Params(":org") - var err error - ctx.Org.Organization, err = organization.GetOrgByName(ctx, orgName) - if err != nil { - if organization.IsErrOrgNotExist(err) { - redirectUserID, err := user_model.LookupUserRedirect(orgName) - if err == nil { - RedirectToUser(ctx, orgName, redirectUserID) - } else if user_model.IsErrUserRedirectNotExist(err) { - ctx.NotFound("GetUserByName", err) - } else { - ctx.ServerError("LookupUserRedirect", err) - } - } else { - ctx.ServerError("GetUserByName", err) + + // if Organization is not defined, get it from params + if ctx.Org.Organization == nil { + GetOrganizationByParams(ctx) + + if ctx.Written() { + return } - return } + org := ctx.Org.Organization // Handle Visibility diff --git a/routers/web/org/projects.go b/routers/web/org/projects.go index 6449d12de105a..4675d9a56caa9 100644 --- a/routers/web/org/projects.go +++ b/routers/web/org/projects.go @@ -8,12 +8,12 @@ import ( "fmt" "net/http" "net/url" - "strconv" "strings" issues_model "code.gitea.io/gitea/models/issues" project_model "code.gitea.io/gitea/models/project" "code.gitea.io/gitea/models/unit" + unit_model "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" @@ -33,7 +33,7 @@ const ( // MustEnableProjects check if projects are enabled in settings func MustEnableProjects(ctx *context.Context) { - if unit.TypeProjects.UnitGlobalDisabled() { + if unit_model.TypeProjects.UnitGlobalDisabled() { ctx.NotFound("EnableKanbanBoard", nil) return } @@ -108,6 +108,17 @@ func Projects(ctx *context.Context) { ctx.Data["PageIsViewProjects"] = true ctx.Data["SortType"] = sortType + if ctx.ContextUser.IsOrganization() { + ctx.Data["IsOwner"] = ctx.Org.IsOwner + } else { + if ctx.ContextUser.IsAdmin { + ctx.Data["IsOwner"] = true + } else { + ctx.Data["IsOwner"] = ctx.ContextUser.ID == ctx.Doer.ID + } + } + ctx.Data["DoerID"] = ctx.Doer.ID + ctx.HTML(http.StatusOK, tplProjects) } @@ -167,19 +178,19 @@ func ChangeProjectStatus(ctx *context.Context) { case "close": toClose = true default: - ctx.Redirect(ctx.Repo.RepoLink + "/projects") + ctx.Redirect(ctx.ContextUser.HomeLink() + "/-/projects") } id := ctx.ParamsInt64(":id") - if err := project_model.ChangeProjectStatusByRepoIDAndID(ctx.Repo.Repository.ID, id, toClose); err != nil { + if err := project_model.ChangeProjectStatusByRepoIDAndID(int64(0), id, toClose); err != nil { if project_model.IsErrProjectNotExist(err) { ctx.NotFound("", err) } else { - ctx.ServerError("ChangeProjectStatusByIDAndRepoID", err) + ctx.ServerError("ChangeProjectStatusByRepoIDAndID", err) } return } - ctx.Redirect(ctx.Repo.RepoLink + "/projects?state=" + url.QueryEscape(ctx.Params(":action"))) + ctx.Redirect(ctx.ContextUser.HomeLink() + "/-/projects?state=" + url.QueryEscape(ctx.Params(":action"))) } // DeleteProject delete a project @@ -193,7 +204,7 @@ func DeleteProject(ctx *context.Context) { } return } - if p.RepoID != ctx.Repo.Repository.ID { + if p.OwnerID != ctx.ContextUser.ID { ctx.NotFound("", nil) return } @@ -205,7 +216,7 @@ func DeleteProject(ctx *context.Context) { } ctx.JSON(http.StatusOK, map[string]interface{}{ - "redirect": ctx.Repo.RepoLink + "/projects", + "redirect": ctx.ContextUser.HomeLink() + "/-/projects", }) } @@ -226,7 +237,8 @@ func EditProject(ctx *context.Context) { } return } - if p.RepoID != ctx.Repo.Repository.ID { + + if p.OwnerID != ctx.ContextUser.ID { ctx.NotFound("", nil) return } @@ -260,7 +272,8 @@ func EditProjectPost(ctx *context.Context) { } return } - if p.RepoID != ctx.Repo.Repository.ID { + + if p.OwnerID != ctx.ContextUser.ID { ctx.NotFound("", nil) return } @@ -273,7 +286,7 @@ func EditProjectPost(ctx *context.Context) { } ctx.Flash.Success(ctx.Tr("repo.projects.edit_success", p.Title)) - ctx.Redirect(ctx.Repo.RepoLink + "/projects") + ctx.Redirect(ctx.ContextUser.HomeLink() + "/-/projects") } // ViewProject renders the project board for a project @@ -336,73 +349,21 @@ func ViewProject(ctx *context.Context) { ctx.Data["Project"] = project ctx.Data["IssuesMap"] = issuesMap ctx.Data["Boards"] = boards - shared_user.RenderUserHeader(ctx) - ctx.HTML(http.StatusOK, tplProjectsView) -} - -func getActionIssues(ctx *context.Context) []*issues_model.Issue { - commaSeparatedIssueIDs := ctx.FormString("issue_ids") - if len(commaSeparatedIssueIDs) == 0 { - return nil - } - issueIDs := make([]int64, 0, 10) - for _, stringIssueID := range strings.Split(commaSeparatedIssueIDs, ",") { - issueID, err := strconv.ParseInt(stringIssueID, 10, 64) - if err != nil { - ctx.ServerError("ParseInt", err) - return nil - } - issueIDs = append(issueIDs, issueID) - } - issues, err := issues_model.GetIssuesByIDs(ctx, issueIDs) - if err != nil { - ctx.ServerError("GetIssuesByIDs", err) - return nil - } - // Check access rights for all issues - issueUnitEnabled := ctx.Repo.CanRead(unit.TypeIssues) - prUnitEnabled := ctx.Repo.CanRead(unit.TypePullRequests) - for _, issue := range issues { - if issue.RepoID != ctx.Repo.Repository.ID { - ctx.NotFound("some issue's RepoID is incorrect", errors.New("some issue's RepoID is incorrect")) - return nil - } - if issue.IsPull && !prUnitEnabled || !issue.IsPull && !issueUnitEnabled { - ctx.NotFound("IssueOrPullRequestUnitNotAllowed", nil) - return nil - } - if err = issue.LoadAttributes(ctx); err != nil { - ctx.ServerError("LoadAttributes", err) - return nil + if ctx.ContextUser.IsOrganization() { + ctx.Data["IsOwner"] = ctx.Org.IsOwner + } else { + if ctx.ContextUser.IsAdmin { + ctx.Data["IsOwner"] = true + } else { + ctx.Data["IsOwner"] = ctx.ContextUser.ID == ctx.Doer.ID } } - return issues -} - -// UpdateIssueProject change an issue's project -func UpdateIssueProject(ctx *context.Context) { - issues := getActionIssues(ctx) - if ctx.Written() { - return - } + ctx.Data["IsProjectCreator"] = project.CreatorID == ctx.Doer.ID - projectID := ctx.FormInt64("id") - for _, issue := range issues { - oldProjectID := issue.ProjectID() - if oldProjectID == projectID { - continue - } - - if err := issues_model.ChangeProjectAssign(issue, ctx.Doer, projectID); err != nil { - ctx.ServerError("ChangeProjectAssign", err) - return - } - } + shared_user.RenderUserHeader(ctx) - ctx.JSON(http.StatusOK, map[string]interface{}{ - "ok": true, - }) + ctx.HTML(http.StatusOK, tplProjectsView) } // DeleteProjectBoard allows for the deletion of a project board diff --git a/routers/web/repo/projects.go b/routers/web/repo/projects.go index 967b81c608516..fe21a65dd9721 100644 --- a/routers/web/repo/projects.go +++ b/routers/web/repo/projects.go @@ -177,7 +177,7 @@ func ChangeProjectStatus(ctx *context.Context) { if project_model.IsErrProjectNotExist(err) { ctx.NotFound("", err) } else { - ctx.ServerError("ChangeProjectStatusByIDAndRepoID", err) + ctx.ServerError("ChangeProjectStatusByRepoIDAndID", err) } return } diff --git a/services/context/user.go b/services/context/user.go index 7642cba4e1f03..29a02a4aa563e 100644 --- a/services/context/user.go +++ b/services/context/user.go @@ -63,7 +63,8 @@ func userAssignment(ctx *context.Context, errCb func(int, string, interface{})) ctx.Org = &context.Organization{} } ctx.Org.Organization = (*org_model.Organization)(ctx.ContextUser) - ctx.Data["Org"] = ctx.Org.Organization + + context.HandleOrgAssignment(ctx) } } } diff --git a/templates/projects/list.tmpl b/templates/projects/list.tmpl index 21a3350a75db1..fb76c01f36d9b 100644 --- a/templates/projects/list.tmpl +++ b/templates/projects/list.tmpl @@ -50,8 +50,8 @@ {{svg "octicon-check" 16 "mr-3"}} {{JsPrettyNumber .NumClosedIssues}} {{$.locale.Tr "repo.issues.closed_title"}} - - {{if and (or $.CanWriteIssues $.CanWritePulls) (not $.Repository.IsArchived)}} + + {{if or $.IsOwner (eq .CreatorID $.DoerID)}}