Skip to content

Commit 02906e2

Browse files
committed
complete repo transfer
1 parent 25386e1 commit 02906e2

File tree

7 files changed

+75
-44
lines changed

7 files changed

+75
-44
lines changed

models/repo_transfer.go

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ const (
3131
// RepoTransfer is used to manage repository transfers
3232
type RepoTransfer struct {
3333
ID int64 `xorm:"pk autoincr"`
34+
UserID int64
35+
User *User `xorm:"-"`
3436
RecipientID int64
3537
Recipient *User `xorm:"-"`
3638
RepoID int64
@@ -39,18 +41,30 @@ type RepoTransfer struct {
3941
Status TransferStatus
4042
}
4143

42-
// LoadRecipient fetches the transfer recipient from the database
43-
func (r *RepoTransfer) LoadRecipient() error {
44-
if r.Recipient != nil {
44+
// LoadAttributes fetches the transfer recipient from the database
45+
func (r *RepoTransfer) LoadAttributes() error {
46+
if r.Recipient != nil && r.User != nil {
4547
return nil
4648
}
4749

48-
u, err := GetUserByID(r.RecipientID)
49-
if err != nil {
50-
return err
50+
if r.Recipient == nil {
51+
u, err := GetUserByID(r.RecipientID)
52+
if err != nil {
53+
return err
54+
}
55+
56+
r.Recipient = u
57+
}
58+
59+
if r.User == nil {
60+
u, err := GetUserByID(r.UserID)
61+
if err != nil {
62+
return err
63+
}
64+
65+
r.User = u
5166
}
5267

53-
r.Recipient = u
5468
return nil
5569
}
5670

@@ -59,20 +73,26 @@ func (r *RepoTransfer) LoadRecipient() error {
5973
func GetPendingRepositoryTransfer(repo *Repository) (*RepoTransfer, error) {
6074
var transfer = new(RepoTransfer)
6175

62-
_, err := x.Where("status = ? AND repo_id = ? ", Pending, repo.ID).
76+
has, err := x.Where("status = ? AND repo_id = ? ", Pending, repo.ID).
6377
Get(transfer)
64-
6578
if err != nil {
6679
return nil, err
6780
}
6881

69-
if transfer.ID == 0 {
82+
if transfer.ID == 0 || !has {
7083
return nil, ErrNoPendingRepoTransfer{RepoID: repo.ID}
7184
}
7285

7386
return transfer, nil
7487
}
7588

89+
func acceptRepositoryTransfer(repo *Repository) error {
90+
_, err := x.Where("repo_id = ?", repo.ID).Cols("status").Update(&RepoTransfer{
91+
Status: Accepted,
92+
})
93+
return err
94+
}
95+
7696
// CancelRepositoryTransfer makes sure to set the transfer process as
7797
// "rejected". Thus ending the transfer process
7898
func CancelRepositoryTransfer(repoTransfer *RepoTransfer) error {
@@ -85,15 +105,12 @@ func CancelRepositoryTransfer(repoTransfer *RepoTransfer) error {
85105

86106
// StartRepositoryTransfer marks the repository transfer as "pending". It
87107
// doesn't actually transfer the repository until the user acks the transfer.
88-
func StartRepositoryTransfer(newOwnerName string, repo *Repository) error {
108+
func StartRepositoryTransfer(doer *User, newOwnerName string, repo *Repository) error {
89109
// Make sure the repo isn't being transferred to someone currently
90110
// Only one transfer process can be initiated at a time.
91-
// It has to be cancelled for a new transfer to occur
92-
93-
n, err := x.Count(&RepoTransfer{
94-
RepoID: repo.ID,
95-
Status: Pending,
96-
})
111+
// It has to be cancelled for a new one to occur
112+
n, err := x.Where("status = ? AND repo_id = ?", Pending, repo.ID).
113+
Count(new(RepoTransfer))
97114
if err != nil {
98115
return err
99116
}
@@ -121,25 +138,23 @@ func StartRepositoryTransfer(newOwnerName string, repo *Repository) error {
121138
Status: Pending,
122139
CreatedUnix: util.TimeStampNow(),
123140
UpdatedUnix: util.TimeStampNow(),
141+
UserID: doer.ID,
124142
}
125143

126144
_, err = x.Insert(transfer)
127145
return err
128146
}
129147

130-
// TransferOwnership transfers all corresponding setting from old user to new one.
131-
func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error {
132-
newOwner, err := GetUserByName(newOwnerName)
133-
if err != nil {
134-
return fmt.Errorf("get new owner '%s': %v", newOwnerName, err)
135-
}
148+
// TransferOwnership transfers all corresponding setting from one user to
149+
// another.
150+
func TransferOwnership(doer, newOwner *User, repo *Repository) error {
136151

137152
// Check if new owner has repository with same name.
138153
has, err := IsRepositoryExist(newOwner, repo.Name)
139154
if err != nil {
140155
return fmt.Errorf("IsRepositoryExist: %v", err)
141156
} else if has {
142-
return ErrRepoAlreadyExist{newOwnerName, repo.Name}
157+
return ErrRepoAlreadyExist{newOwner.Name, repo.Name}
143158
}
144159

145160
sess := x.NewSession()
@@ -160,6 +175,10 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error
160175
return fmt.Errorf("update owner: %v", err)
161176
}
162177

178+
if err := acceptRepositoryTransfer(repo); err != nil {
179+
return err
180+
}
181+
163182
// Remove redundant collaborators.
164183
collaborators, err := repo.getCollaborators(sess)
165184
if err != nil {

modules/context/repo.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -453,8 +453,8 @@ func RepoAssignment() macaron.Handler {
453453
ctx.Data["PullRequestCtx"] = ctx.Repo.PullRequest
454454

455455
repoTransfer, err := models.GetPendingRepositoryTransfer(ctx.Repo.Repository)
456-
if err == nil && repoTransfer != nil {
457-
if err := repoTransfer.LoadRecipient(); err != nil {
456+
if err == nil {
457+
if err := repoTransfer.LoadAttributes(); err != nil {
458458
ctx.ServerError("LoadRecipient", err)
459459
return
460460
}

options/locale/locale_en-US.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,7 @@ settings.transfer_desc = Transfer this repository to a user or to an organizatio
11021102
settings.transfer_notices_1 = - You will lose access to the repository if you transfer it to an individual user.
11031103
settings.transfer_notices_2 = - You will keep access to the repository if you transfer it to an organization that you (co-)own.
11041104
settings.transfer_form_title = Enter the repository name as confirmation:
1105+
settings.transfer.success = Repository transfer was successful.
11051106
settings.wiki_delete = Delete Wiki Data
11061107
settings.wiki_delete_desc = Deleting repository wiki data is permanent and cannot be undone.
11071108
settings.wiki_delete_notices_1 = - This will permanently delete and disable the repository wiki for %s.

routers/repo/repo.go

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -296,15 +296,36 @@ func Action(ctx *context.Context) {
296296
err = models.StarRepo(ctx.User.ID, ctx.Repo.Repository.ID, true)
297297
case "unstar":
298298
err = models.StarRepo(ctx.User.ID, ctx.Repo.Repository.ID, false)
299-
case "desc": // FIXME: this is not used
300-
if !ctx.Repo.IsOwner() {
301-
ctx.Error(404)
299+
case "acknowledge_transfer":
300+
repoTransfer, err := models.GetPendingRepositoryTransfer(ctx.Repo.Repository)
301+
if err != nil {
302+
ctx.ServerError(fmt.Sprintf("Action (%s)", ctx.Params(":action")), err)
303+
}
304+
305+
if repoTransfer.RecipientID != ctx.User.ID {
306+
ctx.Status(404)
302307
return
303308
}
304309

305-
ctx.Repo.Repository.Description = ctx.Query("desc")
306-
ctx.Repo.Repository.Website = ctx.Query("site")
307-
err = models.UpdateRepository(ctx.Repo.Repository, false)
310+
if err := repoTransfer.LoadAttributes(); err != nil {
311+
ctx.ServerError(fmt.Sprintf("Action (%s)", ctx.Params(":action")), err)
312+
return
313+
}
314+
315+
if err := models.TransferOwnership(repoTransfer.User, repoTransfer.Recipient, ctx.Repo.Repository); err != nil {
316+
ctx.ServerError(fmt.Sprintf("Action (%s)", ctx.Params(":action")), err)
317+
return
318+
}
319+
320+
repo, err := models.GetRepositoryByID(ctx.Repo.Repository.ID)
321+
if err != nil {
322+
ctx.ServerError(fmt.Sprintf("Action (%s)", ctx.Params(":action")), err)
323+
return
324+
}
325+
326+
ctx.Flash.Success(ctx.Tr("repo.settings.transfer.success"))
327+
ctx.Redirect(repo.HTMLURL())
328+
return
308329
}
309330

310331
if err != nil {

routers/repo/repo_transfer.go

Lines changed: 0 additions & 8 deletions
This file was deleted.

routers/repo/setting.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
321321
return
322322
}
323323

324-
if err = models.StartRepositoryTransfer(newOwner, repo); err != nil {
324+
if err = models.StartRepositoryTransfer(ctx.User, newOwner, repo); err != nil {
325325
if models.IsErrRepoAlreadyExist(err) {
326326
ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplSettingsOptions, nil)
327327
} else if models.IsErrRepoTransferInProgress(err) {
@@ -361,7 +361,7 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
361361
return
362362
}
363363

364-
if err := repoTransfer.LoadRecipient(); err != nil {
364+
if err := repoTransfer.LoadAttributes(); err != nil {
365365
ctx.ServerError("LoadRecipient", err)
366366
return
367367
}

routers/routes/routes.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -581,8 +581,6 @@ func RegisterRoutes(m *macaron.Macaron) {
581581
m.Get("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), context.UnitTypes(), context.RepoMustNotBeArchived(), repo.Action)
582582
m.Get("/:username/:reponame/settings/transfer/acknowledge", reqSignIn, context.RepoAssignment(), repo.TransferRepo)
583583

584-
m.Get("/:username/:reponame/transfer/acknowledge", reqSignIn, context.RepoAssignment(), repo.AcknowledgeTranfer)
585-
586584
m.Group("/:username/:reponame", func() {
587585
m.Group("/issues", func() {
588586
m.Combo("/new").Get(context.RepoRef(), repo.NewIssue).

0 commit comments

Comments
 (0)