@@ -27,49 +27,51 @@ func getRepoWorkingLockKey(repoID int64) string {
27
27
return fmt .Sprintf ("repo_working_%d" , repoID )
28
28
}
29
29
30
- // TransferOwnership transfers all corresponding setting from old user to new one.
31
- func TransferOwnership (ctx context.Context , doer , newOwner * user_model.User , repo * repo_model.Repository , teams []* organization.Team ) error {
32
- if err := repo .LoadOwner (ctx ); err != nil {
33
- return err
34
- }
35
- for _ , team := range teams {
36
- if newOwner .ID != team .OrgID {
37
- return fmt .Errorf ("team %d does not belong to organization" , team .ID )
38
- }
39
- }
40
-
41
- oldOwner := repo .Owner
42
-
30
+ // AcceptTransferOwnership transfers all corresponding setting from old user to new one.
31
+ func AcceptTransferOwnership (ctx context.Context , repo * repo_model.Repository , doer * user_model.User ) error {
43
32
releaser , err := globallock .Lock (ctx , getRepoWorkingLockKey (repo .ID ))
44
33
if err != nil {
45
34
log .Error ("lock.Lock(): %v" , err )
46
35
return fmt .Errorf ("lock.Lock: %w" , err )
47
36
}
48
37
defer releaser ()
49
38
50
- if err := transferOwnership (ctx , doer , newOwner .Name , repo ); err != nil {
51
- return err
52
- }
53
- releaser ()
54
-
55
- newRepo , err := repo_model .GetRepositoryByID (ctx , repo .ID )
39
+ repoTransfer , err := repo_model .GetPendingRepositoryTransfer (ctx , repo )
56
40
if err != nil {
57
41
return err
58
42
}
59
43
60
- for _ , team := range teams {
61
- if err := addRepositoryToTeam (ctx , team , newRepo ); err != nil {
44
+ if err := db . WithTx ( ctx , func ( ctx context. Context ) error {
45
+ if err := repoTransfer . LoadAttributes (ctx ); err != nil {
62
46
return err
63
47
}
48
+
49
+ if ! repoTransfer .CanUserAcceptOrRejectTransfer (ctx , doer ) {
50
+ return util .ErrPermissionDenied
51
+ }
52
+
53
+ if err := repo .LoadOwner (ctx ); err != nil {
54
+ return err
55
+ }
56
+ for _ , team := range repoTransfer .Teams {
57
+ if repoTransfer .Recipient .ID != team .OrgID {
58
+ return fmt .Errorf ("team %d does not belong to organization" , team .ID )
59
+ }
60
+ }
61
+
62
+ return transferOwnership (ctx , repoTransfer .Doer , repoTransfer .Recipient .Name , repo , repoTransfer .Teams )
63
+ }); err != nil {
64
+ return err
64
65
}
66
+ releaser ()
65
67
66
- notify_service .TransferRepository (ctx , doer , repo , oldOwner .Name )
68
+ notify_service .TransferRepository (ctx , doer , repo , repoTransfer . Recipient .Name )
67
69
68
70
return nil
69
71
}
70
72
71
73
// transferOwnership transfers all corresponding repository items from old user to new one.
72
- func transferOwnership (ctx context.Context , doer * user_model.User , newOwnerName string , repo * repo_model.Repository ) (err error ) {
74
+ func transferOwnership (ctx context.Context , doer * user_model.User , newOwnerName string , repo * repo_model.Repository , teams [] * organization. Team ) (err error ) {
73
75
repoRenamed := false
74
76
wikiRenamed := false
75
77
oldOwnerName := doer .Name
@@ -301,6 +303,17 @@ func transferOwnership(ctx context.Context, doer *user_model.User, newOwnerName
301
303
return fmt .Errorf ("repo_model.NewRedirect: %w" , err )
302
304
}
303
305
306
+ newRepo , err := repo_model .GetRepositoryByID (ctx , repo .ID )
307
+ if err != nil {
308
+ return err
309
+ }
310
+
311
+ for _ , team := range teams {
312
+ if err := addRepositoryToTeam (ctx , team , newRepo ); err != nil {
313
+ return err
314
+ }
315
+ }
316
+
304
317
return committer .Commit ()
305
318
}
306
319
@@ -343,17 +356,9 @@ func changeRepositoryName(ctx context.Context, repo *repo_model.Repository, newR
343
356
}
344
357
}
345
358
346
- ctx , committer , err := db .TxContext (ctx )
347
- if err != nil {
348
- return err
349
- }
350
- defer committer .Close ()
351
-
352
- if err := repo_model .NewRedirect (ctx , repo .Owner .ID , repo .ID , oldRepoName , newRepoName ); err != nil {
353
- return err
354
- }
355
-
356
- return committer .Commit ()
359
+ return db .WithTx (ctx , func (ctx context.Context ) error {
360
+ return repo_model .NewRedirect (ctx , repo .Owner .ID , repo .ID , oldRepoName , newRepoName )
361
+ })
357
362
}
358
363
359
364
// ChangeRepositoryName changes all corresponding setting from old repository name to new one.
@@ -391,66 +396,81 @@ func StartRepositoryTransfer(ctx context.Context, doer, newOwner *user_model.Use
391
396
return err
392
397
}
393
398
394
- // Admin is always allowed to transfer || user transfer repo back to his account
395
- if doer .IsAdmin || doer .ID == newOwner .ID {
396
- return TransferOwnership (ctx , doer , newOwner , repo , teams )
397
- }
399
+ var isTransfer bool
398
400
399
- if user_model .IsUserBlockedBy (ctx , doer , newOwner .ID ) {
400
- return user_model .ErrBlockedUser
401
- }
401
+ if err := db .WithTx (ctx , func (ctx context.Context ) error {
402
+ // Admin is always allowed to transfer || user transfer repo back to his account
403
+ if doer .IsAdmin || doer .ID == newOwner .ID {
404
+ isTransfer = true
405
+ return transferOwnership (ctx , doer , newOwner .Name , repo , teams )
406
+ }
402
407
403
- // If new owner is an org and user can create repos he can transfer directly too
404
- if newOwner .IsOrganization () {
405
- allowed , err := organization .CanCreateOrgRepo (ctx , newOwner .ID , doer .ID )
406
- if err != nil {
407
- return err
408
+ if user_model .IsUserBlockedBy (ctx , doer , newOwner .ID ) {
409
+ return user_model .ErrBlockedUser
408
410
}
409
- if allowed {
410
- return TransferOwnership (ctx , doer , newOwner , repo , teams )
411
+
412
+ // If new owner is an org and user can create repos he can transfer directly too
413
+ if newOwner .IsOrganization () {
414
+ allowed , err := organization .CanCreateOrgRepo (ctx , newOwner .ID , doer .ID )
415
+ if err != nil {
416
+ return err
417
+ }
418
+ if allowed {
419
+ isTransfer = true
420
+ return transferOwnership (ctx , doer , newOwner .Name , repo , teams )
421
+ }
411
422
}
412
- }
413
423
414
- // In case the new owner would not have sufficient access to the repo, give access rights for read
415
- hasAccess , err := access_model .HasAnyUnitAccess (ctx , newOwner .ID , repo )
416
- if err != nil {
417
- return err
418
- }
419
- if ! hasAccess {
420
- if err := AddOrUpdateCollaborator (ctx , repo , newOwner , perm .AccessModeRead ); err != nil {
424
+ // In case the new owner would not have sufficient access to the repo, give access rights for read
425
+ hasAccess , err := access_model .HasAnyUnitAccess (ctx , newOwner .ID , repo )
426
+ if err != nil {
421
427
return err
422
428
}
423
- }
429
+ if ! hasAccess {
430
+ if err := AddOrUpdateCollaborator (ctx , repo , newOwner , perm .AccessModeRead ); err != nil {
431
+ return err
432
+ }
433
+ }
424
434
425
- // Make repo as pending for transfer
426
- repo .Status = repo_model .RepositoryPendingTransfer
427
- if err := repo_model .CreatePendingRepositoryTransfer (ctx , doer , newOwner , repo .ID , teams ); err != nil {
435
+ // Make repo as pending for transfer
436
+ repo .Status = repo_model .RepositoryPendingTransfer
437
+ return repo_model .CreatePendingRepositoryTransfer (ctx , doer , newOwner , repo .ID , teams )
438
+ }); err != nil {
428
439
return err
429
440
}
430
441
431
- // notify users who are able to accept / reject transfer
432
- notify_service .RepoPendingTransfer (ctx , doer , newOwner , repo )
442
+ if isTransfer {
443
+ notify_service .TransferRepository (ctx , doer , repo , newOwner .Name )
444
+ } else {
445
+ // notify users who are able to accept / reject transfer
446
+ notify_service .RepoPendingTransfer (ctx , doer , newOwner , repo )
447
+ }
433
448
434
449
return nil
435
450
}
436
451
437
- // CancelRepositoryTransfer marks the repository as ready and remove pending transfer entry,
452
+ // RejectRepositoryTransfer marks the repository as ready and remove pending transfer entry,
438
453
// thus cancel the transfer process.
439
- func CancelRepositoryTransfer (ctx context.Context , repo * repo_model.Repository ) error {
440
- ctx , committer , err := db .TxContext (ctx )
441
- if err != nil {
442
- return err
443
- }
444
- defer committer . Close ()
454
+ func RejectRepositoryTransfer (ctx context.Context , repo * repo_model.Repository , doer * user_model. User ) error {
455
+ return db .WithTx (ctx , func ( ctx context. Context ) error {
456
+ repoTransfer , err := repo_model . GetPendingRepositoryTransfer ( ctx , repo )
457
+ if err != nil {
458
+ return err
459
+ }
445
460
446
- repo .Status = repo_model .RepositoryReady
447
- if err := repo_model .UpdateRepositoryCols (ctx , repo , "status" ); err != nil {
448
- return err
449
- }
461
+ if err := repoTransfer .LoadAttributes (ctx ); err != nil {
462
+ return err
463
+ }
450
464
451
- if err := repo_model . DeleteRepositoryTransfer (ctx , repo . ID ); err != nil {
452
- return err
453
- }
465
+ if ! repoTransfer . CanUserAcceptOrRejectTransfer (ctx , doer ) {
466
+ return util . ErrPermissionDenied
467
+ }
454
468
455
- return committer .Commit ()
469
+ repo .Status = repo_model .RepositoryReady
470
+ if err := repo_model .UpdateRepositoryCols (ctx , repo , "status" ); err != nil {
471
+ return err
472
+ }
473
+
474
+ return repo_model .DeleteRepositoryTransfer (ctx , repo .ID )
475
+ })
456
476
}
0 commit comments