- modules/middleware/context.go: add HandleAPI methodtags/v1.21.12.1
| @@ -79,7 +79,7 @@ func checkVersion() { | |||||
| // Check dependency version. | // Check dependency version. | ||||
| checkers := []VerChecker{ | checkers := []VerChecker{ | ||||
| {"github.com/Unknwon/macaron", macaron.Version, "0.5.1"}, | {"github.com/Unknwon/macaron", macaron.Version, "0.5.1"}, | ||||
| {"github.com/macaron-contrib/binding", binding.Version, "0.0.4"}, | |||||
| {"github.com/macaron-contrib/binding", binding.Version, "0.0.5"}, | |||||
| {"github.com/macaron-contrib/cache", cache.Version, "0.0.7"}, | {"github.com/macaron-contrib/cache", cache.Version, "0.0.7"}, | ||||
| {"github.com/macaron-contrib/csrf", csrf.Version, "0.0.3"}, | {"github.com/macaron-contrib/csrf", csrf.Version, "0.0.3"}, | ||||
| {"github.com/macaron-contrib/i18n", i18n.Version, "0.0.5"}, | {"github.com/macaron-contrib/i18n", i18n.Version, "0.0.5"}, | ||||
| @@ -229,7 +229,7 @@ func runWeb(ctx *cli.Context) { | |||||
| }) | }) | ||||
| m.Any("/*", func(ctx *middleware.Context) { | m.Any("/*", func(ctx *middleware.Context) { | ||||
| ctx.JSON(404, &base.ApiJsonErr{"Not Found", base.DOC_URL}) | |||||
| ctx.HandleAPI(404, "Page not found") | |||||
| }) | }) | ||||
| }) | }) | ||||
| }) | }) | ||||
| @@ -286,6 +286,8 @@ need_auth = Need Authorization | |||||
| migrate_type = Migration Type | migrate_type = Migration Type | ||||
| migrate_type_helper = This repository will be a <span class="label label-blue label-radius">Mirror</span> | migrate_type_helper = This repository will be a <span class="label label-blue label-radius">Mirror</span> | ||||
| migrate_repo = Migrate Repository | migrate_repo = Migrate Repository | ||||
| migrate.clone_address = Clone Address | |||||
| migrate.invalid_local_path = Invalid local path, it does not exist or not a directory. | |||||
| copy_link = Copy | copy_link = Copy | ||||
| click_to_copy = Copy to clipboard | click_to_copy = Copy to clipboard | ||||
| @@ -31,7 +31,7 @@ func (f *CreateRepoForm) Validate(ctx *macaron.Context, errs binding.Errors) bin | |||||
| } | } | ||||
| type MigrateRepoForm struct { | type MigrateRepoForm struct { | ||||
| HttpsUrl string `form:"url" binding:"Required;Url"` | |||||
| CloneAddr string `binding:"Required"` | |||||
| AuthUserName string `form:"auth_username"` | AuthUserName string `form:"auth_username"` | ||||
| AuthPasswd string `form:"auth_password"` | AuthPasswd string `form:"auth_password"` | ||||
| Uid int64 `form:"uid" binding:"Required"` | Uid int64 `form:"uid" binding:"Required"` | ||||
| @@ -130,6 +130,18 @@ func (ctx *Context) Handle(status int, title string, err error) { | |||||
| ctx.HTML(status, base.TplName(fmt.Sprintf("status/%d", status))) | ctx.HTML(status, base.TplName(fmt.Sprintf("status/%d", status))) | ||||
| } | } | ||||
| func (ctx *Context) HandleAPI(status int, obj interface{}) { | |||||
| var message string | |||||
| if err, ok := obj.(error); ok { | |||||
| message = err.Error() | |||||
| } else { | |||||
| message = obj.(string) | |||||
| } | |||||
| ctx.JSON(status, map[string]string{ | |||||
| "message": message, | |||||
| }) | |||||
| } | |||||
| func (ctx *Context) ServeContent(name string, r io.ReadSeeker, params ...interface{}) { | func (ctx *Context) ServeContent(name string, r io.ReadSeeker, params ...interface{}) { | ||||
| modtime := time.Now() | modtime := time.Now() | ||||
| for _, p := range params { | for _, p := range params { | ||||
| @@ -5,7 +5,7 @@ | |||||
| package v1 | package v1 | ||||
| import ( | import ( | ||||
| "fmt" | |||||
| "net/url" | |||||
| "path" | "path" | ||||
| "strings" | "strings" | ||||
| @@ -156,17 +156,15 @@ func CreateOrgRepo(ctx *middleware.Context, opt api.CreateRepoOption) { | |||||
| func MigrateRepo(ctx *middleware.Context, form auth.MigrateRepoForm) { | func MigrateRepo(ctx *middleware.Context, form auth.MigrateRepoForm) { | ||||
| u, err := models.GetUserByName(ctx.Query("username")) | u, err := models.GetUserByName(ctx.Query("username")) | ||||
| if err != nil { | if err != nil { | ||||
| ctx.JSON(500, map[string]interface{}{ | |||||
| "ok": false, | |||||
| "error": err.Error(), | |||||
| }) | |||||
| if err == models.ErrUserNotExist { | |||||
| ctx.HandleAPI(422, err) | |||||
| } else { | |||||
| ctx.HandleAPI(500, err) | |||||
| } | |||||
| return | return | ||||
| } | } | ||||
| if !u.ValidtePassword(ctx.Query("password")) { | if !u.ValidtePassword(ctx.Query("password")) { | ||||
| ctx.JSON(500, map[string]interface{}{ | |||||
| "ok": false, | |||||
| "error": "username or password is not correct", | |||||
| }) | |||||
| ctx.HandleAPI(422, "Username or password is not correct.") | |||||
| return | return | ||||
| } | } | ||||
| @@ -175,56 +173,59 @@ func MigrateRepo(ctx *middleware.Context, form auth.MigrateRepoForm) { | |||||
| if form.Uid != u.Id { | if form.Uid != u.Id { | ||||
| org, err := models.GetUserById(form.Uid) | org, err := models.GetUserById(form.Uid) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error(4, "GetUserById: %v", err) | |||||
| ctx.Error(500) | |||||
| if err == models.ErrUserNotExist { | |||||
| ctx.HandleAPI(422, err) | |||||
| } else { | |||||
| ctx.HandleAPI(500, err) | |||||
| } | |||||
| return | return | ||||
| } | } | ||||
| ctxUser = org | ctxUser = org | ||||
| } | } | ||||
| if ctx.HasError() { | if ctx.HasError() { | ||||
| ctx.JSON(422, map[string]interface{}{ | |||||
| "ok": false, | |||||
| "error": ctx.GetErrMsg(), | |||||
| }) | |||||
| ctx.HandleAPI(422, ctx.GetErrMsg()) | |||||
| return | return | ||||
| } | } | ||||
| if ctxUser.IsOrganization() { | if ctxUser.IsOrganization() { | ||||
| // Check ownership of organization. | // Check ownership of organization. | ||||
| if !ctxUser.IsOwnedBy(u.Id) { | if !ctxUser.IsOwnedBy(u.Id) { | ||||
| ctx.JSON(403, map[string]interface{}{ | |||||
| "ok": false, | |||||
| "error": "given user is not owner of organization", | |||||
| }) | |||||
| ctx.HandleAPI(403, "Given user is not owner of organization.") | |||||
| return | return | ||||
| } | } | ||||
| } | } | ||||
| authStr := strings.Replace(fmt.Sprintf("://%s:%s", | |||||
| form.AuthUserName, form.AuthPasswd), "@", "%40", -1) | |||||
| url := strings.Replace(form.HttpsUrl, "://", authStr+"@", 1) | |||||
| repo, err := models.MigrateRepository(ctxUser, form.RepoName, form.Description, form.Private, | |||||
| form.Mirror, url) | |||||
| if err == nil { | |||||
| log.Trace("Repository migrated: %s/%s", ctxUser.Name, form.RepoName) | |||||
| ctx.JSON(200, map[string]interface{}{ | |||||
| "ok": true, | |||||
| "data": "/" + ctxUser.Name + "/" + form.RepoName, | |||||
| }) | |||||
| // Remote address can be HTTPS URL or local path. | |||||
| remoteAddr := form.CloneAddr | |||||
| if strings.HasPrefix(form.CloneAddr, "http") { | |||||
| u, err := url.Parse(form.CloneAddr) | |||||
| if err != nil { | |||||
| ctx.HandleAPI(422, err) | |||||
| return | |||||
| } | |||||
| if len(form.AuthUserName) > 0 || len(form.AuthPasswd) > 0 { | |||||
| u.User = url.UserPassword(form.AuthUserName, form.AuthPasswd) | |||||
| } | |||||
| remoteAddr = u.String() | |||||
| } else if !com.IsDir(remoteAddr) { | |||||
| ctx.HandleAPI(422, "Invalid local path, it does not exist or not a directory.") | |||||
| return | return | ||||
| } | } | ||||
| if repo != nil { | |||||
| if errDelete := models.DeleteRepository(ctxUser.Id, repo.Id, ctxUser.Name); errDelete != nil { | |||||
| log.Error(4, "DeleteRepository: %v", errDelete) | |||||
| repo, err := models.MigrateRepository(ctxUser, form.RepoName, form.Description, form.Private, form.Mirror, remoteAddr) | |||||
| if err != nil { | |||||
| if repo != nil { | |||||
| if errDelete := models.DeleteRepository(ctxUser.Id, repo.Id, ctxUser.Name); errDelete != nil { | |||||
| log.Error(4, "DeleteRepository: %v", errDelete) | |||||
| } | |||||
| } | } | ||||
| ctx.HandleAPI(500, err) | |||||
| return | |||||
| } | } | ||||
| ctx.JSON(500, map[string]interface{}{ | |||||
| "ok": false, | |||||
| "error": err.Error(), | |||||
| }) | |||||
| log.Trace("Repository migrated: %s/%s", ctxUser.Name, form.RepoName) | |||||
| ctx.WriteHeader(200) | |||||
| } | } | ||||
| // GET /user/repos | // GET /user/repos | ||||
| @@ -181,20 +181,26 @@ func MigratePost(ctx *middleware.Context, form auth.MigrateRepoForm) { | |||||
| } | } | ||||
| } | } | ||||
| u, err := url.Parse(form.HttpsUrl) | |||||
| if err != nil || u.Scheme != "https" { | |||||
| ctx.Data["Err_HttpsUrl"] = true | |||||
| ctx.RenderWithErr(ctx.Tr("form.url_error"), MIGRATE, &form) | |||||
| // Remote address can be HTTPS URL or local path. | |||||
| remoteAddr := form.CloneAddr | |||||
| if strings.HasPrefix(form.CloneAddr, "http") { | |||||
| u, err := url.Parse(form.CloneAddr) | |||||
| if err != nil { | |||||
| ctx.Data["Err_CloneAddr"] = true | |||||
| ctx.RenderWithErr(ctx.Tr("form.url_error"), MIGRATE, &form) | |||||
| return | |||||
| } | |||||
| if len(form.AuthUserName) > 0 || len(form.AuthPasswd) > 0 { | |||||
| u.User = url.UserPassword(form.AuthUserName, form.AuthPasswd) | |||||
| } | |||||
| remoteAddr = u.String() | |||||
| } else if !com.IsDir(remoteAddr) { | |||||
| ctx.Data["Err_CloneAddr"] = true | |||||
| ctx.RenderWithErr(ctx.Tr("repo.migrate.invalid_local_path"), MIGRATE, &form) | |||||
| return | return | ||||
| } | } | ||||
| if len(form.AuthUserName) > 0 || len(form.AuthPasswd) > 0 { | |||||
| u.User = url.UserPassword(form.AuthUserName, form.AuthPasswd) | |||||
| } | |||||
| repo, err := models.MigrateRepository(ctxUser, form.RepoName, form.Description, form.Private, | |||||
| form.Mirror, u.String()) | |||||
| repo, err := models.MigrateRepository(ctxUser, form.RepoName, form.Description, form.Private, form.Mirror, remoteAddr) | |||||
| if err == nil { | if err == nil { | ||||
| log.Trace("Repository migrated: %s/%s", ctxUser.Name, form.RepoName) | log.Trace("Repository migrated: %s/%s", ctxUser.Name, form.RepoName) | ||||
| ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + form.RepoName) | ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + form.RepoName) | ||||
| @@ -7,8 +7,8 @@ | |||||
| <div class="panel-content"> | <div class="panel-content"> | ||||
| {{template "ng/base/alert" .}} | {{template "ng/base/alert" .}} | ||||
| <div class="field"> | <div class="field"> | ||||
| <label class="req" for="url">HTTPS URL</label> | |||||
| <input class="ipt ipt-large ipt-radius {{if .Err_HttpsUrl}}ipt-error{{end}}" id="url" name="url" type="text" value="{{.url}}" required /> | |||||
| <label class="req" for="clone_addr">{{.i18n.Tr "repo.migrate.clone_address"}}</label> | |||||
| <input class="ipt ipt-large ipt-radius {{if .Err_CloneAddr}}ipt-error{{end}}" id="clone_addr" name="clone_addr" type="text" value="{{.clone_addr}}" required /> | |||||
| </div> | </div> | ||||
| <div class="field"> | <div class="field"> | ||||
| <span class="form-label"></span> | <span class="form-label"></span> | ||||