Revert to an int64 keyed accessMap

* Add type `userAccess`
* Add convenience func updateUserAccess()
* Turn accessMap into a `map[int64]userAccess`

Signed-off-by: Manush Dodunekov <manush@stendahls.se>
This commit is contained in:
Manush Dodunekov 2020-01-08 21:42:59 +01:00
parent 5b652427c0
commit 124f056e19

View File

@ -170,24 +170,40 @@ func maxAccessMode(modes ...AccessMode) AccessMode {
return max return max
} }
type userAccess struct {
User *User
Mode AccessMode
}
// updateUserAccess updates an access map so that user has at least mode
func updateUserAccess(accessMap map[int64]userAccess, user *User, mode AccessMode) {
ua, ok := accessMap[user.ID]
if !ok {
ua = userAccess{User: user, Mode: mode}
accessMap[user.ID] = ua
} else {
ua.Mode = maxAccessMode(ua.Mode, mode)
}
}
// FIXME: do cross-comparison so reduce deletions and additions to the minimum? // FIXME: do cross-comparison so reduce deletions and additions to the minimum?
func (repo *Repository) refreshAccesses(e Engine, accessMap map[*User]AccessMode) (err error) { func (repo *Repository) refreshAccesses(e Engine, accessMap map[int64]userAccess) (err error) {
minMode := AccessModeRead minMode := AccessModeRead
if !repo.IsPrivate { if !repo.IsPrivate {
minMode = AccessModeWrite minMode = AccessModeWrite
} }
// merge accessMap contents into a single ID-keyed map to eliminate duplicates // build a map of the actual entries we want to create
idMap := make(map[int64]AccessMode, len(accessMap)) entryMap := make(map[int64]AccessMode, len(accessMap))
for user, mode := range accessMap { for userID, ua := range accessMap {
if mode < minMode && !user.IsRestricted { if ua.Mode < minMode && !ua.User.IsRestricted {
continue continue
} }
idMap[user.ID] = maxAccessMode(idMap[user.ID], mode) entryMap[userID] = ua.Mode
} }
newAccesses := make([]Access, 0, len(idMap)) newAccesses := make([]Access, 0, len(entryMap))
for userID, mode := range idMap { for userID, mode := range entryMap {
newAccesses = append(newAccesses, Access{ newAccesses = append(newAccesses, Access{
UserID: userID, UserID: userID,
RepoID: repo.ID, RepoID: repo.ID,
@ -205,13 +221,13 @@ func (repo *Repository) refreshAccesses(e Engine, accessMap map[*User]AccessMode
} }
// refreshCollaboratorAccesses retrieves repository collaborations with their access modes. // refreshCollaboratorAccesses retrieves repository collaborations with their access modes.
func (repo *Repository) refreshCollaboratorAccesses(e Engine, accessMap map[*User]AccessMode) error { func (repo *Repository) refreshCollaboratorAccesses(e Engine, accessMap map[int64]userAccess) error {
collaborators, err := repo.getCollaborators(e) collaborators, err := repo.getCollaborators(e)
if err != nil { if err != nil {
return fmt.Errorf("getCollaborations: %v", err) return fmt.Errorf("getCollaborations: %v", err)
} }
for _, c := range collaborators { for _, c := range collaborators {
accessMap[c.User] = maxAccessMode(accessMap[c.User], c.Collaboration.Mode) updateUserAccess(accessMap, c.User, c.Collaboration.Mode)
} }
return nil return nil
} }
@ -220,7 +236,7 @@ func (repo *Repository) refreshCollaboratorAccesses(e Engine, accessMap map[*Use
// except the team whose ID is given. It is used to assign a team ID when // except the team whose ID is given. It is used to assign a team ID when
// remove repository from that team. // remove repository from that team.
func (repo *Repository) recalculateTeamAccesses(e Engine, ignTeamID int64) (err error) { func (repo *Repository) recalculateTeamAccesses(e Engine, ignTeamID int64) (err error) {
accessMap := make(map[*User]AccessMode, 20) accessMap := make(map[int64]userAccess, 20)
if err = repo.getOwner(e); err != nil { if err = repo.getOwner(e); err != nil {
return err return err
@ -253,7 +269,7 @@ func (repo *Repository) recalculateTeamAccesses(e Engine, ignTeamID int64) (err
return fmt.Errorf("getMembers '%d': %v", t.ID, err) return fmt.Errorf("getMembers '%d': %v", t.ID, err)
} }
for _, m := range t.Members { for _, m := range t.Members {
accessMap[m] = maxAccessMode(accessMap[m], t.Authorize) updateUserAccess(accessMap, m, t.Authorize)
} }
} }
@ -314,7 +330,7 @@ func (repo *Repository) recalculateAccesses(e Engine) error {
return repo.recalculateTeamAccesses(e, 0) return repo.recalculateTeamAccesses(e, 0)
} }
accessMap := make(map[*User]AccessMode, 20) accessMap := make(map[int64]userAccess, 20)
if err := repo.refreshCollaboratorAccesses(e, accessMap); err != nil { if err := repo.refreshCollaboratorAccesses(e, accessMap); err != nil {
return fmt.Errorf("refreshCollaboratorAccesses: %v", err) return fmt.Errorf("refreshCollaboratorAccesses: %v", err)
} }