Skip to content

Commit 98ede08

Browse files
committed
fix
1 parent bf9500b commit 98ede08

File tree

11 files changed

+271
-123
lines changed

11 files changed

+271
-123
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
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
+152
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
package setting
2+
3+
import (
4+
"net/http"
5+
"slices"
6+
"strconv"
7+
8+
"code.gitea.io/gitea/models/perm"
9+
"code.gitea.io/gitea/models/repo"
10+
"code.gitea.io/gitea/models/unit"
11+
"code.gitea.io/gitea/modules/setting"
12+
"code.gitea.io/gitea/modules/templates"
13+
"code.gitea.io/gitea/services/context"
14+
)
15+
16+
const tplRepoSettingsPublicAccess templates.TplName = "repo/settings/public_access"
17+
18+
func parsePublicAccessMode(permission string, allowed []string) (ret struct {
19+
AnonymousAccessMode, EveryoneAccessMode perm.AccessMode
20+
},
21+
) {
22+
ret.AnonymousAccessMode = perm.AccessModeNone
23+
ret.EveryoneAccessMode = perm.AccessModeNone
24+
25+
// if site admin forces repositories to be private, then do not allow any other access mode,
26+
// otherwise the "force private" setting would be bypassed
27+
if setting.Repository.ForcePrivate {
28+
return ret
29+
}
30+
if !slices.Contains(allowed, permission) {
31+
return ret
32+
}
33+
switch permission {
34+
case paAnonymousRead:
35+
ret.AnonymousAccessMode = perm.AccessModeRead
36+
case paEveryoneRead:
37+
ret.EveryoneAccessMode = perm.AccessModeRead
38+
case paEveryoneWrite:
39+
ret.EveryoneAccessMode = perm.AccessModeWrite
40+
}
41+
return ret
42+
}
43+
44+
const (
45+
paNotSet = "not-set"
46+
paAnonymousRead = "anonymous-read"
47+
paEveryoneRead = "everyone-read"
48+
paEveryoneWrite = "everyone-write"
49+
)
50+
51+
type repoUnitPublicAccess struct {
52+
UnitType unit.Type
53+
FormKey string
54+
DisplayName string
55+
PublicAccessTypes []string
56+
UnitPublicAccess string
57+
}
58+
59+
func repoUnitPublicAccesses(ctx *context.Context) []*repoUnitPublicAccess {
60+
accesses := []*repoUnitPublicAccess{
61+
{
62+
UnitType: unit.TypeCode,
63+
DisplayName: ctx.Locale.TrString("repo.code"),
64+
PublicAccessTypes: []string{paAnonymousRead, paEveryoneRead},
65+
},
66+
{
67+
UnitType: unit.TypeIssues,
68+
DisplayName: ctx.Locale.TrString("issues"),
69+
PublicAccessTypes: []string{paAnonymousRead, paEveryoneRead},
70+
},
71+
{
72+
UnitType: unit.TypePullRequests,
73+
DisplayName: ctx.Locale.TrString("pull_requests"),
74+
PublicAccessTypes: []string{paAnonymousRead, paEveryoneRead},
75+
},
76+
{
77+
UnitType: unit.TypeReleases,
78+
DisplayName: ctx.Locale.TrString("repo.releases"),
79+
PublicAccessTypes: []string{paAnonymousRead, paEveryoneRead},
80+
},
81+
{
82+
UnitType: unit.TypeWiki,
83+
DisplayName: ctx.Locale.TrString("repo.wiki"),
84+
PublicAccessTypes: []string{paAnonymousRead, paEveryoneRead, paEveryoneWrite},
85+
},
86+
{
87+
UnitType: unit.TypeProjects,
88+
DisplayName: ctx.Locale.TrString("repo.projects"),
89+
PublicAccessTypes: []string{paAnonymousRead, paEveryoneRead},
90+
},
91+
{
92+
UnitType: unit.TypePackages,
93+
DisplayName: ctx.Locale.TrString("repo.packages"),
94+
PublicAccessTypes: []string{paAnonymousRead, paEveryoneRead},
95+
},
96+
{
97+
UnitType: unit.TypeActions,
98+
DisplayName: ctx.Locale.TrString("repo.actions"),
99+
PublicAccessTypes: []string{paAnonymousRead, paEveryoneRead},
100+
},
101+
}
102+
for _, ua := range accesses {
103+
ua.FormKey = "repo-unit-access-" + strconv.Itoa(int(ua.UnitType))
104+
for _, u := range ctx.Repo.Repository.Units {
105+
if u.Type == ua.UnitType {
106+
ua.UnitPublicAccess = paNotSet
107+
switch {
108+
case u.EveryoneAccessMode == perm.AccessModeWrite:
109+
ua.UnitPublicAccess = paEveryoneWrite
110+
case u.EveryoneAccessMode == perm.AccessModeRead:
111+
ua.UnitPublicAccess = paEveryoneRead
112+
case u.AnonymousAccessMode == perm.AccessModeRead:
113+
ua.UnitPublicAccess = paAnonymousRead
114+
}
115+
break
116+
}
117+
}
118+
}
119+
return slices.DeleteFunc(accesses, func(ua *repoUnitPublicAccess) bool {
120+
return ua.UnitPublicAccess == ""
121+
})
122+
}
123+
124+
func PublicAccess(ctx *context.Context) {
125+
ctx.Data["PageIsSettingsPublicAccess"] = true
126+
ctx.Data["RepoUnitPublicAccesses"] = repoUnitPublicAccesses(ctx)
127+
ctx.Data["GlobalForcePrivate"] = setting.Repository.ForcePrivate
128+
if setting.Repository.ForcePrivate {
129+
ctx.Flash.Error(ctx.Tr("form.repository_force_private"), true)
130+
}
131+
ctx.HTML(http.StatusOK, tplRepoSettingsPublicAccess)
132+
}
133+
134+
func PublicAccessPost(ctx *context.Context) {
135+
accesses := repoUnitPublicAccesses(ctx)
136+
for _, ua := range accesses {
137+
formVal := ctx.FormString(ua.FormKey)
138+
parsed := parsePublicAccessMode(formVal, ua.PublicAccessTypes)
139+
err := repo.UpdateRepoUnitPublicAccess(ctx, &repo.RepoUnit{
140+
RepoID: ctx.Repo.Repository.ID,
141+
Type: ua.UnitType,
142+
AnonymousAccessMode: parsed.AnonymousAccessMode,
143+
EveryoneAccessMode: parsed.EveryoneAccessMode,
144+
})
145+
if err != nil {
146+
ctx.ServerError("UpdateRepoUnitPublicAccess", err)
147+
return
148+
}
149+
}
150+
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
151+
ctx.Redirect(ctx.Repo.Repository.Link() + "/settings/public_access")
152+
}

0 commit comments

Comments
 (0)