mirror of
https://github.com/coder/coder.git
synced 2025-07-09 11:45:56 +00:00
feat: add notification preferences database & audit support (#14100)
This commit is contained in:
@ -1474,6 +1474,23 @@ func (q *querier) GetNotificationMessagesByStatus(ctx context.Context, arg datab
|
||||
return q.db.GetNotificationMessagesByStatus(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) GetNotificationTemplateByID(ctx context.Context, id uuid.UUID) (database.NotificationTemplate, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceNotificationTemplate); err != nil {
|
||||
return database.NotificationTemplate{}, err
|
||||
}
|
||||
return q.db.GetNotificationTemplateByID(ctx, id)
|
||||
}
|
||||
|
||||
func (q *querier) GetNotificationTemplatesByKind(ctx context.Context, kind database.NotificationTemplateKind) ([]database.NotificationTemplate, error) {
|
||||
// TODO: restrict 'system' kind to admins only?
|
||||
// All notification templates share the same rbac.Object, so there is no need
|
||||
// to authorize them individually. If this passes, all notification templates can be read.
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceNotificationTemplate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetNotificationTemplatesByKind(ctx, kind)
|
||||
}
|
||||
|
||||
func (q *querier) GetNotificationsSettings(ctx context.Context) (string, error) {
|
||||
// No authz checks
|
||||
return q.db.GetNotificationsSettings(ctx)
|
||||
@ -2085,6 +2102,13 @@ func (q *querier) GetUserLinksByUserID(ctx context.Context, userID uuid.UUID) ([
|
||||
return q.db.GetUserLinksByUserID(ctx, userID)
|
||||
}
|
||||
|
||||
func (q *querier) GetUserNotificationPreferences(ctx context.Context, userID uuid.UUID) ([]database.NotificationPreference, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceNotificationPreference.WithOwner(userID.String())); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetUserNotificationPreferences(ctx, userID)
|
||||
}
|
||||
|
||||
func (q *querier) GetUserWorkspaceBuildParameters(ctx context.Context, params database.GetUserWorkspaceBuildParametersParams) ([]database.GetUserWorkspaceBuildParametersRow, error) {
|
||||
u, err := q.db.GetUserByID(ctx, params.OwnerID)
|
||||
if err != nil {
|
||||
@ -3011,6 +3035,13 @@ func (q *querier) UpdateMemberRoles(ctx context.Context, arg database.UpdateMemb
|
||||
return q.db.UpdateMemberRoles(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) UpdateNotificationTemplateMethodByID(ctx context.Context, arg database.UpdateNotificationTemplateMethodByIDParams) (database.NotificationTemplate, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceNotificationTemplate); err != nil {
|
||||
return database.NotificationTemplate{}, err
|
||||
}
|
||||
return q.db.UpdateNotificationTemplateMethodByID(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) UpdateOAuth2ProviderAppByID(ctx context.Context, arg database.UpdateOAuth2ProviderAppByIDParams) (database.OAuth2ProviderApp, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceOauth2App); err != nil {
|
||||
return database.OAuth2ProviderApp{}, err
|
||||
@ -3326,6 +3357,13 @@ func (q *querier) UpdateUserLoginType(ctx context.Context, arg database.UpdateUs
|
||||
return q.db.UpdateUserLoginType(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) UpdateUserNotificationPreferences(ctx context.Context, arg database.UpdateUserNotificationPreferencesParams) (int64, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceNotificationPreference.WithOwner(arg.UserID.String())); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
return q.db.UpdateUserNotificationPreferences(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) UpdateUserProfile(ctx context.Context, arg database.UpdateUserProfileParams) (database.User, error) {
|
||||
u, err := q.db.GetUserByID(ctx, arg.ID)
|
||||
if err != nil {
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
"cdr.dev/slog"
|
||||
|
||||
"github.com/coder/coder/v2/coderd/database/db2sdk"
|
||||
"github.com/coder/coder/v2/coderd/notifications"
|
||||
"github.com/coder/coder/v2/coderd/rbac/policy"
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
|
||||
@ -2561,6 +2562,10 @@ func (s *MethodTestSuite) TestSystemFunctions() {
|
||||
AgentID: uuid.New(),
|
||||
}).Asserts(tpl, policy.ActionCreate)
|
||||
}))
|
||||
}
|
||||
|
||||
func (s *MethodTestSuite) TestNotifications() {
|
||||
// System functions
|
||||
s.Run("AcquireNotificationMessages", s.Subtest(func(db database.Store, check *expects) {
|
||||
// TODO: update this test once we have a specific role for notifications
|
||||
check.Args(database.AcquireNotificationMessagesParams{}).Asserts(rbac.ResourceSystem, policy.ActionUpdate)
|
||||
@ -2596,6 +2601,40 @@ func (s *MethodTestSuite) TestSystemFunctions() {
|
||||
Limit: 10,
|
||||
}).Asserts(rbac.ResourceSystem, policy.ActionRead)
|
||||
}))
|
||||
|
||||
// Notification templates
|
||||
s.Run("GetNotificationTemplateByID", s.Subtest(func(db database.Store, check *expects) {
|
||||
user := dbgen.User(s.T(), db, database.User{})
|
||||
check.Args(user.ID).Asserts(rbac.ResourceNotificationTemplate, policy.ActionRead).
|
||||
Errors(dbmem.ErrUnimplemented)
|
||||
}))
|
||||
s.Run("GetNotificationTemplatesByKind", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args(database.NotificationTemplateKindSystem).
|
||||
Asserts(rbac.ResourceNotificationTemplate, policy.ActionRead).
|
||||
Errors(dbmem.ErrUnimplemented)
|
||||
}))
|
||||
s.Run("UpdateNotificationTemplateMethodByID", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args(database.UpdateNotificationTemplateMethodByIDParams{
|
||||
Method: database.NullNotificationMethod{NotificationMethod: database.NotificationMethodWebhook, Valid: true},
|
||||
ID: notifications.TemplateWorkspaceDormant,
|
||||
}).Asserts(rbac.ResourceNotificationTemplate, policy.ActionUpdate).
|
||||
Errors(dbmem.ErrUnimplemented)
|
||||
}))
|
||||
|
||||
// Notification preferences
|
||||
s.Run("GetUserNotificationPreferences", s.Subtest(func(db database.Store, check *expects) {
|
||||
user := dbgen.User(s.T(), db, database.User{})
|
||||
check.Args(user.ID).
|
||||
Asserts(rbac.ResourceNotificationPreference.WithOwner(user.ID.String()), policy.ActionRead)
|
||||
}))
|
||||
s.Run("UpdateUserNotificationPreferences", s.Subtest(func(db database.Store, check *expects) {
|
||||
user := dbgen.User(s.T(), db, database.User{})
|
||||
check.Args(database.UpdateUserNotificationPreferencesParams{
|
||||
UserID: user.ID,
|
||||
NotificationTemplateIds: []uuid.UUID{notifications.TemplateWorkspaceAutoUpdated, notifications.TemplateWorkspaceDeleted},
|
||||
Disableds: []bool{true, false},
|
||||
}).Asserts(rbac.ResourceNotificationPreference.WithOwner(user.ID.String()), policy.ActionUpdate)
|
||||
}))
|
||||
}
|
||||
|
||||
func (s *MethodTestSuite) TestOAuth2ProviderApps() {
|
||||
|
Reference in New Issue
Block a user