From 4fab997871bad708febda2c3260353a02dfc8d0b Mon Sep 17 00:00:00 2001 From: Joachim Hill-Grannec Date: Wed, 16 Aug 2017 16:21:13 -0700 Subject: [PATCH 1/6] Adding the ability to update the repo owner and name via patch with the owner and name props --- model/repo.go | 2 ++ server/repo.go | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/model/repo.go b/model/repo.go index 094969625..c2009ac6a 100644 --- a/model/repo.go +++ b/model/repo.go @@ -67,4 +67,6 @@ type RepoPatch struct { AllowDeploy *bool `json:"allow_deploy,omitempty"` AllowTag *bool `json:"allow_tag,omitempty"` BuildCounter *int `json:"build_counter,omitempty"` + Name *string `json:"name",omitempty` + Owner *string `json:"owner,omitempty"` } diff --git a/server/repo.go b/server/repo.go index 3f58b7de7..77c01396a 100644 --- a/server/repo.go +++ b/server/repo.go @@ -88,6 +88,7 @@ func PostRepo(c *gin.Context) { func PatchRepo(c *gin.Context) { repo := session.Repo(c) user := session.User(c) + remote := remote.FromContext(c) in := new(model.RepoPatch) if err := c.Bind(in); err != nil { @@ -95,7 +96,7 @@ func PatchRepo(c *gin.Context) { return } - if (in.IsTrusted != nil || in.Timeout != nil || in.BuildCounter != nil) && !user.Admin { + if (in.IsTrusted != nil || in.Timeout != nil || in.BuildCounter != nil || in.Owner != nil || in.Name != nil) && !user.Admin { c.String(403, "Insufficient privileges") return } @@ -137,6 +138,19 @@ func PatchRepo(c *gin.Context) { repo.Counter = *in.BuildCounter } + if in.Name != nil && in.Owner != nil { + from, err := remote.Repo(user, *in.Owner, *in.Name) + if err != nil { + c.AbortWithError(http.StatusInternalServerError, err) + } + repo.Name = from.Name + repo.Owner = from.Owner + repo.FullName = from.FullName + repo.Avatar = from.Avatar + repo.Link = from.Link + repo.Clone = from.Clone + } + err := store.UpdateRepo(c, repo) if err != nil { c.AbortWithError(http.StatusInternalServerError, err) From 8e13d374bc89f9c4c133ba5dc924c738abfcf0b2 Mon Sep 17 00:00:00 2001 From: Joachim Hill-Grannec Date: Mon, 21 Aug 2017 13:16:24 -0400 Subject: [PATCH 2/6] Fix quote location --- model/repo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/repo.go b/model/repo.go index c2009ac6a..ca6fd0177 100644 --- a/model/repo.go +++ b/model/repo.go @@ -67,6 +67,6 @@ type RepoPatch struct { AllowDeploy *bool `json:"allow_deploy,omitempty"` AllowTag *bool `json:"allow_tag,omitempty"` BuildCounter *int `json:"build_counter,omitempty"` - Name *string `json:"name",omitempty` + Name *string `json:"name,omitempty"` Owner *string `json:"owner,omitempty"` } From 6c386b18a602f315df1da0d85c9fcc50023303e6 Mon Sep 17 00:00:00 2001 From: Joachim Hill-Grannec Date: Mon, 21 Aug 2017 15:56:44 -0400 Subject: [PATCH 3/6] Update to add visibility and isPrivate from the rename --- server/repo.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/repo.go b/server/repo.go index 77c01396a..38b15c443 100644 --- a/server/repo.go +++ b/server/repo.go @@ -149,6 +149,8 @@ func PatchRepo(c *gin.Context) { repo.Avatar = from.Avatar repo.Link = from.Link repo.Clone = from.Clone + repo.IsPrivate = from.IsPrivate + repo.Visibility = from.Visibility } err := store.UpdateRepo(c, repo) From cee90e93aac627fcfd61cc2d660be42a75205e13 Mon Sep 17 00:00:00 2001 From: Joachim Hill-Grannec Date: Mon, 21 Aug 2017 17:56:37 -0400 Subject: [PATCH 4/6] Update to create move endpoint to allow changing the repo name --- model/repo.go | 2 -- router/router.go | 1 + server/repo.go | 71 ++++++++++++++++++++++++++++++++++++------------ 3 files changed, 54 insertions(+), 20 deletions(-) diff --git a/model/repo.go b/model/repo.go index ca6fd0177..094969625 100644 --- a/model/repo.go +++ b/model/repo.go @@ -67,6 +67,4 @@ type RepoPatch struct { AllowDeploy *bool `json:"allow_deploy,omitempty"` AllowTag *bool `json:"allow_tag,omitempty"` BuildCounter *int `json:"build_counter,omitempty"` - Name *string `json:"name,omitempty"` - Owner *string `json:"owner,omitempty"` } diff --git a/router/router.go b/router/router.go index a05b65beb..2503300d7 100644 --- a/router/router.go +++ b/router/router.go @@ -104,6 +104,7 @@ func Load(mux *httptreemux.ContextMux, middleware ...gin.HandlerFunc) http.Handl repo.DELETE("", session.MustRepoAdmin(), server.DeleteRepo) repo.POST("/chown", session.MustRepoAdmin(), server.ChownRepo) repo.POST("/repair", session.MustRepoAdmin(), server.RepairRepo) + repo.POST("/move", session.MustRepoAdmin(), server.MoveRepo) repo.POST("/builds/:number", session.MustPush, server.PostBuild) repo.DELETE("/builds/:number", session.MustAdmin(), server.ZombieKill) diff --git a/server/repo.go b/server/repo.go index 38b15c443..ba00a54b5 100644 --- a/server/repo.go +++ b/server/repo.go @@ -15,6 +15,7 @@ import ( "github.com/drone/drone/shared/httputil" "github.com/drone/drone/shared/token" "github.com/drone/drone/store" + "strings" ) func PostRepo(c *gin.Context) { @@ -88,7 +89,6 @@ func PostRepo(c *gin.Context) { func PatchRepo(c *gin.Context) { repo := session.Repo(c) user := session.User(c) - remote := remote.FromContext(c) in := new(model.RepoPatch) if err := c.Bind(in); err != nil { @@ -96,7 +96,7 @@ func PatchRepo(c *gin.Context) { return } - if (in.IsTrusted != nil || in.Timeout != nil || in.BuildCounter != nil || in.Owner != nil || in.Name != nil) && !user.Admin { + if (in.IsTrusted != nil || in.Timeout != nil || in.BuildCounter != nil) && !user.Admin { c.String(403, "Insufficient privileges") return } @@ -138,21 +138,6 @@ func PatchRepo(c *gin.Context) { repo.Counter = *in.BuildCounter } - if in.Name != nil && in.Owner != nil { - from, err := remote.Repo(user, *in.Owner, *in.Name) - if err != nil { - c.AbortWithError(http.StatusInternalServerError, err) - } - repo.Name = from.Name - repo.Owner = from.Owner - repo.FullName = from.FullName - repo.Avatar = from.Avatar - repo.Link = from.Link - repo.Clone = from.Clone - repo.IsPrivate = from.IsPrivate - repo.Visibility = from.Visibility - } - err := store.UpdateRepo(c, repo) if err != nil { c.AbortWithError(http.StatusInternalServerError, err) @@ -211,7 +196,7 @@ func RepairRepo(c *gin.Context) { repo := session.Repo(c) user := session.User(c) - // crates the jwt token used to verify the repository + // creates the jwt token used to verify the repository t := token.New(token.HookToken, repo.FullName) sig, err := t.Sign(repo.Hash) if err != nil { @@ -235,3 +220,53 @@ func RepairRepo(c *gin.Context) { } c.Writer.WriteHeader(http.StatusOK) } + +func MoveRepo(c *gin.Context) { + remote := remote.FromContext(c) + repo := session.Repo(c) + user := session.User(c) + + to, exists := c.GetQuery("to") + if !exists { + err := fmt.Errorf("Missing required to query value") + c.AbortWithError(http.StatusInternalServerError, err) + } + + owner, name, errParse := ParseRepo(to) + if errParse != nil { + c.AbortWithError(http.StatusInternalServerError, errParse) + } + + from, err := remote.Repo(user, owner, name) + if err != nil { + c.AbortWithError(http.StatusInternalServerError, err) + } + repo.Name = from.Name + repo.Owner = from.Owner + repo.FullName = from.FullName + repo.Avatar = from.Avatar + repo.Link = from.Link + repo.Clone = from.Clone + repo.IsPrivate = from.IsPrivate + repo.Visibility = from.Visibility + + errStore := store.UpdateRepo(c, repo) + if errStore != nil { + c.AbortWithError(http.StatusInternalServerError, errStore) + return + } + + RepairRepo(c) +} + +// ParseRepo parses the repository owner and name from a string. +func ParseRepo(str string) (user, repo string, err error) { + var parts = strings.Split(str, "/") + if len(parts) != 2 { + err = fmt.Errorf("Error: Invalid or missing repository. eg octocat/hello-world.") + return + } + user = parts[0] + repo = parts[1] + return +} From f54175de91aee295f53d66074d381bfccc568b32 Mon Sep 17 00:00:00 2001 From: Joachim Hill-Grannec Date: Mon, 21 Aug 2017 18:49:09 -0400 Subject: [PATCH 5/6] Made ResetVisibility and ParseRepo generic. Validate new from repo has admin rights --- model/repo.go | 24 ++++++++++++++++++++++++ server/repo.go | 25 ++++++++++++------------- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/model/repo.go b/model/repo.go index 094969625..4b22cf53d 100644 --- a/model/repo.go +++ b/model/repo.go @@ -1,5 +1,10 @@ package model +import ( + "strings" + "fmt" +) + type RepoLite struct { Owner string `json:"owner"` Name string `json:"name"` @@ -38,6 +43,25 @@ type Repo struct { Perm *Perm `json:"-" meddler:"-"` } +func (r *Repo) ResetVisibility() { + r.Visibility = VisibilityPublic + if r.IsPrivate { + r.Visibility = VisibilityPrivate + } +} + +// ParseRepo parses the repository owner and name from a string. +func ParseRepo(str string) (user, repo string, err error) { + var parts = strings.Split(str, "/") + if len(parts) != 2 { + err = fmt.Errorf("Error: Invalid or missing repository. eg octocat/hello-world.") + return + } + user = parts[0] + repo = parts[1] + return +} + // Update updates the repository with values from the given Repo. func (r *Repo) Update(from *Repo) { r.Avatar = from.Avatar diff --git a/server/repo.go b/server/repo.go index ba00a54b5..2429b6fbc 100644 --- a/server/repo.go +++ b/server/repo.go @@ -15,7 +15,6 @@ import ( "github.com/drone/drone/shared/httputil" "github.com/drone/drone/shared/token" "github.com/drone/drone/store" - "strings" ) func PostRepo(c *gin.Context) { @@ -230,17 +229,25 @@ func MoveRepo(c *gin.Context) { if !exists { err := fmt.Errorf("Missing required to query value") c.AbortWithError(http.StatusInternalServerError, err) + return } - owner, name, errParse := ParseRepo(to) + owner, name, errParse := model.ParseRepo(to) if errParse != nil { c.AbortWithError(http.StatusInternalServerError, errParse) + return } from, err := remote.Repo(user, owner, name) if err != nil { c.AbortWithError(http.StatusInternalServerError, err) + return } + if !from.Perm.Admin { + c.AbortWithStatus(http.StatusUnauthorized) + return + } + repo.Name = from.Name repo.Owner = from.Owner repo.FullName = from.FullName @@ -248,6 +255,9 @@ func MoveRepo(c *gin.Context) { repo.Link = from.Link repo.Clone = from.Clone repo.IsPrivate = from.IsPrivate + if repo.IsPrivate != from.IsPrivate { + repo.ResetVisibility() + } repo.Visibility = from.Visibility errStore := store.UpdateRepo(c, repo) @@ -259,14 +269,3 @@ func MoveRepo(c *gin.Context) { RepairRepo(c) } -// ParseRepo parses the repository owner and name from a string. -func ParseRepo(str string) (user, repo string, err error) { - var parts = strings.Split(str, "/") - if len(parts) != 2 { - err = fmt.Errorf("Error: Invalid or missing repository. eg octocat/hello-world.") - return - } - user = parts[0] - repo = parts[1] - return -} From 06bffddf963337be703b146faa3ee93764ade920 Mon Sep 17 00:00:00 2001 From: Joachim Hill-Grannec Date: Mon, 21 Aug 2017 18:52:09 -0400 Subject: [PATCH 6/6] remove lingering visibility --- server/repo.go | 1 - 1 file changed, 1 deletion(-) diff --git a/server/repo.go b/server/repo.go index 2429b6fbc..a8ea75cf8 100644 --- a/server/repo.go +++ b/server/repo.go @@ -258,7 +258,6 @@ func MoveRepo(c *gin.Context) { if repo.IsPrivate != from.IsPrivate { repo.ResetVisibility() } - repo.Visibility = from.Visibility errStore := store.UpdateRepo(c, repo) if errStore != nil {