@@ -15,6 +15,7 @@ import (
1515 "code.gitea.io/gitea/models/unit"
1616 user_model "code.gitea.io/gitea/models/user"
1717 "code.gitea.io/gitea/modules/log"
18+ "code.gitea.io/gitea/modules/setting"
1819 "code.gitea.io/gitea/modules/util"
1920)
2021
@@ -25,7 +26,8 @@ type Permission struct {
2526 units []* repo_model.RepoUnit
2627 unitsMode map [unit.Type ]perm_model.AccessMode
2728
28- everyoneAccessMode map [unit.Type ]perm_model.AccessMode
29+ everyoneAccessMode map [unit.Type ]perm_model.AccessMode // the unit's minimal access mode for every signed-in user
30+ anonymousAccessMode map [unit.Type ]perm_model.AccessMode // the unit's minimal access mode for anonymous (non-signed-in) user
2931}
3032
3133// IsOwner returns true if current user is the owner of repository.
@@ -39,7 +41,7 @@ func (p *Permission) IsAdmin() bool {
3941}
4042
4143// HasAnyUnitAccess returns true if the user might have at least one access mode to any unit of this repository.
42- // It doesn't count the "everyone access mode".
44+ // It doesn't count the "public(anonymous/ everyone) access mode".
4345func (p * Permission ) HasAnyUnitAccess () bool {
4446 for _ , v := range p .unitsMode {
4547 if v >= perm_model .AccessModeRead {
@@ -49,13 +51,22 @@ func (p *Permission) HasAnyUnitAccess() bool {
4951 return p .AccessMode >= perm_model .AccessModeRead
5052}
5153
52- func (p * Permission ) HasAnyUnitAccessOrEveryoneAccess () bool {
54+ func (p * Permission ) HasAnyUnitPublicAccess () bool {
55+ for _ , v := range p .anonymousAccessMode {
56+ if v >= perm_model .AccessModeRead {
57+ return true
58+ }
59+ }
5360 for _ , v := range p .everyoneAccessMode {
5461 if v >= perm_model .AccessModeRead {
5562 return true
5663 }
5764 }
58- return p .HasAnyUnitAccess ()
65+ return false
66+ }
67+
68+ func (p * Permission ) HasAnyUnitAccessOrPublicAccess () bool {
69+ return p .HasAnyUnitPublicAccess () || p .HasAnyUnitAccess ()
5970}
6071
6172// HasUnits returns true if the permission contains attached units
@@ -73,14 +84,16 @@ func (p *Permission) GetFirstUnitRepoID() int64 {
7384}
7485
7586// UnitAccessMode returns current user access mode to the specify unit of the repository
76- // It also considers "everyone access mode"
87+ // It also considers "public (anonymous/ everyone) access mode"
7788func (p * Permission ) UnitAccessMode (unitType unit.Type ) perm_model.AccessMode {
7889 // if the units map contains the access mode, use it, but admin/owner mode could override it
7990 if m , ok := p .unitsMode [unitType ]; ok {
8091 return util .Iif (p .AccessMode >= perm_model .AccessModeAdmin , p .AccessMode , m )
8192 }
8293 // if the units map does not contain the access mode, return the default access mode if the unit exists
83- unitDefaultAccessMode := max (p .AccessMode , p .everyoneAccessMode [unitType ])
94+ unitDefaultAccessMode := p .AccessMode
95+ unitDefaultAccessMode = max (unitDefaultAccessMode , p .anonymousAccessMode [unitType ])
96+ unitDefaultAccessMode = max (unitDefaultAccessMode , p .everyoneAccessMode [unitType ])
8497 hasUnit := slices .ContainsFunc (p .units , func (u * repo_model.RepoUnit ) bool { return u .Type == unitType })
8598 return util .Iif (hasUnit , unitDefaultAccessMode , perm_model .AccessModeNone )
8699}
@@ -171,27 +184,41 @@ func (p *Permission) LogString() string {
171184 format += "\n \t unitsMode[%-v]: %-v"
172185 args = append (args , key .LogString (), value .LogString ())
173186 }
187+ format += "\n \t anonymousAccessMode: %-v"
188+ args = append (args , p .anonymousAccessMode )
174189 format += "\n \t everyoneAccessMode: %-v"
175190 args = append (args , p .everyoneAccessMode )
176191 format += "\n \t ]>"
177192 return fmt .Sprintf (format , args ... )
178193}
179194
195+ func applyPublicAccessPermission (unitType unit.Type , accessMode perm_model.AccessMode , modeMap * map [unit.Type ]perm_model.AccessMode ) {
196+ if setting .Repository .ForcePrivate {
197+ return
198+ }
199+ if accessMode >= perm_model .AccessModeRead && accessMode > (* modeMap )[unitType ] {
200+ if * modeMap == nil {
201+ * modeMap = make (map [unit.Type ]perm_model.AccessMode )
202+ }
203+ (* modeMap )[unitType ] = accessMode
204+ }
205+ }
206+
180207func finalProcessRepoUnitPermission (user * user_model.User , perm * Permission ) {
208+ // apply public (anonymous) access permissions
209+ for _ , u := range perm .units {
210+ applyPublicAccessPermission (u .Type , u .AnonymousAccessMode , & perm .anonymousAccessMode )
211+ }
212+
181213 if user == nil || user .ID <= 0 {
182214 // for anonymous access, it could be:
183215 // AccessMode is None or Read, units has repo units, unitModes is nil
184216 return
185217 }
186218
187- // apply everyone access permissions
219+ // apply public ( everyone) access permissions
188220 for _ , u := range perm .units {
189- if u .EveryoneAccessMode >= perm_model .AccessModeRead && u .EveryoneAccessMode > perm .everyoneAccessMode [u .Type ] {
190- if perm .everyoneAccessMode == nil {
191- perm .everyoneAccessMode = make (map [unit.Type ]perm_model.AccessMode )
192- }
193- perm .everyoneAccessMode [u .Type ] = u .EveryoneAccessMode
194- }
221+ applyPublicAccessPermission (u .Type , u .EveryoneAccessMode , & perm .everyoneAccessMode )
195222 }
196223
197224 if perm .unitsMode == nil {
@@ -209,6 +236,11 @@ func finalProcessRepoUnitPermission(user *user_model.User, perm *Permission) {
209236 break
210237 }
211238 }
239+ for t := range perm .anonymousAccessMode {
240+ if shouldKeep = shouldKeep || u .Type == t ; shouldKeep {
241+ break
242+ }
243+ }
212244 for t := range perm .everyoneAccessMode {
213245 if shouldKeep = shouldKeep || u .Type == t ; shouldKeep {
214246 break
0 commit comments