MCPcopy Index your code
hub / github.com/coder/coder / templateAvailablePermissions

Method templateAvailablePermissions

enterprise/coderd/templates.go:34–121  ·  view source on GitHub ↗

@Summary Get template available acl users/groups @ID get-template-available-acl-usersgroups @Security CoderSessionToken @Produce json @Tags Enterprise @Param template path string true "Template ID" format(uuid) @Success 200 {array} codersdk.ACLAvailable @Router /api/v2/templates/{template}/acl/avail

(rw http.ResponseWriter, r *http.Request)

Source from the content-addressed store, hash-verified

32// @Success 200 {array} codersdk.ACLAvailable
33// @Router /api/v2/templates/{template}/acl/available [get]
34func (api *API) templateAvailablePermissions(rw http.ResponseWriter, r *http.Request) {
35 var (
36 ctx = r.Context()
37 template = httpmw.TemplateParam(r)
38 )
39
40 // Requires update permission on the template to list all avail users/groups
41 // for assignment.
42 if !api.Authorize(r, policy.ActionUpdate, template) {
43 httpapi.ResourceNotFound(rw)
44 return
45 }
46
47 // We have to use the system restricted context here because the caller
48 // might not have permission to read all users.
49 // nolint:gocritic
50 users, _, ok := api.AGPL.GetUsers(rw, r.WithContext(dbauthz.AsSystemRestricted(ctx)))
51 if !ok {
52 return
53 }
54
55 // Apply the same q/limit semantics to groups as the users half of this response.
56 // The query semantics are defined for the users, which is awkward. But we can
57 // just reuse the search part of the query which is a fuzzy match.
58 userFilter, verr := searchquery.Users(r.URL.Query().Get("q"))
59 if len(verr) > 0 {
60 httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
61 Message: "Invalid user search query.",
62 Validations: verr,
63 })
64 return
65 }
66 groupPagination, ok := agpl.ParsePagination(rw, r)
67 if !ok {
68 return
69 }
70
71 // Perm check is the template update check.
72 // nolint:gocritic
73 groups, err := api.Database.GetGroups(dbauthz.AsSystemRestricted(ctx), database.GetGroupsParams{
74 OrganizationID: template.OrganizationID,
75 Search: userFilter.Search,
76 // #nosec G115 - Pagination limits are small and fit in int32
77 LimitOpt: int32(groupPagination.Limit),
78 })
79 if err != nil {
80 httpapi.InternalServerError(rw, err)
81 return
82 }
83
84 // Fetch member counts for all groups in a single query to avoid an
85 // N+1 lookup pattern that was making this endpoint extremely slow on
86 // deployments with many groups. The per-group member lists are
87 // intentionally not populated here: callers of this endpoint only
88 // surface total_member_count (see Group.TotalMemberCount, which is
89 // already documented as the canonical value).
90 groupIDs := make([]uuid.UUID, len(groups))
91 for i, g := range groups {

Callers

nothing calls this directly

Calls 15

AuthorizeMethod · 0.95
TemplateParamFunction · 0.92
ResourceNotFoundFunction · 0.92
AsSystemRestrictedFunction · 0.92
UsersFunction · 0.92
WriteFunction · 0.92
InternalServerErrorFunction · 0.92
GroupFunction · 0.92
ReducedUsersFunction · 0.92
WithContextMethod · 0.80
ContextMethod · 0.65
GetUsersMethod · 0.65

Tested by

no test coverage detected