fix rules engine atom token

Signed-off-by: Arvindh <arvindh91@gmail.com>
This commit is contained in:
Arvindh
2026-06-26 17:14:41 +05:30
committed by dusan
parent 8408fac353
commit a6264fb5ae
4 changed files with 67 additions and 11 deletions
+8
View File
@@ -20,6 +20,14 @@ var magistralaActionDescriptions = map[string]string{
}
var magistralaActionApplicability = []CapabilityApplicabilitySpec{
{ActionName: atomActionWrite, ObjectKind: atomObjectKindTenant},
{ActionName: atomActionRead, ObjectKind: atomObjectKindGroup},
{ActionName: atomActionWrite, ObjectKind: atomObjectKindGroup},
{ActionName: atomActionDelete, ObjectKind: atomObjectKindGroup},
{ActionName: atomActionManage, ObjectKind: atomObjectKindGroup},
{ActionName: atomActionList, ObjectKind: atomObjectKindGroup},
{ActionName: atomActionRead, ObjectKind: atomObjectKindResource, ObjectType: "resource:channel"},
{ActionName: atomActionWrite, ObjectKind: atomObjectKindResource, ObjectType: "resource:channel"},
{ActionName: atomActionDelete, ObjectKind: atomObjectKindResource, ObjectType: "resource:channel"},
+17 -10
View File
@@ -111,13 +111,19 @@ func TestBootstrapMagistralaActionsCreatesMissingActionsAndApplicability(t *test
if len(applicability) != len(magistralaActionApplicability) {
t.Fatalf("unexpected applicability count: got %d want %d", len(applicability), len(magistralaActionApplicability))
}
assertApplicability(t, applicability, "publish-id", "resource:channel")
assertApplicability(t, applicability, "execute-id", "resource:rule")
assertApplicability(t, applicability, "list-id", "resource:rule")
assertApplicability(t, applicability, "execute-id", "resource:report")
assertApplicability(t, applicability, "list-id", "resource:report")
assertApplicability(t, applicability, "manage-id", "resource:alarm")
assertApplicability(t, applicability, "list-id", "resource:alarm")
assertApplicability(t, applicability, "write-id", atomObjectKindTenant, "")
assertApplicability(t, applicability, "read-id", atomObjectKindGroup, "")
assertApplicability(t, applicability, "write-id", atomObjectKindGroup, "")
assertApplicability(t, applicability, "delete-id", atomObjectKindGroup, "")
assertApplicability(t, applicability, "manage-id", atomObjectKindGroup, "")
assertApplicability(t, applicability, "list-id", atomObjectKindGroup, "")
assertApplicability(t, applicability, "publish-id", atomObjectKindResource, "resource:channel")
assertApplicability(t, applicability, "execute-id", atomObjectKindResource, "resource:rule")
assertApplicability(t, applicability, "list-id", atomObjectKindResource, "resource:rule")
assertApplicability(t, applicability, "execute-id", atomObjectKindResource, "resource:report")
assertApplicability(t, applicability, "list-id", atomObjectKindResource, "resource:report")
assertApplicability(t, applicability, "manage-id", atomObjectKindResource, "resource:alarm")
assertApplicability(t, applicability, "list-id", atomObjectKindResource, "resource:alarm")
if len(assignmentRules) != len(magistralaActionAssignmentRules) {
t.Fatalf("unexpected assignment guardrail count: got %d want %d", len(assignmentRules), len(magistralaActionAssignmentRules))
}
@@ -125,14 +131,15 @@ func TestBootstrapMagistralaActionsCreatesMissingActionsAndApplicability(t *test
assertAssignmentRule(t, assignmentRules, atomKindDevice, atomActionSubscribe, atomObjectKindResource, "resource:channel", "allow")
}
func assertApplicability(t *testing.T, entries []map[string]any, actionID, objectType string) {
func assertApplicability(t *testing.T, entries []map[string]any, actionID, objectKind, objectType string) {
t.Helper()
for _, entry := range entries {
if entry["actionId"] == actionID && entry["objectKind"] == atomObjectKindResource && entry["objectType"] == objectType {
entryObjectType, _ := entry["objectType"].(string)
if entry["actionId"] == actionID && entry["objectKind"] == objectKind && entryObjectType == objectType {
return
}
}
t.Fatalf("missing applicability action=%s object_type=%s", actionID, objectType)
t.Fatalf("missing applicability action=%s object=%s:%s", actionID, objectKind, objectType)
}
func assertAssignmentRule(t *testing.T, entries []map[string]any, entityKind, actionName, objectKind, objectType, decision string) {
+4 -1
View File
@@ -208,8 +208,11 @@ func policyGrantObjectKind(pr policies.Policy) string {
if policyGrantScopeMode(pr) != atomScopeModeObject {
return ""
}
if pr.ObjectType == policies.ClientType {
switch pr.ObjectType {
case policies.ClientType:
return atomObjectKindEntity
case policies.GroupType:
return atomObjectKindGroup
}
return atomObjectKindResource
}
+38
View File
@@ -135,6 +135,44 @@ func TestPolicyServiceAddPolicyCreatesInternalCapabilityPolicy(t *testing.T) {
}
}
func TestPolicyServiceAddPolicyCreatesGroupCapabilityPolicy(t *testing.T) {
client := &fakePolicyClient{capID: "cap-read"}
svc := NewPolicyService(client)
err := svc.AddPolicy(context.Background(), policies.Policy{
Domain: testDomainID,
Subject: testDomainID + "_user-1",
SubjectType: policies.UserType,
Object: "group-1",
ObjectType: policies.GroupType,
Permission: policies.ViewPermission,
})
if err != nil {
t.Fatalf("add policy failed: %v", err)
}
if len(client.blocks) != 1 || len(client.created) != 1 {
t.Fatalf("expected one permission block and direct policy, got %d/%d", len(client.blocks), len(client.created))
}
block := client.blocks[0]
if block.TenantID != testDomainID ||
block.ScopeMode != atomScopeModeObject ||
block.ObjectKind != atomObjectKindGroup ||
block.ObjectType != "" ||
block.ObjectID != "group-1" ||
block.Effect != "allow" ||
len(block.ActionIDs) != 1 ||
block.ActionIDs[0] != "cap-read" {
t.Fatalf("unexpected permission block: %+v", block)
}
created := client.created[0]
if created.TenantID != testDomainID ||
created.SubjectKind != atomObjectKindEntity ||
created.SubjectID != "user-1" ||
created.PermissionBlockID != "block-1" {
t.Fatalf("unexpected direct policy: %+v", created)
}
}
func TestPolicyServiceDeletePolicyFilterRemovesMatchingCapabilityPolicy(t *testing.T) {
client := &fakePolicyClient{
capID: "cap-subscribe",