diff --git a/models/permission.go b/models/permission.go index d0a8cfa2..5d196d08 100644 --- a/models/permission.go +++ b/models/permission.go @@ -1,11 +1,11 @@ package models import ( - "encoding/json" "fmt" "strings" "time" + "github.com/flanksource/commons/collections" "github.com/flanksource/duty/types" "github.com/google/uuid" "github.com/lib/pq" @@ -35,7 +35,7 @@ type Permission struct { Agents pq.StringArray `json:"agents,omitempty" gorm:"type:[]text"` // List of config/component tags a person is allowed access to when RLS is enabled - Tags types.JSONMap `json:"tags,omitempty"` + Tags types.JSONStringMap `json:"tags,omitempty"` } func (t *Permission) Principal() string { @@ -54,35 +54,28 @@ func (t *Permission) Condition() string { var rule []string if t.ComponentID != nil { - rule = append(rule, fmt.Sprintf("!isString(r.obj) && r.obj.component != undefined && r.obj.component.id == %q", t.ComponentID.String())) + rule = append(rule, fmt.Sprintf("r.obj.component != undefined && r.obj.component.id == %q", t.ComponentID.String())) } if t.ConfigID != nil { - rule = append(rule, fmt.Sprintf("!isString(r.obj) && r.obj.config != undefined && r.obj.config.id == %q", t.ConfigID.String())) + rule = append(rule, fmt.Sprintf("r.obj.config != undefined && r.obj.config.id == %q", t.ConfigID.String())) } if t.CanaryID != nil { - rule = append(rule, fmt.Sprintf("!isString(r.obj) && r.obj.canary != undefined && r.obj.canary.id == %q", t.CanaryID.String())) + rule = append(rule, fmt.Sprintf("r.obj.canary != undefined && r.obj.canary.id == %q", t.CanaryID.String())) } if t.PlaybookID != nil { - rule = append(rule, fmt.Sprintf("!isString(r.obj) && r.obj.playbook != undefined && r.obj.playbook.id == %q", t.PlaybookID.String())) + rule = append(rule, fmt.Sprintf("r.obj.playbook != undefined && r.obj.playbook.id == %q", t.PlaybookID.String())) } - if len(t.Agents) > 0 { + if len(t.Agents) > 0 || len(t.Tags) > 0 { var agents []string for _, agentID := range t.Agents { agents = append(agents, fmt.Sprintf("'%s'", agentID)) } - rule = append(rule, fmt.Sprintf("!isString(r.obj) && r.obj.config != undefined && r.obj.config.agent_id in (%s)", strings.Join(agents, ","))) - rule = append(rule, fmt.Sprintf("!isString(r.obj) && r.obj.component != undefined && r.obj.component.agent_id in (%s)", strings.Join(agents, ","))) - rule = append(rule, fmt.Sprintf("!isString(r.obj) && r.obj.canary != undefined && r.obj.canary.agent_id in (%s)", strings.Join(agents, ","))) - } - - if len(t.Tags) > 0 { - b, _ := json.Marshal(t.Tags) - rule = append(rule, fmt.Sprintf("!isString(r.obj) && r.obj.config != undefined && mapContains(%q, r.obj.config.tags)", string(b))) + rule = append(rule, fmt.Sprintf(`"matchPerm(r.obj, (%s), '%s')"`, strings.Join(agents, ","), collections.SortedMap(t.Tags))) } return strings.Join(rule, " && ") diff --git a/models/permission_test.go b/models/permission_test.go index b31e66d8..6829d0cc 100644 --- a/models/permission_test.go +++ b/models/permission_test.go @@ -3,7 +3,6 @@ package models import ( "testing" - "github.com/flanksource/duty/types" "github.com/google/uuid" "github.com/lib/pq" "github.com/samber/lo" @@ -20,7 +19,7 @@ func TestPermission_Condition(t *testing.T) { perm: Permission{ PlaybookID: lo.ToPtr(uuid.MustParse("33333333-3333-3333-3333-333333333333")), }, - expected: `!isString(r.obj) && r.obj.playbook != undefined && r.obj.playbook.id == "33333333-3333-3333-3333-333333333333"`, + expected: `r.obj.playbook != undefined && r.obj.playbook.id == "33333333-3333-3333-3333-333333333333"`, }, { name: "Multiple fields II", @@ -28,7 +27,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: `!isString(r.obj) && r.obj.config != undefined && r.obj.config.id == "88888888-8888-8888-8888-888888888888" && !isString(r.obj) && r.obj.playbook != undefined && r.obj.playbook.id == "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"`, }, { name: "No fields set", @@ -40,16 +39,16 @@ func TestPermission_Condition(t *testing.T) { perm: Permission{ Agents: pq.StringArray([]string{"aws", "azure"}), }, - expected: "!isString(r.obj) && r.obj.config != undefined && r.obj.config.agent_id in ('aws','azure') && !isString(r.obj) && r.obj.component != undefined && r.obj.component.agent_id in ('aws','azure') && !isString(r.obj) && r.obj.canary != undefined && r.obj.canary.agent_id in ('aws','azure')", + expected: `"matchPerm(r.obj, ('aws','azure'), '')"`, }, { name: "tags", perm: Permission{ - Tags: types.JSONMap{ - "cluster": []string{"aws"}, + Tags: map[string]string{ + "cluster": "aws", }, }, - expected: `!isString(r.obj) && r.obj.config != undefined && mapContains("{\"cluster\":[\"aws\"]}", r.obj.config.tags)`, + expected: `"matchPerm(r.obj, (), 'cluster=aws')"`, }, } diff --git a/schema/permissions.hcl b/schema/permissions.hcl index 6223711d..cd0370f3 100644 --- a/schema/permissions.hcl +++ b/schema/permissions.hcl @@ -99,7 +99,7 @@ table "permissions" { column "tags" { null = true type = jsonb - comment = "a list of tags a user is allowed to access when row-level security is enabled" + comment = "a list of tags user is allowed to access when row-level security is enabled" } primary_key { diff --git a/views/034_rls_enable.sql b/views/034_rls_enable.sql index e0ccfcf0..b1d47023 100644 --- a/views/034_rls_enable.sql +++ b/views/034_rls_enable.sql @@ -112,12 +112,10 @@ ALTER VIEW checks_by_config OWNER TO api_views_owner; ALTER VIEW config_analysis_analyzers OWNER TO api_views_owner; ALTER VIEW config_analysis_by_severity OWNER TO api_views_owner; ALTER VIEW config_analysis_items OWNER TO api_views_owner; -ALTER VIEW config_changes OWNER TO api_views_owner; ALTER VIEW config_changes_by_types OWNER TO api_views_owner; ALTER VIEW config_class_summary OWNER TO api_views_owner; ALTER VIEW config_classes OWNER TO api_views_owner; ALTER VIEW config_detail OWNER TO api_views_owner; -ALTER VIEW config_items OWNER TO api_views_owner; ALTER VIEW config_items_aws OWNER TO api_views_owner; ALTER VIEW config_labels OWNER TO api_views_owner; ALTER VIEW config_names OWNER TO api_views_owner; diff --git a/views/035_rls_disable.sql b/views/035_rls_disable.sql index d242c0ec..69b34627 100644 --- a/views/035_rls_disable.sql +++ b/views/035_rls_disable.sql @@ -34,8 +34,6 @@ ALTER VIEW config_analysis_items OWNER TO CURRENT_USER; ALTER VIEW config_changes_by_types OWNER TO CURRENT_USER; -ALTER VIEW config_changes_items OWNER TO CURRENT_USER; - ALTER VIEW config_class_summary OWNER TO CURRENT_USER; ALTER VIEW config_classes OWNER TO CURRENT_USER;