summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwULLSnpAXbWZGYDYyhWTKKspEQoaYxXyhoisqHf <61180606+wULLSnpAXbWZGYDYyhWTKKspEQoaYxXyhoisqHf@users.noreply.github.com>2020-08-22 08:58:59 +0200
committerGitHub <noreply@github.com>2020-08-22 02:58:59 -0400
commitd4e35b9dc61779559fe28a7537d28bef2938a443 (patch)
tree833e669f014fc661fec2b1842e268bcda119462f
parenta0484890c11a088330db0e3a0c03474ee2408b13 (diff)
downloadgitea-d4e35b9dc61779559fe28a7537d28bef2938a443.tar.gz
gitea-d4e35b9dc61779559fe28a7537d28bef2938a443.zip
Hide 'New Project board' button for users that are not signed in (#12547)
* hide: 'New Project board' button * there is no reason to show the button for users that are not signed in * update template: specifies the condition together with another one as per lafriks' suggestion in the comment * chore: add proper user authorization check * chore: also hide button if repo is archived * chore: show project board edit/delete menu to authorized users only * chore: drop the redundant IsSigned check * CanWriteIssues and CanWritePulls implies (and requires) signed in user * Add CanWriteProjects and properly assert permissions Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: Andrew Thornton <art27@cantab.net> Co-authored-by: techknowlogick <techknowlogick@gitea.io>
-rw-r--r--routers/repo/projects.go17
-rw-r--r--routers/routes/routes.go37
-rw-r--r--templates/repo/projects/list.tmpl62
-rw-r--r--templates/repo/projects/new.tmpl2
-rw-r--r--templates/repo/projects/view.tmpl100
5 files changed, 112 insertions, 106 deletions
diff --git a/routers/repo/projects.go b/routers/repo/projects.go
index daa94a308d..948f88375e 100644
--- a/routers/repo/projects.go
+++ b/routers/repo/projects.go
@@ -95,6 +95,7 @@ func Projects(ctx *context.Context) {
pager.AddParam(ctx, "state", "State")
ctx.Data["Page"] = pager
+ ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(models.UnitTypeProjects)
ctx.Data["IsShowClosed"] = isShowClosed
ctx.Data["IsProjectsPage"] = true
ctx.Data["SortType"] = sortType
@@ -106,16 +107,17 @@ func Projects(ctx *context.Context) {
func NewProject(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.projects.new")
ctx.Data["ProjectTypes"] = models.GetProjectsConfig()
-
+ ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(models.UnitTypeProjects)
ctx.HTML(200, tplProjectsNew)
}
-// NewRepoProjectPost creates a new project
-func NewRepoProjectPost(ctx *context.Context, form auth.CreateProjectForm) {
-
+// NewProjectPost creates a new project
+func NewProjectPost(ctx *context.Context, form auth.CreateProjectForm) {
ctx.Data["Title"] = ctx.Tr("repo.projects.new")
if ctx.HasError() {
+ ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(models.UnitTypeProjects)
+ ctx.Data["ProjectTypes"] = models.GetProjectsConfig()
ctx.HTML(200, tplProjectsNew)
return
}
@@ -192,6 +194,7 @@ func EditProject(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.projects.edit")
ctx.Data["PageIsProjects"] = true
ctx.Data["PageIsEditProjects"] = true
+ ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(models.UnitTypeProjects)
p, err := models.GetProjectByID(ctx.ParamsInt64(":id"))
if err != nil {
@@ -218,9 +221,10 @@ func EditProjectPost(ctx *context.Context, form auth.CreateProjectForm) {
ctx.Data["Title"] = ctx.Tr("repo.projects.edit")
ctx.Data["PageIsProjects"] = true
ctx.Data["PageIsEditProjects"] = true
+ ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(models.UnitTypeProjects)
if ctx.HasError() {
- ctx.HTML(200, tplMilestoneNew)
+ ctx.HTML(200, tplProjectsNew)
return
}
@@ -287,6 +291,7 @@ func ViewProject(ctx *context.Context) {
return
}
+ ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(models.UnitTypeProjects)
ctx.Data["Project"] = project
ctx.Data["Boards"] = allBoards
ctx.Data["PageIsProjects"] = true
@@ -551,6 +556,7 @@ func MoveIssueAcrossBoards(ctx *context.Context) {
func CreateProject(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.projects.new")
ctx.Data["ProjectTypes"] = models.GetProjectsConfig()
+ ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(models.UnitTypeProjects)
ctx.HTML(200, tplGenericProjectsNew)
}
@@ -566,6 +572,7 @@ func CreateProjectPost(ctx *context.Context, form auth.UserCreateProjectForm) {
ctx.Data["ContextUser"] = user
if ctx.HasError() {
+ ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(models.UnitTypeProjects)
ctx.HTML(200, tplGenericProjectsNew)
return
}
diff --git a/routers/routes/routes.go b/routers/routes/routes.go
index 27af9275ed..bdb82db6f5 100644
--- a/routers/routes/routes.go
+++ b/routers/routes/routes.go
@@ -535,6 +535,7 @@ func RegisterRoutes(m *macaron.Macaron) {
reqRepoIssuesOrPullsWriter := context.RequireRepoWriterOr(models.UnitTypeIssues, models.UnitTypePullRequests)
reqRepoIssuesOrPullsReader := context.RequireRepoReaderOr(models.UnitTypeIssues, models.UnitTypePullRequests)
reqRepoProjectsReader := context.RequireRepoReader(models.UnitTypeProjects)
+ reqRepoProjectsWriter := context.RequireRepoWriter(models.UnitTypeProjects)
// ***** START: Organization *****
m.Group("/org", func() {
@@ -858,24 +859,26 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Group("/projects", func() {
m.Get("", repo.Projects)
- m.Get("/new", repo.NewProject)
- m.Post("/new", bindIgnErr(auth.CreateProjectForm{}), repo.NewRepoProjectPost)
- m.Group("/:id", func() {
- m.Get("", repo.ViewProject)
- m.Post("", bindIgnErr(auth.EditProjectBoardTitleForm{}), repo.AddBoardToProjectPost)
- m.Post("/delete", repo.DeleteProject)
-
- m.Get("/edit", repo.EditProject)
- m.Post("/edit", bindIgnErr(auth.CreateProjectForm{}), repo.EditProjectPost)
- m.Post("/^:action(open|close)$", repo.ChangeProjectStatus)
-
- m.Group("/:boardID", func() {
- m.Put("", bindIgnErr(auth.EditProjectBoardTitleForm{}), repo.EditProjectBoardTitle)
- m.Delete("", repo.DeleteProjectBoard)
-
- m.Post("/:index", repo.MoveIssueAcrossBoards)
+ m.Get("/:id", repo.ViewProject)
+ m.Group("", func() {
+ m.Get("/new", repo.NewProject)
+ m.Post("/new", bindIgnErr(auth.CreateProjectForm{}), repo.NewProjectPost)
+ m.Group("/:id", func() {
+ m.Post("", bindIgnErr(auth.EditProjectBoardTitleForm{}), repo.AddBoardToProjectPost)
+ m.Post("/delete", repo.DeleteProject)
+
+ m.Get("/edit", repo.EditProject)
+ m.Post("/edit", bindIgnErr(auth.CreateProjectForm{}), repo.EditProjectPost)
+ m.Post("/^:action(open|close)$", repo.ChangeProjectStatus)
+
+ m.Group("/:boardID", func() {
+ m.Put("", bindIgnErr(auth.EditProjectBoardTitleForm{}), repo.EditProjectBoardTitle)
+ m.Delete("", repo.DeleteProjectBoard)
+
+ m.Post("/:index", repo.MoveIssueAcrossBoards)
+ })
})
- })
+ }, reqRepoProjectsWriter, context.RepoMustNotBeArchived())
}, reqRepoProjectsReader, repo.MustEnableProjects)
m.Group("/wiki", func() {
diff --git a/templates/repo/projects/list.tmpl b/templates/repo/projects/list.tmpl
index f48cf400ba..6e98bd3fd0 100644
--- a/templates/repo/projects/list.tmpl
+++ b/templates/repo/projects/list.tmpl
@@ -4,10 +4,10 @@
<div class="ui container">
<div class="navbar">
{{template "repo/issue/navbar" .}}
- {{if and (or .CanWriteIssues .CanWritePulls) (not .Repository.IsArchived)}}
- <div class="ui right">
- <a class="ui green button" href="{{$.Link}}/new">{{.i18n.Tr "repo.projects.new"}}</a>
- </div>
+ {{if and .CanWriteProjects (not .Repository.IsArchived)}}
+ <div class="ui right">
+ <a class="ui green button" href="{{$.Link}}/new">{{.i18n.Tr "repo.projects.new"}}</a>
+ </div>
{{end}}
</div>
<div class="ui divider"></div>
@@ -39,35 +39,35 @@
</div>
<div class="milestone list">
{{range .Projects}}
- <li class="item">
- {{svg "octicon-project" 16}} <a href="{{$.RepoLink}}/projects/{{.ID}}">{{.Title}}</a>
- <div class="meta">
- {{ $closedDate:= TimeSinceUnix .ClosedDateUnix $.Lang }}
- {{if .IsClosed }}
- {{svg "octicon-clock" 16}} {{$.i18n.Tr "repo.milestones.closed" $closedDate|Str2html}}
+ <li class="item">
+ {{svg "octicon-project" 16}} <a href="{{$.RepoLink}}/projects/{{.ID}}">{{.Title}}</a>
+ <div class="meta">
+ {{ $closedDate:= TimeSinceUnix .ClosedDateUnix $.Lang }}
+ {{if .IsClosed }}
+ {{svg "octicon-clock" 16}} {{$.i18n.Tr "repo.milestones.closed" $closedDate|Str2html}}
+ {{end}}
+ <span class="issue-stats">
+ {{svg "octicon-issue-opened" 16}} {{$.i18n.Tr "repo.issues.open_tab" .NumOpenIssues}}
+ {{svg "octicon-issue-closed" 16}} {{$.i18n.Tr "repo.issues.close_tab" .NumClosedIssues}}
+ </span>
+ </div>
+ {{if and (or $.CanWriteIssues $.CanWritePulls) (not $.Repository.IsArchived)}}
+ <div class="ui right operate">
+ <a href="{{$.Link}}/{{.ID}}/edit" data-id={{.ID}} data-title={{.Title}}>{{svg "octicon-pencil" 16}} {{$.i18n.Tr "repo.issues.label_edit"}}</a>
+ {{if .IsClosed}}
+ <a class="link-action" href data-url="{{$.Link}}/{{.ID}}/open">{{svg "octicon-check" 16}} {{$.i18n.Tr "repo.projects.open"}}</a>
+ {{else}}
+ <a class="link-action" href data-url="{{$.Link}}/{{.ID}}/close">{{svg "octicon-x" 16}} {{$.i18n.Tr "repo.projects.close"}}</a>
+ {{end}}
+ <a class="delete-button" href="#" data-url="{{$.RepoLink}}/projects/{{.ID}}/delete" data-id="{{.ID}}">{{svg "octicon-trashcan" 16}} {{$.i18n.Tr "repo.issues.label_delete"}}</a>
+ </div>
{{end}}
- <span class="issue-stats">
- {{svg "octicon-issue-opened" 16}} {{$.i18n.Tr "repo.issues.open_tab" .NumOpenIssues}}
- {{svg "octicon-issue-closed" 16}} {{$.i18n.Tr "repo.issues.close_tab" .NumClosedIssues}}
- </span>
- </div>
- {{if and (or $.CanWriteIssues $.CanWritePulls) (not $.Repository.IsArchived)}}
- <div class="ui right operate">
- <a href="{{$.Link}}/{{.ID}}/edit" data-id={{.ID}} data-title={{.Title}}>{{svg "octicon-pencil" 16}} {{$.i18n.Tr "repo.issues.label_edit"}}</a>
- {{if .IsClosed}}
- <a class="link-action" href data-url="{{$.Link}}/{{.ID}}/open">{{svg "octicon-check" 16}} {{$.i18n.Tr "repo.projects.open"}}</a>
- {{else}}
- <a class="link-action" href data-url="{{$.Link}}/{{.ID}}/close">{{svg "octicon-x" 16}} {{$.i18n.Tr "repo.projects.close"}}</a>
+ {{if .Description}}
+ <div class="content">
+ {{.RenderedContent|Str2html}}
+ </div>
{{end}}
- <a class="delete-button" href="#" data-url="{{$.RepoLink}}/projects/{{.ID}}/delete" data-id="{{.ID}}">{{svg "octicon-trashcan" 16}} {{$.i18n.Tr "repo.issues.label_delete"}}</a>
- </div>
- {{end}}
- {{if .Description}}
- <div class="content">
- {{.RenderedContent|Str2html}}
- </div>
- {{end}}
- </li>
+ </li>
{{end}}
{{template "base/paginate" .}}
diff --git a/templates/repo/projects/new.tmpl b/templates/repo/projects/new.tmpl
index 2da722bf9e..aabc09c80d 100644
--- a/templates/repo/projects/new.tmpl
+++ b/templates/repo/projects/new.tmpl
@@ -4,7 +4,7 @@
<div class="ui container">
<div class="navbar">
{{template "repo/issue/navbar" .}}
- {{if and (or .CanWriteIssues .CanWritePulls) .PageIsEditProject}}
+ {{if and .CanWriteProjects .PageIsEditProject}}
<div class="ui right floated secondary menu">
<a class="ui green button" href="{{$.RepoLink}}/projects/new">{{.i18n.Tr "repo.milestones.new"}}</a>
</div>
diff --git a/templates/repo/projects/view.tmpl b/templates/repo/projects/view.tmpl
index 21c6f01733..653004aa27 100644
--- a/templates/repo/projects/view.tmpl
+++ b/templates/repo/projects/view.tmpl
@@ -10,10 +10,9 @@
{{template "repo/issue/search" .}}
</div>
<div class="column right aligned">
- {{if .PageIsProjects}}
- <a class="ui green button show-modal item" data-modal="#new-board-item">{{.i18n.Tr "new_project_board"}}</a>
+ {{if and .CanWriteProjects (not .Repository.IsArchived) .PageIsProjects}}
+ <a class="ui green button show-modal item" data-modal="#new-board-item">{{.i18n.Tr "new_project_board"}}</a>
{{end}}
-
<div class="ui small modal" id="new-board-item">
<div class="header">
{{$.i18n.Tr "repo.projects.board.new"}}
@@ -45,65 +44,62 @@
<div class="ui segment board-column">
<div class="board-column-header">
<div class="ui large label board-label">{{.Title}}</div>
-
- {{ if $.IsSigned }}
- {{ if not (eq .ID 0) }}
- <div class="ui dropdown jump item poping up right" data-variation="tiny inverted">
- <span class="ui text">
- <img class="ui tiny avatar image" width="24" height="24">
- <span class="fitted not-mobile" tabindex="-1">{{svg "octicon-kebab-horizontal" 24}}</span>
- </span>
- <div class="menu user-menu" tabindex="-1">
- <a class="item show-modal button" data-modal="#edit-project-board-modal-{{.ID}}">
- {{svg "octicon-pencil" 16}}
- {{$.i18n.Tr "repo.projects.board.edit"}}
- </a>
- <a class="item show-modal button" data-modal="#delete-board-modal-{{.ID}}">
- {{svg "octicon-trashcan" 16}}
- {{$.i18n.Tr "repo.projects.board.delete"}}
- </a>
-
- <div class="ui small modal edit-project-board" id="edit-project-board-modal-{{.ID}}">
- <div class="header">
+ {{if and $.CanWriteProjects (not $.Repository.IsArchived) $.PageIsProjects (ne .ID 0)}}
+ <div class="ui dropdown jump item poping up right" data-variation="tiny inverted">
+ <span class="ui text">
+ <img class="ui tiny avatar image" width="24" height="24">
+ <span class="fitted not-mobile" tabindex="-1">{{svg "octicon-kebab-horizontal" 24}}</span>
+ </span>
+ <div class="menu user-menu" tabindex="-1">
+ <a class="item show-modal button" data-modal="#edit-project-board-modal-{{.ID}}">
+ {{svg "octicon-pencil" 16}}
{{$.i18n.Tr "repo.projects.board.edit"}}
+ </a>
+ <a class="item show-modal button" data-modal="#delete-board-modal-{{.ID}}">
+ {{svg "octicon-trashcan" 16}}
+ {{$.i18n.Tr "repo.projects.board.delete"}}
+ </a>
+
+ <div class="ui small modal edit-project-board" id="edit-project-board-modal-{{.ID}}">
+ <div class="header">
+ {{$.i18n.Tr "repo.projects.board.edit"}}
+ </div>
+ <div class="content">
+ <form class="ui form">
+ <div class="required field">
+ <label for="new_board_title">{{$.i18n.Tr "repo.projects.board.edit_title"}}</label>
+ <input class="project-board-title" id="new_board_title" name="title" value="{{.Title}}" required>
+ </div>
+
+ <div class="text right actions">
+ <div class="ui cancel button">{{$.i18n.Tr "settings.cancel"}}</div>
+ <button data-url="{{$.RepoLink}}/projects/{{$.Project.ID}}/{{.ID}}" class="ui red button">{{$.i18n.Tr "repo.projects.board.edit"}}</button>
+ </div>
+ </form>
+ </div>
</div>
- <div class="content">
- <form class="ui form">
- <div class="required field">
- <label for="new_board_title">{{$.i18n.Tr "repo.projects.board.edit_title"}}</label>
- <input class="project-board-title" id="new_board_title" name="title" value="{{.Title}}" required>
- </div>
+ <div class="ui basic modal" id="delete-board-modal-{{.ID}}">
+ <div class="ui icon header">
+ {{$.i18n.Tr "repo.projects.board.delete"}}
+ </div>
+ <div class="content center">
+ <input type="hidden" name="action" value="delete">
+ <div class="field">
+ <label>
+ {{$.i18n.Tr "repo.projects.board.deletion_desc"}}
+ </label>
+ </div>
+ </div>
+ <form class="ui form" method="post">
<div class="text right actions">
<div class="ui cancel button">{{$.i18n.Tr "settings.cancel"}}</div>
- <button data-url="{{$.RepoLink}}/projects/{{$.Project.ID}}/{{.ID}}" class="ui red button">{{$.i18n.Tr "repo.projects.board.edit"}}</button>
+ <button class="ui red button delete-project-board" data-url="{{$.RepoLink}}/projects/{{$.Project.ID}}/{{.ID}}">{{$.i18n.Tr "repo.projects.board.delete"}}</button>
</div>
</form>
</div>
</div>
-
- <div class="ui basic modal" id="delete-board-modal-{{.ID}}">
- <div class="ui icon header">
- {{$.i18n.Tr "repo.projects.board.delete"}}
- </div>
- <div class="content center">
- <input type="hidden" name="action" value="delete">
- <div class="field">
- <label>
- {{$.i18n.Tr "repo.projects.board.deletion_desc"}}
- </label>
- </div>
- </div>
- <form class="ui form" method="post">
- <div class="text right actions">
- <div class="ui cancel button">{{$.i18n.Tr "settings.cancel"}}</div>
- <button class="ui red button delete-project-board" data-url="{{$.RepoLink}}/projects/{{$.Project.ID}}/{{.ID}}">{{$.i18n.Tr "repo.projects.board.delete"}}</button>
- </div>
- </form>
- </div>
</div>
- </div>
- {{ end }}
{{ end }}
</div>
<div class="ui divider"></div>