Skip to content

Commit 4b2dfc0

Browse files
committed
fix
1 parent bf9500b commit 4b2dfc0

File tree

11 files changed

+274
-124
lines changed

11 files changed

+274
-124
lines changed

models/perm/access/repo_permission.go

+10-2
Original file line numberDiff line numberDiff line change
@@ -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

@@ -50,7 +51,7 @@ func (p *Permission) HasAnyUnitAccess() bool {
5051
return p.AccessMode >= perm_model.AccessModeRead
5152
}
5253

53-
func (p *Permission) HasAnyUnitAccessOrPublicAccess() bool {
54+
func (p *Permission) HasAnyUnitPublicAccess() bool {
5455
for _, v := range p.anonymousAccessMode {
5556
if v >= perm_model.AccessModeRead {
5657
return true
@@ -61,7 +62,11 @@ func (p *Permission) HasAnyUnitAccessOrPublicAccess() bool {
6162
return true
6263
}
6364
}
64-
return p.HasAnyUnitAccess()
65+
return false
66+
}
67+
68+
func (p *Permission) HasAnyUnitAccessOrPublicAccess() bool {
69+
return p.HasAnyUnitPublicAccess() || p.HasAnyUnitAccess()
6570
}
6671

6772
// HasUnits returns true if the permission contains attached units
@@ -188,6 +193,9 @@ func (p *Permission) LogString() string {
188193
}
189194

190195
func applyPublicAccessPermission(unitType unit.Type, accessMode perm_model.AccessMode, modeMap *map[unit.Type]perm_model.AccessMode) {
196+
if setting.Repository.ForcePrivate {
197+
return
198+
}
191199
if accessMode >= perm_model.AccessModeRead && accessMode > (*modeMap)[unitType] {
192200
if *modeMap == nil {
193201
*modeMap = make(map[unit.Type]perm_model.AccessMode)

models/repo/repo_unit.go

+6
Original file line numberDiff line numberDiff line change
@@ -342,3 +342,9 @@ func UpdateRepoUnit(ctx context.Context, unit *RepoUnit) error {
342342
_, err := db.GetEngine(ctx).ID(unit.ID).Update(unit)
343343
return err
344344
}
345+
346+
func UpdateRepoUnitPublicAccess(ctx context.Context, unit *RepoUnit) error {
347+
_, err := db.GetEngine(ctx).Where("repo_id=? AND `type`=?", unit.RepoID, unit.Type).
348+
Cols("anonymous_access_mode", "everyone_access_mode").Update(unit)
349+
return err
350+
}

options/locale/locale_en-US.ini

+5-1
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,9 @@ permission_not_set = Not set
926926
permission_no_access = No Access
927927
permission_read = Read
928928
permission_write = Read and Write
929+
permission_anonymous_read = Anonymous Read
930+
permission_everyone_read = Everyone Read
931+
permission_everyone_write = Everyone Write
929932
access_token_desc = Selected token permissions limit authorization only to the corresponding <a %s>API</a> routes. Read the <a %s>documentation</a> for more information.
930933
at_least_one_permission = You must select at least one permission to create a token
931934
permissions_list = Permissions:
@@ -1138,6 +1141,7 @@ transfer.no_permission_to_reject = You do not have permission to reject this tra
11381141

11391142
desc.private = Private
11401143
desc.public = Public
1144+
desc.public_access = Public Access
11411145
desc.template = Template
11421146
desc.internal = Internal
11431147
desc.archived = Archived
@@ -2133,6 +2137,7 @@ contributors.contribution_type.deletions = Deletions
21332137
settings = Settings
21342138
settings.desc = Settings is where you can manage the settings for the repository
21352139
settings.options = Repository
2140+
settings.public_access = Public Access
21362141
settings.collaboration = Collaborators
21372142
settings.collaboration.admin = Administrator
21382143
settings.collaboration.write = Write
@@ -2179,7 +2184,6 @@ settings.advanced_settings = Advanced Settings
21792184
settings.wiki_desc = Enable Repository Wiki
21802185
settings.use_internal_wiki = Use Built-In Wiki
21812186
settings.default_wiki_branch_name = Default Wiki Branch Name
2182-
settings.default_permission_everyone_access = Default access permission for all signed-in users:
21832187
settings.failed_to_change_default_wiki_branch = Failed to change the default wiki branch.
21842188
settings.use_external_wiki = Use External Wiki
21852189
settings.external_wiki_url = External Wiki URL
+155
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package setting
5+
6+
import (
7+
"net/http"
8+
"slices"
9+
"strconv"
10+
11+
"code.gitea.io/gitea/models/perm"
12+
"code.gitea.io/gitea/models/repo"
13+
"code.gitea.io/gitea/models/unit"
14+
"code.gitea.io/gitea/modules/setting"
15+
"code.gitea.io/gitea/modules/templates"
16+
"code.gitea.io/gitea/services/context"
17+
)
18+
19+
const tplRepoSettingsPublicAccess templates.TplName = "repo/settings/public_access"
20+
21+
func parsePublicAccessMode(permission string, allowed []string) (ret struct {
22+
AnonymousAccessMode, EveryoneAccessMode perm.AccessMode
23+
},
24+
) {
25+
ret.AnonymousAccessMode = perm.AccessModeNone
26+
ret.EveryoneAccessMode = perm.AccessModeNone
27+
28+
// if site admin forces repositories to be private, then do not allow any other access mode,
29+
// otherwise the "force private" setting would be bypassed
30+
if setting.Repository.ForcePrivate {
31+
return ret
32+
}
33+
if !slices.Contains(allowed, permission) {
34+
return ret
35+
}
36+
switch permission {
37+
case paAnonymousRead:
38+
ret.AnonymousAccessMode = perm.AccessModeRead
39+
case paEveryoneRead:
40+
ret.EveryoneAccessMode = perm.AccessModeRead
41+
case paEveryoneWrite:
42+
ret.EveryoneAccessMode = perm.AccessModeWrite
43+
}
44+
return ret
45+
}
46+
47+
const (
48+
paNotSet = "not-set"
49+
paAnonymousRead = "anonymous-read"
50+
paEveryoneRead = "everyone-read"
51+
paEveryoneWrite = "everyone-write"
52+
)
53+
54+
type repoUnitPublicAccess struct {
55+
UnitType unit.Type
56+
FormKey string
57+
DisplayName string
58+
PublicAccessTypes []string
59+
UnitPublicAccess string
60+
}
61+
62+
func repoUnitPublicAccesses(ctx *context.Context) []*repoUnitPublicAccess {
63+
accesses := []*repoUnitPublicAccess{
64+
{
65+
UnitType: unit.TypeCode,
66+
DisplayName: ctx.Locale.TrString("repo.code"),
67+
PublicAccessTypes: []string{paAnonymousRead, paEveryoneRead},
68+
},
69+
{
70+
UnitType: unit.TypeIssues,
71+
DisplayName: ctx.Locale.TrString("issues"),
72+
PublicAccessTypes: []string{paAnonymousRead, paEveryoneRead},
73+
},
74+
{
75+
UnitType: unit.TypePullRequests,
76+
DisplayName: ctx.Locale.TrString("pull_requests"),
77+
PublicAccessTypes: []string{paAnonymousRead, paEveryoneRead},
78+
},
79+
{
80+
UnitType: unit.TypeReleases,
81+
DisplayName: ctx.Locale.TrString("repo.releases"),
82+
PublicAccessTypes: []string{paAnonymousRead, paEveryoneRead},
83+
},
84+
{
85+
UnitType: unit.TypeWiki,
86+
DisplayName: ctx.Locale.TrString("repo.wiki"),
87+
PublicAccessTypes: []string{paAnonymousRead, paEveryoneRead, paEveryoneWrite},
88+
},
89+
{
90+
UnitType: unit.TypeProjects,
91+
DisplayName: ctx.Locale.TrString("repo.projects"),
92+
PublicAccessTypes: []string{paAnonymousRead, paEveryoneRead},
93+
},
94+
{
95+
UnitType: unit.TypePackages,
96+
DisplayName: ctx.Locale.TrString("repo.packages"),
97+
PublicAccessTypes: []string{paAnonymousRead, paEveryoneRead},
98+
},
99+
{
100+
UnitType: unit.TypeActions,
101+
DisplayName: ctx.Locale.TrString("repo.actions"),
102+
PublicAccessTypes: []string{paAnonymousRead, paEveryoneRead},
103+
},
104+
}
105+
for _, ua := range accesses {
106+
ua.FormKey = "repo-unit-access-" + strconv.Itoa(int(ua.UnitType))
107+
for _, u := range ctx.Repo.Repository.Units {
108+
if u.Type == ua.UnitType {
109+
ua.UnitPublicAccess = paNotSet
110+
switch {
111+
case u.EveryoneAccessMode == perm.AccessModeWrite:
112+
ua.UnitPublicAccess = paEveryoneWrite
113+
case u.EveryoneAccessMode == perm.AccessModeRead:
114+
ua.UnitPublicAccess = paEveryoneRead
115+
case u.AnonymousAccessMode == perm.AccessModeRead:
116+
ua.UnitPublicAccess = paAnonymousRead
117+
}
118+
break
119+
}
120+
}
121+
}
122+
return slices.DeleteFunc(accesses, func(ua *repoUnitPublicAccess) bool {
123+
return ua.UnitPublicAccess == ""
124+
})
125+
}
126+
127+
func PublicAccess(ctx *context.Context) {
128+
ctx.Data["PageIsSettingsPublicAccess"] = true
129+
ctx.Data["RepoUnitPublicAccesses"] = repoUnitPublicAccesses(ctx)
130+
ctx.Data["GlobalForcePrivate"] = setting.Repository.ForcePrivate
131+
if setting.Repository.ForcePrivate {
132+
ctx.Flash.Error(ctx.Tr("form.repository_force_private"), true)
133+
}
134+
ctx.HTML(http.StatusOK, tplRepoSettingsPublicAccess)
135+
}
136+
137+
func PublicAccessPost(ctx *context.Context) {
138+
accesses := repoUnitPublicAccesses(ctx)
139+
for _, ua := range accesses {
140+
formVal := ctx.FormString(ua.FormKey)
141+
parsed := parsePublicAccessMode(formVal, ua.PublicAccessTypes)
142+
err := repo.UpdateRepoUnitPublicAccess(ctx, &repo.RepoUnit{
143+
RepoID: ctx.Repo.Repository.ID,
144+
Type: ua.UnitType,
145+
AnonymousAccessMode: parsed.AnonymousAccessMode,
146+
EveryoneAccessMode: parsed.EveryoneAccessMode,
147+
})
148+
if err != nil {
149+
ctx.ServerError("UpdateRepoUnitPublicAccess", err)
150+
return
151+
}
152+
}
153+
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
154+
ctx.Redirect(ctx.Repo.Repository.Link() + "/settings/public_access")
155+
}

0 commit comments

Comments
 (0)