mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 11:41:32 +01:00 
			
		
		
		
	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>
This commit is contained in:
		
							parent
							
								
									a0484890c1
								
							
						
					
					
						commit
						d4e35b9dc6
					
				| @ -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 | ||||
| 	} | ||||
|  | ||||
| @ -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("/: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.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.Group("/:boardID", func() { | ||||
| 						m.Put("", bindIgnErr(auth.EditProjectBoardTitleForm{}), repo.EditProjectBoardTitle) | ||||
| 						m.Delete("", repo.DeleteProjectBoard) | ||||
| 
 | ||||
| 					m.Post("/:index", repo.MoveIssueAcrossBoards) | ||||
| 						m.Post("/:index", repo.MoveIssueAcrossBoards) | ||||
| 					}) | ||||
| 				}) | ||||
| 			}) | ||||
| 			}, reqRepoProjectsWriter, context.RepoMustNotBeArchived()) | ||||
| 		}, reqRepoProjectsReader, repo.MustEnableProjects) | ||||
| 
 | ||||
| 		m.Group("/wiki", func() { | ||||
|  | ||||
| @ -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" .}} | ||||
|  | ||||
| @ -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> | ||||
|  | ||||
| @ -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"}} | ||||
| 								</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> | ||||
| 								</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="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> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user