mirror of
https://github.com/coder/coder.git
synced 2025-07-15 22:20:27 +00:00
chore: create ResourceNotificationMessage and AsNotifier (#15301)
Closes https://github.com/coder/coder/issues/15213 This PR enables sending notifications without requiring the auth system context, instead using a new auth notifier context.
This commit is contained in:
@ -264,6 +264,23 @@ var (
|
||||
Scope: rbac.ScopeAll,
|
||||
}.WithCachedASTValue()
|
||||
|
||||
subjectNotifier = rbac.Subject{
|
||||
FriendlyName: "Notifier",
|
||||
ID: uuid.Nil.String(),
|
||||
Roles: rbac.Roles([]rbac.Role{
|
||||
{
|
||||
Identifier: rbac.RoleIdentifier{Name: "notifier"},
|
||||
DisplayName: "Notifier",
|
||||
Site: rbac.Permissions(map[string][]policy.Action{
|
||||
rbac.ResourceNotificationMessage.Type: {policy.ActionCreate, policy.ActionRead, policy.ActionUpdate, policy.ActionDelete},
|
||||
}),
|
||||
Org: map[string][]rbac.Permission{},
|
||||
User: []rbac.Permission{},
|
||||
},
|
||||
}),
|
||||
Scope: rbac.ScopeAll,
|
||||
}.WithCachedASTValue()
|
||||
|
||||
subjectSystemRestricted = rbac.Subject{
|
||||
FriendlyName: "System",
|
||||
ID: uuid.Nil.String(),
|
||||
@ -287,6 +304,7 @@ var (
|
||||
rbac.ResourceWorkspace.Type: {policy.ActionUpdate, policy.ActionDelete, policy.ActionWorkspaceStart, policy.ActionWorkspaceStop, policy.ActionSSH},
|
||||
rbac.ResourceWorkspaceProxy.Type: {policy.ActionCreate, policy.ActionUpdate, policy.ActionDelete},
|
||||
rbac.ResourceDeploymentConfig.Type: {policy.ActionCreate, policy.ActionUpdate, policy.ActionDelete},
|
||||
rbac.ResourceNotificationMessage.Type: {policy.ActionCreate, policy.ActionRead, policy.ActionUpdate, policy.ActionDelete},
|
||||
rbac.ResourceNotificationPreference.Type: {policy.ActionCreate, policy.ActionUpdate, policy.ActionDelete},
|
||||
rbac.ResourceNotificationTemplate.Type: {policy.ActionCreate, policy.ActionUpdate, policy.ActionDelete},
|
||||
rbac.ResourceCryptoKey.Type: {policy.ActionCreate, policy.ActionUpdate, policy.ActionDelete},
|
||||
@ -327,6 +345,12 @@ func AsKeyReader(ctx context.Context) context.Context {
|
||||
return context.WithValue(ctx, authContextKey{}, subjectCryptoKeyReader)
|
||||
}
|
||||
|
||||
// AsNotifier returns a context with an actor that has permissions required for
|
||||
// creating/reading/updating/deleting notifications.
|
||||
func AsNotifier(ctx context.Context) context.Context {
|
||||
return context.WithValue(ctx, authContextKey{}, subjectNotifier)
|
||||
}
|
||||
|
||||
// AsSystemRestricted returns a context with an actor that has permissions
|
||||
// required for various system operations (login, logout, metrics cache).
|
||||
func AsSystemRestricted(ctx context.Context) context.Context {
|
||||
@ -950,7 +974,7 @@ func (q *querier) AcquireLock(ctx context.Context, id int64) error {
|
||||
}
|
||||
|
||||
func (q *querier) AcquireNotificationMessages(ctx context.Context, arg database.AcquireNotificationMessagesParams) ([]database.AcquireNotificationMessagesRow, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceSystem); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceNotificationMessage); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.AcquireNotificationMessages(ctx, arg)
|
||||
@ -1001,14 +1025,14 @@ func (q *querier) BatchUpdateWorkspaceLastUsedAt(ctx context.Context, arg databa
|
||||
}
|
||||
|
||||
func (q *querier) BulkMarkNotificationMessagesFailed(ctx context.Context, arg database.BulkMarkNotificationMessagesFailedParams) (int64, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceSystem); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceNotificationMessage); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return q.db.BulkMarkNotificationMessagesFailed(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) BulkMarkNotificationMessagesSent(ctx context.Context, arg database.BulkMarkNotificationMessagesSentParams) (int64, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceSystem); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceNotificationMessage); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return q.db.BulkMarkNotificationMessagesSent(ctx, arg)
|
||||
@ -1185,7 +1209,7 @@ func (q *querier) DeleteOAuth2ProviderAppTokensByAppAndUserID(ctx context.Contex
|
||||
}
|
||||
|
||||
func (q *querier) DeleteOldNotificationMessages(ctx context.Context) error {
|
||||
if err := q.authorizeContext(ctx, policy.ActionDelete, rbac.ResourceSystem); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionDelete, rbac.ResourceNotificationMessage); err != nil {
|
||||
return err
|
||||
}
|
||||
return q.db.DeleteOldNotificationMessages(ctx)
|
||||
@ -1307,7 +1331,7 @@ func (q *querier) DeleteWorkspaceAgentPortSharesByTemplate(ctx context.Context,
|
||||
}
|
||||
|
||||
func (q *querier) EnqueueNotificationMessage(ctx context.Context, arg database.EnqueueNotificationMessageParams) error {
|
||||
if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceSystem); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceNotificationMessage); err != nil {
|
||||
return err
|
||||
}
|
||||
return q.db.EnqueueNotificationMessage(ctx, arg)
|
||||
@ -1321,7 +1345,7 @@ func (q *querier) FavoriteWorkspace(ctx context.Context, id uuid.UUID) error {
|
||||
}
|
||||
|
||||
func (q *querier) FetchNewMessageMetadata(ctx context.Context, arg database.FetchNewMessageMetadataParams) (database.FetchNewMessageMetadataRow, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceNotificationMessage); err != nil {
|
||||
return database.FetchNewMessageMetadataRow{}, err
|
||||
}
|
||||
return q.db.FetchNewMessageMetadata(ctx, arg)
|
||||
@ -1686,7 +1710,7 @@ func (q *querier) GetLogoURL(ctx context.Context) (string, error) {
|
||||
}
|
||||
|
||||
func (q *querier) GetNotificationMessagesByStatus(ctx context.Context, arg database.GetNotificationMessagesByStatusParams) ([]database.NotificationMessage, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceNotificationMessage); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetNotificationMessagesByStatus(ctx, arg)
|
||||
|
@ -2888,40 +2888,33 @@ func (s *MethodTestSuite) TestSystemFunctions() {
|
||||
|
||||
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)
|
||||
s.Run("AcquireNotificationMessages", s.Subtest(func(_ database.Store, check *expects) {
|
||||
check.Args(database.AcquireNotificationMessagesParams{}).Asserts(rbac.ResourceNotificationMessage, policy.ActionUpdate)
|
||||
}))
|
||||
s.Run("BulkMarkNotificationMessagesFailed", s.Subtest(func(db database.Store, check *expects) {
|
||||
// TODO: update this test once we have a specific role for notifications
|
||||
check.Args(database.BulkMarkNotificationMessagesFailedParams{}).Asserts(rbac.ResourceSystem, policy.ActionUpdate)
|
||||
s.Run("BulkMarkNotificationMessagesFailed", s.Subtest(func(_ database.Store, check *expects) {
|
||||
check.Args(database.BulkMarkNotificationMessagesFailedParams{}).Asserts(rbac.ResourceNotificationMessage, policy.ActionUpdate)
|
||||
}))
|
||||
s.Run("BulkMarkNotificationMessagesSent", s.Subtest(func(db database.Store, check *expects) {
|
||||
// TODO: update this test once we have a specific role for notifications
|
||||
check.Args(database.BulkMarkNotificationMessagesSentParams{}).Asserts(rbac.ResourceSystem, policy.ActionUpdate)
|
||||
s.Run("BulkMarkNotificationMessagesSent", s.Subtest(func(_ database.Store, check *expects) {
|
||||
check.Args(database.BulkMarkNotificationMessagesSentParams{}).Asserts(rbac.ResourceNotificationMessage, policy.ActionUpdate)
|
||||
}))
|
||||
s.Run("DeleteOldNotificationMessages", s.Subtest(func(db database.Store, check *expects) {
|
||||
// TODO: update this test once we have a specific role for notifications
|
||||
check.Args().Asserts(rbac.ResourceSystem, policy.ActionDelete)
|
||||
s.Run("DeleteOldNotificationMessages", s.Subtest(func(_ database.Store, check *expects) {
|
||||
check.Args().Asserts(rbac.ResourceNotificationMessage, policy.ActionDelete)
|
||||
}))
|
||||
s.Run("EnqueueNotificationMessage", s.Subtest(func(db database.Store, check *expects) {
|
||||
// TODO: update this test once we have a specific role for notifications
|
||||
s.Run("EnqueueNotificationMessage", s.Subtest(func(_ database.Store, check *expects) {
|
||||
check.Args(database.EnqueueNotificationMessageParams{
|
||||
Method: database.NotificationMethodWebhook,
|
||||
Payload: []byte("{}"),
|
||||
}).Asserts(rbac.ResourceSystem, policy.ActionCreate)
|
||||
}).Asserts(rbac.ResourceNotificationMessage, policy.ActionCreate)
|
||||
}))
|
||||
s.Run("FetchNewMessageMetadata", s.Subtest(func(db database.Store, check *expects) {
|
||||
// TODO: update this test once we have a specific role for notifications
|
||||
u := dbgen.User(s.T(), db, database.User{})
|
||||
check.Args(database.FetchNewMessageMetadataParams{UserID: u.ID}).Asserts(rbac.ResourceSystem, policy.ActionRead)
|
||||
check.Args(database.FetchNewMessageMetadataParams{UserID: u.ID}).Asserts(rbac.ResourceNotificationMessage, policy.ActionRead)
|
||||
}))
|
||||
s.Run("GetNotificationMessagesByStatus", s.Subtest(func(db database.Store, check *expects) {
|
||||
// TODO: update this test once we have a specific role for notifications
|
||||
s.Run("GetNotificationMessagesByStatus", s.Subtest(func(_ database.Store, check *expects) {
|
||||
check.Args(database.GetNotificationMessagesByStatusParams{
|
||||
Status: database.NotificationMessageStatusLeased,
|
||||
Limit: 10,
|
||||
}).Asserts(rbac.ResourceSystem, policy.ActionRead)
|
||||
}).Asserts(rbac.ResourceNotificationMessage, policy.ActionRead)
|
||||
}))
|
||||
|
||||
// Notification templates
|
||||
|
Reference in New Issue
Block a user