Skip to content

Commit 3104c6b

Browse files
add functions to populate web context with group info where appropriate
1 parent 6b30415 commit 3104c6b

File tree

1 file changed

+276
-0
lines changed

1 file changed

+276
-0
lines changed

services/context/group.go

Lines changed: 276 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,276 @@
1+
package context
2+
3+
import (
4+
group_model "code.gitea.io/gitea/models/group"
5+
"code.gitea.io/gitea/models/organization"
6+
"code.gitea.io/gitea/models/perm"
7+
shared_group "code.gitea.io/gitea/models/shared/group"
8+
"code.gitea.io/gitea/models/unit"
9+
user_model "code.gitea.io/gitea/models/user"
10+
"code.gitea.io/gitea/modules/log"
11+
"code.gitea.io/gitea/modules/markup"
12+
"code.gitea.io/gitea/modules/markup/markdown"
13+
"code.gitea.io/gitea/modules/setting"
14+
"code.gitea.io/gitea/modules/structs"
15+
"context"
16+
"strings"
17+
)
18+
19+
type RepoGroup struct {
20+
IsOwner bool
21+
IsMember bool
22+
IsGroupAdmin bool
23+
Group *group_model.Group
24+
GroupLink string
25+
OrgGroupLink string
26+
CanCreateRepoOrGroup bool
27+
Team *organization.Team
28+
Teams []*organization.Team
29+
GroupTeam *group_model.RepoGroupTeam
30+
}
31+
32+
func (g *RepoGroup) CanWriteUnit(ctx *Context, unitType unit.Type) bool {
33+
return g.UnitPermission(ctx, ctx.Doer, unitType) >= perm.AccessModeWrite
34+
}
35+
36+
func (g *RepoGroup) CanReadUnit(ctx *Context, unitType unit.Type) bool {
37+
return g.UnitPermission(ctx, ctx.Doer, unitType) >= perm.AccessModeRead
38+
}
39+
func (g *RepoGroup) UnitPermission(ctx context.Context, doer *user_model.User, unitType unit.Type) perm.AccessMode {
40+
if doer != nil {
41+
teams, err := organization.GetUserGroupTeams(ctx, g.Group.ID, doer.ID)
42+
if err != nil {
43+
log.Error("GetUserOrgTeams: %v", err)
44+
return perm.AccessModeNone
45+
}
46+
47+
if err := teams.LoadUnits(ctx); err != nil {
48+
log.Error("LoadUnits: %v", err)
49+
return perm.AccessModeNone
50+
}
51+
52+
if len(teams) > 0 {
53+
return teams.UnitMaxAccess(unitType)
54+
}
55+
}
56+
57+
if g.Group.Visibility.IsPublic() {
58+
return perm.AccessModeRead
59+
}
60+
61+
return perm.AccessModeNone
62+
}
63+
64+
func GetGroupByParams(ctx *Context) {
65+
groupID := ctx.PathParamInt64("group_id")
66+
67+
var err error
68+
ctx.RepoGroup.Group, err = group_model.GetGroupByID(ctx, groupID)
69+
if err != nil {
70+
if group_model.IsErrGroupNotExist(err) {
71+
ctx.NotFound(err)
72+
} else {
73+
ctx.ServerError("GetUserByName", err)
74+
}
75+
return
76+
}
77+
if err = ctx.RepoGroup.Group.LoadAttributes(ctx); err != nil {
78+
ctx.ServerError("LoadAttributes", err)
79+
}
80+
}
81+
82+
type GroupAssignmentOptions struct {
83+
RequireMember bool
84+
RequireOwner bool
85+
RequireGroupAdmin bool
86+
}
87+
88+
func GroupAssignment(args GroupAssignmentOptions) func(ctx *Context) {
89+
return func(ctx *Context) {
90+
var err error
91+
92+
if ctx.RepoGroup.Group == nil {
93+
GetGroupByParams(ctx)
94+
if ctx.Written() {
95+
return
96+
}
97+
}
98+
99+
group := ctx.RepoGroup.Group
100+
if ctx.RepoGroup.Group.Visibility != structs.VisibleTypePublic && !ctx.IsSigned {
101+
ctx.NotFound(err)
102+
return
103+
}
104+
if ctx.RepoGroup.Group.Visibility == structs.VisibleTypePrivate {
105+
args.RequireMember = true
106+
} else if ctx.IsSigned && ctx.Doer.IsRestricted {
107+
args.RequireMember = true
108+
}
109+
if ctx.IsSigned && ctx.Doer.IsAdmin {
110+
ctx.RepoGroup.IsOwner = true
111+
ctx.RepoGroup.IsMember = true
112+
ctx.RepoGroup.IsGroupAdmin = true
113+
ctx.RepoGroup.CanCreateRepoOrGroup = true
114+
} else if ctx.IsSigned {
115+
ctx.RepoGroup.IsOwner, err = group.IsOwnedBy(ctx, ctx.Doer.ID)
116+
if err != nil {
117+
ctx.ServerError("IsOwnedBy", err)
118+
return
119+
}
120+
121+
if ctx.RepoGroup.IsOwner {
122+
ctx.RepoGroup.IsMember = true
123+
ctx.RepoGroup.IsGroupAdmin = true
124+
ctx.RepoGroup.CanCreateRepoOrGroup = true
125+
} else {
126+
ctx.RepoGroup.IsMember, err = shared_group.IsGroupMember(ctx, group.ID, ctx.Doer)
127+
if err != nil {
128+
ctx.ServerError("IsOrgMember", err)
129+
return
130+
}
131+
ctx.RepoGroup.CanCreateRepoOrGroup, err = group.CanCreateIn(ctx, ctx.Doer.ID)
132+
if err != nil {
133+
ctx.ServerError("CanCreateIn", err)
134+
return
135+
}
136+
}
137+
} else {
138+
ctx.Data["SignedUser"] = &user_model.User{}
139+
}
140+
if (args.RequireMember && !ctx.RepoGroup.IsMember) ||
141+
(args.RequireOwner && !ctx.RepoGroup.IsOwner) {
142+
ctx.NotFound(err)
143+
return
144+
}
145+
ctx.Data["EnableFeed"] = setting.Other.EnableFeed
146+
ctx.Data["FeedURL"] = ctx.RepoGroup.Group.GroupLink()
147+
ctx.Data["IsGroupOwner"] = ctx.RepoGroup.IsOwner
148+
ctx.Data["IsGroupMember"] = ctx.RepoGroup.IsMember
149+
ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled
150+
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
151+
ctx.Data["IsPublicMember"] = func(uid int64) bool {
152+
is, _ := organization.IsPublicMembership(ctx, ctx.Org.Organization.ID, uid)
153+
return is
154+
}
155+
ctx.Data["CanReadProjects"] = ctx.RepoGroup.CanReadUnit(ctx, unit.TypeProjects)
156+
ctx.Data["CanCreateOrgRepo"] = ctx.RepoGroup.CanCreateRepoOrGroup
157+
158+
ctx.RepoGroup.GroupLink = group.GroupLink()
159+
ctx.RepoGroup.OrgGroupLink = group.OrgGroupLink()
160+
161+
if ctx.RepoGroup.IsMember {
162+
shouldSeeAllTeams := false
163+
if ctx.RepoGroup.IsOwner {
164+
shouldSeeAllTeams = true
165+
} else {
166+
teams, err := shared_group.GetGroupTeams(ctx, group.ID)
167+
if err != nil {
168+
ctx.ServerError("GetUserTeams", err)
169+
return
170+
}
171+
for _, team := range teams {
172+
if team.IncludesAllRepositories && team.AccessMode >= perm.AccessModeAdmin {
173+
shouldSeeAllTeams = true
174+
break
175+
}
176+
}
177+
}
178+
if shouldSeeAllTeams {
179+
ctx.RepoGroup.Teams, err = shared_group.GetGroupTeams(ctx, group.ID)
180+
if err != nil {
181+
ctx.ServerError("LoadTeams", err)
182+
return
183+
}
184+
} else {
185+
ctx.RepoGroup.Teams, err = organization.GetUserGroupTeams(ctx, group.ID, ctx.Doer.ID)
186+
if err != nil {
187+
ctx.ServerError("GetUserTeams", err)
188+
return
189+
}
190+
}
191+
ctx.Data["NumTeams"] = len(ctx.RepoGroup.Teams)
192+
}
193+
194+
teamName := ctx.PathParam("team")
195+
if len(teamName) > 0 {
196+
teamExists := false
197+
for _, team := range ctx.RepoGroup.Teams {
198+
if team.LowerName == strings.ToLower(teamName) {
199+
teamExists = true
200+
var groupTeam *group_model.RepoGroupTeam
201+
groupTeam, err = group_model.FindGroupTeamByTeamID(ctx, group.ID, team.ID)
202+
if err != nil {
203+
ctx.ServerError("FindGroupTeamByTeamID", err)
204+
return
205+
}
206+
ctx.RepoGroup.GroupTeam = groupTeam
207+
ctx.RepoGroup.Team = team
208+
ctx.RepoGroup.IsMember = true
209+
ctx.Data["Team"] = ctx.RepoGroup.Team
210+
break
211+
}
212+
}
213+
214+
if !teamExists {
215+
ctx.NotFound(err)
216+
return
217+
}
218+
219+
ctx.Data["IsTeamMember"] = ctx.RepoGroup.IsMember
220+
if args.RequireMember && !ctx.RepoGroup.IsMember {
221+
ctx.NotFound(err)
222+
return
223+
}
224+
225+
ctx.RepoGroup.IsGroupAdmin = ctx.RepoGroup.Team.IsOwnerTeam() || ctx.RepoGroup.Team.AccessMode >= perm.AccessModeAdmin
226+
} else {
227+
for _, team := range ctx.RepoGroup.Teams {
228+
if team.AccessMode >= perm.AccessModeAdmin {
229+
ctx.RepoGroup.IsGroupAdmin = true
230+
break
231+
}
232+
}
233+
}
234+
if ctx.IsSigned {
235+
isAdmin, err := group.IsAdminOf(ctx, ctx.Doer.ID)
236+
if err != nil {
237+
ctx.ServerError("IsAdminOf", err)
238+
return
239+
}
240+
ctx.RepoGroup.IsGroupAdmin = ctx.RepoGroup.IsGroupAdmin || isAdmin
241+
}
242+
243+
ctx.Data["IsGroupAdmin"] = ctx.RepoGroup.IsGroupAdmin
244+
if args.RequireGroupAdmin && !ctx.RepoGroup.IsGroupAdmin {
245+
ctx.NotFound(err)
246+
return
247+
}
248+
249+
if len(ctx.RepoGroup.Group.Description) != 0 {
250+
ctx.Data["RenderedDescription"], err = markdown.RenderString(markup.NewRenderContext(ctx), ctx.RepoGroup.Group.Description)
251+
if err != nil {
252+
ctx.ServerError("RenderString", err)
253+
return
254+
}
255+
}
256+
ctx.Data["Group"] = ctx.RepoGroup.Group
257+
ctx.Data["ContextGroup"] = ctx.RepoGroup
258+
ctx.Data["Doer"] = ctx.Doer
259+
ctx.Data["GroupLink"] = ctx.RepoGroup.Group.GroupLink()
260+
ctx.Data["OrgGroupLink"] = ctx.RepoGroup.OrgGroupLink
261+
ctx.Data["Breadcrumbs"], err = group_model.GetParentGroupChain(ctx, group.ID)
262+
if err != nil {
263+
ctx.ServerError("GetParentGroupChain", err)
264+
return
265+
}
266+
}
267+
}
268+
269+
func groupIsCurrent(ctx *Context) func(groupID int64) bool {
270+
return func(groupID int64) bool {
271+
if ctx.RepoGroup.Group == nil {
272+
return false
273+
}
274+
return ctx.RepoGroup.Group.ID == groupID
275+
}
276+
}

0 commit comments

Comments
 (0)