From 278530ed409f73b7bc55eb88ba24c78c6a6191f3 Mon Sep 17 00:00:00 2001 From: Aditya Thebe Date: Wed, 18 Dec 2024 11:47:18 +0545 Subject: [PATCH] feat: notification as permission subject --- context/context.go | 20 +++++++++++++++++ models/permission.go | 45 ++++++++++++++++++++++----------------- models/permission_test.go | 4 ++-- models/playbooks.go | 8 +++---- postq/sync_consumer.go | 2 +- schema/permissions.hcl | 12 ++++++++++- 6 files changed, 63 insertions(+), 28 deletions(-) diff --git a/context/context.go b/context/context.go index 4e6f49f6..821ed3f2 100644 --- a/context/context.go +++ b/context/context.go @@ -181,6 +181,26 @@ func (k Context) WithUser(user *models.Person) Context { return k.WithValue("user", user) } +// Rbac subject +func (k Context) WithSubject(subject string) Context { + k.GetSpan().SetAttributes(attribute.String("rbac-subject", subject)) + return k.WithValue("rbac-subject", subject) +} + +func (k Context) Subject() string { + subject := k.Value("rbac-subject") + if subject != "" { + return subject.(string) + } + + user := k.User() + if user != nil { + return user.ID.String() + } + + return "" +} + func (k Context) WithoutName() Context { k.Logger = logger.GetLogger() return k diff --git a/models/permission.go b/models/permission.go index 0bc4ffa9..91fe5c4d 100644 --- a/models/permission.go +++ b/models/permission.go @@ -9,22 +9,23 @@ import ( ) type Permission struct { - ID uuid.UUID `json:"id" gorm:"default:generate_ulid()"` - Action string `json:"action"` - ConnectionID *uuid.UUID `json:"connection_id,omitempty"` - CanaryID *uuid.UUID `json:"canary_id,omitempty"` - ComponentID *uuid.UUID `json:"component_id,omitempty"` - ConfigID *uuid.UUID `json:"config_id,omitempty"` - CreatedAt time.Time `json:"created_at"` - CreatedBy uuid.UUID `json:"created_by"` - Deny bool `json:"deny"` - Description string `json:"description"` - PersonID *uuid.UUID `json:"person_id,omitempty"` - PlaybookID *uuid.UUID `json:"playbook_id,omitempty"` - TeamID *uuid.UUID `json:"team_id,omitempty"` - Until *time.Time `json:"until"` - UpdatedAt *time.Time `json:"updated_at"` - UpdatedBy *uuid.UUID `json:"updated_by"` + ID uuid.UUID `json:"id" gorm:"default:generate_ulid()"` + Action string `json:"action"` + ConnectionID *uuid.UUID `json:"connection_id,omitempty"` + CanaryID *uuid.UUID `json:"canary_id,omitempty"` + ComponentID *uuid.UUID `json:"component_id,omitempty"` + ConfigID *uuid.UUID `json:"config_id,omitempty"` + CreatedAt time.Time `json:"created_at"` + CreatedBy uuid.UUID `json:"created_by"` + Deny bool `json:"deny"` + Description string `json:"description"` + PersonID *uuid.UUID `json:"person_id,omitempty"` + PlaybookID *uuid.UUID `json:"playbook_id,omitempty"` + TeamID *uuid.UUID `json:"team_id,omitempty"` + NotificationID *uuid.UUID `json:"notification_id,omitempty"` + Until *time.Time `json:"until"` + UpdatedAt *time.Time `json:"updated_at"` + UpdatedBy *uuid.UUID `json:"updated_by"` } func (t *Permission) Principal() string { @@ -36,6 +37,10 @@ func (t *Permission) Principal() string { return t.TeamID.String() } + if t.NotificationID != nil { + return t.NotificationID.String() + } + return "" } @@ -43,19 +48,19 @@ func (t *Permission) Condition() string { var rule []string if t.ComponentID != nil { - rule = append(rule, fmt.Sprintf("r.obj.component != undefined && r.obj.component.id == %q", t.ComponentID.String())) + rule = append(rule, fmt.Sprintf("r.obj.component.id == %q", t.ComponentID.String())) } if t.ConfigID != nil { - rule = append(rule, fmt.Sprintf("r.obj.config != undefined && r.obj.config.id == %q", t.ConfigID.String())) + rule = append(rule, fmt.Sprintf("r.obj.config.id == %q", t.ConfigID.String())) } if t.CanaryID != nil { - rule = append(rule, fmt.Sprintf("r.obj.canary != undefined && r.obj.canary.id == %q", t.CanaryID.String())) + rule = append(rule, fmt.Sprintf("r.obj.canary.id == %q", t.CanaryID.String())) } if t.PlaybookID != nil { - rule = append(rule, fmt.Sprintf("r.obj.playbook != undefined && r.obj.playbook.id == %q", t.PlaybookID.String())) + rule = append(rule, fmt.Sprintf("r.obj.playbook.id == %q", t.PlaybookID.String())) } return strings.Join(rule, " && ") diff --git a/models/permission_test.go b/models/permission_test.go index 1ddd9525..8ce1cb75 100644 --- a/models/permission_test.go +++ b/models/permission_test.go @@ -18,7 +18,7 @@ func TestPermission_Condition(t *testing.T) { perm: Permission{ PlaybookID: lo.ToPtr(uuid.MustParse("33333333-3333-3333-3333-333333333333")), }, - expected: `r.obj.playbook != undefined && r.obj.playbook.id == "33333333-3333-3333-3333-333333333333"`, + expected: `r.obj.playbook.id == "33333333-3333-3333-3333-333333333333"`, }, { name: "Multiple fields II", @@ -26,7 +26,7 @@ func TestPermission_Condition(t *testing.T) { ConfigID: lo.ToPtr(uuid.MustParse("88888888-8888-8888-8888-888888888888")), PlaybookID: lo.ToPtr(uuid.MustParse("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa")), }, - expected: `r.obj.config != undefined && r.obj.config.id == "88888888-8888-8888-8888-888888888888" && r.obj.playbook != undefined && r.obj.playbook.id == "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"`, + expected: `r.obj.config.id == "88888888-8888-8888-8888-888888888888" && r.obj.playbook.id == "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"`, }, { name: "No fields set", diff --git a/models/playbooks.go b/models/playbooks.go index 82c82087..b484c002 100644 --- a/models/playbooks.go +++ b/models/playbooks.go @@ -348,14 +348,14 @@ func (run *PlaybookRun) GetRBACAttributes(db *gorm.DB) (map[string]any, error) { if err := db.First(&playbook, run.PlaybookID).Error; err != nil { return nil, err } - output["playbook"] = playbook + output["playbook"] = playbook.AsMap() if run.ComponentID != nil { var component Component if err := db.First(&component, run.ComponentID).Error; err != nil { return nil, err } - output["component"] = component + output["component"] = component.AsMap() } if run.CheckID != nil { @@ -363,7 +363,7 @@ func (run *PlaybookRun) GetRBACAttributes(db *gorm.DB) (map[string]any, error) { if err := db.First(&check, run.CheckID).Error; err != nil { return nil, err } - output["check"] = check + output["check"] = check.AsMap() } if run.ConfigID != nil { @@ -371,7 +371,7 @@ func (run *PlaybookRun) GetRBACAttributes(db *gorm.DB) (map[string]any, error) { if err := db.First(&config, run.ConfigID).Error; err != nil { return nil, err } - output["config"] = config + output["config"] = config.AsMap() } return output, nil diff --git a/postq/sync_consumer.go b/postq/sync_consumer.go index a74ee8e5..59a887f4 100644 --- a/postq/sync_consumer.go +++ b/postq/sync_consumer.go @@ -55,7 +55,7 @@ func (t *SyncEventConsumer) Handle(ctx context.Context) (int, error) { } event.Attempts++ - // event.SetError(err.Error()) + event.SetError(err.Error()) const query = `UPDATE event_queue SET error=$1, attempts=$2, last_attempt=NOW() WHERE id=$3` if _, err := ctx.Pool().Exec(ctx, query, event.Error, event.Attempts, event.ID); err != nil { ctx.Debugf("error saving event attempt updates to event_queue: %v\n", err) diff --git a/schema/permissions.hcl b/schema/permissions.hcl index 2e92f88d..535fb50c 100644 --- a/schema/permissions.hcl +++ b/schema/permissions.hcl @@ -70,6 +70,11 @@ table "permissions" { type = uuid } + column "notification_id" { + null = true + type = uuid + } + column "updated_by" { null = true type = uuid @@ -130,7 +135,12 @@ table "permissions" { on_update = NO_ACTION on_delete = NO_ACTION } - + foreign_key "permissions_notification_fkey" { + columns = [column.notification_id] + ref_columns = [table.notifications.column.id] + on_update = NO_ACTION + on_delete = NO_ACTION + } foreign_key "permissions_person_fkey" { columns = [column.person_id] ref_columns = [table.people.column.id]