Skip to content

Commit 76e724c

Browse files
committed
chore: templates conditionally return created by
If omitted, the caller does not have permission to view said data
1 parent 04a2cae commit 76e724c

File tree

3 files changed

+43
-18
lines changed

3 files changed

+43
-18
lines changed

coderd/templates.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -679,11 +679,19 @@ func (api *API) templateExamples(rw http.ResponseWriter, r *http.Request) {
679679
httpapi.Write(ctx, rw, http.StatusOK, ex)
680680
}
681681

682+
// getCreatedByNamesByTemplateIDs returns a map of template IDs to the
683+
// usernames of the users who created them. If the caller does not have
684+
// permission to view the given creator, then the username will be the empty
685+
// string.
682686
func getCreatedByNamesByTemplateIDs(ctx context.Context, db database.Store, templates []database.Template) (map[string]string, error) {
683687
creators := make(map[string]string, len(templates))
684688
for _, template := range templates {
685689
creator, err := db.GetUserByID(ctx, template.CreatedBy)
686690
if err != nil {
691+
if errors.Is(err, sql.ErrNoRows) || dbauthz.IsNotAuthorizedError(err) {
692+
// Users might be omitted if the caller does not have access.
693+
continue
694+
}
687695
return map[string]string{}, err
688696
}
689697
creators[template.ID.String()] = creator.Username
@@ -713,6 +721,12 @@ func (api *API) convertTemplate(
713721

714722
buildTimeStats := api.metricsCache.TemplateBuildTimeStats(template.ID)
715723

724+
// Only include this uuid if the user has permission to view the user.
725+
// We know this if the username is not empty.
726+
createdBy := uuid.Nil
727+
if createdByName != "" {
728+
createdBy = template.CreatedBy
729+
}
716730
return codersdk.Template{
717731
ID: template.ID,
718732
CreatedAt: template.CreatedAt,
@@ -728,7 +742,7 @@ func (api *API) convertTemplate(
728742
Icon: template.Icon,
729743
DefaultTTLMillis: time.Duration(template.DefaultTTL).Milliseconds(),
730744
MaxTTLMillis: time.Duration(template.MaxTTL).Milliseconds(),
731-
CreatedByID: template.CreatedBy,
745+
CreatedByID: createdBy,
732746
CreatedByName: createdByName,
733747
AllowUserAutostart: template.AllowUserAutostart,
734748
AllowUserAutostop: template.AllowUserAutostop,

coderd/templateversions.go

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020

2121
"github.com/coder/coder/coderd/audit"
2222
"github.com/coder/coder/coderd/database"
23+
"github.com/coder/coder/coderd/database/dbauthz"
2324
"github.com/coder/coder/coderd/gitauth"
2425
"github.com/coder/coder/coderd/httpapi"
2526
"github.com/coder/coder/coderd/httpmw"
@@ -53,8 +54,9 @@ func (api *API) templateVersion(rw http.ResponseWriter, r *http.Request) {
5354
return
5455
}
5556

57+
// User can be the empty user if the caller does not have permission.
5658
user, err := api.Database.GetUserByID(ctx, templateVersion.CreatedBy)
57-
if err != nil {
59+
if err != nil && !dbauthz.IsNotAuthorizedError(err) {
5860
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
5961
Message: "Internal error on fetching user.",
6062
Detail: err.Error(),
@@ -165,7 +167,7 @@ func (api *API) patchTemplateVersion(rw http.ResponseWriter, r *http.Request) {
165167
}
166168

167169
user, err := api.Database.GetUserByID(ctx, templateVersion.CreatedBy)
168-
if err != nil {
170+
if err != nil && !dbauthz.IsNotAuthorizedError(err) {
169171
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
170172
Message: "Internal error on fetching user.",
171173
Detail: err.Error(),
@@ -843,7 +845,7 @@ func (api *API) templateVersionByName(rw http.ResponseWriter, r *http.Request) {
843845
}
844846

845847
user, err := api.Database.GetUserByID(ctx, templateVersion.CreatedBy)
846-
if err != nil {
848+
if err != nil && !dbauthz.IsNotAuthorizedError(err) {
847849
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
848850
Message: "Internal error on fetching user.",
849851
Detail: err.Error(),
@@ -1012,7 +1014,7 @@ func (api *API) previousTemplateVersionByOrganizationTemplateAndName(rw http.Res
10121014
}
10131015

10141016
user, err := api.Database.GetUserByID(ctx, templateVersion.CreatedBy)
1015-
if err != nil {
1017+
if err != nil && !dbauthz.IsNotAuthorizedError(err) {
10161018
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
10171019
Message: "Internal error on fetching user.",
10181020
Detail: err.Error(),
@@ -1325,7 +1327,7 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
13251327
aReq.New = templateVersion
13261328

13271329
user, err := api.Database.GetUserByID(ctx, templateVersion.CreatedBy)
1328-
if err != nil {
1330+
if err != nil && !dbauthz.IsNotAuthorizedError(err) {
13291331
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
13301332
Message: "Internal error on fetching user.",
13311333
Detail: err.Error(),
@@ -1404,14 +1406,20 @@ func (api *API) templateVersionLogs(rw http.ResponseWriter, r *http.Request) {
14041406
}
14051407

14061408
func convertTemplateVersion(version database.TemplateVersion, job codersdk.ProvisionerJob, user database.User, warnings []codersdk.TemplateVersionWarning) codersdk.TemplateVersion {
1407-
createdBy := codersdk.User{
1408-
ID: user.ID,
1409-
Username: user.Username,
1410-
Email: user.Email,
1411-
CreatedAt: user.CreatedAt,
1412-
Status: codersdk.UserStatus(user.Status),
1413-
Roles: []codersdk.Role{},
1414-
AvatarURL: user.AvatarURL.String,
1409+
// Only populate these fields if the user is not nil.
1410+
// It is usually nil because the caller cannot access the user
1411+
// resource in question.
1412+
var createdBy codersdk.User
1413+
if user.ID != uuid.Nil {
1414+
createdBy = codersdk.User{
1415+
ID: user.ID,
1416+
Username: user.Username,
1417+
Email: user.Email,
1418+
CreatedAt: user.CreatedAt,
1419+
Status: codersdk.UserStatus(user.Status),
1420+
Roles: []codersdk.Role{},
1421+
AvatarURL: user.AvatarURL.String,
1422+
}
14151423
}
14161424

14171425
return codersdk.TemplateVersion{

site/src/components/TemplateStats/TemplateStats.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
formatTemplateActiveDevelopers,
88
} from "utils/templates"
99
import { Template, TemplateVersion } from "../../api/typesGenerated"
10+
import { Maybe } from "components/Conditionals/Maybe"
1011

1112
const Language = {
1213
usedByLabel: "Used by",
@@ -56,10 +57,12 @@ export const TemplateStats: FC<TemplateStatsProps> = ({
5657
label={Language.lastUpdateLabel}
5758
value={createDayString(template.updated_at)}
5859
/>
59-
<StatsItem
60-
label={Language.createdByLabel}
61-
value={template.created_by_name}
62-
/>
60+
<Maybe condition={template.created_by_name !== ""}>
61+
<StatsItem
62+
label={Language.createdByLabel}
63+
value={template.created_by_name}
64+
/>
65+
</Maybe>
6366
</Stats>
6467
)
6568
}

0 commit comments

Comments
 (0)