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