Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
wxiaoguang committed Jan 7, 2025
1 parent 98637fe commit c9325c8
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 98 deletions.
48 changes: 34 additions & 14 deletions models/perm/access/repo_permission.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,19 @@ func (p *Permission) GetFirstUnitRepoID() int64 {
}

// UnitAccessMode returns current user access mode to the specify unit of the repository
// It also considers "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)
}
return p.AccessMode
}

// UnitAccessModeWithEveryone works like UnitAccessMode, it also considers "everyone access mode"
func (p *Permission) UnitAccessModeWithEveryone(unitType unit.Type) perm_model.AccessMode {
if m := p.UnitAccessMode(unitType); m > perm_model.AccessModeNone {
return 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])
hasUnit := slices.ContainsFunc(p.units, func(u *repo_model.RepoUnit) bool { return u.Type == unitType })
Expand All @@ -98,6 +105,11 @@ func (p *Permission) CanAccess(mode perm_model.AccessMode, unitType unit.Type) b
return p.UnitAccessMode(unitType) >= mode
}

// CanAccessWithEveryone works like CanAccess but also considers "everyone access mode"
func (p *Permission) CanAccessWithEveryone(mode perm_model.AccessMode, unitType unit.Type) bool {
return p.UnitAccessModeWithEveryone(unitType) >= mode
}

