Skip to content

Commit 9a58412

Browse files
committed
fix
1 parent 1508a85 commit 9a58412

File tree

14 files changed

+126
-49
lines changed

14 files changed

+126
-49
lines changed

models/migrations/migrations.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,8 @@ var migrations = []Migration{
582582
NewMigration("Add commit status summary table", v1_23.AddCommitStatusSummary),
583583
// v296 -> v297
584584
NewMigration("Add missing field of commit status summary table", v1_23.AddCommitStatusSummary2),
585+
// v297 -> v298
586+
NewMigration("Add everyone_access_mode for repo_unit", v1_23.AddRepoUnitEveryoneAccessMode),
585587
}
586588

587589
// GetCurrentDBVersion returns the current db version

models/migrations/v1_23/v297.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2024 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package v1_23 //nolint
5+
6+
import (
7+
"xorm.io/xorm"
8+
9+
"code.gitea.io/gitea/models/perm"
10+
)
11+
12+
func AddRepoUnitEveryoneAccessMode(x *xorm.Engine) error {
13+
type RepoUnit struct { //revive:disable-line:exported
14+
EveryoneAccessMode perm.AccessMode `xorm:"NOT NULL DEFAULT -1"`
15+
}
16+
return x.Sync(&RepoUnit{})
17+
}

