Merge branch 'main' into lunny/issue_dev

This commit is contained in:
Lunny Xiao committed 2025-03-28 20:19:36 -07:00
commit 097c649387
25 files changed
+1605 -1120

No files matched your search

+1
View File
@@ -378,6 +378,7 @@ func prepareMigrationTasks() []*migration {
newMigration(315, "Add Ephemeral to ActionRunner", v1_24.AddEphemeralToActionRunner),
newMigration(316, "Add description for secrets and variables", v1_24.AddDescriptionForSecretsAndVariables),
newMigration(317, "Add new index for action for heatmap", v1_24.AddNewIndexForUserDashboard),
newMigration(318, "Add anonymous_access_mode for repo_unit", v1_24.AddRepoUnitAnonymousAccessMode),
newMigration(318, "Add table issue_dev_link", v1_24.CreateTableIssueDevLink),
}
return preparedMigrations
+12
View File
@@ -4,11 +4,16 @@
package v1_24 //nolint
import (
<<<<<<< HEAD
"code.gitea.io/gitea/modules/timeutil"
=======
"code.gitea.io/gitea/models/perm"
>>>>>>> main
"xorm.io/xorm"
)
<<<<<<< HEAD
func CreateTableIssueDevLink(x *xorm.Engine) error {
type IssueDevLink struct {
ID int64 `xorm:"pk autoincr"`
@@ -19,4 +24,11 @@ func CreateTableIssueDevLink(x *xorm.Engine) error {
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
}
return x.Sync(new(IssueDevLink))
=======
func AddRepoUnitAnonymousAccessMode(x *xorm.Engine) error {
type RepoUnit struct { //revive:disable-line:exported
AnonymousAccessMode perm.AccessMode `xorm:"NOT NULL DEFAULT 0"`
}
return x.Sync(&RepoUnit{})
>>>>>>> main
}
+22
View File
@@ -0,0 +1,22 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_24 //nolint
import (
"code.gitea.io/gitea/modules/timeutil"
"xorm.io/xorm"
)
func CreateTableIssueDevLink(x *xorm.Engine) error {
type IssueDevLink struct {
ID int64 `xorm:"pk autoincr"`
IssueID int64 `xorm:"INDEX"`
LinkType int
LinkedRepoID int64 `xorm:"INDEX"` // it can link to self repo or other repo
LinkIndex string // branch name, pull request number or commit sha
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
}
return x.Sync(new(IssueDevLink))
}
+36 -12
View File
@@ -25,7 +25,8 @@ type Permission struct {
units []*repo_model.RepoUnit
unitsMode map[unit.Type]perm_model.AccessMode
everyoneAccessMode map[unit.Type]perm_model.AccessMode
everyoneAccessMode map[unit.Type]perm_model.AccessMode // the unit's minimal access mode for every signed-in user
anonymousAccessMode map[unit.Type]perm_model.AccessMode // the unit's minimal access mode for anonymous (non-signed-in) user
}
// IsOwner returns true if current user is the owner of repository.
@@ -39,7 +40,7 @@ func (p *Permission) IsAdmin() bool {
}
// HasAnyUnitAccess returns true if the user might have at least one access mode to any unit of this repository.
// It doesn't count the "everyone access mode".
// It doesn't count the "public(anonymous/everyone) access mode".
func (p *Permission) HasAnyUnitAccess() bool {
for _, v := range p.unitsMode {
if v >= perm_model.AccessModeRead {
@@ -49,7 +50,12 @@ func (p *Permission) HasAnyUnitAccess() bool {
return p.AccessMode >= perm_model.AccessModeRead
}
func (p *Permission) HasAnyUnitAccessOrEveryoneAccess() bool {
func (p *Permission) HasAnyUnitAccessOrPublicAccess() bool {
for _, v := range p.anonymousAccessMode {
if v >= perm_model.AccessModeRead {
return true
}
}
for _, v := range p.everyoneAccessMode {
if v >= perm_model.AccessModeRead {
return true
@@ -73,14 +79,16 @@ func (p *Permission) GetFirstUnitRepoID() int64 {
}
// UnitAccessMode returns current user access mode to the specify unit of the repository
// It also considers "everyone access mode"
// It also considers "public (anonymous/everyone) access mode"
func (p *Permission) UnitAccessMode(unitType unit.Type) perm_model.AccessMode {
// if the units map contains the access mode, use it, but admin/owner mode could override it
if m, ok := p.unitsMode[unitType]; ok {
return util.Iif(p.AccessMode >= perm_model.AccessModeAdmin, p.AccessMode, m)
}
// if the units map does not contain the access mode, return the default access mode if the unit exists
unitDefaultAccessMode := max(p.AccessMode, p.everyoneAccessMode[unitType])
unitDefaultAccessMode := p.AccessMode
unitDefaultAccessMode = max(unitDefaultAccessMode, p.anonymousAccessMode[unitType])
unitDefaultAccessMode = max(unitDefaultAccessMode, p.everyoneAccessMode[unitType])
hasUnit := slices.ContainsFunc(p.units, func(u *repo_model.RepoUnit) bool { return u.Type == unitType })
return util.Iif(hasUnit, unitDefaultAccessMode, perm_model.AccessModeNone)
}
@@ -171,27 +179,38 @@ func (p *Permission) LogString() string {
format += "\n\tunitsMode[%-v]: %-v"
args = append(args, key.LogString(), value.LogString())
}
format += "\n\tanonymousAccessMode: %-v"
args = append(args, p.anonymousAccessMode)
format += "\n\teveryoneAccessMode: %-v"
args = append(args, p.everyoneAccessMode)
format += "\n\t]>"
return fmt.Sprintf(format, args...)
}
func applyPublicAccessPermission(unitType unit.Type, accessMode perm_model.AccessMode, modeMap *map[unit.Type]perm_model.AccessMode) {
if accessMode >= perm_model.AccessModeRead && accessMode > (*modeMap)[unitType] {
if *modeMap == nil {
*modeMap = make(map[unit.Type]perm_model.AccessMode)
}
(*modeMap)[unitType] = accessMode
}
}
func finalProcessRepoUnitPermission(user *user_model.User, perm *Permission) {
// apply public (anonymous) access permissions
for _, u := range perm.units {
applyPublicAccessPermission(u.Type, u.AnonymousAccessMode, &perm.anonymousAccessMode)
}
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
// apply public (everyone) access permissions
for _, u := range perm.units {
if u.EveryoneAccessMode >= perm_model.AccessModeRead && u.EveryoneAccessMode > perm.everyoneAccessMode[u.Type] {
if perm.everyoneAccessMode == nil {
perm.everyoneAccessMode = make(map[unit.Type]perm_model.AccessMode)
}
perm.everyoneAccessMode[u.Type] = u.EveryoneAccessMode
}
applyPublicAccessPermission(u.Type, u.EveryoneAccessMode, &perm.everyoneAccessMode)
}
if perm.unitsMode == nil {
@@ -209,6 +228,11 @@ func finalProcessRepoUnitPermission(user *user_model.User, perm *Permission) {
break
}
}
for t := range perm.anonymousAccessMode {
if shouldKeep = shouldKeep || u.Type == t; shouldKeep {
break
}
}
for t := range perm.everyoneAccessMode {
if shouldKeep = shouldKeep || u.Type == t; shouldKeep {
break
+19 -3
View File
@@ -22,14 +22,21 @@ func TestHasAnyUnitAccess(t *testing.T) {
units: []*repo_model.RepoUnit{{Type: unit.TypeWiki}},
}
assert.False(t, perm.HasAnyUnitAccess())
assert.False(t, perm.HasAnyUnitAccessOrEveryoneAccess())
assert.False(t, perm.HasAnyUnitAccessOrPublicAccess())
perm = Permission{
units: []*repo_model.RepoUnit{{Type: unit.TypeWiki}},
everyoneAccessMode: map[unit.Type]perm_model.AccessMode{unit.TypeIssues: perm_model.AccessModeRead},
}
assert.False(t, perm.HasAnyUnitAccess())
assert.True(t, perm.HasAnyUnitAccessOrEveryoneAccess())
assert.True(t, perm.HasAnyUnitAccessOrPublicAccess())
perm = Permission{
units: []*repo_model.RepoUnit{{Type: unit.TypeWiki}},
anonymousAccessMode: map[unit.Type]perm_model.AccessMode{unit.TypeIssues: perm_model.AccessModeRead},
}
assert.False(t, perm.HasAnyUnitAccess())
assert.True(t, perm.HasAnyUnitAccessOrPublicAccess())
perm = Permission{
AccessMode: perm_model.AccessModeRead,
@@ -43,7 +50,7 @@ func TestHasAnyUnitAccess(t *testing.T) {
assert.True(t, perm.HasAnyUnitAccess())
}
func TestApplyEveryoneRepoPermission(t *testing.T) {
func TestApplyPublicAccessRepoPermission(t *testing.T) {
perm := Permission{
AccessMode: perm_model.AccessModeNone,
units: []*repo_model.RepoUnit{
@@ -53,6 +60,15 @@ func TestApplyEveryoneRepoPermission(t *testing.T) {
finalProcessRepoUnitPermission(nil, &perm)
assert.False(t, perm.CanRead(unit.TypeWiki))
perm = Permission{
AccessMode: perm_model.AccessModeNone,
units: []*repo_model.RepoUnit{
{Type: unit.TypeWiki, AnonymousAccessMode: perm_model.AccessModeRead},
},
}
finalProcessRepoUnitPermission(nil, &perm)
assert.True(t, perm.CanRead(unit.TypeWiki))
perm = Permission{
AccessMode: perm_model.AccessModeNone,
units: []*repo_model.RepoUnit{
+7 -6
View File
@@ -42,12 +42,13 @@ func (err ErrUnitTypeNotExist) Unwrap() error {
// RepoUnit describes all units of a repository
type RepoUnit struct { //revive:disable-line:exported
ID int64
RepoID int64 `xorm:"INDEX(s)"`
Type unit.Type `xorm:"INDEX(s)"`
Config convert.Conversion `xorm:"TEXT"`
CreatedUnix timeutil.TimeStamp `xorm:"INDEX CREATED"`
EveryoneAccessMode perm.AccessMode `xorm:"NOT NULL DEFAULT 0"`
ID int64
RepoID int64 `xorm:"INDEX(s)"`
Type unit.Type `xorm:"INDEX(s)"`
Config convert.Conversion `xorm:"TEXT"`
CreatedUnix timeutil.TimeStamp `xorm:"INDEX CREATED"`
AnonymousAccessMode perm.AccessMode `xorm:"NOT NULL DEFAULT 0"`
EveryoneAccessMode perm.AccessMode `xorm:"NOT NULL DEFAULT 0"`
}
func init() {