소스 검색

make state changing routes to POST method #81

Yoginth 7 년 전
부모
커밋
1b6e333ac4
9개의 변경된 파일96개의 추가작업 그리고 120개의 파일을 삭제
  1. 5 5
      cmd/web.go
  2. 6 0
      public/less/_base.less
  3. 3 0
      public/less/_user.less
  4. 2 4
      routes/user/certificate.go
  5. 4 7
      routes/user/embed.go
  6. 30 74
      routes/user/profile.go
  7. 7 4
      templates/base/head.tmpl
  8. 23 20
      templates/repo/header.tmpl
  9. 16 6
      templates/user/profile.tmpl

+ 5 - 5
cmd/web.go

@@ -242,7 +242,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 *****
 
@@ -326,7 +326,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"))
@@ -358,8 +358,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)
@@ -498,7 +498,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)

+ 6 - 0
public/less/_base.less

@@ -469,6 +469,12 @@ footer {
 	display: none;
 }
 
+.display {
+	&.inline {
+		display: inline;
+	}
+}
+
 .center {
 	text-align: center;
 }

+ 3 - 0
public/less/_user.less

@@ -70,6 +70,9 @@
 
 	&.profile {
 		.ui.card {
+			.profile-avatar {
+				height: 287px;
+			}
 			.header {
 				word-break: break-all;
 			}

+ 2 - 4
routes/user/certificate.go

@@ -2,16 +2,14 @@ package user
 
 import (
 	"gitote/gitote/pkg/context"
-	"strings"
 )
 
 const (
 	INTERNCERTIFICATE = "misc/internscert"
 )
 
-func InternCertificate(c *context.Context) {
-	ctxUser := GetUserByName(c, strings.TrimSuffix(c.Params(":username"), ""))
-	c.Data["Owner"] = ctxUser
+func InternCertificate(c *context.Context, puser *context.ParamsUser) {
+	c.Data["Owner"] = puser
 
 	c.HTML(200, INTERNCERTIFICATE)
 }

+ 4 - 7
routes/user/embed.go

@@ -2,19 +2,16 @@ package user
 
 import (
 	"gitote/gitote/pkg/context"
-	"strings"
 )
 
 const (
 	EMBED = "embed/user"
 )
 
-func Embed(c *context.Context) {
-	ctxUser := GetUserByName(c, strings.TrimSuffix(c.Params(":username"), ""))
-
-	c.Data["Title"] = ctxUser.DisplayName()
-	c.Data["PageIsUserProfile"] = true
-	c.Data["Owner"] = ctxUser
+func Embed(c *context.Context, puser *context.ParamsUser) {
+	c.Title(puser.DisplayName())
+	c.PageIs("PageIsUserProfile")
+	c.Data["Owner"] = puser
 
 	c.HTML(200, EMBED)
 }

+ 30 - 74
routes/user/profile.go

@@ -3,12 +3,10 @@ package user
 import (
 	"fmt"
 	"gitote/gitote/models"
-	"gitote/gitote/models/errors"
 	"gitote/gitote/pkg/context"
 	"gitote/gitote/pkg/setting"
 	"gitote/gitote/pkg/tool"
 	"gitote/gitote/routes/repo"
-	"path"
 	"strings"
 
 	"gitlab.com/yoginth/paginater"
@@ -19,59 +17,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
 	}
 
@@ -81,7 +50,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
 		}
@@ -91,68 +60,55 @@ 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)
 	}
-	if ctxUser.Suspended == true {
+	if puser.Suspended == true {
 		c.Handle(404, "Suspended", err)
 	} else {
-		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 {
@@ -162,7 +118,7 @@ func Action(c *context.Context) {
 
 	redirectTo := c.Query("redirect_to")
 	if !tool.IsSameSiteURLPath(redirectTo) {
-		redirectTo = u.HomeLink()
+		redirectTo = puser.HomeLink()
 	}
 	c.Redirect(redirectTo)
 }

+ 7 - 4
templates/base/head.tmpl

@@ -74,7 +74,7 @@
 	{{end}}
 
 	<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.1/semantic.min.js"></script>
-	<script src="https://cdn.jsdelivr.net/npm/gitote@1.3.2/js/gitote.min.js?v={{MD5 AppVer}}"></script>
+	<script src="https://cdn.jsdelivr.net/npm/gitote@1.3.4/js/gitote.min.js?v={{MD5 AppVer}}"></script>
 	<script src="{{AppURL}}expansion/expansion.js?v={{MD5 AppVer}}"></script>
 
 	{{if not .IsLogged}}
@@ -214,9 +214,12 @@
 													</div>
 													<div class="divider"></div>
 												{{end}}
-												<a class="item" href="{{AppSubURL}}/user/logout">
-													<i class="menu-icon octicon">👋</i>{{.i18n.Tr "sign_out"}}
-												</a>
+												<form id="logout-form" class="item" action="{{AppSubURL}}/user/logout" method="POST">
+													{{.CSRFTokenHTML}}
+													<div class="submit-button" data-form="#logout-form">
+														<i class="menu-icon octicon">👋</i>{{.i18n.Tr "sign_out"}}
+													</div>
+												</form>
 												<div class="divider"></div>
 												<a style="margin-top:-8px" class="item" target="_blank" href="https://madewithlove.org.in">
 													<span>

+ 23 - 20
templates/repo/header.tmpl

@@ -24,26 +24,29 @@
 
 					{{if not $.IsGuest}}
 						<div class="ui right">
-							<div class="ui labeled button" tabindex="0">
-								<a class="ui basic button" href="{{$.RepoLink}}/action/{{if $.IsWatchingRepo}}un{{end}}watch?redirect_to={{$.Link}}">
-									<i class="menu-icon octicon">👀</i> {{if $.IsWatchingRepo}}{{$.i18n.Tr "repo.unwatch"}}{{else}}{{$.i18n.Tr "repo.watch"}}{{end}}
-								</a>
-								<a class="ui basic label" href="{{.Link}}/watchers">
-									{{.NumWatches}}
-								</a>
-							</div>
-							<div class="ui labeled button" tabindex="0">
-								<a class="ui basic button" href="{{$.RepoLink}}/action/{{if $.IsStaringRepo}}un{{end}}star?redirect_to={{$.Link}}">
-									{{if $.IsStaringRepo}}
-										<i class="menu-icon octicon">🌟</i> {{$.i18n.Tr "repo.unstar"}}
-									{{else}}
-										<i class="menu-icon octicon">⭐</i> {{$.i18n.Tr "repo.star"}}
-									{{end}}
-								</a>
-								<a class="ui basic label" href="{{.Link}}/stars">
-									{{.NumStars}}
-								</a>
-							</div>
+							<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">
+									<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}}
+									</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">
+									<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}}
+									</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}}">

+ 16 - 6
templates/user/profile.tmpl

@@ -94,12 +94,12 @@
 			<div class="ui five wide column">
 				<div class="ui card" style="border: 2px solid {{.Owner.ThemeColor}};box-shadow: 5px 6px 0px {{.Owner.ThemeColor}}"> 
 					{{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">
@@ -229,9 +229,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="menu-icon octicon">👦🏽</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="menu-icon octicon">👦</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}}