Skip to content

Commit 71979d9

Browse files
6543adelowotechknowlogicklafriks
authored
Automatically remove Watches, Assignments, etc if user loses access due to being removed as collaborator or from a team (#10997)
* remove a user from being assigned to any issue/PR if (s)he is removed as a collaborator * fix gender specific comment * do not remove users that still have access to the repo if they are a member of a team that can access the repo * add context to errors * updates * incorporate review fixes * Update models/repo_collaboration.go Co-Authored-By: 6543 <[email protected]> * Update models/repo_collaboration.go Co-Authored-By: 6543 <[email protected]> * Fix Rebase Relict * Fix & Impruve * use xorm builder * all in one session * generalize reconsiderIssueAssignees * Only Unwatch if have no access anymore * prepare for reuse * Same things if remove User from Team * fix lint * let mysql take time to react * add description * CI.restart() * CI.restart() Co-authored-by: Lanre Adelowo <[email protected]> Co-authored-by: techknowlogick <[email protected]> Co-authored-by: Lauris BH <[email protected]>
1 parent d00ebf4 commit 71979d9

File tree

4 files changed

+51
-13
lines changed

4 files changed

+51
-13
lines changed

integrations/release_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"fmt"
99
"net/http"
1010
"testing"
11+
"time"
1112

1213
"code.gitea.io/gitea/modules/test"
1314

@@ -63,6 +64,9 @@ func TestViewReleases(t *testing.T) {
6364
session := loginUser(t, "user2")
6465
req := NewRequest(t, "GET", "/user2/repo1/releases")
6566
session.MakeRequest(t, req, http.StatusOK)
67+
68+
// if CI is to slow this test fail, so lets wait a bit
69+
time.Sleep(time.Millisecond * 100)
6670
}
6771

6872
func TestViewReleasesNoLogin(t *testing.T) {

models/org_team.go

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -917,19 +917,12 @@ func removeTeamMember(e *xorm.Session, team *Team, userID int64) error {
917917
}
918918

919919
// Remove watches from now unaccessible
920-
has, err := hasAccess(e, userID, repo)
921-
if err != nil {
920+
if err := repo.reconsiderWatches(e, userID); err != nil {
922921
return err
923-
} else if has {
924-
continue
925922
}
926923

927-
if err = watchRepo(e, userID, repo.ID, false); err != nil {
928-
return err
929-
}
930-
931-
// Remove all IssueWatches a user has subscribed to in the repositories
932-
if err := removeIssueWatchersByRepoID(e, userID, repo.ID); err != nil {
924+
// Remove issue assignments from now unaccessible
925+
if err := repo.reconsiderIssueAssignees(e, userID); err != nil {
933926
return err
934927
}
935928
}

models/repo_collaboration.go

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ package models
77

88
import (
99
"fmt"
10+
11+
"xorm.io/builder"
1012
)
1113

1214
// Collaboration represent the relation between an individual and a repository.
@@ -189,14 +191,49 @@ func (repo *Repository) DeleteCollaboration(uid int64) (err error) {
189191
return err
190192
}
191193

192-
// Remove all IssueWatches a user has subscribed to in the repository
193-
if err := removeIssueWatchersByRepoID(sess, uid, repo.ID); err != nil {
194+
if err = repo.reconsiderWatches(sess, uid); err != nil {
195+
return err
196+
}
197+
198+
// Unassign a user from any issue (s)he has been assigned to in the repository
199+
if err := repo.reconsiderIssueAssignees(sess, uid); err != nil {
194200
return err
195201
}
196202

197203
return sess.Commit()
198204
}
199205

206+
func (repo *Repository) reconsiderIssueAssignees(e Engine, uid int64) error {
207+
user, err := getUserByID(e, uid)
208+
if err != nil {
209+
return err
210+
}
211+
212+
if canAssigned, err := canBeAssigned(e, user, repo, true); err != nil || canAssigned {
213+
return err
214+
}
215+
216+
if _, err := e.Where(builder.Eq{"assignee_id": uid}).
217+
In("issue_id", builder.Select("id").From("issue").Where(builder.Eq{"repo_id": repo.ID})).
218+
Delete(&IssueAssignees{}); err != nil {
219+
return fmt.Errorf("Could not delete assignee[%d] %v", uid, err)
220+
}
221+
return nil
222+
}
223+
224+
func (repo *Repository) reconsiderWatches(e Engine, uid int64) error {
225+
if has, err := hasAccess(e, uid, repo); err != nil || has {
226+
return err
227+
}
228+
229+
if err := watchRepo(e, uid, repo.ID, false); err != nil {
230+
return err
231+
}
232+
233+
// Remove all IssueWatches a user has subscribed to in the repository
234+
return removeIssueWatchersByRepoID(e, uid, repo.ID)
235+
}
236+
200237
func (repo *Repository) getRepoTeams(e Engine) (teams []*Team, err error) {
201238
return teams, e.
202239
Join("INNER", "team_repo", "team_repo.team_id = team.id").

models/repo_permission.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,10 +339,14 @@ func HasAccessUnit(user *User, repo *Repository, unitType UnitType, testMode Acc
339339
// Currently any write access (code, issues or pr's) is assignable, to match assignee list in user interface.
340340
// FIXME: user could send PullRequest also could be assigned???
341341
func CanBeAssigned(user *User, repo *Repository, isPull bool) (bool, error) {
342+
return canBeAssigned(x, user, repo, isPull)
343+
}
344+
345+
func canBeAssigned(e Engine, user *User, repo *Repository, _ bool) (bool, error) {
342346
if user.IsOrganization() {
343347
return false, fmt.Errorf("Organization can't be added as assignee [user_id: %d, repo_id: %d]", user.ID, repo.ID)
344348
}
345-
perm, err := GetUserRepoPermission(repo, user)
349+
perm, err := getUserRepoPermission(e, repo, user)
346350
if err != nil {
347351
return false, err
348352
}

0 commit comments

Comments
 (0)