Skip to content

Commit 4399cd6

Browse files
committed
Merge branch 'main' of https://github.com/coder/coder into bq/user-notifications
2 parents d97dd82 + abbcffe commit 4399cd6

File tree

121 files changed

+3108
-575
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

121 files changed

+3108
-575
lines changed

agent/agent.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -588,10 +588,12 @@ func (a *agent) reportMetadata(ctx context.Context, conn drpc.Conn) error {
588588
updatedMetadata[mr.key] = mr.result
589589
continue
590590
case err := <-reportError:
591-
a.logger.Debug(ctx, "batch update metadata complete", slog.Error(err))
591+
logMsg := "batch update metadata complete"
592592
if err != nil {
593+
a.logger.Debug(ctx, logMsg, slog.Error(err))
593594
return xerrors.Errorf("failed to report metadata: %w", err)
594595
}
596+
a.logger.Debug(ctx, logMsg)
595597
reportInFlight = false
596598
case <-report:
597599
if len(updatedMetadata) == 0 {

cli/testdata/coder_server_--help.golden

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ OPTIONS:
2222
--cache-dir string, $CODER_CACHE_DIRECTORY (default: [cache dir])
2323
The directory to cache temporary files. If unspecified and
2424
$CACHE_DIRECTORY is set, it will be used for compatibility with
25-
systemd.
25+
systemd. This directory is NOT safe to be configured as a shared
26+
directory across coderd/provisionerd replicas.
2627

2728
--disable-owner-workspace-access bool, $CODER_DISABLE_OWNER_WORKSPACE_ACCESS
2829
Remove the permission for the 'owner' role to have workspace execution

cli/testdata/server-config.yaml.golden

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,8 @@ updateCheck: false
414414
# (default: <unset>, type: bool)
415415
enableSwagger: false
416416
# The directory to cache temporary files. If unspecified and $CACHE_DIRECTORY is
417-
# set, it will be used for compatibility with systemd.
417+
# set, it will be used for compatibility with systemd. This directory is NOT safe
418+
# to be configured as a shared directory across coderd/provisionerd replicas.
418419
# (default: [cache dir], type: string)
419420
cacheDir: [cache dir]
420421
# Controls whether data will be stored in an in-memory database.

coderd/apidoc/docs.go

Lines changed: 74 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

Lines changed: 66 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/autobuild/lifecycle_executor.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"golang.org/x/xerrors"
1414

1515
"cdr.dev/slog"
16+
1617
"github.com/coder/coder/v2/coderd/audit"
1718
"github.com/coder/coder/v2/coderd/database"
1819
"github.com/coder/coder/v2/coderd/database/dbauthz"
@@ -296,10 +297,11 @@ func (e *Executor) runOnce(t time.Time) Stats {
296297

297298
if _, err := e.notificationsEnqueuer.Enqueue(e.ctx, ws.OwnerID, notifications.TemplateWorkspaceAutoUpdated,
298299
map[string]string{
299-
"name": ws.Name,
300-
"initiator": "autobuild",
301-
"reason": nextBuildReason,
302-
"template_version_name": activeTemplateVersion.Name,
300+
"name": ws.Name,
301+
"initiator": "autobuild",
302+
"reason": nextBuildReason,
303+
"template_version_name": activeTemplateVersion.Name,
304+
"template_version_message": activeTemplateVersion.Message,
303305
}, "autobuild",
304306
// Associate this notification with all the related entities.
305307
ws.ID, ws.OwnerID, ws.TemplateID, ws.OrganizationID,

coderd/coderd.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -871,7 +871,7 @@ func New(options *Options) *API {
871871
r.Route("/templates", func(r chi.Router) {
872872
r.Post("/", api.postTemplateByOrganization)
873873
r.Get("/", api.templatesByOrganization())
874-
r.Get("/examples", api.templateExamples)
874+
r.Get("/examples", api.templateExamplesByOrganization)
875875
r.Route("/{templatename}", func(r chi.Router) {
876876
r.Get("/", api.templateByOrganizationAndName)
877877
r.Route("/versions/{templateversionname}", func(r chi.Router) {
@@ -915,6 +915,7 @@ func New(options *Options) *API {
915915
apiKeyMiddleware,
916916
)
917917
r.Get("/", api.fetchTemplates(nil))
918+
r.Get("/examples", api.templateExamples)
918919
r.Route("/{template}", func(r chi.Router) {
919920
r.Use(
920921
httpmw.ExtractTemplateParam(options.Database),

coderd/database/dbauthz/dbauthz.go

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,20 @@ func (q *querier) DeleteCoordinator(ctx context.Context, id uuid.UUID) error {
958958
return q.db.DeleteCoordinator(ctx, id)
959959
}
960960

961+
func (q *querier) DeleteCustomRole(ctx context.Context, arg database.DeleteCustomRoleParams) error {
962+
if arg.OrganizationID.UUID != uuid.Nil {
963+
if err := q.authorizeContext(ctx, policy.ActionDelete, rbac.ResourceAssignOrgRole.InOrg(arg.OrganizationID.UUID)); err != nil {
964+
return err
965+
}
966+
} else {
967+
if err := q.authorizeContext(ctx, policy.ActionDelete, rbac.ResourceAssignRole); err != nil {
968+
return err
969+
}
970+
}
971+
972+
return q.db.DeleteCustomRole(ctx, arg)
973+
}
974+
961975
func (q *querier) DeleteExternalAuthLink(ctx context.Context, arg database.DeleteExternalAuthLinkParams) error {
962976
return fetchAndExec(q.log, q.auth, policy.ActionUpdatePersonal, func(ctx context.Context, arg database.DeleteExternalAuthLinkParams) (database.ExternalAuthLink, error) {
963977
//nolint:gosimple
@@ -1489,13 +1503,13 @@ func (q *querier) GetNotificationTemplateByID(ctx context.Context, id uuid.UUID)
14891503
}
14901504

14911505
func (q *querier) GetNotificationTemplatesByKind(ctx context.Context, kind database.NotificationTemplateKind) ([]database.NotificationTemplate, error) {
1492-
// TODO: restrict 'system' kind to admins only?
1493-
// All notification templates share the same rbac.Object, so there is no need
1494-
// to authorize them individually. If this passes, all notification templates can be read.
1495-
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceNotificationTemplate); err != nil {
1496-
return nil, err
1506+
// Anyone can read the system notification templates.
1507+
if kind == database.NotificationTemplateKindSystem {
1508+
return q.db.GetNotificationTemplatesByKind(ctx, kind)
14971509
}
1498-
return q.db.GetNotificationTemplatesByKind(ctx, kind)
1510+
1511+
// TODO(dannyk): handle template ownership when we support user-default notification templates.
1512+
return nil, sql.ErrNoRows
14991513
}
15001514

15011515
func (q *querier) GetNotificationsSettings(ctx context.Context) (string, error) {

coderd/database/dbauthz/dbauthz_test.go

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1247,6 +1247,31 @@ func (s *MethodTestSuite) TestUser() {
12471247
s.Run("CustomRoles", s.Subtest(func(db database.Store, check *expects) {
12481248
check.Args(database.CustomRolesParams{}).Asserts(rbac.ResourceAssignRole, policy.ActionRead).Returns([]database.CustomRole{})
12491249
}))
1250+
s.Run("Organization/DeleteCustomRole", s.Subtest(func(db database.Store, check *expects) {
1251+
customRole := dbgen.CustomRole(s.T(), db, database.CustomRole{
1252+
OrganizationID: uuid.NullUUID{
1253+
UUID: uuid.New(),
1254+
Valid: true,
1255+
},
1256+
})
1257+
check.Args(database.DeleteCustomRoleParams{
1258+
Name: customRole.Name,
1259+
OrganizationID: customRole.OrganizationID,
1260+
}).Asserts(
1261+
rbac.ResourceAssignOrgRole.InOrg(customRole.OrganizationID.UUID), policy.ActionDelete)
1262+
}))
1263+
s.Run("Site/DeleteCustomRole", s.Subtest(func(db database.Store, check *expects) {
1264+
customRole := dbgen.CustomRole(s.T(), db, database.CustomRole{
1265+
OrganizationID: uuid.NullUUID{
1266+
UUID: uuid.Nil,
1267+
Valid: false,
1268+
},
1269+
})
1270+
check.Args(database.DeleteCustomRoleParams{
1271+
Name: customRole.Name,
1272+
}).Asserts(
1273+
rbac.ResourceAssignRole, policy.ActionDelete)
1274+
}))
12501275
s.Run("Blank/UpsertCustomRole", s.Subtest(func(db database.Store, check *expects) {
12511276
// Blank is no perms in the role
12521277
check.Args(database.UpsertCustomRoleParams{
@@ -2610,8 +2635,10 @@ func (s *MethodTestSuite) TestNotifications() {
26102635
}))
26112636
s.Run("GetNotificationTemplatesByKind", s.Subtest(func(db database.Store, check *expects) {
26122637
check.Args(database.NotificationTemplateKindSystem).
2613-
Asserts(rbac.ResourceNotificationTemplate, policy.ActionRead).
2638+
Asserts().
26142639
Errors(dbmem.ErrUnimplemented)
2640+
2641+
// TODO(dannyk): add support for other database.NotificationTemplateKind types once implemented.
26152642
}))
26162643
s.Run("UpdateNotificationTemplateMethodByID", s.Subtest(func(db database.Store, check *expects) {
26172644
check.Args(database.UpdateNotificationTemplateMethodByIDParams{

coderd/database/dbmem/dbmem.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,6 +1381,35 @@ func (*FakeQuerier) DeleteCoordinator(context.Context, uuid.UUID) error {
13811381
return ErrUnimplemented
13821382
}
13831383

1384+
func (q *FakeQuerier) DeleteCustomRole(_ context.Context, arg database.DeleteCustomRoleParams) error {
1385+
err := validateDatabaseType(arg)
1386+
if err != nil {
1387+
return err
1388+
}
1389+
1390+
q.mutex.RLock()
1391+
defer q.mutex.RUnlock()
1392+
1393+
initial := len(q.data.customRoles)
1394+
q.data.customRoles = slices.DeleteFunc(q.data.customRoles, func(role database.CustomRole) bool {
1395+
return role.OrganizationID.UUID == arg.OrganizationID.UUID && role.Name == arg.Name
1396+
})
1397+
if initial == len(q.data.customRoles) {
1398+
return sql.ErrNoRows
1399+
}
1400+
1401+
// Emulate the trigger 'remove_organization_member_custom_role'
1402+
for i, mem := range q.organizationMembers {
1403+
if mem.OrganizationID == arg.OrganizationID.UUID {
1404+
mem.Roles = slices.DeleteFunc(mem.Roles, func(role string) bool {
1405+
return role == arg.Name
1406+
})
1407+
q.organizationMembers[i] = mem
1408+
}
1409+
}
1410+
return nil
1411+
}
1412+
13841413
func (q *FakeQuerier) DeleteExternalAuthLink(_ context.Context, arg database.DeleteExternalAuthLinkParams) error {
13851414
err := validateDatabaseType(arg)
13861415
if err != nil {

0 commit comments

Comments
 (0)