// CanAccessAny returns true if user has mode access to any of the units of the repository
func (p *Permission) CanAccessAny(mode perm_model.AccessMode, unitTypes ...unit.Type) bool {
for _, u := range unitTypes {
Expand Down Expand Up @@ -177,6 +189,7 @@ func (p *Permission) LogString() string {

func applyEveryoneRepoPermission(user *user_model.User, perm *Permission) {
if user == nil || user.ID <= 0 {
perm.units = nil
return
}
for _, u := range perm.units {
Expand All @@ -187,6 +200,25 @@ func applyEveryoneRepoPermission(user *user_model.User, perm *Permission) {
perm.everyoneAccessMode[u.Type] = u.EveryoneAccessMode
}
}
// 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
Expand All @@ -195,9 +227,7 @@ func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, use
if err == nil {
applyEveryoneRepoPermission(user, &perm)
}
if log.IsTrace() {
log.Trace("Permission Loaded for user %-v in repo %-v, permissions: %-+v", user, repo, perm)
}
log.Trace("Permission Loaded for user %-v in repo %-v, permissions: %-+v", user, repo, perm)
}()

if err = repo.LoadUnits(ctx); err != nil {
Expand Down Expand Up @@ -294,16 +324,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
}

Expand Down
9 changes: 7 additions & 2 deletions models/perm/access/repo_permission_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func TestApplyEveryoneRepoPermission(t *testing.T) {
},
}
applyEveryoneRepoPermission(nil, &perm)
assert.Empty(t, perm.units)
assert.False(t, perm.CanRead(unit.TypeWiki))

perm = Permission{
Expand All @@ -60,16 +61,20 @@ func TestApplyEveryoneRepoPermission(t *testing.T) {
},
}
applyEveryoneRepoPermission(&user_model.User{ID: 0}, &perm)
assert.Empty(t, perm.units)
assert.False(t, perm.CanRead(unit.TypeWiki))

perm = Permission{
AccessMode: perm_model.AccessModeNone,
units: []*repo_model.RepoUnit{
{Type: unit.TypeWiki, EveryoneAccessMode: perm_model.AccessModeRead},
{Type: unit.TypeCode}, // will be removed
},
}
applyEveryoneRepoPermission(&user_model.User{ID: 1}, &perm)
assert.True(t, perm.CanRead(unit.TypeWiki))
assert.Len(t, perm.units, 1)
assert.False(t, perm.CanAccess(perm_model.AccessModeRead, unit.TypeWiki))
assert.True(t, perm.CanAccessWithEveryone(perm_model.AccessModeRead, unit.TypeWiki))

perm = Permission{
AccessMode: perm_model.AccessModeWrite,
Expand All @@ -79,7 +84,7 @@ func TestApplyEveryoneRepoPermission(t *testing.T) {
}
applyEveryoneRepoPermission(&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))
assert.True(t, perm.CanWrite(unit.TypeWiki)) // no unitsMode, so it uses AccessMode

perm = Permission{
units: []*repo_model.RepoUnit{
Expand Down
2 changes: 1 addition & 1 deletion options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2160,7 +2160,7 @@ settings.advanced_settings = Advanced Settings
settings.wiki_desc = Enable Repository Wiki
settings.use_internal_wiki = Use Built-In Wiki
settings.default_wiki_branch_name = Default Wiki Branch Name
settings.default_wiki_everyone_access = Default Access Permission for signed-in users:
settings.default_permission_everyone_access = Default access permission for all signed-in users:
settings.failed_to_change_default_wiki_branch = Failed to change the default wiki branch.
settings.use_external_wiki = Use External Wiki
settings.external_wiki_url = External Wiki URL
Expand Down
10 changes: 3 additions & 7 deletions routers/web/repo/issue_poster.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,9 @@ type userSearchResponse struct {
Results []*userSearchInfo `json:"results"`
}

// IssuePosters get posters for current repo's issues/pull requests
func IssuePosters(ctx *context.Context) {
issuePosters(ctx, false)
}

func PullPosters(ctx *context.Context) {
issuePosters(ctx, true)
func IssuePullPosters(ctx *context.Context) {
isPullList := ctx.PathParam("type") == "pulls"
issuePosters(ctx, isPullList)
}

func issuePosters(ctx *context.Context, isPullList bool) {
Expand Down
6 changes: 4 additions & 2 deletions routers/web/repo/setting/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -447,8 +447,9 @@ func SettingsPost(ctx *context.Context) {

if form.EnableCode && !unit_model.TypeCode.UnitGlobalDisabled() {
units = append(units, repo_model.RepoUnit{
RepoID: repo.ID,
Type: unit_model.TypeCode,
RepoID: repo.ID,
Type: unit_model.TypeCode,
EveryoneAccessMode: perm.ParseAccessMode(form.DefaultCodeEveryoneAccess, perm.AccessModeNone, perm.AccessModeRead),
})
} else if !unit_model.TypeCode.UnitGlobalDisabled() {
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeCode)
Expand Down Expand Up @@ -524,6 +525,7 @@ func SettingsPost(ctx *context.Context) {
AllowOnlyContributorsToTrackTime: form.AllowOnlyContributorsToTrackTime,
EnableDependencies: form.EnableIssueDependencies,
},
EveryoneAccessMode: perm.ParseAccessMode(form.DefaultIssuesEveryoneAccess, perm.AccessModeNone, perm.AccessModeRead),
})
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeExternalTracker)
} else {
Expand Down
3 changes: 1 addition & 2 deletions routers/web/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -1169,13 +1169,12 @@ func registerRoutes(m *web.Router) {
// end "/{username}/{reponame}": repo code: find, compare, list

m.Group("/{username}/{reponame}", func() {
m.Get("/issues/posters", repo.IssuePosters) // it can't use {type:issues|pulls} because it would conflict with other routes like "/pulls/{index}"
m.Get("/pulls/posters", repo.PullPosters)
m.Get("/comments/{id}/attachments", repo.GetCommentAttachments)
m.Get("/labels", repo.RetrieveLabelsForList, repo.Labels)
m.Get("/milestones", repo.Milestones)
m.Get("/milestone/{id}", context.RepoRef(), repo.MilestoneIssuesAndPulls)
m.Group("/{type:issues|pulls}", func() {
m.Get("/posters", repo.IssuePullPosters)
m.Group("/{index}", func() {
m.Get("/info", repo.GetIssueInfo)
m.Get("/attachments", repo.GetIssueAttachments)
Expand Down
46 changes: 5 additions & 41 deletions services/context/permission.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@ import (
auth_model "code.gitea.io/gitea/models/auth"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/modules/log"
)

// RequireRepoAdmin returns a middleware for requiring repository admin permission
func RequireRepoAdmin() func(ctx *Context) {
return func(ctx *Context) {
if !ctx.IsSigned || !ctx.Repo.IsAdmin() {
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
ctx.NotFound("RequireRepoAdmin denies the request", nil)
return
}
}
Expand All @@ -26,7 +25,7 @@ func RequireRepoAdmin() func(ctx *Context) {
func RequireRepoWriter(unitType unit.Type) func(ctx *Context) {
return func(ctx *Context) {
if !ctx.Repo.CanWrite(unitType) {
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
ctx.NotFound("RequireRepoWriter denies the request", nil)
return
}
}
Expand All @@ -50,7 +49,7 @@ func RequireRepoWriterOr(unitTypes ...unit.Type) func(ctx *Context) {
return
}
}
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
ctx.NotFound("RequireRepoWriterOr denies the request", nil)
}
}

Expand All @@ -61,23 +60,7 @@ func RequireRepoReader(unitType unit.Type) func(ctx *Context) {
if unitType == unit.TypeCode && canWriteAsMaintainer(ctx) {
return
}
if log.IsTrace() {
if ctx.IsSigned {
log.Trace("Permission Denied: User %-v cannot read %-v in Repo %-v\n"+
"User in Repo has Permissions: %-+v",
ctx.Doer,
unitType,
ctx.Repo.Repository,
ctx.Repo.Permission)
} else {
log.Trace("Permission Denied: Anonymous user cannot read %-v in Repo %-v\n"+
"Anonymous user in Repo has Permissions: %-+v",
unitType,
ctx.Repo.Repository,
ctx.Repo.Permission)
}
}
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
ctx.NotFound("RequireRepoReader denies the request", nil)
return
}
}
Expand All @@ -91,26 +74,7 @@ func RequireRepoReaderOr(unitTypes ...unit.Type) func(ctx *Context) {
return
}
}
if log.IsTrace() {
var format string
var args []any
if ctx.IsSigned {
format = "Permission Denied: User %-v cannot read ["
args = append(args, ctx.Doer)
} else {
format = "Permission Denied: Anonymous user cannot read ["
}
for _, unit := range unitTypes {
format += "%-v, "
args = append(args, unit)
}

format = format[:len(format)-2] + "] in Repo %-v\n" +
"User in Repo has Permissions: %-+v"
args = append(args, ctx.Repo.Repository, ctx.Repo.Permission)
log.Trace(format, args...)
}
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
ctx.NotFound("RequireRepoReaderOr denies the request", nil)
}
}

Expand Down
66 changes: 38 additions & 28 deletions services/forms/repo_form.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,41 +110,51 @@ type RepoSettingForm struct {
EnablePrune bool

// Advanced settings
EnableCode bool
EnableWiki bool
EnableExternalWiki bool
DefaultWikiBranch string
DefaultWikiEveryoneAccess string
ExternalWikiURL string
EnableCode bool
DefaultCodeEveryoneAccess string

EnableWiki bool
EnableExternalWiki bool
DefaultWikiBranch string
DefaultWikiEveryoneAccess string
ExternalWikiURL string

EnableIssues bool
DefaultIssuesEveryoneAccess string
EnableExternalTracker bool
ExternalTrackerURL string
TrackerURLFormat string
TrackerIssueStyle string
ExternalTrackerRegexpPattern string
EnableCloseIssuesViaCommitInAnyBranch bool
EnableProjects bool
ProjectsMode string
EnableReleases bool
EnablePackages bool
EnablePulls bool
EnableActions bool
PullsIgnoreWhitespace bool
PullsAllowMerge bool
PullsAllowRebase bool
PullsAllowRebaseMerge bool
PullsAllowSquash bool
PullsAllowFastForwardOnly bool
PullsAllowManualMerge bool
PullsDefaultMergeStyle string
EnableAutodetectManualMerge bool
PullsAllowRebaseUpdate bool
DefaultDeleteBranchAfterMerge bool
DefaultAllowMaintainerEdit bool
EnableTimetracker bool
AllowOnlyContributorsToTrackTime bool
EnableIssueDependencies bool
IsArchived bool

EnableProjects bool
ProjectsMode string

EnableReleases bool

EnablePackages bool

EnablePulls bool
PullsIgnoreWhitespace bool
PullsAllowMerge bool
PullsAllowRebase bool
PullsAllowRebaseMerge bool
PullsAllowSquash bool
PullsAllowFastForwardOnly bool
PullsAllowManualMerge bool
PullsDefaultMergeStyle string
EnableAutodetectManualMerge bool
PullsAllowRebaseUpdate bool
DefaultDeleteBranchAfterMerge bool
DefaultAllowMaintainerEdit bool
EnableTimetracker bool
AllowOnlyContributorsToTrackTime bool
EnableIssueDependencies bool

EnableActions bool

IsArchived bool

// Signing Settings
TrustModel string
Expand Down
Loading

0 comments on commit c9325c8

Please sign in to comment.