models/organization/team.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,11 @@ func (t *Team) GetUnitsMap() map[string]string {
130130
m := make(map[string]string)
131131
if t.AccessMode >= perm.AccessModeAdmin {
132132
for _, u := range unit.Units {
133-
m[u.NameKey] = t.AccessMode.String()
133+
m[u.NameKey] = t.AccessMode.ToString()
134134
}
135135
} else {
136136
for _, u := range t.Units {
137-
m[u.Unit().NameKey] = u.AccessMode.String()
137+
m[u.Unit().NameKey] = u.AccessMode.ToString()
138138
}
139139
}
140140
return m

models/perm/access/repo_permission.go

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ func (p *Permission) CanWriteIssuesOrPulls(isPull bool) bool {
104104

105105
func (p *Permission) LogString() string {
106106
format := "<Permission AccessMode=%s, %d Units, %d UnitsMode(s): [ "
107-
args := []any{p.AccessMode.String(), len(p.Units), len(p.UnitsMode)}
107+
args := []any{p.AccessMode.ToString(), len(p.Units), len(p.UnitsMode)}
108108

109109
for i, unit := range p.Units {
110110
config := ""
@@ -126,23 +126,24 @@ func (p *Permission) LogString() string {
126126
return fmt.Sprintf(format, args...)
127127
}
128128

129-
// GetUserRepoPermission returns the user permissions to the repository
130-
func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, user *user_model.User) (Permission, error) {
131-
var perm Permission
132-
if log.IsTrace() {
133-
defer func() {
134-
if user == nil {
135-
log.Trace("Permission Loaded for anonymous user in %-v:\nPermissions: %-+v",
136-
repo,
137-
perm)
138-
return
129+
func applyDefaultUserRepoPermission(user *user_model.User, perm *Permission) {
130+
if user != nil {
131+
for _, u := range perm.Units {
132+
if u.EveryoneAccessMode != perm_model.AccessModeUnset && u.EveryoneAccessMode > perm.UnitsMode[u.Type] {
133+
perm.UnitsMode[u.Type] = u.EveryoneAccessMode
139134
}
140-
log.Trace("Permission Loaded for %-v in %-v:\nPermissions: %-+v",
141-
user,
142-
repo,
143-
perm)
144-
}()
135+
}
145136
}
137+
}
138+
139+
// GetUserRepoPermission returns the user permissions to the repository
140+
func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, user *user_model.User) (perm Permission, err error) {
141+
defer func() {
142+
applyDefaultUserRepoPermission(user, &perm)
143+
if log.IsTrace() {
144+
log.Trace("Permission Loaded for user %-v in repo %-v, permissions: %-+v", user, repo, perm)
145+
}
146+
}()
146147

147148
// anonymous user visit private repo.
148149
// TODO: anonymous user visit public unit of private repo???
@@ -152,7 +153,6 @@ func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, use
152153
}
153154

154155
var isCollaborator bool
155-
var err error
156156
if user != nil {
157157
isCollaborator, err = repo_model.IsCollaborator(ctx, repo.ID, user.ID)
158158
if err != nil {

models/perm/access_mode.go

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,29 @@ package perm
55

66
import (
77
"fmt"
8+
"slices"
9+
10+
"code.gitea.io/gitea/modules/util"
811
)
912

1013
// AccessMode specifies the users access mode
1114
type AccessMode int
1215

1316
const (
14-
// AccessModeNone no access
15-
AccessModeNone AccessMode = iota // 0
16-
// AccessModeRead read access
17-
AccessModeRead // 1
18-
// AccessModeWrite write access
19-
AccessModeWrite // 2
20-
// AccessModeAdmin admin access
21-
AccessModeAdmin // 3
22-
// AccessModeOwner owner access
23-
AccessModeOwner // 4
17+
AccessModeUnset AccessMode = -1 + iota // -1: no access mode is set
18+
19+
AccessModeNone // 0: no access
20+
AccessModeRead // 1: read access
21+
AccessModeWrite // 2: write access
22+
AccessModeAdmin // 3: admin access
23+
AccessModeOwner // 4: owner access
2424
)
2525

26-
func (mode AccessMode) String() string {
26+
// ToString returns the string representation of the access mode, do not make it a Stringer, otherwise it's difficult to render in templates
27+
func (mode AccessMode) ToString() string {
2728
switch mode {
29+
case AccessModeUnset:
30+
return "unset"
2831
case AccessModeRead:
2932
return "read"
3033
case AccessModeWrite:
@@ -39,19 +42,26 @@ func (mode AccessMode) String() string {
3942
}
4043

4144
func (mode AccessMode) LogString() string {
42-
return fmt.Sprintf("<AccessMode:%d:%s>", mode, mode.String())
45+
return fmt.Sprintf("<AccessMode:%d:%s>", mode, mode.ToString())
4346
}
4447

4548
// ParseAccessMode returns corresponding access mode to given permission string.
46-
func ParseAccessMode(permission string) AccessMode {
49+
func ParseAccessMode(permission string, allowed ...AccessMode) AccessMode {
50+
m := AccessModeNone
4751
switch permission {
52+
case "unset":
53+
m = AccessModeUnset
4854
case "read":
49-
return AccessModeRead
55+
m = AccessModeRead
5056
case "write":
51-
return AccessModeWrite
57+
m = AccessModeWrite
5258
case "admin":
53-
return AccessModeAdmin
59+
m = AccessModeAdmin
5460
default:
55-
return AccessModeNone
61+
// the "owner" access is not really used for user input, it's mainly for checking access level in code, so don't parse it
62+
}
63+
if len(allowed) == 0 {
64+
return m
5665
}
66+
return util.Iif(slices.Contains(allowed, m), m, AccessModeNone)
5767
}

models/perm/access_mode_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2024 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package perm
5+
6+
import (
7+
"testing"
8+
9+
"github.com/stretchr/testify/assert"
10+
)
11+
12+
func TestAccessMode(t *testing.T) {
13+
names := []string{ /*-1*/ "unset", "none", "read", "write", "admin"}
14+
for i, name := range names {
15+
m := ParseAccessMode(name)
16+
assert.Equal(t, AccessMode(i-1), m)
17+
}
18+
assert.Equal(t, "owner", AccessModeOwner.ToString())
19+
assert.Equal(t, AccessModeNone, ParseAccessMode("owner"))
20+
assert.Equal(t, AccessModeNone, ParseAccessMode("invalid"))
21+
}

models/repo/repo_unit.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"strings"
1111

1212
"code.gitea.io/gitea/models/db"
13+
"code.gitea.io/gitea/models/perm"
1314
"code.gitea.io/gitea/models/unit"
1415
"code.gitea.io/gitea/modules/json"
1516
"code.gitea.io/gitea/modules/setting"
@@ -41,11 +42,12 @@ func (err ErrUnitTypeNotExist) Unwrap() error {
4142

4243
// RepoUnit describes all units of a repository
4344
type RepoUnit struct { //revive:disable-line:exported
44-
ID int64
45-
RepoID int64 `xorm:"INDEX(s)"`
46-
Type unit.Type `xorm:"INDEX(s)"`
47-
Config convert.Conversion `xorm:"TEXT"`
48-
CreatedUnix timeutil.TimeStamp `xorm:"INDEX CREATED"`
45+
ID int64
46+
RepoID int64 `xorm:"INDEX(s)"`
47+
Type unit.Type `xorm:"INDEX(s)"`
48+
Config convert.Conversion `xorm:"TEXT"`
49+
CreatedUnix timeutil.TimeStamp `xorm:"INDEX CREATED"`
50+
EveryoneAccessMode perm.AccessMode `xorm:"NOT NULL DEFAULT -1"`
4951
}
5052

5153
func init() {

modules/templates/helper.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ func NewFuncMap() template.FuncMap {
3434
// -----------------------------------------------------------------
3535
// html/template related functions
3636
"dict": dict, // it's lowercase because this name has been widely used. Our other functions should have uppercase names.
37+
"Iif": Iif,
3738
"Eval": Eval,
3839
"SafeHTML": SafeHTML,
3940
"HTMLFormat": HTMLFormat,
@@ -238,6 +239,15 @@ func DotEscape(raw string) string {
238239
return strings.ReplaceAll(raw, ".", "\u200d.\u200d")
239240
}
240241

242+
func Iif(condition bool, vals ...any) any {
243+
if condition {
244+
return vals[0]
245+
} else if len(vals) > 1 {
246+
return vals[1]
247+
}
248+
return nil
249+
}
250+
241251
// Eval the expression and return the result, see the comment of eval.Expr for details.
242252
// To use this helper function in templates, pass each token as a separate parameter.
243253
//

options/locale/locale_en-US.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2096,6 +2096,7 @@ settings.advanced_settings = Advanced Settings
20962096
settings.wiki_desc = Enable Repository Uncyclo
20972097
settings.use_internal_wiki = Use Built-In Uncyclo
20982098
settings.default_wiki_branch_name = Default Uncyclo Branch Name
2099+
settings.default_wiki_everyone_access = Default Access Permission for every signed-in user:
20992100
settings.failed_to_change_default_wiki_branch = Failed to change the default wiki branch.
21002101
settings.use_external_wiki = Use External Uncyclo
21012102
settings.external_wiki_url = External Uncyclo URL

routers/web/repo/setting/setting.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
actions_model "code.gitea.io/gitea/models/actions"
1717
"code.gitea.io/gitea/models/db"
1818
"code.gitea.io/gitea/models/organization"
19+
"code.gitea.io/gitea/models/perm"
1920
repo_model "code.gitea.io/gitea/models/repo"
2021
unit_model "code.gitea.io/gitea/models/unit"
2122
user_model "code.gitea.io/gitea/models/user"
@@ -476,9 +477,10 @@ func SettingsPost(ctx *context.Context) {
476477
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeUncyclo)
477478
} else if form.EnableUncyclo && !form.EnableExternalUncyclo && !unit_model.TypeUncyclo.UnitGlobalDisabled() {
478479
units = append(units, repo_model.RepoUnit{
479-
RepoID: repo.ID,
480-
Type: unit_model.TypeUncyclo,
481-
Config: new(repo_model.UnitConfig),
480+
RepoID: repo.ID,
481+
Type: unit_model.TypeUncyclo,
482+
Config: new(repo_model.UnitConfig),
483+
EveryoneAccessMode: perm.ParseAccessMode(form.DefaultUncycloEveryoneAccess, perm.AccessModeUnset, perm.AccessModeRead, perm.AccessModeWrite),
482484
})
483485
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeExternalUncyclo)
484486
} else {

services/convert/convert.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ func ToTeams(ctx context.Context, teams []*organization.Team, loadOrgs bool) ([]
322322
Description: t.Description,
323323
IncludesAllRepositories: t.IncludesAllRepositories,
324324
CanCreateOrgRepo: t.CanCreateOrgRepo,
325-
Permission: t.AccessMode.String(),
325+
Permission: t.AccessMode.ToString(),
326326
Units: t.GetUnitNames(),
327327
UnitsMap: t.GetUnitsMap(),
328328
}

services/convert/user.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ func User2UserSettings(user *user_model.User) api.UserSettings {
102102
func ToUserAndPermission(ctx context.Context, user, doer *user_model.User, accessMode perm.AccessMode) api.RepoCollaboratorPermission {
103103
return api.RepoCollaboratorPermission{
104104
User: ToUser(ctx, user, doer),
105-
Permission: accessMode.String(),
106-
RoleName: accessMode.String(),
105+
Permission: accessMode.ToString(),
106+
RoleName: accessMode.ToString(),
107107
}
108108
}

services/forms/repo_form.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ type RepoSettingForm struct {
134134
EnableUncyclo bool
135135
EnableExternalUncyclo bool
136136
DefaultUncycloBranch string
137+
DefaultUncycloEveryoneAccess string
137138
ExternalUncycloURL string
138139
EnableIssues bool
139140
EnableExternalTracker bool

templates/repo/settings/options.tmpl

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,9 @@
317317
</div>
318318
</div>
319319

320-
{{$isUncycloEnabled := or (.Repository.UnitEnabled $.Context $.UnitTypeUncyclo) (.Repository.UnitEnabled $.Context $.UnitTypeExternalUncyclo)}}
320+
{{$isBulitinUncycloEnabled := .Repository.UnitEnabled $.Context $.UnitTypeUncyclo}}
321+
{{$isExternalUncycloEnabled := .Repository.UnitEnabled $.Context $.UnitTypeExternalUncyclo}}
322+
{{$isUncycloEnabled := or $isBulitinUncycloEnabled $isExternalUncycloEnabled}}
321323
{{$isUncycloGlobalDisabled := .UnitTypeUncyclo.UnitGlobalDisabled}}
322324
{{$isExternalUncycloGlobalDisabled := .UnitTypeExternalUncyclo.UnitGlobalDisabled}}
323325
{{$isBothUncycloGlobalDisabled := and $isUncycloGlobalDisabled $isExternalUncycloGlobalDisabled}}
@@ -331,14 +333,23 @@
331333
<div class="field{{if not $isUncycloEnabled}} disabled{{end}}" id="wiki_box">
332334
<div class="field">
333335
<div class="ui radio checkbox{{if $isUncycloGlobalDisabled}} disabled{{end}}"{{if $isUncycloGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
334-
<input class="enable-system-radio" name="enable_external_wiki" type="radio" value="false" data-target="#external_wiki_box" {{if not (.Repository.UnitEnabled $.Context $.UnitTypeExternalUncyclo)}}checked{{end}}>
336+
<input class="enable-system-radio" name="enable_external_wiki" type="radio" value="false" data-target="#external_wiki_box" {{if $isBulitinUncycloEnabled}}checked{{end}}>
335337
<label>{{ctx.Locale.Tr "repo.settings.use_internal_wiki"}}</label>
336338
</div>
337339
</div>
338340
<div class="inline field tw-pl-4">
339341
<label>{{ctx.Locale.Tr "repo.settings.default_wiki_branch_name"}}</label>
340342
<input name="default_wiki_branch" value="{{.Repository.DefaultUncycloBranch}}">
341343
</div>
344+
<div class="inline field tw-pl-4">
345+
{{$unitBuiltinUncyclo := .Repository.MustGetUnit ctx $.UnitTypeUncyclo}}
346+
<label>{{ctx.Locale.Tr "repo.settings.default_wiki_everyone_access"}}</label>
347+
<select name="default_wiki_everyone_access" class="ui dropdown">
348+
<option value="unset" {{Iif (eq $unitBuiltinUncyclo.EveryoneAccessMode -1) "selected"}}>unset</option>
349+
<option value="read" {{Iif (eq $unitBuiltinUncyclo.EveryoneAccessMode 1) "selected"}}>read</option>
350+
<option value="write" {{Iif (eq $unitBuiltinUncyclo.EveryoneAccessMode 2) "selected"}}>write</option>
351+
</select>
352+
</div>
342353
<div class="field">
343354
<div class="ui radio checkbox{{if $isExternalUncycloGlobalDisabled}} disabled{{end}}"{{if $isExternalUncycloGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
344355
<input class="enable-system-radio" name="enable_external_wiki" type="radio" value="true" data-target="#external_wiki_box" {{if .Repository.UnitEnabled $.Context $.UnitTypeExternalUncyclo}}checked{{end}}>

0 commit comments

Comments
 (0)