Change action GETs to POST (#10462) (#10464)

* Change action GETs to POST

* submite = submit + smite

* No more # href

* Fix test

* Match other tests

* Explicit csrf

Signed-off-by: jolheiser <john.olheiser@gmail.com>

Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>
This commit is contained in:
John Olheiser 2020-02-25 15:08:21 -06:00 committed by GitHub
parent 3abb25166c
commit 4cb18601ff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 79 additions and 35 deletions

View file

@ -20,7 +20,7 @@ func createNewRelease(t *testing.T, session *TestSession, repoURL, tag, title st
resp := session.MakeRequest(t, req, http.StatusOK) resp := session.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body) htmlDoc := NewHTMLParser(t, resp.Body)
link, exists := htmlDoc.doc.Find("form").Attr("action") link, exists := htmlDoc.doc.Find("form.ui.form").Attr("action")
assert.True(t, exists, "The template has changed") assert.True(t, exists, "The template has changed")
postData := map[string]string{ postData := map[string]string{

View file

@ -485,7 +485,7 @@ func RegisterRoutes(m *macaron.Macaron) {
}, reqSignIn) }, reqSignIn)
m.Group("/:username", func() { m.Group("/:username", func() {
m.Get("/action/:action", user.Action) m.Post("/action/:action", user.Action)
}, reqSignIn) }, reqSignIn)
if macaron.Env == macaron.DEV { if macaron.Env == macaron.DEV {
@ -517,7 +517,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/^:type(issues|pulls)$", user.Issues) m.Get("/^:type(issues|pulls)$", user.Issues)
m.Get("/milestones", reqMilestonesDashboardPageEnabled, user.Milestones) m.Get("/milestones", reqMilestonesDashboardPageEnabled, user.Milestones)
m.Get("/members", org.Members) m.Get("/members", org.Members)
m.Get("/members/action/:action", org.MembersAction) m.Post("/members/action/:action", org.MembersAction)
m.Get("/teams", org.Teams) m.Get("/teams", org.Teams)
}, context.OrgAssignment(true)) }, context.OrgAssignment(true))
@ -525,8 +525,8 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Group("/:org", func() { m.Group("/:org", func() {
m.Get("/teams/:team", org.TeamMembers) m.Get("/teams/:team", org.TeamMembers)
m.Get("/teams/:team/repositories", org.TeamRepositories) m.Get("/teams/:team/repositories", org.TeamRepositories)
m.Route("/teams/:team/action/:action", "GET,POST", org.TeamsAction) m.Post("/teams/:team/action/:action", org.TeamsAction)
m.Route("/teams/:team/action/repo/:action", "GET,POST", org.TeamsRepoAction) m.Post("/teams/:team/action/repo/:action", org.TeamsRepoAction)
}, context.OrgAssignment(true, false, true)) }, context.OrgAssignment(true, false, true))
m.Group("/:org", func() { m.Group("/:org", func() {
@ -660,7 +660,7 @@ func RegisterRoutes(m *macaron.Macaron) {
}) })
}, reqSignIn, context.RepoAssignment(), context.UnitTypes(), reqRepoAdmin, context.RepoRef()) }, reqSignIn, context.RepoAssignment(), context.UnitTypes(), reqRepoAdmin, context.RepoRef())
m.Get("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), context.UnitTypes(), repo.Action) m.Post("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), context.UnitTypes(), repo.Action)
m.Group("/:username/:reponame", func() { m.Group("/:username/:reponame", func() {
m.Group("/issues", func() { m.Group("/issues", func() {
@ -714,7 +714,7 @@ func RegisterRoutes(m *macaron.Macaron) {
Post(bindIgnErr(auth.CreateMilestoneForm{}), repo.NewMilestonePost) Post(bindIgnErr(auth.CreateMilestoneForm{}), repo.NewMilestonePost)
m.Get("/:id/edit", repo.EditMilestone) m.Get("/:id/edit", repo.EditMilestone)
m.Post("/:id/edit", bindIgnErr(auth.CreateMilestoneForm{}), repo.EditMilestonePost) m.Post("/:id/edit", bindIgnErr(auth.CreateMilestoneForm{}), repo.EditMilestonePost)
m.Get("/:id/:action", repo.ChangeMilestonStatus) m.Post("/:id/:action", repo.ChangeMilestonStatus)
m.Post("/delete", repo.DeleteMilestone) m.Post("/delete", repo.DeleteMilestone)
}, context.RepoMustNotBeArchived(), reqRepoIssuesOrPullsWriter, context.RepoRef()) }, context.RepoMustNotBeArchived(), reqRepoIssuesOrPullsWriter, context.RepoRef())
m.Group("/milestone", func() { m.Group("/milestone", func() {

View file

@ -22,10 +22,10 @@
{{ $isPublic := index $.MembersIsPublicMember .ID}} {{ $isPublic := index $.MembersIsPublicMember .ID}}
{{if $isPublic}} {{if $isPublic}}
<strong>{{$.i18n.Tr "org.members.public"}}</strong> <strong>{{$.i18n.Tr "org.members.public"}}</strong>
{{if or (eq $.SignedUser.ID .ID) $.IsOrganizationOwner}}(<a href="{{$.OrgLink}}/members/action/private?uid={{.ID}}">{{$.i18n.Tr "org.members.public_helper"}}</a>){{end}} {{if or (eq $.SignedUser.ID .ID) $.IsOrganizationOwner}}(<a class="link-action" href data-url="{{$.OrgLink}}/members/action/private?uid={{.ID}}">{{$.i18n.Tr "org.members.public_helper"}}</a>){{end}}
{{else}} {{else}}
<strong>{{$.i18n.Tr "org.members.private"}}</strong> <strong>{{$.i18n.Tr "org.members.private"}}</strong>
{{if or (eq $.SignedUser.ID .ID) $.IsOrganizationOwner}}(<a href="{{$.OrgLink}}/members/action/public?uid={{.ID}}">{{$.i18n.Tr "org.members.private_helper"}}</a>){{end}} {{if or (eq $.SignedUser.ID .ID) $.IsOrganizationOwner}}(<a class="link-action" href data-url="{{$.OrgLink}}/members/action/public?uid={{.ID}}">{{$.i18n.Tr "org.members.private_helper"}}</a>){{end}}
{{end}} {{end}}
</div> </div>
</div> </div>

View file

@ -27,7 +27,10 @@
{{range .Team.Members}} {{range .Team.Members}}
<div class="item"> <div class="item">
{{if $.IsOrganizationOwner}} {{if $.IsOrganizationOwner}}
<a class="ui red small button right" href="{{$.OrgLink}}/teams/{{$.Team.LowerName}}/action/remove?uid={{.ID}}">{{$.i18n.Tr "org.members.remove"}}</a> <form method="post" action="{{$.OrgLink}}/teams/{{$.Team.LowerName}}/action/remove?uid={{.ID}}">
{{$.CsrfTokenHtml}}
<button type="submit" class="ui red small button right" >{{$.i18n.Tr "org.members.remove"}}</button>
</form>
{{end}} {{end}}
<a href="{{.HomeLink}}"> <a href="{{.HomeLink}}">
<img class="ui avatar image" src="{{.RelAvatarLink}}"> <img class="ui avatar image" src="{{.RelAvatarLink}}">

View file

@ -35,7 +35,10 @@
{{range .Team.Repos}} {{range .Team.Repos}}
<div class="item"> <div class="item">
{{if $canAddRemove}} {{if $canAddRemove}}
<a class="ui red small button right" href="{{$.OrgLink}}/teams/{{$.Team.LowerName}}/action/repo/remove?repoid={{.ID}}">{{$.i18n.Tr "remove"}}</a> <form method="post" action="{{$.OrgLink}}/teams/{{$.Team.LowerName}}/action/repo/remove?repoid={{.ID}}">
{{$.CsrfTokenHtml}}
<button type="submit" class="ui red small button right">{{$.i18n.Tr "remove"}}</button>
</form>
{{end}} {{end}}
<a class="member" href="{{AppSubUrl}}/{{$.Org.Name}}/{{.Name}}"> <a class="member" href="{{AppSubUrl}}/{{$.Org.Name}}/{{.Name}}">
<i class="octicon octicon-{{if .IsPrivate}}lock{{else if .IsFork}}repo-forked{{else if .IsMirror}}repo-clone{{else}}repo{{end}}"></i> <i class="octicon octicon-{{if .IsPrivate}}lock{{else if .IsFork}}repo-forked{{else if .IsMirror}}repo-clone{{else}}repo{{end}}"></i>

View file

@ -3,9 +3,15 @@
<strong>{{.Team.Name}}</strong> <strong>{{.Team.Name}}</strong>
<div class="ui right"> <div class="ui right">
{{if .Team.IsMember $.SignedUser.ID}} {{if .Team.IsMember $.SignedUser.ID}}
<a class="ui red tiny button" href="{{.OrgLink}}/teams/{{.Team.LowerName}}/action/leave?uid={{$.SignedUser.ID}}&page=home">{{$.i18n.Tr "org.teams.leave"}}</a> <form method="post" action="{{.OrgLink}}/teams/{{.Team.LowerName}}/action/leave?uid={{$.SignedUser.ID}}&page=home">
{{$.CsrfTokenHtml}}
<button type="submit" class="ui red tiny button">{{$.i18n.Tr "org.teams.leave"}}</button>
</form>
{{else if .IsOrganizationOwner}} {{else if .IsOrganizationOwner}}
<a class="ui blue tiny button" href="{{.OrgLink}}/teams/{{.Team.LowerName}}/action/join?uid={{$.SignedUser.ID}}&page=team">{{$.i18n.Tr "org.teams.join"}}</a> <form method="post" action="{{.OrgLink}}/teams/{{.Team.LowerName}}/action/join?uid={{$.SignedUser.ID}}&page=team">
{{$.CsrfTokenHtml}}
<button type="submit" class="ui blue tiny button">{{$.i18n.Tr "org.teams.join"}}</button>
</form>
{{end}} {{end}}
</div> </div>
</h4> </h4>

View file

@ -17,9 +17,15 @@
<a class="text black" href="{{$.OrgLink}}/teams/{{.LowerName}}"><strong>{{.Name}}</strong></a> <a class="text black" href="{{$.OrgLink}}/teams/{{.LowerName}}"><strong>{{.Name}}</strong></a>
<div class="ui right"> <div class="ui right">
{{if .IsMember $.SignedUser.ID}} {{if .IsMember $.SignedUser.ID}}
<a class="ui red small button" href="{{$.OrgLink}}/teams/{{.LowerName}}/action/leave?uid={{$.SignedUser.ID}}">{{$.i18n.Tr "org.teams.leave"}}</a> <form method="post" action="{{$.OrgLink}}/teams/{{.LowerName}}/action/leave?uid={{$.SignedUser.ID}}">
{{$.CsrfTokenHtml}}
<button type="submit" class="ui red small button">{{$.i18n.Tr "org.teams.leave"}}</button>
</form>
{{else if $.IsOrganizationOwner}} {{else if $.IsOrganizationOwner}}
<a class="ui blue small button" href="{{$.OrgLink}}/teams/{{.LowerName}}/action/join?uid={{$.SignedUser.ID}}">{{$.i18n.Tr "org.teams.join"}}</a> <form method="post" action="{{$.OrgLink}}/teams/{{.LowerName}}/action/join?uid={{$.SignedUser.ID}}">
{{$.CsrfTokenHtml}}
<button type="submit" class="ui blue small button">{{$.i18n.Tr "org.teams.join"}}</button>
</form>
{{end}} {{end}}
</div> </div>
</div> </div>

View file

@ -20,22 +20,28 @@
</div> </div>
{{if not .IsBeingCreated}} {{if not .IsBeingCreated}}
<div class="repo-buttons"> <div class="repo-buttons">
<div class="ui labeled button" tabindex="0"> <form method="post" action="{{$.RepoLink}}/action/{{if $.IsWatchingRepo}}un{{end}}watch?redirect_to={{$.Link}}">
<a class="ui compact basic button" href="{{$.RepoLink}}/action/{{if $.IsWatchingRepo}}un{{end}}watch?redirect_to={{$.Link}}"> {{$.CsrfTokenHtml}}
<i class="icon fa-eye{{if not $.IsWatchingRepo}}-slash{{end}}"></i>{{if $.IsWatchingRepo}}{{$.i18n.Tr "repo.unwatch"}}{{else}}{{$.i18n.Tr "repo.watch"}}{{end}} <div class="ui labeled button" tabindex="0">
</a> <button type="submit" class="ui compact basic button">
<a class="ui basic label" href="{{.Link}}/watchers"> <i class="icon fa-eye{{if not $.IsWatchingRepo}}-slash{{end}}"></i>{{if $.IsWatchingRepo}}{{$.i18n.Tr "repo.unwatch"}}{{else}}{{$.i18n.Tr "repo.watch"}}{{end}}
{{.NumWatches}} </button>
</a> <a class="ui basic label" href="{{.Link}}/watchers">
</div> {{.NumWatches}}
<div class="ui labeled button" tabindex="0"> </a>
<a class="ui compact basic button" href="{{$.RepoLink}}/action/{{if $.IsStaringRepo}}un{{end}}star?redirect_to={{$.Link}}"> </div>
<i class="icon star{{if not $.IsStaringRepo}} outline{{end}}"></i>{{if $.IsStaringRepo}}{{$.i18n.Tr "repo.unstar"}}{{else}}{{$.i18n.Tr "repo.star"}}{{end}} </form>
</a> <form method="post" action="{{$.RepoLink}}/action/{{if $.IsStaringRepo}}un{{end}}star?redirect_to={{$.Link}}">
<a class="ui basic label" href="{{.Link}}/stars"> {{$.CsrfTokenHtml}}
{{.NumStars}} <div class="ui labeled button" tabindex="0">
</a> <button type="submit" class="ui compact basic button">
</div> <i class="icon star{{if not $.IsStaringRepo}} outline{{end}}"></i>{{if $.IsStaringRepo}}{{$.i18n.Tr "repo.unstar"}}{{else}}{{$.i18n.Tr "repo.star"}}{{end}}
</button>
<a class="ui basic label" href="{{.Link}}/stars">
{{.NumStars}}
</a>
</div>
</form>
{{if and (not .IsEmpty) ($.Permission.CanRead $.UnitTypeCode)}} {{if and (not .IsEmpty) ($.Permission.CanRead $.UnitTypeCode)}}
<div class="ui labeled button {{if and ($.IsSigned) (not $.CanSignedUserFork)}}disabled-repo-button{{end}}" tabindex="0"> <div class="ui labeled button {{if and ($.IsSigned) (not $.CanSignedUserFork)}}disabled-repo-button{{end}}" tabindex="0">
<a class="ui compact basic button {{if or (not $.IsSigned) (not $.CanSignedUserFork)}}poping up{{end}}" {{if $.CanSignedUserFork}}href="{{AppSubUrl}}/repo/fork/{{.ID}}"{{else if $.IsSigned}} data-content="{{$.i18n.Tr "repo.fork_from_self"}}" {{ else }} data-content="{{$.i18n.Tr "repo.fork_guest_user" }}" rel="nofollow" href="{{AppSubUrl}}/user/login?redirect_to={{AppSubUrl}}/repo/fork/{{.ID}}" {{end}} data-position="top center" data-variation="tiny"> <a class="ui compact basic button {{if or (not $.IsSigned) (not $.CanSignedUserFork)}}poping up{{end}}" {{if $.CanSignedUserFork}}href="{{AppSubUrl}}/repo/fork/{{.ID}}"{{else if $.IsSigned}} data-content="{{$.i18n.Tr "repo.fork_from_self"}}" {{ else }} data-content="{{$.i18n.Tr "repo.fork_guest_user" }}" rel="nofollow" href="{{AppSubUrl}}/user/login?redirect_to={{AppSubUrl}}/repo/fork/{{.ID}}" {{end}} data-position="top center" data-variation="tiny">

View file

@ -71,9 +71,9 @@
<div class="ui right operate"> <div class="ui right operate">
<a href="{{$.Link}}/{{.ID}}/edit" data-id={{.ID}} data-title={{.Name}}><i class="octicon octicon-pencil"></i> {{$.i18n.Tr "repo.issues.label_edit"}}</a> <a href="{{$.Link}}/{{.ID}}/edit" data-id={{.ID}} data-title={{.Name}}><i class="octicon octicon-pencil"></i> {{$.i18n.Tr "repo.issues.label_edit"}}</a>
{{if .IsClosed}} {{if .IsClosed}}
<a href="{{$.Link}}/{{.ID}}/open" data-id={{.ID}} data-title={{.Name}}><i class="octicon octicon-check"></i> {{$.i18n.Tr "repo.milestones.open"}}</a> <a class="link-action" href data-url="{{$.Link}}/{{.ID}}/open" data-id={{.ID}} data-title={{.Name}}><i class="octicon octicon-check"></i> {{$.i18n.Tr "repo.milestones.open"}}</a>
{{else}} {{else}}
<a href="{{$.Link}}/{{.ID}}/close" data-id={{.ID}} data-title={{.Name}}><i class="octicon octicon-x"></i> {{$.i18n.Tr "repo.milestones.close"}}</a> <a class="link-action" href data-url="{{$.Link}}/{{.ID}}/close" data-id={{.ID}} data-title={{.Name}}><i class="octicon octicon-x"></i> {{$.i18n.Tr "repo.milestones.close"}}</a>
{{end}} {{end}}
<a class="delete-button" href="#" data-url="{{$.RepoLink}}/milestones/delete" data-id="{{.ID}}"><i class="octicon octicon-trashcan"></i> {{$.i18n.Tr "repo.issues.label_delete"}}</a> <a class="delete-button" href="#" data-url="{{$.RepoLink}}/milestones/delete" data-id="{{.ID}}"><i class="octicon octicon-trashcan"></i> {{$.i18n.Tr "repo.issues.label_delete"}}</a>
</div> </div>

View file

@ -65,9 +65,15 @@
{{if and .IsSigned (ne .SignedUserName .Owner.Name)}} {{if and .IsSigned (ne .SignedUserName .Owner.Name)}}
<li class="follow"> <li class="follow">
{{if .SignedUser.IsFollowing .Owner.ID}} {{if .SignedUser.IsFollowing .Owner.ID}}
<a class="ui basic red button" href="{{.Link}}/action/unfollow?redirect_to={{$.Link}}"><i class="octicon octicon-person"></i> {{.i18n.Tr "user.unfollow"}}</a> <form method="post" action="{{.Link}}/action/unfollow?redirect_to={{$.Link}}">
{{$.CsrfTokenHtml}}
<button type="submit" class="ui basic red button"><i class="octicon octicon-person"></i> {{.i18n.Tr "user.unfollow"}}</button>
</form>
{{else}} {{else}}
<a class="ui basic green button" href="{{.Link}}/action/follow?redirect_to={{$.Link}}"><i class="octicon octicon-person"></i> {{.i18n.Tr "user.follow"}}</a> <form method="post" action="{{.Link}}/action/follow?redirect_to={{$.Link}}">
{{$.CsrfTokenHtml}}
<button type="submit" class="ui basic green button"><i class="octicon octicon-person"></i> {{.i18n.Tr "user.follow"}}</button>
</form>
{{end}} {{end}}
</li> </li>
{{end}} {{end}}

View file

@ -2479,6 +2479,7 @@ $(document).ready(() => {
// Helpers. // Helpers.
$('.delete-button').click(showDeletePopup); $('.delete-button').click(showDeletePopup);
$('.add-all-button').click(showAddAllPopup); $('.add-all-button').click(showAddAllPopup);
$('.link-action').click(linkAction);
$('.delete-branch-button').click(showDeletePopup); $('.delete-branch-button').click(showDeletePopup);
@ -2736,6 +2737,19 @@ function showAddAllPopup() {
return false; return false;
} }
function linkAction() {
const $this = $(this);
$.post($this.data('url'), {
_csrf: csrf
}).done((data) => {
if (data.redirect) {
window.location.href = data.redirect;
} else {
window.location.reload();
}
});
}
function initVueComponents() { function initVueComponents() {
const vueDelimeters = ['${', '}']; const vueDelimeters = ['${', '}'];