mirror of
https://github.com/gogs/gogs.git
synced 2025-12-17 12:03:16 +01:00
templates: make state changing routes to POST method (#5541)
- pkg/context: add ParamsUser to unify the injection process
This commit is contained in:
10
cmd/web.go
10
cmd/web.go
@@ -257,7 +257,7 @@ func runWeb(c *cli.Context) error {
|
||||
m.Get("/email2user", user.Email2User)
|
||||
m.Get("/forget_password", user.ForgotPasswd)
|
||||
m.Post("/forget_password", user.ForgotPasswdPost)
|
||||
m.Get("/logout", user.SignOut)
|
||||
m.Post("/logout", user.SignOut)
|
||||
})
|
||||
// ***** END: User *****
|
||||
|
||||
@@ -308,7 +308,7 @@ func runWeb(c *cli.Context) error {
|
||||
m.Get("/followers", user.Followers)
|
||||
m.Get("/following", user.Following)
|
||||
m.Get("/stars", user.Stars)
|
||||
})
|
||||
}, context.InjectParamsUser())
|
||||
|
||||
m.Get("/attachments/:uuid", func(c *context.Context) {
|
||||
attach, err := models.GetAttachmentByUUID(c.Params(":uuid"))
|
||||
@@ -340,8 +340,8 @@ func runWeb(c *cli.Context) error {
|
||||
}, ignSignIn)
|
||||
|
||||
m.Group("/:username", func() {
|
||||
m.Get("/action/:action", user.Action)
|
||||
}, reqSignIn)
|
||||
m.Post("/action/:action", user.Action)
|
||||
}, reqSignIn, context.InjectParamsUser())
|
||||
|
||||
if macaron.Env == macaron.DEV {
|
||||
m.Get("/template/*", dev.TemplatePreview)
|
||||
@@ -484,7 +484,7 @@ func runWeb(c *cli.Context) error {
|
||||
})
|
||||
}, reqSignIn, context.RepoAssignment(), reqRepoAdmin, context.RepoRef())
|
||||
|
||||
m.Get("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), repo.Action)
|
||||
m.Post("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), repo.Action)
|
||||
m.Group("/:username/:reponame", func() {
|
||||
m.Get("/issues", repo.RetrieveLabels, repo.Issues)
|
||||
m.Get("/issues/:index", repo.ViewIssue)
|
||||
|
||||
2
gogs.go
2
gogs.go
@@ -16,7 +16,7 @@ import (
|
||||
"github.com/gogs/gogs/pkg/setting"
|
||||
)
|
||||
|
||||
const APP_VER = "0.11.76.1204"
|
||||
const APP_VER = "0.11.77.1206"
|
||||
|
||||
func init() {
|
||||
setting.AppVer = APP_VER
|
||||
|
||||
30
pkg/context/user.go
Normal file
30
pkg/context/user.go
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright 2018 The Gogs Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package context
|
||||
|
||||
import (
|
||||
"gopkg.in/macaron.v1"
|
||||
|
||||
"github.com/gogs/gogs/models"
|
||||
"github.com/gogs/gogs/models/errors"
|
||||
)
|
||||
|
||||
// ParamsUser is the wrapper type of the target user defined by URL parameter, namely ':username'.
|
||||
type ParamsUser struct {
|
||||
*models.User
|
||||
}
|
||||
|
||||
// InjectParamsUser returns a handler that retrieves target user based on URL parameter ':username',
|
||||
// and injects it as *ParamsUser.
|
||||
func InjectParamsUser() macaron.Handler {
|
||||
return func(c *Context) {
|
||||
user, err := models.GetUserByName(c.Params(":username"))
|
||||
if err != nil {
|
||||
c.NotFoundOrServerError("GetUserByName", errors.IsUserNotExist, err)
|
||||
return
|
||||
}
|
||||
c.Map(&ParamsUser{user})
|
||||
}
|
||||
}
|
||||
@@ -347,6 +347,9 @@ footer .ui.language .menu {
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
.display.inline {
|
||||
display: inline;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
@@ -2934,6 +2937,9 @@ footer .ui.language .menu {
|
||||
margin-top: 5px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
.user.profile .ui.card .profile-avatar {
|
||||
height: 287px;
|
||||
}
|
||||
.user.profile .ui.card .header {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
@@ -1336,6 +1336,10 @@ $(document).ready(function () {
|
||||
window.location.href = $this.data('done-url');
|
||||
});
|
||||
});
|
||||
// To make arbitrary form element to behave like a submit button
|
||||
$('.submit-button').click(function () {
|
||||
$($(this).data('form')).submit();
|
||||
});
|
||||
|
||||
// Check or select on option to enable/disable target region
|
||||
$('.enable-system').change(function () {
|
||||
|
||||
@@ -384,6 +384,11 @@ footer {
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
.display {
|
||||
&.inline {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -60,6 +60,9 @@
|
||||
|
||||
&.profile {
|
||||
.ui.card {
|
||||
.profile-avatar {
|
||||
height: 287px;
|
||||
}
|
||||
.header {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
@@ -6,13 +6,11 @@ package user
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/Unknwon/paginater"
|
||||
|
||||
"github.com/gogs/gogs/models"
|
||||
"github.com/gogs/gogs/models/errors"
|
||||
"github.com/gogs/gogs/pkg/context"
|
||||
"github.com/gogs/gogs/pkg/setting"
|
||||
"github.com/gogs/gogs/pkg/tool"
|
||||
@@ -24,59 +22,30 @@ const (
|
||||
STARS = "user/meta/stars"
|
||||
)
|
||||
|
||||
func GetUserByName(c *context.Context, name string) *models.User {
|
||||
user, err := models.GetUserByName(name)
|
||||
if err != nil {
|
||||
c.NotFoundOrServerError("GetUserByName", errors.IsUserNotExist, err)
|
||||
return nil
|
||||
}
|
||||
return user
|
||||
}
|
||||
|
||||
// GetUserByParams returns user whose name is presented in URL paramenter.
|
||||
func GetUserByParams(c *context.Context) *models.User {
|
||||
return GetUserByName(c, c.Params(":username"))
|
||||
}
|
||||
|
||||
func Profile(c *context.Context) {
|
||||
uname := c.Params(":username")
|
||||
// Special handle for FireFox requests favicon.ico.
|
||||
if uname == "favicon.ico" {
|
||||
c.ServeFile(path.Join(setting.StaticRootPath, "public/img/favicon.png"))
|
||||
return
|
||||
} else if strings.HasSuffix(uname, ".png") {
|
||||
c.Error(404)
|
||||
return
|
||||
}
|
||||
|
||||
func Profile(c *context.Context, puser *context.ParamsUser) {
|
||||
isShowKeys := false
|
||||
if strings.HasSuffix(uname, ".keys") {
|
||||
if strings.HasSuffix(c.Params(":username"), ".keys") {
|
||||
isShowKeys = true
|
||||
}
|
||||
|
||||
ctxUser := GetUserByName(c, strings.TrimSuffix(uname, ".keys"))
|
||||
if c.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
// Show SSH keys.
|
||||
if isShowKeys {
|
||||
ShowSSHKeys(c, ctxUser.ID)
|
||||
ShowSSHKeys(c, puser.ID)
|
||||
return
|
||||
}
|
||||
|
||||
if ctxUser.IsOrganization() {
|
||||
if puser.IsOrganization() {
|
||||
showOrgProfile(c)
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["Title"] = ctxUser.DisplayName()
|
||||
c.Data["PageIsUserProfile"] = true
|
||||
c.Data["Owner"] = ctxUser
|
||||
c.Title(puser.DisplayName())
|
||||
c.PageIs("UserProfile")
|
||||
c.Data["Owner"] = puser
|
||||
|
||||
orgs, err := models.GetOrgsByUserID(ctxUser.ID, c.IsLogged && (c.User.IsAdmin || c.User.ID == ctxUser.ID))
|
||||
orgs, err := models.GetOrgsByUserID(puser.ID, c.IsLogged && (c.User.IsAdmin || c.User.ID == puser.ID))
|
||||
if err != nil {
|
||||
c.Handle(500, "GetOrgsByUserIDDesc", err)
|
||||
c.ServerError("GetOrgsByUserIDDesc", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -86,7 +55,7 @@ func Profile(c *context.Context) {
|
||||
c.Data["TabName"] = tab
|
||||
switch tab {
|
||||
case "activity":
|
||||
retrieveFeeds(c, ctxUser, -1, true)
|
||||
retrieveFeeds(c, puser.User, -1, true)
|
||||
if c.Written() {
|
||||
return
|
||||
}
|
||||
@@ -96,65 +65,52 @@ func Profile(c *context.Context) {
|
||||
page = 1
|
||||
}
|
||||
|
||||
showPrivate := c.IsLogged && (ctxUser.ID == c.User.ID || c.User.IsAdmin)
|
||||
showPrivate := c.IsLogged && (puser.ID == c.User.ID || c.User.IsAdmin)
|
||||
c.Data["Repos"], err = models.GetUserRepositories(&models.UserRepoOptions{
|
||||
UserID: ctxUser.ID,
|
||||
UserID: puser.ID,
|
||||
Private: showPrivate,
|
||||
Page: page,
|
||||
PageSize: setting.UI.User.RepoPagingNum,
|
||||
})
|
||||
if err != nil {
|
||||
c.Handle(500, "GetRepositories", err)
|
||||
c.ServerError("GetRepositories", err)
|
||||
return
|
||||
}
|
||||
|
||||
count := models.CountUserRepositories(ctxUser.ID, showPrivate)
|
||||
count := models.CountUserRepositories(puser.ID, showPrivate)
|
||||
c.Data["Page"] = paginater.New(int(count), setting.UI.User.RepoPagingNum, page, 5)
|
||||
}
|
||||
|
||||
c.HTML(200, PROFILE)
|
||||
c.Success(PROFILE)
|
||||
}
|
||||
|
||||
func Followers(c *context.Context) {
|
||||
u := GetUserByParams(c)
|
||||
if c.Written() {
|
||||
return
|
||||
}
|
||||
c.Data["Title"] = u.DisplayName()
|
||||
func Followers(c *context.Context, puser *context.ParamsUser) {
|
||||
c.Title(puser.DisplayName())
|
||||
c.PageIs("Followers")
|
||||
c.Data["CardsTitle"] = c.Tr("user.followers")
|
||||
c.Data["PageIsFollowers"] = true
|
||||
c.Data["Owner"] = u
|
||||
repo.RenderUserCards(c, u.NumFollowers, u.GetFollowers, FOLLOWERS)
|
||||
c.Data["Owner"] = puser
|
||||
repo.RenderUserCards(c, puser.NumFollowers, puser.GetFollowers, FOLLOWERS)
|
||||
}
|
||||
|
||||
func Following(c *context.Context) {
|
||||
u := GetUserByParams(c)
|
||||
if c.Written() {
|
||||
return
|
||||
}
|
||||
c.Data["Title"] = u.DisplayName()
|
||||
func Following(c *context.Context, puser *context.ParamsUser) {
|
||||
c.Title(puser.DisplayName())
|
||||
c.PageIs("Following")
|
||||
c.Data["CardsTitle"] = c.Tr("user.following")
|
||||
c.Data["PageIsFollowing"] = true
|
||||
c.Data["Owner"] = u
|
||||
repo.RenderUserCards(c, u.NumFollowing, u.GetFollowing, FOLLOWERS)
|
||||
c.Data["Owner"] = puser
|
||||
repo.RenderUserCards(c, puser.NumFollowing, puser.GetFollowing, FOLLOWERS)
|
||||
}
|
||||
|
||||
func Stars(c *context.Context) {
|
||||
|
||||
}
|
||||
|
||||
func Action(c *context.Context) {
|
||||
u := GetUserByParams(c)
|
||||
if c.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
func Action(c *context.Context, puser *context.ParamsUser) {
|
||||
var err error
|
||||
switch c.Params(":action") {
|
||||
case "follow":
|
||||
err = models.FollowUser(c.User.ID, u.ID)
|
||||
err = models.FollowUser(c.UserID(), puser.ID)
|
||||
case "unfollow":
|
||||
err = models.UnfollowUser(c.User.ID, u.ID)
|
||||
err = models.UnfollowUser(c.UserID(), puser.ID)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@@ -164,7 +120,7 @@ func Action(c *context.Context) {
|
||||
|
||||
redirectTo := c.Query("redirect_to")
|
||||
if !tool.IsSameSiteURLPath(redirectTo) {
|
||||
redirectTo = u.HomeLink()
|
||||
redirectTo = puser.HomeLink()
|
||||
}
|
||||
c.Redirect(redirectTo)
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
0.11.76.1204
|
||||
0.11.77.1206
|
||||
|
||||
@@ -160,9 +160,13 @@
|
||||
{{end}}
|
||||
|
||||
<div class="divider"></div>
|
||||
<a class="item" href="{{AppSubURL}}/user/logout">
|
||||
|
||||
<form id="logout-form" class="item" action="{{AppSubURL}}/user/logout" method="POST">
|
||||
{{.CSRFTokenHTML}}
|
||||
<div class="submit-button" data-form="#logout-form">
|
||||
<i class="octicon octicon-sign-out"></i> {{.i18n.Tr "sign_out"}}
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div><!-- end content avatar menu -->
|
||||
</div><!-- end dropdown avatar menu -->
|
||||
</div><!-- end signed user right menu -->
|
||||
|
||||
@@ -20,22 +20,28 @@
|
||||
|
||||
{{if not $.IsGuest}}
|
||||
<div class="ui right">
|
||||
<form class="display inline" action="{{$.RepoLink}}/action/{{if $.IsWatchingRepo}}un{{end}}watch?redirect_to={{$.Link}}" method="POST">
|
||||
{{$.CSRFTokenHTML}}
|
||||
<div class="ui labeled button" tabindex="0">
|
||||
<a class="ui basic button" href="{{$.RepoLink}}/action/{{if $.IsWatchingRepo}}un{{end}}watch?redirect_to={{$.Link}}">
|
||||
<button class="ui basic button">
|
||||
<i class="eye{{if not $.IsWatchingRepo}} slash outline{{end}} icon"></i>{{if $.IsWatchingRepo}}{{$.i18n.Tr "repo.unwatch"}}{{else}}{{$.i18n.Tr "repo.watch"}}{{end}}
|
||||
</a>
|
||||
</button>
|
||||
<a class="ui basic label" href="{{.Link}}/watchers">
|
||||
{{.NumWatches}}
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
<form class="display inline" action="{{$.RepoLink}}/action/{{if $.IsStaringRepo}}un{{end}}star?redirect_to={{$.Link}}" method="POST">
|
||||
{{$.CSRFTokenHTML}}
|
||||
<div class="ui labeled button" tabindex="0">
|
||||
<a class="ui basic button" href="{{$.RepoLink}}/action/{{if $.IsStaringRepo}}un{{end}}star?redirect_to={{$.Link}}">
|
||||
<button class="ui basic button">
|
||||
<i class="star{{if not $.IsStaringRepo}} outline{{end}} icon"></i>{{if $.IsStaringRepo}}{{$.i18n.Tr "repo.unstar"}}{{else}}{{$.i18n.Tr "repo.star"}}{{end}}
|
||||
</a>
|
||||
</button>
|
||||
<a class="ui basic label" href="{{.Link}}/stars">
|
||||
{{.NumStars}}
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
{{if .CanBeForked}}
|
||||
<div class="ui labeled button" tabindex="0">
|
||||
<a class="ui basic button {{if eq .OwnerID $.LoggedUserID}}poping up{{end}}" href="{{AppSubURL}}/repo/fork/{{.ID}}">
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
<div class="ui five wide column">
|
||||
<div class="ui card">
|
||||
{{if eq .LoggedUserName .Owner.Name}}
|
||||
<a class="image poping up" href="{{AppSubURL}}/user/settings/avatar" id="profile-avatar" data-content="{{.i18n.Tr "user.change_avatar"}}" data-variation="inverted tiny" data-position="bottom center">
|
||||
<img src="{{AppendAvatarSize .Owner.RelAvatarLink 290}}" title="{{.Owner.Name}}"/>
|
||||
<a class="profile-avatar image poping up" href="{{AppSubURL}}/user/settings/avatar" id="profile-avatar" data-content="{{.i18n.Tr "user.change_avatar"}}" data-variation="inverted tiny" data-position="bottom center">
|
||||
<img src="{{AppendAvatarSize .Owner.RelAvatarLink 287}}" title="{{.Owner.Name}}"/>
|
||||
</a>
|
||||
{{else}}
|
||||
<span class="image">
|
||||
<img src="{{AppendAvatarSize .Owner.RelAvatarLink 290}}" title="{{.Owner.Name}}"/>
|
||||
<span class="profile-avatar image">
|
||||
<img src="{{AppendAvatarSize .Owner.RelAvatarLink 287}}" title="{{.Owner.Name}}"/>
|
||||
</span>
|
||||
{{end}}
|
||||
<div class="content">
|
||||
@@ -63,9 +63,19 @@
|
||||
{{if and .IsLogged (ne .LoggedUserName .Owner.Name)}}
|
||||
<li class="follow">
|
||||
{{if .LoggedUser.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 action="{{.Link}}/action/unfollow?redirect_to={{$.Link}}" method="POST">
|
||||
{{.CSRFTokenHTML}}
|
||||
<button class="ui basic red button">
|
||||
<i class="octicon octicon-person"></i> {{.i18n.Tr "user.unfollow"}}
|
||||
</button>
|
||||
</form>
|
||||
{{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 action="{{.Link}}/action/follow?redirect_to={{$.Link}}" method="POST">
|
||||
{{.CSRFTokenHTML}}
|
||||
<button class="ui basic green button">
|
||||
<i class="octicon octicon-person"></i> {{.i18n.Tr "user.follow"}}
|
||||
</button>
|
||||
</form>
|
||||
{{end}}
|
||||
</li>
|
||||
{{end}}
|
||||
|
||||
Reference in New Issue
Block a user