models: done testing on new access system

tokarchuk/v1.17
Unknwon 10 years ago
parent e3dece1371
commit 473e265727
  1. 2
      gogs.go
  2. 98
      models/access.go
  3. 55
      models/org.go
  4. 41
      models/repo.go
  5. 2
      templates/.VERSION

@ -17,7 +17,7 @@ import (
"github.com/gogits/gogs/modules/setting" "github.com/gogits/gogs/modules/setting"
) )
const APP_VER = "0.5.15.0224 Beta" const APP_VER = "0.5.16.0228 Beta"
func init() { func init() {
runtime.GOMAXPROCS(runtime.NumCPU()) runtime.GOMAXPROCS(runtime.NumCPU())

@ -100,25 +100,58 @@ func maxAccessMode(modes ...AccessMode) AccessMode {
return max return max
} }
func (repo *Repository) recalculateTeamAccesses(e Engine, mode AccessMode) error { // FIXME: do corss-comparison so reduce deletions and additions to the minimum?
func (repo *Repository) refreshAccesses(e Engine, accessMap map[int64]AccessMode) (err error) {
minMode := ACCESS_MODE_READ
if !repo.IsPrivate {
minMode = ACCESS_MODE_WRITE
}
newAccesses := make([]Access, 0, len(accessMap))
for userID, mode := range accessMap {
if mode < minMode {
continue
}
newAccesses = append(newAccesses, Access{
UserID: userID,
RepoID: repo.Id,
Mode: mode,
})
}
// Delete old accesses and insert new ones for repository.
if _, err = e.Delete(&Access{RepoID: repo.Id}); err != nil {
return fmt.Errorf("delete old accesses: %v", err)
} else if _, err = e.Insert(newAccesses); err != nil {
return fmt.Errorf("insert new accesses: %v", err)
}
return nil return nil
} }
func (repo *Repository) recalculateAccesses(e Engine) error { // FIXME: should be able to have read-only access.
accessMap := make(map[int64]AccessMode, 20) // Give all collaborators write access.
func (repo *Repository) refreshCollaboratorAccesses(e Engine, accessMap map[int64]AccessMode) error {
// FIXME: should be able to have read-only access.
// Give all collaborators write access.
collaborators, err := repo.getCollaborators(e) collaborators, err := repo.getCollaborators(e)
if err != nil { if err != nil {
return err return fmt.Errorf("getCollaborators: %v", err)
} }
for _, c := range collaborators { for _, c := range collaborators {
accessMap[c.Id] = ACCESS_MODE_WRITE accessMap[c.Id] = ACCESS_MODE_WRITE
} }
return nil
}
if err := repo.getOwner(e); err != nil { // recalculateTeamAccesses recalculates new accesses for teams of an organization
// except the team whose ID is given. It is used to assign a team ID when
// remove repository from that team.
func (repo *Repository) recalculateTeamAccesses(e Engine, ignTeamID int64) (err error) {
accessMap := make(map[int64]AccessMode, 20)
if err = repo.refreshCollaboratorAccesses(e, accessMap); err != nil {
return fmt.Errorf("refreshCollaboratorAccesses: %v", err)
}
if err = repo.getOwner(e); err != nil {
return err return err
} }
if repo.Owner.IsOrganization() { if repo.Owner.IsOrganization() {
@ -126,47 +159,32 @@ func (repo *Repository) recalculateAccesses(e Engine) error {
return err return err
} }
for _, team := range repo.Owner.Teams { for _, t := range repo.Owner.Teams {
if team.IsOwnerTeam() { if t.ID == ignTeamID {
team.Authorize = ACCESS_MODE_OWNER continue
}
if t.IsOwnerTeam() {
t.Authorize = ACCESS_MODE_OWNER
} }
if err = team.getMembers(e); err != nil { if err = t.getMembers(e); err != nil {
return fmt.Errorf("getMembers '%d': %v", team.ID, err) return fmt.Errorf("getMembers '%d': %v", t.ID, err)
} }
for _, u := range team.Members { for _, m := range t.Members {
accessMap[u.Id] = maxAccessMode(accessMap[u.Id], team.Authorize) accessMap[m.Id] = maxAccessMode(accessMap[m.Id], t.Authorize)
} }
} }
} }
// FIXME: do corss-comparison so reduce deletions and additions to the minimum? return repo.refreshAccesses(e, accessMap)
}
minMode := ACCESS_MODE_READ
if !repo.IsPrivate {
minMode = ACCESS_MODE_WRITE
}
newAccesses := make([]Access, 0, len(accessMap))
for userID, mode := range accessMap {
if mode < minMode {
continue
}
newAccesses = append(newAccesses, Access{
UserID: userID,
RepoID: repo.Id,
Mode: mode,
})
}
// Delete old accesses and insert new ones for repository. func (repo *Repository) recalculateAccesses(e Engine) error {
if _, err = e.Delete(&Access{RepoID: repo.Id}); err != nil { accessMap := make(map[int64]AccessMode, 20)
return fmt.Errorf("delete old accesses: %v", err) if err := repo.refreshCollaboratorAccesses(e, accessMap); err != nil {
} else if _, err = e.Insert(newAccesses); err != nil { return fmt.Errorf("refreshCollaboratorAccesses: %v", err)
return fmt.Errorf("insert new accesses: %v", err)
} }
return repo.refreshAccesses(e, accessMap)
return nil
} }
// RecalculateAccesses recalculates all accesses for repository. // RecalculateAccesses recalculates all accesses for repository.

