diff options
author | Unknwon <joe2010xtmf@163.com> | 2014-12-12 20:30:32 -0500 |
---|---|---|
committer | Unknwon <joe2010xtmf@163.com> | 2014-12-12 20:30:32 -0500 |
commit | ac4a10456ea4515091c3c90a83a82c1e59cdf428 (patch) | |
tree | db68f1f7a8f290322bd4da9892487cca5a1a5843 /routers/api | |
parent | 2f3a7e53cb58e922055baf3cf14138100a1f05ac (diff) | |
download | gitea-ac4a10456ea4515091c3c90a83a82c1e59cdf428.tar.gz gitea-ac4a10456ea4515091c3c90a83a82c1e59cdf428.zip |
api: able to create repo and fix #726
- POST /user/repos
- POST /org/:org/repos
Diffstat (limited to 'routers/api')
-rw-r--r-- | routers/api/v1/repo.go | 129 | ||||
-rw-r--r-- | routers/api/v1/repo_hooks.go | 15 | ||||
-rw-r--r-- | routers/api/v1/user.go | 10 |
3 files changed, 95 insertions, 59 deletions
diff --git a/routers/api/v1/repo.go b/routers/api/v1/repo.go index 33e3b05a4b..6f23723164 100644 --- a/routers/api/v1/repo.go +++ b/routers/api/v1/repo.go @@ -21,6 +21,26 @@ import ( "github.com/gogits/gogs/modules/setting" ) +// ToApiRepository converts repository to API format. +func ToApiRepository(owner *models.User, repo *models.Repository, permission api.Permission) *api.Repository { + sshUrlFmt := "%s@%s:%s/%s.git" + if setting.SshPort != 22 { + sshUrlFmt = "ssh://%s@%s:%d/%s/%s.git" + } + htmlUrl := setting.AppUrl + owner.Name + "/" + repo.Name + return &api.Repository{ + Id: repo.Id, + Owner: *ToApiUser(owner), + FullName: owner.Name + "/" + repo.Name, + Private: repo.IsPrivate, + Fork: repo.IsFork, + HtmlUrl: htmlUrl, + SshUrl: fmt.Sprintf(sshUrlFmt, setting.RunUser, setting.Domain, owner.LowerName, repo.LowerName), + CloneUrl: htmlUrl + ".git", + Permissions: permission, + } +} + func SearchRepos(ctx *middleware.Context) { opt := models.SearchOption{ Keyword: path.Base(ctx.Query("q")), @@ -44,7 +64,7 @@ func SearchRepos(ctx *middleware.Context) { }) return } - if u.IsOrganization() && u.IsOrgOwner(ctx.User.Id) { + if u.IsOrganization() && u.IsOwnedBy(ctx.User.Id) { opt.Private = true } // FIXME: how about collaborators? @@ -75,13 +95,66 @@ func SearchRepos(ctx *middleware.Context) { } } - ctx.Render.JSON(200, map[string]interface{}{ + ctx.JSON(200, map[string]interface{}{ "ok": true, "data": results, }) } -func Migrate(ctx *middleware.Context, form auth.MigrateRepoForm) { +func createRepo(ctx *middleware.Context, owner *models.User, opt api.CreateRepoOption) { + repo, err := models.CreateRepository(owner, opt.Name, opt.Description, + opt.Gitignore, opt.License, opt.Private, false, opt.AutoInit) + if err != nil { + if err == models.ErrRepoAlreadyExist || + err == models.ErrRepoNameIllegal { + ctx.JSON(422, &base.ApiJsonErr{err.Error(), base.DOC_URL}) + } else { + log.Error(4, "CreateRepository: %v", err) + if repo != nil { + if err = models.DeleteRepository(ctx.User.Id, repo.Id, ctx.User.Name); err != nil { + log.Error(4, "DeleteRepository: %v", err) + } + } + ctx.Error(500) + } + return + } + + ctx.JSON(200, ToApiRepository(owner, repo, api.Permission{true, true, true})) +} + +// POST /user/repos +// https://developer.github.com/v3/repos/#create +func CreateRepo(ctx *middleware.Context, opt api.CreateRepoOption) { + // Shouldn't reach this condition, but just in case. + if ctx.User.IsOrganization() { + ctx.JSON(422, "not allowed creating repository for organization") + return + } + createRepo(ctx, ctx.User, opt) +} + +// POST /orgs/:org/repos +// https://developer.github.com/v3/repos/#create +func CreateOrgRepo(ctx *middleware.Context, opt api.CreateRepoOption) { + org, err := models.GetOrgByName(ctx.Params(":org")) + if err != nil { + if err == models.ErrUserNotExist { + ctx.Error(404) + } else { + ctx.Error(500) + } + return + } + + if !org.IsOwnedBy(ctx.User.Id) { + ctx.Error(403) + return + } + createRepo(ctx, org, opt) +} + +func MigrateRepo(ctx *middleware.Context, form auth.MigrateRepoForm) { u, err := models.GetUserByName(ctx.Query("username")) if err != nil { ctx.JSON(500, map[string]interface{}{ @@ -103,17 +176,15 @@ func Migrate(ctx *middleware.Context, form auth.MigrateRepoForm) { if form.Uid != u.Id { org, err := models.GetUserById(form.Uid) if err != nil { - ctx.JSON(500, map[string]interface{}{ - "ok": false, - "error": err.Error(), - }) + log.Error(4, "GetUserById: %v", err) + ctx.Error(500) return } ctxUser = org } if ctx.HasError() { - ctx.JSON(500, map[string]interface{}{ + ctx.JSON(422, map[string]interface{}{ "ok": false, "error": ctx.GetErrMsg(), }) @@ -122,7 +193,7 @@ func Migrate(ctx *middleware.Context, form auth.MigrateRepoForm) { if ctxUser.IsOrganization() { // Check ownership of organization. - if !ctxUser.IsOrgOwner(u.Id) { + if !ctxUser.IsOwnedBy(u.Id) { ctx.JSON(403, map[string]interface{}{ "ok": false, "error": "given user is not owner of organization", @@ -173,29 +244,9 @@ func ListMyRepos(ctx *middleware.Context) { return } - sshUrlFmt := "%s@%s:%s/%s.git" - if setting.SshPort != 22 { - sshUrlFmt = "ssh://%s@%s:%d/%s/%s.git" - } - repos := make([]*api.Repository, numOwnRepos+len(collaRepos)) - // FIXME: make only one loop for i := range ownRepos { - repos[i] = &api.Repository{ - Id: ownRepos[i].Id, - Owner: api.User{ - Id: ctx.User.Id, - UserName: ctx.User.Name, - AvatarUrl: string(setting.Protocol) + ctx.User.AvatarLink(), - }, - FullName: ctx.User.Name + "/" + ownRepos[i].Name, - Private: ownRepos[i].IsPrivate, - Fork: ownRepos[i].IsFork, - HtmlUrl: setting.AppUrl + ctx.User.Name + "/" + ownRepos[i].Name, - SshUrl: fmt.Sprintf(sshUrlFmt, setting.RunUser, setting.Domain, ctx.User.LowerName, ownRepos[i].LowerName), - Permissions: api.Permission{true, true, true}, - } - repos[i].CloneUrl = repos[i].HtmlUrl + ".git" + repos[i] = ToApiRepository(ctx.User, ownRepos[i], api.Permission{true, true, true}) } for i := range collaRepos { if err = collaRepos[i].GetOwner(); err != nil { @@ -203,24 +254,10 @@ func ListMyRepos(ctx *middleware.Context) { return } j := i + numOwnRepos - repos[j] = &api.Repository{ - Id: collaRepos[i].Id, - Owner: api.User{ - Id: collaRepos[i].Owner.Id, - UserName: collaRepos[i].Owner.Name, - AvatarUrl: string(setting.Protocol) + collaRepos[i].Owner.AvatarLink(), - }, - FullName: collaRepos[i].Owner.Name + "/" + collaRepos[i].Name, - Private: collaRepos[i].IsPrivate, - Fork: collaRepos[i].IsFork, - HtmlUrl: setting.AppUrl + collaRepos[i].Owner.Name + "/" + collaRepos[i].Name, - SshUrl: fmt.Sprintf(sshUrlFmt, setting.RunUser, setting.Domain, collaRepos[i].Owner.LowerName, collaRepos[i].LowerName), - Permissions: api.Permission{false, collaRepos[i].CanPush, true}, - } - repos[j].CloneUrl = repos[j].HtmlUrl + ".git" + repos[j] = ToApiRepository(collaRepos[i].Owner, collaRepos[i].Repository, api.Permission{false, collaRepos[i].CanPush, true}) // FIXME: cache result to reduce DB query? - if collaRepos[i].Owner.IsOrganization() && collaRepos[i].Owner.IsOrgOwner(ctx.User.Id) { + if collaRepos[i].Owner.IsOrganization() && collaRepos[i].Owner.IsOwnedBy(ctx.User.Id) { repos[j].Permissions.Admin = true } } diff --git a/routers/api/v1/repo_hooks.go b/routers/api/v1/repo_hooks.go index 5dddbc5a3d..afe18a0058 100644 --- a/routers/api/v1/repo_hooks.go +++ b/routers/api/v1/repo_hooks.go @@ -48,15 +48,9 @@ func ListRepoHooks(ctx *middleware.Context) { ctx.JSON(200, &apiHooks) } -type CreateRepoHookForm struct { - Type string `json:"type" binding:"Required"` - Config map[string]string `json:"config" binding:"Required"` - Active bool `json:"active"` -} - // POST /repos/:username/:reponame/hooks // https://developer.github.com/v3/repos/hooks/#create-a-hook -func CreateRepoHook(ctx *middleware.Context, form CreateRepoHookForm) { +func CreateRepoHook(ctx *middleware.Context, form api.CreateHookOption) { if !models.IsValidHookTaskType(form.Type) { ctx.JSON(422, &base.ApiJsonErr{"invalid hook type", base.DOC_URL}) return @@ -124,14 +118,9 @@ func CreateRepoHook(ctx *middleware.Context, form CreateRepoHookForm) { ctx.JSON(201, apiHook) } -type EditRepoHookForm struct { - Config map[string]string `json:"config"` - Active *bool `json:"active"` -} - // PATCH /repos/:username/:reponame/hooks/:id // https://developer.github.com/v3/repos/hooks/#edit-a-hook -func EditRepoHook(ctx *middleware.Context, form EditRepoHookForm) { +func EditRepoHook(ctx *middleware.Context, form api.EditHookOption) { w, err := models.GetWebhookById(ctx.ParamsInt64(":id")) if err != nil { ctx.JSON(500, &base.ApiJsonErr{"GetWebhookById: " + err.Error(), base.DOC_URL}) diff --git a/routers/api/v1/user.go b/routers/api/v1/user.go index 15c423f72c..e9ba615fcb 100644 --- a/routers/api/v1/user.go +++ b/routers/api/v1/user.go @@ -12,8 +12,18 @@ import ( "github.com/gogits/gogs/models" "github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/middleware" + "github.com/gogits/gogs/modules/setting" ) +// ToApiUser converts user to API format. +func ToApiUser(u *models.User) *api.User { + return &api.User{ + Id: u.Id, + UserName: u.Name, + AvatarUrl: string(setting.Protocol) + u.AvatarLink(), + } +} + func SearchUsers(ctx *middleware.Context) { opt := models.SearchOption{ Keyword: ctx.Query("q"), |