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

repo.go 6.1 kB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  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 v1
  5. import (
  6. "fmt"
  7. "path"
  8. "strings"
  9. "github.com/Unknwon/com"
  10. api "github.com/gogits/go-gogs-client"
  11. "github.com/gogits/gogs/models"
  12. "github.com/gogits/gogs/modules/auth"
  13. "github.com/gogits/gogs/modules/base"
  14. "github.com/gogits/gogs/modules/log"
  15. "github.com/gogits/gogs/modules/middleware"
  16. "github.com/gogits/gogs/modules/setting"
  17. )
  18. func SearchRepos(ctx *middleware.Context) {
  19. opt := models.SearchOption{
  20. Keyword: path.Base(ctx.Query("q")),
  21. Uid: com.StrTo(ctx.Query("uid")).MustInt64(),
  22. Limit: com.StrTo(ctx.Query("limit")).MustInt(),
  23. }
  24. if opt.Limit == 0 {
  25. opt.Limit = 10
  26. }
  27. // Check visibility.
  28. if ctx.IsSigned && opt.Uid > 0 {
  29. if ctx.User.Id == opt.Uid {
  30. opt.Private = true
  31. } else {
  32. u, err := models.GetUserById(opt.Uid)
  33. if err != nil {
  34. ctx.JSON(500, map[string]interface{}{
  35. "ok": false,
  36. "error": err.Error(),
  37. })
  38. return
  39. }
  40. if u.IsOrganization() && u.IsOrgOwner(ctx.User.Id) {
  41. opt.Private = true
  42. }
  43. // FIXME: how about collaborators?
  44. }
  45. }
  46. repos, err := models.SearchRepositoryByName(opt)
  47. if err != nil {
  48. ctx.JSON(500, map[string]interface{}{
  49. "ok": false,
  50. "error": err.Error(),
  51. })
  52. return
  53. }
  54. results := make([]*api.Repository, len(repos))
  55. for i := range repos {
  56. if err = repos[i].GetOwner(); err != nil {
  57. ctx.JSON(500, map[string]interface{}{
  58. "ok": false,
  59. "error": err.Error(),
  60. })
  61. return
  62. }
  63. results[i] = &api.Repository{
  64. Id: repos[i].Id,
  65. FullName: path.Join(repos[i].Owner.Name, repos[i].Name),
  66. }
  67. }
  68. ctx.Render.JSON(200, map[string]interface{}{
  69. "ok": true,
  70. "data": results,
  71. })
  72. }
  73. func Migrate(ctx *middleware.Context, form auth.MigrateRepoForm) {
  74. u, err := models.GetUserByName(ctx.Query("username"))
  75. if err != nil {
  76. ctx.JSON(500, map[string]interface{}{
  77. "ok": false,
  78. "error": err.Error(),
  79. })
  80. return
  81. }
  82. if !u.ValidtePassword(ctx.Query("password")) {
  83. ctx.JSON(500, map[string]interface{}{
  84. "ok": false,
  85. "error": "username or password is not correct",
  86. })
  87. return
  88. }
  89. ctxUser := u
  90. // Not equal means current user is an organization.
  91. if form.Uid != u.Id {
  92. org, err := models.GetUserById(form.Uid)
  93. if err != nil {
  94. ctx.JSON(500, map[string]interface{}{
  95. "ok": false,
  96. "error": err.Error(),
  97. })
  98. return
  99. }
  100. ctxUser = org
  101. }
  102. if ctx.HasError() {
  103. ctx.JSON(500, map[string]interface{}{
  104. "ok": false,
  105. "error": ctx.GetErrMsg(),
  106. })
  107. return
  108. }
  109. if ctxUser.IsOrganization() {
  110. // Check ownership of organization.
  111. if !ctxUser.IsOrgOwner(u.Id) {
  112. ctx.JSON(403, map[string]interface{}{
  113. "ok": false,
  114. "error": "given user is not owner of organization",
  115. })
  116. return
  117. }
  118. }
  119. authStr := strings.Replace(fmt.Sprintf("://%s:%s",
  120. form.AuthUserName, form.AuthPasswd), "@", "%40", -1)
  121. url := strings.Replace(form.HttpsUrl, "://", authStr+"@", 1)
  122. repo, err := models.MigrateRepository(ctxUser, form.RepoName, form.Description, form.Private,
  123. form.Mirror, url)
  124. if err == nil {
  125. log.Trace("Repository migrated: %s/%s", ctxUser.Name, form.RepoName)
  126. ctx.JSON(200, map[string]interface{}{
  127. "ok": true,
  128. "data": "/" + ctxUser.Name + "/" + form.RepoName,
  129. })
  130. return
  131. }
  132. if repo != nil {
  133. if errDelete := models.DeleteRepository(ctxUser.Id, repo.Id, ctxUser.Name); errDelete != nil {
  134. log.Error(4, "DeleteRepository: %v", errDelete)
  135. }
  136. }
  137. ctx.JSON(500, map[string]interface{}{
  138. "ok": false,
  139. "error": err.Error(),
  140. })
  141. }
  142. // GET /user/repos
  143. // https://developer.github.com/v3/repos/#list-your-repositories
  144. func ListMyRepos(ctx *middleware.Context) {
  145. ownRepos, err := models.GetRepositories(ctx.User.Id, true)
  146. if err != nil {
  147. ctx.JSON(500, &base.ApiJsonErr{"GetRepositories: " + err.Error(), base.DOC_URL})
  148. return
  149. }
  150. numOwnRepos := len(ownRepos)
  151. collaRepos, err := models.GetCollaborativeRepos(ctx.User.Name)
  152. if err != nil {
  153. ctx.JSON(500, &base.ApiJsonErr{"GetCollaborativeRepos: " + err.Error(), base.DOC_URL})
  154. return
  155. }
  156. sshUrlFmt := "%s@%s:%s/%s.git"
  157. if setting.SshPort != 22 {
  158. sshUrlFmt = "ssh://%s@%s:%d/%s/%s.git"
  159. }
  160. repos := make([]*api.Repository, numOwnRepos+len(collaRepos))
  161. // FIXME: make only one loop
  162. for i := range ownRepos {
  163. repos[i] = &api.Repository{
  164. Id: ownRepos[i].Id,
  165. Owner: api.User{
  166. Id: ctx.User.Id,
  167. UserName: ctx.User.Name,
  168. AvatarUrl: string(setting.Protocol) + ctx.User.AvatarLink(),
  169. },
  170. FullName: ctx.User.Name + "/" + ownRepos[i].Name,
  171. Private: ownRepos[i].IsPrivate,
  172. Fork: ownRepos[i].IsFork,
  173. HtmlUrl: setting.AppUrl + ctx.User.Name + "/" + ownRepos[i].Name,
  174. SshUrl: fmt.Sprintf(sshUrlFmt, setting.RunUser, setting.Domain, ctx.User.LowerName, ownRepos[i].LowerName),
  175. Permissions: api.Permission{true, true, true},
  176. }
  177. repos[i].CloneUrl = repos[i].HtmlUrl + ".git"
  178. }
  179. for i := range collaRepos {
  180. if err = collaRepos[i].GetOwner(); err != nil {
  181. ctx.JSON(500, &base.ApiJsonErr{"GetOwner: " + err.Error(), base.DOC_URL})
  182. return
  183. }
  184. j := i + numOwnRepos
  185. repos[j] = &api.Repository{
  186. Id: collaRepos[i].Id,
  187. Owner: api.User{
  188. Id: collaRepos[i].Owner.Id,
  189. UserName: collaRepos[i].Owner.Name,
  190. AvatarUrl: string(setting.Protocol) + collaRepos[i].Owner.AvatarLink(),
  191. },
  192. FullName: collaRepos[i].Owner.Name + "/" + collaRepos[i].Name,
  193. Private: collaRepos[i].IsPrivate,
  194. Fork: collaRepos[i].IsFork,
  195. HtmlUrl: setting.AppUrl + collaRepos[i].Owner.Name + "/" + collaRepos[i].Name,
  196. SshUrl: fmt.Sprintf(sshUrlFmt, setting.RunUser, setting.Domain, collaRepos[i].Owner.LowerName, collaRepos[i].LowerName),
  197. Permissions: api.Permission{false, collaRepos[i].CanPush, true},
  198. }
  199. repos[j].CloneUrl = repos[j].HtmlUrl + ".git"
  200. // FIXME: cache result to reduce DB query?
  201. if collaRepos[i].Owner.IsOrganization() && collaRepos[i].Owner.IsOrgOwner(ctx.User.Id) {
  202. repos[j].Permissions.Admin = true
  203. }
  204. }
  205. ctx.JSON(200, &repos)
  206. }