Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc074f77

Browse files
authored
feat: add notifications inbox db (#16599)
This PR is linked [to the followingissue](coder/internal#334).The objective is to create the DB layer and migration for the new `CoderInbox`.
1 parentd0e2060 commitc074f77

27 files changed

+966
-0
lines changed

‎coderd/apidoc/docs.go

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

‎coderd/apidoc/swagger.json

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

‎coderd/database/dbauthz/dbauthz.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ var (
281281
DisplayName:"Notifier",
282282
Site:rbac.Permissions(map[string][]policy.Action{
283283
rbac.ResourceNotificationMessage.Type: {policy.ActionCreate,policy.ActionRead,policy.ActionUpdate,policy.ActionDelete},
284+
rbac.ResourceInboxNotification.Type: {policy.ActionCreate},
284285
}),
285286
Org:map[string][]rbac.Permission{},
286287
User: []rbac.Permission{},
@@ -1126,6 +1127,14 @@ func (q *querier) CleanTailnetTunnels(ctx context.Context) error {
11261127
returnq.db.CleanTailnetTunnels(ctx)
11271128
}
11281129

1130+
func (q*querier)CountUnreadInboxNotificationsByUserID(ctx context.Context,userID uuid.UUID) (int64,error) {
1131+
iferr:=q.authorizeContext(ctx,policy.ActionRead,rbac.ResourceInboxNotification.WithOwner(userID.String()));err!=nil {
1132+
return0,err
1133+
}
1134+
returnq.db.CountUnreadInboxNotificationsByUserID(ctx,userID)
1135+
}
1136+
1137+
// TODO: Handle org scoped lookups
11291138
func (q*querier)CustomRoles(ctx context.Context,arg database.CustomRolesParams) ([]database.CustomRole,error) {
11301139
roleObject:=rbac.ResourceAssignRole
11311140
ifarg.OrganizationID!=uuid.Nil {
@@ -1689,6 +1698,10 @@ func (q *querier) GetFileTemplates(ctx context.Context, fileID uuid.UUID) ([]dat
16891698
returnq.db.GetFileTemplates(ctx,fileID)
16901699
}
16911700

1701+
func (q*querier)GetFilteredInboxNotificationsByUserID(ctx context.Context,arg database.GetFilteredInboxNotificationsByUserIDParams) ([]database.InboxNotification,error) {
1702+
returnfetchWithPostFilter(q.auth,policy.ActionRead,q.db.GetFilteredInboxNotificationsByUserID)(ctx,arg)
1703+
}
1704+
16921705
func (q*querier)GetGitSSHKey(ctx context.Context,userID uuid.UUID) (database.GitSSHKey,error) {
16931706
returnfetchWithAction(q.log,q.auth,policy.ActionReadPersonal,q.db.GetGitSSHKey)(ctx,userID)
16941707
}
@@ -1748,6 +1761,14 @@ func (q *querier) GetHungProvisionerJobs(ctx context.Context, hungSince time.Tim
17481761
returnq.db.GetHungProvisionerJobs(ctx,hungSince)
17491762
}
17501763

1764+
func (q*querier)GetInboxNotificationByID(ctx context.Context,id uuid.UUID) (database.InboxNotification,error) {
1765+
returnfetchWithAction(q.log,q.auth,policy.ActionRead,q.db.GetInboxNotificationByID)(ctx,id)
1766+
}
1767+
1768+
func (q*querier)GetInboxNotificationsByUserID(ctx context.Context,userID database.GetInboxNotificationsByUserIDParams) ([]database.InboxNotification,error) {
1769+
returnfetchWithPostFilter(q.auth,policy.ActionRead,q.db.GetInboxNotificationsByUserID)(ctx,userID)
1770+
}
1771+
17511772
func (q*querier)GetJFrogXrayScanByWorkspaceAndAgentID(ctx context.Context,arg database.GetJFrogXrayScanByWorkspaceAndAgentIDParams) (database.JfrogXrayScan,error) {
17521773
if_,err:=fetch(q.log,q.auth,q.db.GetWorkspaceByID)(ctx,arg.WorkspaceID);err!=nil {
17531774
return database.JfrogXrayScan{},err
@@ -3079,6 +3100,10 @@ func (q *querier) InsertGroupMember(ctx context.Context, arg database.InsertGrou
30793100
returnupdate(q.log,q.auth,fetch,q.db.InsertGroupMember)(ctx,arg)
30803101
}
30813102

3103+
func (q*querier)InsertInboxNotification(ctx context.Context,arg database.InsertInboxNotificationParams) (database.InboxNotification,error) {
3104+
returninsert(q.log,q.auth,rbac.ResourceInboxNotification.WithOwner(arg.UserID.String()),q.db.InsertInboxNotification)(ctx,arg)
3105+
}
3106+
30823107
func (q*querier)InsertLicense(ctx context.Context,arg database.InsertLicenseParams) (database.License,error) {
30833108
iferr:=q.authorizeContext(ctx,policy.ActionCreate,rbac.ResourceLicense);err!=nil {
30843109
return database.License{},err
@@ -3666,6 +3691,14 @@ func (q *querier) UpdateInactiveUsersToDormant(ctx context.Context, lastSeenAfte
36663691
returnq.db.UpdateInactiveUsersToDormant(ctx,lastSeenAfter)
36673692
}
36683693

3694+
func (q*querier)UpdateInboxNotificationReadStatus(ctx context.Context,args database.UpdateInboxNotificationReadStatusParams)error {
3695+
fetchFunc:=func(ctx context.Context,args database.UpdateInboxNotificationReadStatusParams) (database.InboxNotification,error) {
3696+
returnq.db.GetInboxNotificationByID(ctx,args.ID)
3697+
}
3698+
3699+
returnupdate(q.log,q.auth,fetchFunc,q.db.UpdateInboxNotificationReadStatus)(ctx,args)
3700+
}
3701+
36693702
func (q*querier)UpdateMemberRoles(ctx context.Context,arg database.UpdateMemberRolesParams) (database.OrganizationMember,error) {
36703703
// Authorized fetch will check that the actor has read access to the org member since the org member is returned.
36713704
member,err:=database.ExpectOne(q.OrganizationMembers(ctx, database.OrganizationMembersParams{

‎coderd/database/dbauthz/dbauthz_test.go

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4466,6 +4466,141 @@ func (s *MethodTestSuite) TestNotifications() {
44664466
Disableds: []bool{true,false},
44674467
}).Asserts(rbac.ResourceNotificationPreference.WithOwner(user.ID.String()),policy.ActionUpdate)
44684468
}))
4469+
4470+
s.Run("GetInboxNotificationsByUserID",s.Subtest(func(db database.Store,check*expects) {
4471+
u:=dbgen.User(s.T(),db, database.User{})
4472+
4473+
notifID:=uuid.New()
4474+
4475+
notif:=dbgen.NotificationInbox(s.T(),db, database.InsertInboxNotificationParams{
4476+
ID:notifID,
4477+
UserID:u.ID,
4478+
TemplateID:notifications.TemplateWorkspaceAutoUpdated,
4479+
Title:"test title",
4480+
Content:"test content notification",
4481+
Icon:"https://coder.com/favicon.ico",
4482+
Actions:json.RawMessage("{}"),
4483+
})
4484+
4485+
check.Args(database.GetInboxNotificationsByUserIDParams{
4486+
UserID:u.ID,
4487+
ReadStatus:database.InboxNotificationReadStatusAll,
4488+
}).Asserts(rbac.ResourceInboxNotification.WithID(notifID).WithOwner(u.ID.String()),policy.ActionRead).Returns([]database.InboxNotification{notif})
4489+
}))
4490+
4491+
s.Run("GetFilteredInboxNotificationsByUserID",s.Subtest(func(db database.Store,check*expects) {
4492+
u:=dbgen.User(s.T(),db, database.User{})
4493+
4494+
notifID:=uuid.New()
4495+
4496+
targets:= []uuid.UUID{u.ID,notifications.TemplateWorkspaceAutoUpdated}
4497+
4498+
notif:=dbgen.NotificationInbox(s.T(),db, database.InsertInboxNotificationParams{
4499+
ID:notifID,
4500+
UserID:u.ID,
4501+
TemplateID:notifications.TemplateWorkspaceAutoUpdated,
4502+
Targets:targets,
4503+
Title:"test title",
4504+
Content:"test content notification",
4505+
Icon:"https://coder.com/favicon.ico",
4506+
Actions:json.RawMessage("{}"),
4507+
})
4508+
4509+
check.Args(database.GetFilteredInboxNotificationsByUserIDParams{
4510+
UserID:u.ID,
4511+
Templates: []uuid.UUID{notifications.TemplateWorkspaceAutoUpdated},
4512+
Targets: []uuid.UUID{u.ID},
4513+
ReadStatus:database.InboxNotificationReadStatusAll,
4514+
}).Asserts(rbac.ResourceInboxNotification.WithID(notifID).WithOwner(u.ID.String()),policy.ActionRead).Returns([]database.InboxNotification{notif})
4515+
}))
4516+
4517+
s.Run("GetInboxNotificationByID",s.Subtest(func(db database.Store,check*expects) {
4518+
u:=dbgen.User(s.T(),db, database.User{})
4519+
4520+
notifID:=uuid.New()
4521+
4522+
targets:= []uuid.UUID{u.ID,notifications.TemplateWorkspaceAutoUpdated}
4523+
4524+
notif:=dbgen.NotificationInbox(s.T(),db, database.InsertInboxNotificationParams{
4525+
ID:notifID,
4526+
UserID:u.ID,
4527+
TemplateID:notifications.TemplateWorkspaceAutoUpdated,
4528+
Targets:targets,
4529+
Title:"test title",
4530+
Content:"test content notification",
4531+
Icon:"https://coder.com/favicon.ico",
4532+
Actions:json.RawMessage("{}"),
4533+
})
4534+
4535+
check.Args(notifID).Asserts(rbac.ResourceInboxNotification.WithID(notifID).WithOwner(u.ID.String()),policy.ActionRead).Returns(notif)
4536+
}))
4537+
4538+
s.Run("CountUnreadInboxNotificationsByUserID",s.Subtest(func(db database.Store,check*expects) {
4539+
u:=dbgen.User(s.T(),db, database.User{})
4540+
4541+
notifID:=uuid.New()
4542+
4543+
targets:= []uuid.UUID{u.ID,notifications.TemplateWorkspaceAutoUpdated}
4544+
4545+
_=dbgen.NotificationInbox(s.T(),db, database.InsertInboxNotificationParams{
4546+
ID:notifID,
4547+
UserID:u.ID,
4548+
TemplateID:notifications.TemplateWorkspaceAutoUpdated,
4549+
Targets:targets,
4550+
Title:"test title",
4551+
Content:"test content notification",
4552+
Icon:"https://coder.com/favicon.ico",
4553+
Actions:json.RawMessage("{}"),
4554+
})
4555+
4556+
check.Args(u.ID).Asserts(rbac.ResourceInboxNotification.WithOwner(u.ID.String()),policy.ActionRead).Returns(int64(1))
4557+
}))
4558+
4559+
s.Run("InsertInboxNotification",s.Subtest(func(db database.Store,check*expects) {
4560+
u:=dbgen.User(s.T(),db, database.User{})
4561+
4562+
notifID:=uuid.New()
4563+
4564+
targets:= []uuid.UUID{u.ID,notifications.TemplateWorkspaceAutoUpdated}
4565+
4566+
check.Args(database.InsertInboxNotificationParams{
4567+
ID:notifID,
4568+
UserID:u.ID,
4569+
TemplateID:notifications.TemplateWorkspaceAutoUpdated,
4570+
Targets:targets,
4571+
Title:"test title",
4572+
Content:"test content notification",
4573+
Icon:"https://coder.com/favicon.ico",
4574+
Actions:json.RawMessage("{}"),
4575+
}).Asserts(rbac.ResourceInboxNotification.WithOwner(u.ID.String()),policy.ActionCreate)
4576+
}))
4577+
4578+
s.Run("UpdateInboxNotificationReadStatus",s.Subtest(func(db database.Store,check*expects) {
4579+
u:=dbgen.User(s.T(),db, database.User{})
4580+
4581+
notifID:=uuid.New()
4582+
4583+
targets:= []uuid.UUID{u.ID,notifications.TemplateWorkspaceAutoUpdated}
4584+
readAt:=dbtestutil.NowInDefaultTimezone()
4585+
4586+
notif:=dbgen.NotificationInbox(s.T(),db, database.InsertInboxNotificationParams{
4587+
ID:notifID,
4588+
UserID:u.ID,
4589+
TemplateID:notifications.TemplateWorkspaceAutoUpdated,
4590+
Targets:targets,
4591+
Title:"test title",
4592+
Content:"test content notification",
4593+
Icon:"https://coder.com/favicon.ico",
4594+
Actions:json.RawMessage("{}"),
4595+
})
4596+
4597+
notif.ReadAt= sql.NullTime{Time:readAt,Valid:true}
4598+
4599+
check.Args(database.UpdateInboxNotificationReadStatusParams{
4600+
ID:notifID,
4601+
ReadAt: sql.NullTime{Time:readAt,Valid:true},
4602+
}).Asserts(rbac.ResourceInboxNotification.WithID(notifID).WithOwner(u.ID.String()),policy.ActionUpdate)
4603+
}))
44694604
}
44704605

44714606
func (s*MethodTestSuite)TestOAuth2ProviderApps() {

‎coderd/database/dbgen/dbgen.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,22 @@ func OrganizationMember(t testing.TB, db database.Store, orig database.Organizat
450450
returnmem
451451
}
452452

453+
funcNotificationInbox(t testing.TB,db database.Store,orig database.InsertInboxNotificationParams) database.InboxNotification {
454+
notification,err:=db.InsertInboxNotification(genCtx, database.InsertInboxNotificationParams{
455+
ID:takeFirst(orig.ID,uuid.New()),
456+
UserID:takeFirst(orig.UserID,uuid.New()),
457+
TemplateID:takeFirst(orig.TemplateID,uuid.New()),
458+
Targets:takeFirstSlice(orig.Targets, []uuid.UUID{}),
459+
Title:takeFirst(orig.Title,testutil.GetRandomName(t)),
460+
Content:takeFirst(orig.Content,testutil.GetRandomName(t)),
461+
Icon:takeFirst(orig.Icon,""),
462+
Actions:orig.Actions,
463+
CreatedAt:takeFirst(orig.CreatedAt,dbtime.Now()),
464+
})
465+
require.NoError(t,err,"insert notification")
466+
returnnotification
467+
}
468+
453469
funcGroup(t testing.TB,db database.Store,orig database.Group) database.Group {
454470
t.Helper()
455471

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp