Skip to content

Commit 33107e8

Browse files
committed
complete repo transfer
1 parent cc7a479 commit 33107e8

File tree

8 files changed

+76
-44
lines changed

8 files changed

+76
-44
lines changed

models/migrations/v79.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
func addRepoTransfer(x *xorm.Engine) error {
1313
type RepoTransfer struct {
1414
ID int64 `xorm:"pk autoincr"`
15+
UserID int64
1516
RecipientID int64
1617
RepoID int64
1718
CreatedUnix util.TimeStamp `xorm:"INDEX NOT NULL created"`

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
@@ -437,8 +437,8 @@ func RepoAssignment() macaron.Handler {
437437
ctx.Data["PullRequestCtx"] = ctx.Repo.PullRequest
438438

439439
repoTransfer, err := models.GetPendingRepositoryTransfer(ctx.Repo.Repository)
440-
if err == nil && repoTransfer != nil {
441-
if err := repoTransfer.LoadRecipient(); err != nil {
440+
if err == nil {
441+
if err := repoTransfer.LoadAttributes(); err != nil {
442442
ctx.ServerError("LoadRecipient", err)
443443
return
444444
}

options/locale/locale_en-US.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,7 @@ settings.transfer_desc = Transfer this repository to a user or to an organizatio
10471047
settings.transfer_notices_1 = - You will lose access to the repository if you transfer it to an individual user.
10481048
settings.transfer_notices_2 = - You will keep access to the repository if you transfer it to an organization that you (co-)own.
10491049
settings.transfer_form_title = Enter the repository name as confirmation:
1050+
settings.transfer.success = Repository transfer was successful.
10501051
settings.wiki_delete = Delete Wiki Data
10511052
settings.wiki_delete_desc = Deleting repository wiki data is permanent and cannot be undone.
10521053
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
@@ -291,15 +291,36 @@ func Action(ctx *context.Context) {
291291
err = models.StarRepo(ctx.User.ID, ctx.Repo.Repository.ID, true)
292292
case "unstar":
293293
err = models.StarRepo(ctx.User.ID, ctx.Repo.Repository.ID, false)
294-
case "desc": // FIXME: this is not used
295-
if !ctx.Repo.IsOwner() {
296-
ctx.Error(404)
294+
case "acknowledge_transfer":
295+
repoTransfer, err := models.GetPendingRepositoryTransfer(ctx.Repo.Repository)
296+
if err != nil {
297+
ctx.ServerError(fmt.Sprintf("Action (%s)", ctx.Params(":action")), err)
298+
}
299+
300+
if repoTransfer.RecipientID != ctx.User.ID {
301+
ctx.Status(404)
297302
return
298303
}
299304

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

305326
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
@@ -307,7 +307,7 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
307307
return
308308
}
309309

310-
if err = models.StartRepositoryTransfer(newOwner, repo); err != nil {
310+
if err = models.StartRepositoryTransfer(ctx.User, newOwner, repo); err != nil {
311311
if models.IsErrRepoAlreadyExist(err) {
312312
ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplSettingsOptions, nil)
313313
} else if models.IsErrRepoTransferInProgress(err) {
@@ -340,7 +340,7 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
340340
return
341341
}
342342

343-
if err := repoTransfer.LoadRecipient(); err != nil {
343+
if err := repoTransfer.LoadAttributes(); err != nil {
344344
ctx.ServerError("LoadRecipient", err)
345345
return
346346
}

routers/routes/routes.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -558,8 +558,6 @@ func RegisterRoutes(m *macaron.Macaron) {
558558

559559
m.Get("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), context.RepoMustNotBeArchived(), repo.Action)
560560

561-
m.Get("/:username/:reponame/transfer/acknowledge", reqSignIn, context.RepoAssignment(), repo.AcknowledgeTranfer)
562-
563561
m.Group("/:username/:reponame", func() {
564562
m.Group("/issues", func() {
565563
m.Combo("/new").Get(context.RepoRef(), repo.NewIssue).

0 commit comments

Comments
 (0)