diff --git a/models/access.go b/models/access.go index 42fccae05..83261575e 100644 --- a/models/access.go +++ b/models/access.go @@ -32,6 +32,14 @@ func AddAccess(access *Access) error { return err } +// UpdateAccess updates access information. +func UpdateAccess(access *Access) error { + access.UserName = strings.ToLower(access.UserName) + access.RepoName = strings.ToLower(access.RepoName) + _, err := orm.Id(access.Id).Update(access) + return err +} + // HasAccess returns true if someone can read or write to given repository. func HasAccess(userName, repoName string, mode int) (bool, error) { return orm.Get(&Access{ diff --git a/models/repo.go b/models/repo.go index e3270b183..11e23ecd0 100644 --- a/models/repo.go +++ b/models/repo.go @@ -369,14 +369,34 @@ func RepoPath(userName, repoName string) string { return filepath.Join(UserPath(userName), strings.ToLower(repoName)+".git") } +// ChangeRepositoryName changes all corresponding setting from old repository name to new one. +func ChangeRepositoryName(userName, oldRepoName, newRepoName string) (err error) { + // Update accesses. + accesses := make([]Access, 0, 5) + err = orm.Find(&accesses, &Access{RepoName: strings.ToLower(userName + "/" + oldRepoName)}) + if err != nil { + return err + } + for i := range accesses { + accesses[i].RepoName = userName + "/" + newRepoName + if err = UpdateAccess(&accesses[i]); err != nil { + return err + } + } + + // Change repository directory name. + return os.Rename(RepoPath(userName, oldRepoName), RepoPath(userName, newRepoName)) +} + func UpdateRepository(repo *Repository) error { + repo.LowerName = strings.ToLower(repo.Name) + if len(repo.Description) > 255 { repo.Description = repo.Description[:255] } if len(repo.Website) > 255 { repo.Website = repo.Website[:255] } - _, err := orm.Id(repo.Id).AllCols().Update(repo) return err } diff --git a/modules/middleware/context.go b/modules/middleware/context.go index d2b268cd8..8129b13b7 100644 --- a/modules/middleware/context.go +++ b/modules/middleware/context.go @@ -90,7 +90,9 @@ func (ctx *Context) HTML(status int, name string, htmlOpt ...HTMLOptions) { func (ctx *Context) RenderWithErr(msg, tpl string, form auth.Form) { ctx.Data["HasError"] = true ctx.Data["ErrorMsg"] = msg - auth.AssignForm(form, ctx.Data) + if form != nil { + auth.AssignForm(form, ctx.Data) + } ctx.HTML(200, tpl) } diff --git a/routers/repo/repo.go b/routers/repo/repo.go index 1cd3dd86b..a55647a31 100644 --- a/routers/repo/repo.go +++ b/routers/repo/repo.go @@ -5,6 +5,7 @@ package repo import ( + "fmt" "path" "path/filepath" "strings" @@ -278,19 +279,44 @@ func SettingPost(ctx *middleware.Context) { switch ctx.Query("action") { case "update": + isNameChanged := false + newRepoName := ctx.Query("name") + // Check if repository name has been changed. + if ctx.Repo.Repository.Name != newRepoName { + isExist, err := models.IsRepositoryExist(ctx.Repo.Owner, newRepoName) + if err != nil { + ctx.Handle(404, "repo.SettingPost(update: check existence)", err) + return + } else if isExist { + ctx.RenderWithErr("Repository name has been taken in your repositories.", "repo/setting", nil) + return + } else if err = models.ChangeRepositoryName(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name, newRepoName); err != nil { + ctx.Handle(404, "repo.SettingPost(update)", err) + return + } + log.Trace("%s Repository name changed: %s/%s -> %s", ctx.Req.RequestURI, ctx.User.Name, ctx.Repo.Repository.Name, newRepoName) + + isNameChanged = true + ctx.Repo.Repository.Name = newRepoName + } + ctx.Repo.Repository.Description = ctx.Query("desc") ctx.Repo.Repository.Website = ctx.Query("site") if err := models.UpdateRepository(ctx.Repo.Repository); err != nil { ctx.Handle(404, "repo.SettingPost(update)", err) return } + ctx.Data["IsSuccess"] = true - ctx.HTML(200, "repo/setting") - log.Trace("%s Repository updated: %s/%s", ctx.Req.RequestURI, ctx.User.LowerName, ctx.Repo.Repository.LowerName) + if isNameChanged { + ctx.Redirect(fmt.Sprintf("/%s/%s/settings", ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)) + } else { + ctx.HTML(200, "repo/setting") + } + log.Trace("%s Repository updated: %s/%s", ctx.Req.RequestURI, ctx.Repo.Owner.Name, ctx.Repo.Repository.Name) case "delete": if len(ctx.Repo.Repository.Name) == 0 || ctx.Repo.Repository.Name != ctx.Query("repository") { - ctx.Data["ErrorMsg"] = "Please make sure you entered repository name is correct." - ctx.HTML(200, "repo/setting") + ctx.RenderWithErr("Please make sure you entered repository name is correct.", "repo/setting", nil) return } diff --git a/templates/repo/setting.tmpl b/templates/repo/setting.tmpl index ea7a5ddb6..a177aba6a 100644 --- a/templates/repo/setting.tmpl +++ b/templates/repo/setting.tmpl @@ -12,7 +12,7 @@
- {{if .IsSuccess}}

Repository option has been successfully updated.

{{else if .HasError}}

{{.ErrorMsg}}

{{end}} + {{if .IsSuccess}}

Repository options has been successfully updated.

{{else if .HasError}}

{{.ErrorMsg}}

{{end}}
Repository Options @@ -22,12 +22,20 @@
{{.CsrfTokenHtml}} +
+ +
+ +
+
+
+