You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

255 lines
6.5 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package middleware
  5. import (
  6. "errors"
  7. "fmt"
  8. "net/url"
  9. "strings"
  10. "github.com/go-martini/martini"
  11. "github.com/gogits/git"
  12. "github.com/gogits/gogs/models"
  13. "github.com/gogits/gogs/modules/base"
  14. "github.com/gogits/gogs/modules/log"
  15. )
  16. func RepoAssignment(redirect bool, args ...bool) martini.Handler {
  17. return func(ctx *Context, params martini.Params) {
  18. // valid brachname
  19. var validBranch bool
  20. // display bare quick start if it is a bare repo
  21. var displayBare bool
  22. if len(args) >= 1 {
  23. // Note: argument has wrong value in Go1.3 martini.
  24. // validBranch = args[0]
  25. validBranch = true
  26. }
  27. if len(args) >= 2 {
  28. // displayBare = args[1]
  29. displayBare = true
  30. }
  31. var (
  32. user *models.User
  33. err error
  34. )
  35. userName := params["username"]
  36. repoName := params["reponame"]
  37. refName := params["branchname"]
  38. // TODO: check collaborators
  39. // get repository owner
  40. ctx.Repo.IsOwner = ctx.IsSigned && ctx.User.LowerName == strings.ToLower(userName)
  41. if !ctx.Repo.IsOwner {
  42. user, err = models.GetUserByName(params["username"])
  43. if err != nil {
  44. if err == models.ErrUserNotExist {
  45. ctx.Handle(404, "RepoAssignment", err)
  46. return
  47. } else if redirect {
  48. ctx.Redirect("/")
  49. return
  50. }
  51. ctx.Handle(500, "RepoAssignment", err)
  52. return
  53. }
  54. } else {
  55. user = ctx.User
  56. }
  57. if user == nil {
  58. if redirect {
  59. ctx.Redirect("/")
  60. return
  61. }
  62. ctx.Handle(403, "RepoAssignment", errors.New("invliad user account for single repository"))
  63. return
  64. }
  65. ctx.Repo.Owner = user
  66. // get repository
  67. repo, err := models.GetRepositoryByName(user.Id, repoName)
  68. if err != nil {
  69. if err == models.ErrRepoNotExist {
  70. ctx.Handle(404, "RepoAssignment", err)
  71. return
  72. } else if redirect {
  73. ctx.Redirect("/")
  74. return
  75. }
  76. ctx.Handle(500, "RepoAssignment", err)
  77. return
  78. }
  79. // Check access.
  80. if repo.IsPrivate {
  81. if ctx.User == nil {
  82. ctx.Handle(404, "RepoAssignment(HasAccess)", nil)
  83. return
  84. }
  85. hasAccess, err := models.HasAccess(ctx.User.Name, ctx.Repo.Owner.Name+"/"+repo.Name, models.AU_READABLE)
  86. if err != nil {
  87. ctx.Handle(500, "RepoAssignment(HasAccess)", err)
  88. return
  89. } else if !hasAccess {
  90. ctx.Handle(404, "RepoAssignment(HasAccess)", nil)
  91. return
  92. }
  93. }
  94. ctx.Repo.HasAccess = true
  95. ctx.Data["HasAccess"] = true
  96. if repo.IsMirror {
  97. ctx.Repo.Mirror, err = models.GetMirror(repo.Id)
  98. if err != nil {
  99. ctx.Handle(500, "RepoAssignment(GetMirror)", err)
  100. return
  101. }
  102. ctx.Data["MirrorInterval"] = ctx.Repo.Mirror.Interval
  103. }
  104. repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues
  105. ctx.Repo.Repository = repo
  106. ctx.Data["IsBareRepo"] = ctx.Repo.Repository.IsBare
  107. gitRepo, err := git.OpenRepository(models.RepoPath(userName, repoName))
  108. if err != nil {
  109. ctx.Handle(500, "RepoAssignment Invalid repo "+models.RepoPath(userName, repoName), err)
  110. return
  111. }
  112. ctx.Repo.GitRepo = gitRepo
  113. ctx.Repo.RepoLink = "/" + user.Name + "/" + repo.Name
  114. tags, err := ctx.Repo.GitRepo.GetTags()
  115. if err != nil {
  116. ctx.Handle(500, "RepoAssignment(GetTags))", err)
  117. return
  118. }
  119. ctx.Repo.Repository.NumTags = len(tags)
  120. ctx.Data["Title"] = user.Name + "/" + repo.Name
  121. ctx.Data["Repository"] = repo
  122. ctx.Data["Owner"] = user
  123. ctx.Data["RepoLink"] = ctx.Repo.RepoLink
  124. ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner
  125. ctx.Data["BranchName"] = ""
  126. ctx.Repo.CloneLink.SSH = fmt.Sprintf("%s@%s:%s/%s.git", base.RunUser, base.Domain, user.LowerName, repo.LowerName)
  127. ctx.Repo.CloneLink.HTTPS = fmt.Sprintf("%s%s/%s.git", base.AppUrl, user.LowerName, repo.LowerName)
  128. ctx.Data["CloneLink"] = ctx.Repo.CloneLink
  129. if ctx.Repo.Repository.IsGoget {
  130. ctx.Data["GoGetLink"] = fmt.Sprintf("%s%s/%s", base.AppUrl, user.LowerName, repo.LowerName)
  131. ctx.Data["GoGetImport"] = fmt.Sprintf("%s/%s/%s", base.Domain, user.LowerName, repo.LowerName)
  132. }
  133. // when repo is bare, not valid branch
  134. if !ctx.Repo.Repository.IsBare && validBranch {
  135. detect:
  136. if len(refName) > 0 {
  137. if gitRepo.IsBranchExist(refName) {
  138. ctx.Repo.IsBranch = true
  139. ctx.Repo.BranchName = refName
  140. ctx.Repo.Commit, err = gitRepo.GetCommitOfBranch(refName)
  141. if err != nil {
  142. ctx.Handle(404, "RepoAssignment invalid branch", nil)
  143. return
  144. }
  145. ctx.Repo.CommitId = ctx.Repo.Commit.Id.String()
  146. } else if gitRepo.IsTagExist(refName) {
  147. ctx.Repo.IsBranch = true
  148. ctx.Repo.BranchName = refName
  149. ctx.Repo.Commit, err = gitRepo.GetCommitOfTag(refName)
  150. if err != nil {
  151. ctx.Handle(404, "RepoAssignment invalid tag", nil)
  152. return
  153. }
  154. ctx.Repo.CommitId = ctx.Repo.Commit.Id.String()
  155. } else if len(refName) == 40 {
  156. ctx.Repo.IsCommit = true
  157. ctx.Repo.CommitId = refName
  158. ctx.Repo.BranchName = refName
  159. ctx.Repo.Commit, err = gitRepo.GetCommit(refName)
  160. if err != nil {
  161. ctx.Handle(404, "RepoAssignment invalid commit", nil)
  162. return
  163. }
  164. } else {
  165. ctx.Handle(404, "RepoAssignment invalid repo", nil)
  166. return
  167. }
  168. } else {
  169. if len(refName) == 0 {
  170. if gitRepo.IsBranchExist(ctx.Repo.Repository.DefaultBranch) {
  171. refName = ctx.Repo.Repository.DefaultBranch
  172. } else {
  173. brs, err := gitRepo.GetBranches()
  174. if err != nil {
  175. ctx.Handle(500, "RepoAssignment(GetBranches))", err)
  176. return
  177. }
  178. refName = brs[0]
  179. }
  180. }
  181. goto detect
  182. }
  183. ctx.Data["IsBranch"] = ctx.Repo.IsBranch
  184. ctx.Data["IsCommit"] = ctx.Repo.IsCommit
  185. log.Debug("Repo.Commit: %v", ctx.Repo.Commit)
  186. }
  187. log.Debug("displayBare: %v; IsBare: %v", displayBare, ctx.Repo.Repository.IsBare)
  188. // repo is bare and display enable
  189. if displayBare && ctx.Repo.Repository.IsBare {
  190. log.Debug("Bare repository: %s", ctx.Repo.RepoLink)
  191. ctx.HTML(200, "repo/single_bare")
  192. return
  193. }
  194. if ctx.IsSigned {
  195. ctx.Repo.IsWatching = models.IsWatching(ctx.User.Id, repo.Id)
  196. }
  197. ctx.Data["BranchName"] = ctx.Repo.BranchName
  198. brs, err := ctx.Repo.GitRepo.GetBranches()
  199. if err != nil {
  200. log.Error("RepoAssignment(GetBranches): %v", err)
  201. }
  202. ctx.Data["Branches"] = brs
  203. ctx.Data["CommitId"] = ctx.Repo.CommitId
  204. ctx.Data["IsRepositoryWatching"] = ctx.Repo.IsWatching
  205. }
  206. }
  207. func RequireOwner() martini.Handler {
  208. return func(ctx *Context) {
  209. if !ctx.Repo.IsOwner {
  210. if !ctx.IsSigned {
  211. ctx.SetCookie("redirect_to", "/"+url.QueryEscape(ctx.Req.RequestURI))
  212. ctx.Redirect("/user/login")
  213. return
  214. }
  215. ctx.Handle(404, ctx.Req.RequestURI, nil)
  216. return
  217. }
  218. }
  219. }