From 32b09681b2da96afe9a44790e7944c4ac51e696c Mon Sep 17 00:00:00 2001
From: Unknown <joe2010xtmf@163.com>
Date: Wed, 25 Jun 2014 05:35:23 -0400
Subject: [PATCH] Migrate repository by organization

---
 models/repo.go              |  8 +++----
 modules/auth/repo.go        |  1 +
 routers/repo/repo.go        | 46 +++++++++++++++++++++++++++++--------
 templates/repo/migrate.tmpl | 32 ++++++++++++++++++++++++--
 4 files changed, 72 insertions(+), 15 deletions(-)

diff --git a/models/repo.go b/models/repo.go
index 728f14a7d6..840529b959 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -251,8 +251,8 @@ func MirrorUpdate() {
 }
 
 // MigrateRepository migrates a existing repository from other project hosting.
-func MigrateRepository(user *User, name, desc string, private, mirror bool, url string) (*Repository, error) {
-	repo, err := CreateRepository(user, name, desc, "", "", private, mirror, false)
+func MigrateRepository(u *User, name, desc string, private, mirror bool, url string) (*Repository, error) {
+	repo, err := CreateRepository(u, name, desc, "", "", private, mirror, false)
 	if err != nil {
 		return nil, err
 	}
@@ -261,11 +261,11 @@ func MigrateRepository(user *User, name, desc string, private, mirror bool, url
 	tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("%d", time.Now().Nanosecond()))
 	os.MkdirAll(tmpDir, os.ModePerm)
 
-	repoPath := RepoPath(user.Name, name)
+	repoPath := RepoPath(u.Name, name)
 
 	repo.IsBare = false
 	if mirror {
-		if err = MirrorRepository(repo.Id, user.Name, repo.Name, repoPath, url); err != nil {
+		if err = MirrorRepository(repo.Id, u.Name, repo.Name, repoPath, url); err != nil {
 			return repo, err
 		}
 		repo.IsMirror = true
diff --git a/modules/auth/repo.go b/modules/auth/repo.go
index 999f33fe81..db13743de8 100644
--- a/modules/auth/repo.go
+++ b/modules/auth/repo.go
@@ -48,6 +48,7 @@ type MigrateRepoForm struct {
 	Url          string `form:"url" binding:"Url"`
 	AuthUserName string `form:"auth_username"`
 	AuthPasswd   string `form:"auth_password"`
+	Uid          int64  `form:"uid" binding:"Required"`
 	RepoName     string `form:"repo" binding:"Required;AlphaDash;MaxSize(100)"`
 	Mirror       bool   `form:"mirror"`
 	Private      bool   `form:"private"`
diff --git a/routers/repo/repo.go b/routers/repo/repo.go
index d96456422b..6cb6c0660e 100644
--- a/routers/repo/repo.go
+++ b/routers/repo/repo.go
@@ -53,7 +53,7 @@ func CreatePost(ctx *middleware.Context, form auth.CreateRepoForm) {
 	ctx.Data["Licenses"] = models.Licenses
 
 	if err := ctx.User.GetOrganizations(); err != nil {
-		ctx.Handle(500, "home.Dashboard(GetOrganizations)", err)
+		ctx.Handle(500, "home.CreatePost(GetOrganizations)", err)
 		return
 	}
 	ctx.Data["Orgs"] = ctx.User.Orgs
@@ -70,9 +70,9 @@ func CreatePost(ctx *middleware.Context, form auth.CreateRepoForm) {
 		u, err = models.GetUserById(form.Uid)
 		if err != nil {
 			if err == models.ErrUserNotExist {
-				ctx.Handle(404, "home.Dashboard(GetUserById)", err)
+				ctx.Handle(404, "home.CreatePost(GetUserById)", err)
 			} else {
-				ctx.Handle(500, "home.Dashboard(GetUserById)", err)
+				ctx.Handle(500, "home.CreatePost(GetUserById)", err)
 			}
 			return
 		}
@@ -97,12 +97,19 @@ func CreatePost(ctx *middleware.Context, form auth.CreateRepoForm) {
 			log.Error("repo.CreatePost(DeleteRepository): %v", errDelete)
 		}
 	}
-	ctx.Handle(500, "repo.CreatePost", err)
+	ctx.Handle(500, "repo.CreatePost(CreateRepository)", err)
 }
 
 func Migrate(ctx *middleware.Context) {
 	ctx.Data["Title"] = "Migrate repository"
 	ctx.Data["PageIsNewRepo"] = true
+
+	if err := ctx.User.GetOrganizations(); err != nil {
+		ctx.Handle(500, "home.Migrate(GetOrganizations)", err)
+		return
+	}
+	ctx.Data["Orgs"] = ctx.User.Orgs
+
 	ctx.HTML(200, MIGRATE)
 }
 
@@ -110,19 +117,40 @@ func MigratePost(ctx *middleware.Context, form auth.MigrateRepoForm) {
 	ctx.Data["Title"] = "Migrate repository"
 	ctx.Data["PageIsNewRepo"] = true
 
+	if err := ctx.User.GetOrganizations(); err != nil {
+		ctx.Handle(500, "home.MigratePost(GetOrganizations)", err)
+		return
+	}
+	ctx.Data["Orgs"] = ctx.User.Orgs
+
 	if ctx.HasError() {
 		ctx.HTML(200, MIGRATE)
 		return
 	}
 
+	u := ctx.User
+	// Not equal means current user is an organization.
+	if u.Id != form.Uid {
+		var err error
+		u, err = models.GetUserById(form.Uid)
+		if err != nil {
+			if err == models.ErrUserNotExist {
+				ctx.Handle(404, "home.MigratePost(GetUserById)", err)
+			} else {
+				ctx.Handle(500, "home.MigratePost(GetUserById)", err)
+			}
+			return
+		}
+	}
+
 	authStr := strings.Replace(fmt.Sprintf("://%s:%s",
 		form.AuthUserName, form.AuthPasswd), "@", "%40", -1)
 	url := strings.Replace(form.Url, "://", authStr+"@", 1)
-	repo, err := models.MigrateRepository(ctx.User, form.RepoName, form.Description, form.Private,
+	repo, err := models.MigrateRepository(u, form.RepoName, form.Description, form.Private,
 		form.Mirror, url)
 	if err == nil {
-		log.Trace("%s Repository migrated: %s/%s", ctx.Req.RequestURI, ctx.User.LowerName, form.RepoName)
-		ctx.Redirect("/" + ctx.User.Name + "/" + form.RepoName)
+		log.Trace("%s Repository migrated: %s/%s", ctx.Req.RequestURI, u.LowerName, form.RepoName)
+		ctx.Redirect("/" + u.Name + "/" + form.RepoName)
 		return
 	} else if err == models.ErrRepoAlreadyExist {
 		ctx.RenderWithErr("Repository name has already been used", MIGRATE, &form)
@@ -133,7 +161,7 @@ func MigratePost(ctx *middleware.Context, form auth.MigrateRepoForm) {
 	}
 
 	if repo != nil {
-		if errDelete := models.DeleteRepository(ctx.User.Id, repo.Id, ctx.User.Name); errDelete != nil {
+		if errDelete := models.DeleteRepository(u.Id, repo.Id, u.Name); errDelete != nil {
 			log.Error("repo.MigratePost(DeleteRepository): %v", errDelete)
 		}
 	}
@@ -142,7 +170,7 @@ func MigratePost(ctx *middleware.Context, form auth.MigrateRepoForm) {
 		ctx.RenderWithErr(err.Error(), MIGRATE, &form)
 		return
 	}
-	ctx.Handle(500, "repo.Migrate", err)
+	ctx.Handle(500, "repo.Migrate(MigrateRepository)", err)
 }
 
 func Single(ctx *middleware.Context, params martini.Params) {
diff --git a/templates/repo/migrate.tmpl b/templates/repo/migrate.tmpl
index 34a4077eec..fff25e6de5 100644
--- a/templates/repo/migrate.tmpl
+++ b/templates/repo/migrate.tmpl
@@ -44,9 +44,37 @@
         <div class="form-group">
             <label class="col-md-2 control-label">Owner<strong class="text-danger">*</strong></label>
             <div class="col-md-8">
-                <p class="form-control-static">{{.SignedUserName}}</p>
-                <input type="hidden" value="{{.SignedUserId}}" name="userId"/>
+                <div class="btn-group" id="repo-owner-switch">
+                    <button type="button" class="btn btn-default" id="repo-owner-current">
+                        <img src="{{.SignedUser.AvatarLink}}?s=28" alt="user-avatar" title="username" id="repo-owner-avatar">
+                        <span id="repo-owner-name">{{.SignedUser.Name}}</span>
+                    </button>
+                    <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
+                        <span class="caret"></span>
+                    </button>
+                    <div class="dropdown-menu clone-group-btn no-propagation">
+                        <ul id="dashboard-switch-menu" class="list-unstyled">
+                            <li data-uid="{{.SignedUser.Id}}" class="checked">
+                                <a>
+                                    <i class="fa fa-check"></i>
+                                    <img src="{{.SignedUser.AvatarLink}}?s=28" alt="user-avatar" title="username">
+                                    {{.SignedUser.Name}}
+                                </a>
+                            </li>
+                            {{range .Orgs}}
+                            <li data-uid="{{.Id}}">
+                                <a>
+                                    <i class="fa fa-check"></i>
+                                    <img src="{{.AvatarLink}}?s=28" alt="user-avatar" title="username">
+                                    {{.Name}}
+                                </a>
+                            </li>
+                            {{end}}
+                        </ul>
+                    </div>
+                </div>
             </div>
+            <input type="hidden" value="{{.SignedUserId}}" name="uid" id="repo-owner-id"/>
         </div>
 
         <div class="form-group {{if .Err_RepoName}}has-error has-feedback{{end}}">