@ -85,6 +85,15 @@ func (org *User) RemoveMember(uid int64) error {
return RemoveOrgUser(org.Id, uid) return RemoveOrgUser(org.Id, uid)
} }
func (org *User) removeOrgRepo(e Engine, repoID int64) error {
return removeOrgRepo(e, org.Id, repoID)
}
// RemoveOrgRepo removes all team-repository relations of organization.
func (org *User) RemoveOrgRepo(repoID int64) error {
return org.removeOrgRepo(x, repoID)
}
// IsOrgEmailUsed returns true if the e-mail has been used in organization account. // IsOrgEmailUsed returns true if the e-mail has been used in organization account.
func IsOrgEmailUsed(email string) (bool, error) { func IsOrgEmailUsed(email string) (bool, error) {
if len(email) == 0 { if len(email) == 0 {
@ -364,7 +373,7 @@ func RemoveOrgUser(orgId, uid int64) error {
if _, err := sess.Id(ou.ID).Delete(ou); err != nil { if _, err := sess.Id(ou.ID).Delete(ou); err != nil {
sess.Rollback() sess.Rollback()
return err return err
} else if _, err = sess.Exec("UPDATE `user` SET num_members = num_members - 1 WHERE id = ?", orgId); err != nil { } else if _, err = sess.Exec("UPDATE `user` SET num_members=num_members-1 WHERE id = ?", orgId); err != nil {
sess.Rollback() sess.Rollback()
return err return err
} }
@ -496,7 +505,7 @@ func (t *Team) addRepository(e Engine, repo *Repository) (err error) {
return fmt.Errorf("update team: %v", err) return fmt.Errorf("update team: %v", err)
} }
if err = repo.recalculateAccesses(e); err != nil { if err = repo.recalculateTeamAccesses(e, 0); err != nil {
return fmt.Errorf("recalculateAccesses: %v", err) return fmt.Errorf("recalculateAccesses: %v", err)
} }
@ -532,7 +541,7 @@ func (t *Team) AddRepository(repo *Repository) (err error) {
return sess.Commit() return sess.Commit()
} }
func (t *Team) removeRepository(e Engine, repo *Repository) (err error) { func (t *Team) removeRepository(e Engine, repo *Repository, recalculate bool) (err error) {
if err = removeTeamRepo(e, t.ID, repo.Id); err != nil { if err = removeTeamRepo(e, t.ID, repo.Id); err != nil {
return err return err
} }
@ -542,9 +551,12 @@ func (t *Team) removeRepository(e Engine, repo *Repository) (err error) {
return err return err
} }
if err = repo.recalculateAccesses(e); err != nil { // Don't need to recalculate when delete a repository from organization.
if recalculate {
if err = repo.recalculateTeamAccesses(e, t.ID); err != nil {
return err return err
} }
}
if err = t.getMembers(e); err != nil { if err = t.getMembers(e); err != nil {
return fmt.Errorf("get team members: %v", err) return fmt.Errorf("get team members: %v", err)
@ -582,7 +594,7 @@ func (t *Team) RemoveRepository(repoID int64) error {
return err return err
} }
if err = t.removeRepository(sess, repo); err != nil { if err = t.removeRepository(sess, repo, true); err != nil {
return err return err
} }
@ -623,7 +635,7 @@ func NewTeam(t *Team) error {
} }
// Update organization number of teams. // Update organization number of teams.
if _, err = sess.Exec("UPDATE `user` SET num_teams = num_teams + 1 WHERE id = ?", t.OrgID); err != nil { if _, err = sess.Exec("UPDATE `user` SET num_teams=num_teams+1 WHERE id = ?", t.OrgID); err != nil {
sess.Rollback() sess.Rollback()
return err return err
} }
@ -683,18 +695,18 @@ func UpdateTeam(t *Team, authChanged bool) (err error) {
t.LowerName = strings.ToLower(t.Name) t.LowerName = strings.ToLower(t.Name)
if _, err = sess.Id(t.ID).AllCols().Update(t); err != nil { if _, err = sess.Id(t.ID).AllCols().Update(t); err != nil {
return err return fmt.Errorf("update: %v", err)
} }
// Update access for team members if needed. // Update access for team members if needed.
if authChanged { if authChanged {
if err = t.getRepositories(sess); err != nil { if err = t.getRepositories(sess); err != nil {
return err return fmt.Errorf("getRepositories:%v", err)
} }
for _, repo := range t.Repos { for _, repo := range t.Repos {
if err = repo.recalculateAccesses(sess); err != nil { if err = repo.recalculateTeamAccesses(sess, 0); err != nil {
return err return fmt.Errorf("recalculateTeamAccesses: %v", err)
} }
} }
} }
@ -707,8 +719,6 @@ func UpdateTeam(t *Team, authChanged bool) (err error) {
func DeleteTeam(t *Team) error { func DeleteTeam(t *Team) error {
if err := t.GetRepositories(); err != nil { if err := t.GetRepositories(); err != nil {
return err return err
} else if err = t.GetMembers(); err != nil {
return err
} }
// Get organization. // Get organization.
@ -725,7 +735,7 @@ func DeleteTeam(t *Team) error {
// Delete all accesses. // Delete all accesses.
for _, repo := range t.Repos { for _, repo := range t.Repos {
if err = repo.recalculateAccesses(sess); err != nil { if err = repo.recalculateTeamAccesses(sess, t.ID); err != nil {
return err return err
} }
} }
@ -850,7 +860,6 @@ func AddTeamMember(orgId, teamId, uid int64) error {
OrgID: orgId, OrgID: orgId,
TeamID: teamId, TeamID: teamId,
} }
if _, err = sess.Insert(tu); err != nil { if _, err = sess.Insert(tu); err != nil {
return err return err
} else if _, err = sess.Id(t.ID).Update(t); err != nil { } else if _, err = sess.Id(t.ID).Update(t); err != nil {
@ -859,7 +868,7 @@ func AddTeamMember(orgId, teamId, uid int64) error {
// Give access to team repositories. // Give access to team repositories.
for _, repo := range t.Repos { for _, repo := range t.Repos {
if err = repo.recalculateAccesses(sess); err != nil { if err = repo.recalculateTeamAccesses(sess, 0); err != nil {
return err return err
} }
} }
@ -913,7 +922,6 @@ func removeTeamMember(e Engine, orgId, teamId, uid int64) error {
OrgID: orgId, OrgID: orgId,
TeamID: teamId, TeamID: teamId,
} }
if _, err := e.Delete(tu); err != nil { if _, err := e.Delete(tu); err != nil {
return err return err
} else if _, err = e.Id(t.ID).AllCols().Update(t); err != nil { } else if _, err = e.Id(t.ID).AllCols().Update(t); err != nil {
@ -922,7 +930,7 @@ func removeTeamMember(e Engine, orgId, teamId, uid int64) error {
// Delete access to team repositories. // Delete access to team repositories.
for _, repo := range t.Repos { for _, repo := range t.Repos {
if err = repo.recalculateAccesses(e); err != nil { if err = repo.recalculateTeamAccesses(e, 0); err != nil {
return err return err
} }
} }
@ -1007,3 +1015,16 @@ func removeTeamRepo(e Engine, teamID, repoID int64) error {
func RemoveTeamRepo(teamID, repoID int64) error { func RemoveTeamRepo(teamID, repoID int64) error {
return removeTeamRepo(x, teamID, repoID) return removeTeamRepo(x, teamID, repoID)
} }
func removeOrgRepo(e Engine, orgID, repoID int64) error {
_, err := e.Delete(&TeamRepo{
OrgID: orgID,
RepoID: repoID,
})
return err
}
// RemoveOrgRepo removes all team-repository relations of given organization.
func RemoveOrgRepo(orgID, repoID int64) error {
return removeOrgRepo(x, orgID, repoID)
}

@ -544,11 +544,6 @@ func CreateRepository(u *User, name, desc, lang, license string, isPrivate, isMi
// Give access to all members in owner team. // Give access to all members in owner team.
if u.IsOrganization() { if u.IsOrganization() {
if err = repo.recalculateAccesses(sess); err != nil {
return nil, err
}
// Update owner team info and count.
t, err := u.getOwnerTeam(sess) t, err := u.getOwnerTeam(sess)
if err != nil { if err != nil {
return nil, fmt.Errorf("getOwnerTeam: %v", err) return nil, fmt.Errorf("getOwnerTeam: %v", err)
@ -556,12 +551,15 @@ func CreateRepository(u *User, name, desc, lang, license string, isPrivate, isMi
return nil, fmt.Errorf("addRepository: %v", err) return nil, fmt.Errorf("addRepository: %v", err)
} }
} else { } else {
if err = watchRepo(sess, u.Id, repo.Id, true); err != nil { // Organization called this in addRepository method.
return nil, fmt.Errorf("watchRepo: %v", err) if err = repo.recalculateAccesses(sess); err != nil {
return nil, fmt.Errorf("recalculateAccesses: %v", err)
} }
} }
if err = newRepoAction(sess, u, repo); err != nil { if err = watchRepo(sess, u.Id, repo.Id, true); err != nil {
return nil, fmt.Errorf("watchRepo: %v", err)
} else if err = newRepoAction(sess, u, repo); err != nil {
return nil, fmt.Errorf("newRepoAction: %v", err) return nil, fmt.Errorf("newRepoAction: %v", err)
} }
@ -667,6 +665,27 @@ func TransferOwnership(u *User, newOwnerName string, repo *Repository) error {
} }
} }
// Remove old team-repository relations.
if owner.IsOrganization() {
if err = owner.getTeams(sess); err != nil {
return fmt.Errorf("getTeams: %v", err)
}
for _, t := range owner.Teams {
if !t.hasRepository(sess, repo.Id) {
continue
}
t.NumRepos--
if _, err := sess.Id(t.ID).AllCols().Update(t); err != nil {
return fmt.Errorf("decrease team repository count '%d': %v", t.ID, err)
}
}
if err = owner.removeOrgRepo(sess, repo.Id); err != nil {
return fmt.Errorf("removeOrgRepo: %v", err)
}
}
if newOwner.IsOrganization() { if newOwner.IsOrganization() {
t, err := newOwner.GetOwnerTeam() t, err := newOwner.GetOwnerTeam()
if err != nil { if err != nil {
@ -763,7 +782,7 @@ func DeleteRepository(uid, repoID int64, userName string) error {
for _, t := range org.Teams { for _, t := range org.Teams {
if !t.hasRepository(sess, repoID) { if !t.hasRepository(sess, repoID) {
continue continue
} else if err = t.removeRepository(sess, repo); err != nil { } else if err = t.removeRepository(sess, repo, false); err != nil {
return err return err
} }
} }
@ -771,9 +790,9 @@ func DeleteRepository(uid, repoID int64, userName string) error {
if _, err = sess.Delete(&Repository{Id: repoID}); err != nil { if _, err = sess.Delete(&Repository{Id: repoID}); err != nil {
return err return err
} else if _, err := sess.Delete(&Access{RepoID: repo.Id}); err != nil { } else if _, err = sess.Delete(&Access{RepoID: repo.Id}); err != nil {
return err return err
} else if _, err := sess.Delete(&Action{RepoId: repo.Id}); err != nil { } else if _, err = sess.Delete(&Action{RepoId: repo.Id}); err != nil {
return err return err
} else if _, err = sess.Delete(&Watch{RepoId: repoID}); err != nil { } else if _, err = sess.Delete(&Watch{RepoId: repoID}); err != nil {
return err return err

@ -1 +1 @@
0.5.15.0224 Beta 0.5.16.0228 Beta
Loading…
Cancel
Save