@@ -68,6 +68,7 @@ type RepoTransfer struct { //nolint
6868 RecipientID int64
6969 Recipient * user_model.User `xorm:"-"`
7070 RepoID int64
71+ Repo * Repository `xorm:"-"`
7172 TeamIDs []int64
7273 Teams []* organization.Team `xorm:"-"`
7374
@@ -79,48 +80,65 @@ func init() {
7980 db .RegisterModel (new (RepoTransfer ))
8081}
8182
82- // LoadAttributes fetches the transfer recipient from the database
83- func (r * RepoTransfer ) LoadAttributes (ctx context.Context ) error {
83+ func (r * RepoTransfer ) LoadRecipient (ctx context.Context ) error {
8484 if r .Recipient == nil {
8585 u , err := user_model .GetUserByID (ctx , r .RecipientID )
8686 if err != nil {
8787 return err
8888 }
89-
9089 r .Recipient = u
9190 }
9291
93- if r .Recipient .IsOrganization () && len (r .TeamIDs ) != len (r .Teams ) {
94- for _ , v := range r .TeamIDs {
95- team , err := organization .GetTeamByID (ctx , v )
96- if err != nil {
97- return err
98- }
92+ return nil
93+ }
9994
100- if team .OrgID != r .Recipient .ID {
101- return fmt .Errorf ("team %d belongs not to org %d" , v , r .Recipient .ID )
102- }
95+ func (r * RepoTransfer ) LoadRepo (ctx context.Context ) error {
96+ if r .Repo == nil {
97+ repo , err := GetRepositoryByID (ctx , r .RepoID )
98+ if err != nil {
99+ return err
100+ }
101+ r .Repo = repo
102+ }
103+
104+ return nil
105+ }
106+
107+ // LoadAttributes fetches the transfer recipient from the database
108+ func (r * RepoTransfer ) LoadAttributes (ctx context.Context ) error {
109+ if err := r .LoadRecipient (ctx ); err != nil {
110+ return err
111+ }
103112
113+ if r .Recipient .IsOrganization () && r .Teams == nil {
114+ teamsMap , err := organization .GetTeamsByIDs (ctx , r .TeamIDs )
115+ if err != nil {
116+ return err
117+ }
118+ for _ , team := range teamsMap {
104119 r .Teams = append (r .Teams , team )
105120 }
106121 }
107122
123+ if err := r .LoadRepo (ctx ); err != nil {
124+ return err
125+ }
126+
108127 if r .Doer == nil {
109128 u , err := user_model .GetUserByID (ctx , r .DoerID )
110129 if err != nil {
111130 return err
112131 }
113-
114132 r .Doer = u
115133 }
116134
117135 return nil
118136}
119137
120- // CanUserAcceptOrRejectTransfer checks if the user has the rights to accept/decline a repo transfer.
138+ // CanUserAcceptTransfer checks if the user has the rights to accept/decline a repo transfer.
121139// For user, it checks if it's himself
122140// For organizations, it checks if the user is able to create repos
123- func (r * RepoTransfer ) CanUserAcceptOrRejectTransfer (ctx context.Context , u * user_model.User ) bool {
141+ func (r * RepoTransfer ) CanUserAcceptTransfer (ctx context.Context , u * user_model.User ) bool {
124142 if err := r .LoadAttributes (ctx ); err != nil {
125143 log .Error ("LoadAttributes: %v" , err )
126144 return false
@@ -139,6 +157,32 @@ func (r *RepoTransfer) CanUserAcceptOrRejectTransfer(ctx context.Context, u *use
139157 return allowed
140158}
141159
160+ func (r * RepoTransfer ) CanUserCancelTransfer (ctx context.Context , u * user_model.User ) bool {
161+ if r .DoerID == u .ID { // sender can cancel the transfer
162+ return true
163+ }
164+ if err := r .Repo .LoadOwner (ctx ); err != nil {
165+ log .Error ("LoadOwner: %v" , err )
166+ return false
167+ }
168+ if ! r .Repo .Owner .IsOrganization () {
169+ if u .ID == r .Repo .OwnerID { // owner can cancel the transfer
170+ return true
171+ }
172+ } else {
173+ allowed , err := organization .CanCreateOrgRepo (ctx , r .Repo .OwnerID , u .ID )
174+ if err != nil {
175+ log .Error ("CanCreateOrgRepo: %v" , err )
176+ return false
177+ }
178+ if allowed {
179+ return true
180+ }
181+ }
182+
183+ return r .CanUserAcceptTransfer (ctx , u ) // the user who can accept the transfer can also reject it
184+ }
185+
142186type PendingRepositoryTransferOptions struct {
143187 RepoID int64
144188 SenderID int64
0 commit comments