Support public code/issue access for private repositories (#33127)
Close #8649, close #639 (will add "anonymous access" in following PRs)
This commit is contained in:
parent
ecd463c2f1
commit
a98a836e76
9 changed files with 220 additions and 215 deletions
|
@ -175,10 +175,14 @@ func (p *Permission) LogString() string {
|
|||
return fmt.Sprintf(format, args...)
|
||||
}
|
||||
|
||||
func applyEveryoneRepoPermission(user *user_model.User, perm *Permission) {
|
||||
func finalProcessRepoUnitPermission(user *user_model.User, perm *Permission) {
|
||||
if user == nil || user.ID <= 0 {
|
||||
// for anonymous access, it could be:
|
||||
// AccessMode is None or Read, units has repo units, unitModes is nil
|
||||
return
|
||||
}
|
||||
|
||||
// apply everyone access permissions
|
||||
for _, u := range perm.units {
|
||||
if u.EveryoneAccessMode >= perm_model.AccessModeRead && u.EveryoneAccessMode > perm.everyoneAccessMode[u.Type] {
|
||||
if perm.everyoneAccessMode == nil {
|
||||
|
@ -187,17 +191,40 @@ func applyEveryoneRepoPermission(user *user_model.User, perm *Permission) {
|
|||
perm.everyoneAccessMode[u.Type] = u.EveryoneAccessMode
|
||||
}
|
||||
}
|
||||
|
||||
if perm.unitsMode == nil {
|
||||
// if unitsMode is not set, then it means that the default p.AccessMode applies to all units
|
||||
return
|
||||
}
|
||||
|
||||
// remove no permission units
|
||||
origPermUnits := perm.units
|
||||
perm.units = make([]*repo_model.RepoUnit, 0, len(perm.units))
|
||||
for _, u := range origPermUnits {
|
||||
shouldKeep := false
|
||||
for t := range perm.unitsMode {
|
||||
if shouldKeep = u.Type == t; shouldKeep {
|
||||
break
|
||||
}
|
||||
}
|
||||
for t := range perm.everyoneAccessMode {
|
||||
if shouldKeep = shouldKeep || u.Type == t; shouldKeep {
|
||||
break
|
||||
}
|
||||
}
|
||||
if shouldKeep {
|
||||
perm.units = append(perm.units, u)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetUserRepoPermission returns the user permissions to the repository
|
||||
func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, user *user_model.User) (perm Permission, err error) {
|
||||
defer func() {
|
||||
if err == nil {
|
||||
applyEveryoneRepoPermission(user, &perm)
|
||||
}
|
||||
if log.IsTrace() {
|
||||
log.Trace("Permission Loaded for user %-v in repo %-v, permissions: %-+v", user, repo, perm)
|
||||
finalProcessRepoUnitPermission(user, &perm)
|
||||
}
|
||||
log.Trace("Permission Loaded for user %-v in repo %-v, permissions: %-+v", user, repo, perm)
|
||||
}()
|
||||
|
||||
if err = repo.LoadUnits(ctx); err != nil {
|
||||
|
@ -294,16 +321,6 @@ func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, use
|
|||
}
|
||||
}
|
||||
|
||||
// remove no permission units
|
||||
perm.units = make([]*repo_model.RepoUnit, 0, len(repo.Units))
|
||||
for t := range perm.unitsMode {
|
||||
for _, u := range repo.Units {
|
||||
if u.Type == t {
|
||||
perm.units = append(perm.units, u)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return perm, err
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ func TestApplyEveryoneRepoPermission(t *testing.T) {
|
|||
{Type: unit.TypeWiki, EveryoneAccessMode: perm_model.AccessModeRead},
|
||||
},
|
||||
}
|
||||
applyEveryoneRepoPermission(nil, &perm)
|
||||
finalProcessRepoUnitPermission(nil, &perm)
|
||||
assert.False(t, perm.CanRead(unit.TypeWiki))
|
||||
|
||||
perm = Permission{
|
||||
|
@ -59,7 +59,7 @@ func TestApplyEveryoneRepoPermission(t *testing.T) {
|
|||
{Type: unit.TypeWiki, EveryoneAccessMode: perm_model.AccessModeRead},
|
||||
},
|
||||
}
|
||||
applyEveryoneRepoPermission(&user_model.User{ID: 0}, &perm)
|
||||
finalProcessRepoUnitPermission(&user_model.User{ID: 0}, &perm)
|
||||
assert.False(t, perm.CanRead(unit.TypeWiki))
|
||||
|
||||
perm = Permission{
|
||||
|
@ -68,7 +68,7 @@ func TestApplyEveryoneRepoPermission(t *testing.T) {
|
|||
{Type: unit.TypeWiki, EveryoneAccessMode: perm_model.AccessModeRead},
|
||||
},
|
||||
}
|
||||
applyEveryoneRepoPermission(&user_model.User{ID: 1}, &perm)
|
||||
finalProcessRepoUnitPermission(&user_model.User{ID: 1}, &perm)
|
||||
assert.True(t, perm.CanRead(unit.TypeWiki))
|
||||
|
||||
perm = Permission{
|
||||
|
@ -77,20 +77,22 @@ func TestApplyEveryoneRepoPermission(t *testing.T) {
|
|||
{Type: unit.TypeWiki, EveryoneAccessMode: perm_model.AccessModeRead},
|
||||
},
|
||||
}
|
||||
applyEveryoneRepoPermission(&user_model.User{ID: 1}, &perm)
|
||||
finalProcessRepoUnitPermission(&user_model.User{ID: 1}, &perm)
|
||||
// it should work the same as "EveryoneAccessMode: none" because the default AccessMode should be applied to units
|
||||
assert.True(t, perm.CanWrite(unit.TypeWiki))
|
||||
|
||||
perm = Permission{
|
||||
units: []*repo_model.RepoUnit{
|
||||
{Type: unit.TypeCode}, // will be removed
|
||||
{Type: unit.TypeWiki, EveryoneAccessMode: perm_model.AccessModeRead},
|
||||
},
|
||||
unitsMode: map[unit.Type]perm_model.AccessMode{
|
||||
unit.TypeWiki: perm_model.AccessModeWrite,
|
||||
},
|
||||
}
|
||||
applyEveryoneRepoPermission(&user_model.User{ID: 1}, &perm)
|
||||
finalProcessRepoUnitPermission(&user_model.User{ID: 1}, &perm)
|
||||
assert.True(t, perm.CanWrite(unit.TypeWiki))
|
||||
assert.Len(t, perm.units, 1)
|
||||
}
|
||||
|
||||
func TestUnitAccessMode(t *testing.T) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue