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.

repo.go 7.1KB

10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
10 lat temu
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  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/log"
  14. "github.com/gogits/gogs/modules/setting"
  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. validBranch = args[0]
  24. }
  25. if len(args) >= 2 {
  26. displayBare = args[1]
  27. }
  28. var (
  29. user *models.User
  30. err error
  31. isTrueOwner bool
  32. )
  33. userName := params["username"]
  34. repoName := params["reponame"]
  35. refName := params["branchname"]
  36. // TODO: need more advanced onwership and access level check.
  37. // Collaborators who have write access can be seen as owners.
  38. if ctx.IsSigned {
  39. ctx.Repo.IsOwner, err = models.HasAccess(ctx.User.Name, userName+"/"+repoName, models.WRITABLE)
  40. if err != nil {
  41. ctx.Handle(500, "RepoAssignment(HasAccess)", err)
  42. return
  43. }
  44. isTrueOwner = ctx.User.LowerName == strings.ToLower(userName)
  45. }
  46. if !isTrueOwner {
  47. user, err = models.GetUserByName(userName)
  48. if err != nil {
  49. if err == models.ErrUserNotExist {
  50. ctx.Handle(404, "RepoAssignment(GetUserByName)", err)
  51. return
  52. } else if redirect {
  53. ctx.Redirect("/")
  54. return
  55. }
  56. ctx.Handle(500, "RepoAssignment(GetUserByName)", err)
  57. return
  58. }
  59. } else {
  60. user = ctx.User
  61. }
  62. if user == nil {
  63. if redirect {
  64. ctx.Redirect("/")
  65. return
  66. }
  67. ctx.Handle(403, "RepoAssignment", errors.New("invliad user account for single repository"))
  68. return
  69. }
  70. ctx.Repo.Owner = user
  71. // get repository
  72. repo, err := models.GetRepositoryByName(user.Id, repoName)
  73. if err != nil {
  74. if err == models.ErrRepoNotExist {
  75. ctx.Handle(404, "RepoAssignment", err)
  76. return
  77. } else if redirect {
  78. ctx.Redirect("/")
  79. return
  80. }
  81. ctx.Handle(500, "RepoAssignment", err)
  82. return
  83. }
  84. // Check if the mirror repository owner(mirror repository doesn't have access).
  85. if ctx.IsSigned && !ctx.Repo.IsOwner && repo.OwnerId == ctx.User.Id {
  86. ctx.Repo.IsOwner = true
  87. }
  88. // Check access.
  89. if repo.IsPrivate && !ctx.Repo.IsOwner {
  90. if ctx.User == nil {
  91. ctx.Handle(404, "RepoAssignment(HasAccess)", nil)
  92. return
  93. }
  94. hasAccess, err := models.HasAccess(ctx.User.Name, ctx.Repo.Owner.Name+"/"+repo.Name, models.READABLE)
  95. if err != nil {
  96. ctx.Handle(500, "RepoAssignment(HasAccess)", err)
  97. return
  98. } else if !hasAccess {
  99. ctx.Handle(404, "RepoAssignment(HasAccess)", nil)
  100. return
  101. }
  102. }
  103. ctx.Repo.HasAccess = true
  104. ctx.Data["HasAccess"] = true
  105. if repo.IsMirror {
  106. ctx.Repo.Mirror, err = models.GetMirror(repo.Id)
  107. if err != nil {
  108. ctx.Handle(500, "RepoAssignment(GetMirror)", err)
  109. return
  110. }
  111. ctx.Data["MirrorInterval"] = ctx.Repo.Mirror.Interval
  112. }
  113. repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues
  114. repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones
  115. ctx.Repo.Repository = repo
  116. ctx.Data["IsBareRepo"] = ctx.Repo.Repository.IsBare
  117. gitRepo, err := git.OpenRepository(models.RepoPath(userName, repoName))
  118. if err != nil {
  119. ctx.Handle(500, "RepoAssignment Invalid repo "+models.RepoPath(userName, repoName), err)
  120. return
  121. }
  122. ctx.Repo.GitRepo = gitRepo
  123. ctx.Repo.RepoLink = "/" + user.Name + "/" + repo.Name
  124. tags, err := ctx.Repo.GitRepo.GetTags()
  125. if err != nil {
  126. ctx.Handle(500, "RepoAssignment(GetTags))", err)
  127. return
  128. }
  129. ctx.Repo.Repository.NumTags = len(tags)
  130. ctx.Data["Title"] = user.Name + "/" + repo.Name
  131. ctx.Data["Repository"] = repo
  132. ctx.Data["Owner"] = user
  133. ctx.Data["RepoLink"] = ctx.Repo.RepoLink
  134. ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner
  135. ctx.Data["BranchName"] = ""
  136. if setting.SshPort != 22 {
  137. ctx.Repo.CloneLink.SSH = fmt.Sprintf("ssh://%s@%s/%s/%s.git", setting.RunUser, setting.Domain, user.LowerName, repo.LowerName)
  138. } else {
  139. ctx.Repo.CloneLink.SSH = fmt.Sprintf("%s@%s:%s/%s.git", setting.RunUser, setting.Domain, user.LowerName, repo.LowerName)
  140. }
  141. ctx.Repo.CloneLink.HTTPS = fmt.Sprintf("%s%s/%s.git", setting.AppUrl, user.LowerName, repo.LowerName)
  142. ctx.Data["CloneLink"] = ctx.Repo.CloneLink
  143. if ctx.Repo.Repository.IsGoget {
  144. ctx.Data["GoGetLink"] = fmt.Sprintf("%s%s/%s", setting.AppUrl, user.LowerName, repo.LowerName)
  145. ctx.Data["GoGetImport"] = fmt.Sprintf("%s/%s/%s", setting.Domain, user.LowerName, repo.LowerName)
  146. }
  147. // when repo is bare, not valid branch
  148. if !ctx.Repo.Repository.IsBare && validBranch {
  149. detect:
  150. if len(refName) > 0 {
  151. if gitRepo.IsBranchExist(refName) {
  152. ctx.Repo.IsBranch = true
  153. ctx.Repo.BranchName = refName
  154. ctx.Repo.Commit, err = gitRepo.GetCommitOfBranch(refName)
  155. if err != nil {
  156. ctx.Handle(404, "RepoAssignment invalid branch", nil)
  157. return
  158. }
  159. ctx.Repo.CommitId = ctx.Repo.Commit.Id.String()
  160. } else if gitRepo.IsTagExist(refName) {
  161. ctx.Repo.IsBranch = true
  162. ctx.Repo.BranchName = refName
  163. ctx.Repo.Commit, err = gitRepo.GetCommitOfTag(refName)
  164. if err != nil {
  165. ctx.Handle(404, "RepoAssignment invalid tag", nil)
  166. return
  167. }
  168. ctx.Repo.CommitId = ctx.Repo.Commit.Id.String()
  169. } else if len(refName) == 40 {
  170. ctx.Repo.IsCommit = true
  171. ctx.Repo.CommitId = refName
  172. ctx.Repo.BranchName = refName
  173. ctx.Repo.Commit, err = gitRepo.GetCommit(refName)
  174. if err != nil {
  175. ctx.Handle(404, "RepoAssignment invalid commit", nil)
  176. return
  177. }
  178. } else {
  179. ctx.Handle(404, "RepoAssignment invalid repo", nil)
  180. return
  181. }
  182. } else {
  183. if len(refName) == 0 {
  184. if gitRepo.IsBranchExist(ctx.Repo.Repository.DefaultBranch) {
  185. refName = ctx.Repo.Repository.DefaultBranch
  186. } else {
  187. brs, err := gitRepo.GetBranches()
  188. if err != nil {
  189. ctx.Handle(500, "RepoAssignment(GetBranches))", err)
  190. return
  191. }
  192. refName = brs[0]
  193. }
  194. }
  195. goto detect
  196. }
  197. ctx.Data["IsBranch"] = ctx.Repo.IsBranch
  198. ctx.Data["IsCommit"] = ctx.Repo.IsCommit
  199. }
  200. log.Debug("displayBare: %v; IsBare: %v", displayBare, ctx.Repo.Repository.IsBare)
  201. // repo is bare and display enable
  202. if displayBare && ctx.Repo.Repository.IsBare {
  203. log.Debug("Bare repository: %s", ctx.Repo.RepoLink)
  204. ctx.HTML(200, "repo/single_bare")
  205. return
  206. }
  207. if ctx.IsSigned {
  208. ctx.Repo.IsWatching = models.IsWatching(ctx.User.Id, repo.Id)
  209. }
  210. ctx.Data["BranchName"] = ctx.Repo.BranchName
  211. brs, err := ctx.Repo.GitRepo.GetBranches()
  212. if err != nil {
  213. log.Error("RepoAssignment(GetBranches): %v", err)
  214. }
  215. ctx.Data["Branches"] = brs
  216. ctx.Data["CommitId"] = ctx.Repo.CommitId
  217. ctx.Data["IsRepositoryWatching"] = ctx.Repo.IsWatching
  218. }
  219. }
  220. func RequireOwner() martini.Handler {
  221. return func(ctx *Context) {
  222. if !ctx.Repo.IsOwner {
  223. if !ctx.IsSigned {
  224. ctx.SetCookie("redirect_to", "/"+url.QueryEscape(ctx.Req.RequestURI))
  225. ctx.Redirect("/user/login")
  226. return
  227. }
  228. ctx.Handle(404, ctx.Req.RequestURI, nil)
  229. return
  230. }
  231. }
  232. }