Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refact: combine schema actions #6406

Merged
merged 10 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix casbin paths and rename to CasbinSchema
  • Loading branch information
moogacs committed Nov 21, 2024
commit c2d54e8439f53866a23b7e0ae9d93180c6316148
18 changes: 3 additions & 15 deletions usecases/auth/authorization/conv/casbin_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,28 70,16 @@ func CasbinRoles(role string) string {
return fmt.Sprintf("meta/roles/%s", role)
}

func CasbinCollections(collection string) string {
if collection == "" {
collection = "*"
}
collection = strings.ReplaceAll(collection, "*", ".*")
return fmt.Sprintf("meta/collections/%s/shards/.*/*", collection)
}

func CasbinShards(collection, shard string) string {
func CasbinSchema(collection, shard string) string {
if collection == "" {
collection = "*"
}
if shard == "" {
shard = "*"
}
collection = strings.ReplaceAll(collection, "*", ".*")
if shard == "*" {
return fmt.Sprintf("meta/collections/%s/*", collection)
}

shard = strings.ReplaceAll(shard, "*", ".*")
return fmt.Sprintf("meta/collections/%s/shards/%s/*", collection, shard)
return fmt.Sprintf("meta/collections/%s/shards/%s", collection, shard)
}

func CasbinObjects(collection, shard, object string) string {
Expand Down Expand Up @@ -153,7 141,7 @@ func policy(permission *models.Permission) (*authorization.Policy, error) {
if permission.Tenant != nil {
tenant = *permission.Tenant
}
resource = CasbinShards(collection, tenant)
resource = CasbinSchema(collection, tenant)
case authorization.ObjectsCollectionsDomain:
collection := "*"
object := "*"
Expand Down
36 changes: 18 additions & 18 deletions usecases/auth/authorization/conv/casbin_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 139,7 @@ func Test_policy(t *testing.T) {
name: "all collections",
permission: &models.Permission{},
policy: &authorization.Policy{
Resource: CasbinCollections("*"),
Resource: CasbinSchema("*", ""),
Domain: authorization.SchemaDomain,
},
tests: collectionsTests,
Expand All @@ -150,7 150,7 @@ func Test_policy(t *testing.T) {
Collection: foo,
},
policy: &authorization.Policy{
Resource: CasbinCollections("foo"),
Resource: CasbinSchema("foo", ""),
Domain: authorization.SchemaDomain,
},
tests: collectionsTests,
Expand All @@ -159,7 159,7 @@ func Test_policy(t *testing.T) {
name: "all tenants in all collections",
permission: &models.Permission{},
policy: &authorization.Policy{
Resource: CasbinShards("*", "*"),
Resource: CasbinSchema("*", "*"),
Domain: authorization.SchemaDomain,
},
tests: tenantsTests,
Expand All @@ -170,7 170,7 @@ func Test_policy(t *testing.T) {
Collection: foo,
},
policy: &authorization.Policy{
Resource: CasbinShards("foo", "*"),
Resource: CasbinSchema("foo", "*"),
Domain: authorization.SchemaDomain,
},
tests: tenantsTests,
Expand All @@ -181,7 181,7 @@ func Test_policy(t *testing.T) {
Tenant: bar,
},
policy: &authorization.Policy{
Resource: CasbinShards("*", "bar"),
Resource: CasbinSchema("*", "bar"),
Domain: authorization.SchemaDomain,
},
tests: tenantsTests,
Expand All @@ -193,7 193,7 @@ func Test_policy(t *testing.T) {
Tenant: bar,
},
policy: &authorization.Policy{
Resource: CasbinShards("foo", "bar"),
Resource: CasbinSchema("foo", "bar"),
Domain: authorization.SchemaDomain,
},
tests: tenantsTests,
Expand Down Expand Up @@ -610,14 610,14 @@ func Test_pCollections(t *testing.T) {
collection string
expected string
}{
{collection: "", expected: "meta/collections/.*/shards/*"},
{collection: "*", expected: "meta/collections/.*/shards/*"},
{collection: "foo", expected: "meta/collections/foo/shards/*"},
{collection: "", expected: "meta/collections/.*/shards/.*"},
{collection: "*", expected: "meta/collections/.*/shards/.*"},
{collection: "foo", expected: "meta/collections/foo/shards/.*"},
}
for _, tt := range tests {
name := fmt.Sprintf("collection: %s", tt.collection)
t.Run(name, func(t *testing.T) {
p := CasbinCollections(tt.collection)
p := CasbinSchema(tt.collection, "")
require.Equal(t, tt.expected, p)
})
}
Expand All @@ -629,18 629,18 @@ func Test_CasbinShards(t *testing.T) {
shard string
expected string
}{
{collection: "", shard: "", expected: "meta/collections/.*/shards/.*/*"},
{collection: "*", shard: "*", expected: "meta/collections/.*/shards/.*/*"},
{collection: "foo", shard: "", expected: "meta/collections/foo/shards/.*/*"},
{collection: "foo", shard: "*", expected: "meta/collections/foo/shards/.*/*"},
{collection: "", shard: "bar", expected: "meta/collections/.*/shards/bar/*"},
{collection: "*", shard: "bar", expected: "meta/collections/.*/shards/bar/*"},
{collection: "foo", shard: "bar", expected: "meta/collections/foo/shards/bar/*"},
{collection: "", shard: "", expected: "meta/collections/.*/shards/.*"},
{collection: "*", shard: "*", expected: "meta/collections/.*/shards/.*"},
{collection: "foo", shard: "", expected: "meta/collections/foo/shards/.*"},
{collection: "foo", shard: "*", expected: "meta/collections/foo/shards/.*"},
{collection: "", shard: "bar", expected: "meta/collections/.*/shards/bar"},
{collection: "*", shard: "bar", expected: "meta/collections/.*/shards/bar"},
{collection: "foo", shard: "bar", expected: "meta/collections/foo/shards/bar"},
}
for _, tt := range tests {
name := fmt.Sprintf("collection: %s; shard: %s", tt.collection, tt.shard)
t.Run(name, func(t *testing.T) {
p := CasbinShards(tt.collection, tt.shard)
p := CasbinSchema(tt.collection, tt.shard)
require.Equal(t, tt.expected, p)
})
}
Expand Down
48 changes: 24 additions & 24 deletions usecases/auth/authorization/rbac/model_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,24 43,24 @@ func TestKeyMatch5AuthZ(t *testing.T) {
{"Allow all objects with Tenant1", authorization.Objects("", "Tenant1", ""), "*", true},

// Class level
{"Class level collections ABC", authorization.CollectionsMetadata("ABC")[0], conv.CasbinCollections("*"), true},
{"Class level shards ABC", authorization.ShardsMetadata("ABC")[0], conv.CasbinCollections("*"), true},
{"Class level collections ABC exact", authorization.CollectionsMetadata("ABC")[0], conv.CasbinCollections("ABC"), true},
{"Class level collections Class1 exact", authorization.CollectionsMetadata("Class1")[0], conv.CasbinCollections("Class1"), true},
{"Class level collections Class2 mismatch", authorization.CollectionsMetadata("Class2")[0], conv.CasbinCollections("Class1"), false},
{"Class level shards ABC TenantX", authorization.ShardsMetadata("ABC", "TenantX")[0], conv.CasbinCollections("ABC"), true},
{"Class level collections ABC", authorization.CollectionsMetadata("ABC")[0], conv.CasbinSchema("*", ""), true},
{"Class level shards ABC", authorization.ShardsMetadata("ABC")[0], conv.CasbinSchema("*", "*"), true},
{"Class level collections ABC exact", authorization.CollectionsMetadata("ABC")[0], conv.CasbinSchema("ABC", ""), true},
{"Class level collections Class1 exact", authorization.CollectionsMetadata("Class1")[0], conv.CasbinSchema("Class1", ""), true},
{"Class level collections Class2 mismatch", authorization.CollectionsMetadata("Class2")[0], conv.CasbinSchema("Class1", ""), false},
{"Class level shards ABC TenantX", authorization.ShardsMetadata("ABC", "TenantX")[0], conv.CasbinSchema("ABC", ""), true},
{"Class level objects ABC TenantX objectY", authorization.Objects("ABC", "TenantX", "objectY"), conv.CasbinObjects("ABC", "*", "*"), true},

// Tenants level
{"Tenants level shards", authorization.ShardsMetadata("")[0], conv.CasbinCollections("*"), true},
{"Tenants level shards ABC Tenant1", authorization.ShardsMetadata("ABC", "Tenant1")[0], conv.CasbinShards("*", "*"), true},
{"Tenants level shards Class1 Tenant1", authorization.ShardsMetadata("Class1", "Tenant1")[0], conv.CasbinShards("*", "Tenant1"), true},
{"Tenants level shards", authorization.ShardsMetadata("")[0], conv.CasbinSchema("*", "*"), true},
{"Tenants level shards ABC Tenant1", authorization.ShardsMetadata("ABC", "Tenant1")[0], conv.CasbinSchema("*", "*"), true},
{"Tenants level shards Class1 Tenant1", authorization.ShardsMetadata("Class1", "Tenant1")[0], conv.CasbinSchema("*", "Tenant1"), true},
{"Tenants level objects Class1 Tenant1 ObjectY", authorization.Objects("Class1", "Tenant1", "ObjectY"), conv.CasbinObjects("*", "Tenant1", ""), true},
{"Tenants level shards Class1 Tenant2 mismatch", authorization.ShardsMetadata("Class1", "Tenant2")[0], conv.CasbinShards("*", "Tenant1"), false},
{"Tenants level shards Class1 Tenant2 mismatch 2", authorization.ShardsMetadata("Class1", "Tenant2")[0], conv.CasbinShards("Class2", "Tenant1"), false},
{"Tenants level shards mismatch", authorization.ShardsMetadata("")[0], conv.CasbinCollections("Class1"), false},
{"Tenants level collections Class1", authorization.CollectionsMetadata("Class1")[0], conv.CasbinCollections("Class1"), true},
{"Tenants level shards Class1 tenant1", authorization.ShardsMetadata("Class1", "tenant1")[0], conv.CasbinCollections("Class1"), true},
{"Tenants level shards Class1 Tenant2 mismatch", authorization.ShardsMetadata("Class1", "Tenant2")[0], conv.CasbinSchema("*", "Tenant1"), false},
{"Tenants level shards Class1 Tenant2 mismatch 2", authorization.ShardsMetadata("Class1", "Tenant2")[0], conv.CasbinSchema("Class2", "Tenant1"), false},
{"Tenants level shards mismatch", authorization.ShardsMetadata("")[0], conv.CasbinSchema("Class1", ""), false},
{"Tenants level collections Class1", authorization.CollectionsMetadata("Class1")[0], conv.CasbinSchema("Class1", ""), true},
{"Tenants level shards Class1 tenant1", authorization.ShardsMetadata("Class1", "tenant1")[0], conv.CasbinSchema("Class1", ""), true},

// Objects level
{"Objects level all", authorization.Objects("", "", ""), conv.CasbinObjects(".*", ".*", ".*"), true},
Expand All @@ -75,27 75,27 @@ func TestKeyMatch5AuthZ(t *testing.T) {
{"Objects level ABC bar abcd", authorization.Objects("ABC", "bar", "abcd"), conv.CasbinObjects("*", "bar", ""), true},

// Regex
{"Regex collections ABCD", authorization.CollectionsMetadata("ABCD")[0], conv.CasbinCollections("ABC"), false},
{"Regex shards ABC", authorization.ShardsMetadata("ABC", "")[0], conv.CasbinCollections("ABC"), true},
{"Regex collections ABCD", authorization.CollectionsMetadata("ABCD")[0], conv.CasbinSchema("ABC", ""), false},
{"Regex shards ABC", authorization.ShardsMetadata("ABC", "")[0], conv.CasbinSchema("ABC", ""), true},
{"Regex objects ABC", authorization.Objects("ABC", "", ""), conv.CasbinObjects("ABC", "*", "*"), true},
{"Regex objects ABCD mismatch", authorization.Objects("ABCD", "", ""), conv.CasbinObjects("ABC", "*", "*"), false},
{"Regex objects ABCD wildcard", authorization.Objects("ABCD", "", ""), conv.CasbinObjects("ABC.*", "*", "*"), true},
{"Regex objects BCD mismatch", authorization.Objects("BCD", "", ""), conv.CasbinObjects("ABC", "*", "*"), false},

{"Regex collections ABC wildcard", authorization.CollectionsMetadata("ABC")[0], conv.CasbinCollections("ABC*"), true},
{"Regex collections ABC wildcard 2", authorization.CollectionsMetadata("ABC")[0], conv.CasbinCollections("ABC*"), true},
{"Regex collections ABCD wildcard", authorization.CollectionsMetadata("ABCD")[0], conv.CasbinCollections("ABC*"), true},
{"Regex collections ABC wildcard", authorization.CollectionsMetadata("ABC")[0], conv.CasbinSchema("ABC*", ""), true},
{"Regex collections ABC wildcard 2", authorization.CollectionsMetadata("ABC")[0], conv.CasbinSchema("ABC*", ""), true},
{"Regex collections ABCD wildcard", authorization.CollectionsMetadata("ABCD")[0], conv.CasbinSchema("ABC*", ""), true},

// ShardsMetadata read on collections level permissions
{"ShardsMetadata read on collections level ABC", authorization.ShardsMetadata("ABC")[0], conv.CasbinCollections("ABC"), true},
{"ShardsMetadata read on collections level ABC", authorization.ShardsMetadata("ABC")[0], conv.CasbinSchema("ABC", ""), true},

// some other cases
{"Mismatched collection", authorization.CollectionsMetadata("Class1")[0], conv.CasbinCollections("Class2"), false},
{"Mismatched shard", authorization.ShardsMetadata("Class1", "Shard1")[0], conv.CasbinShards("Class1", "Shard2"), false},
{"Mismatched collection", authorization.CollectionsMetadata("Class1")[0], conv.CasbinSchema("Class2", ""), false},
{"Mismatched shard", authorization.ShardsMetadata("Class1", "Shard1")[0], conv.CasbinSchema("Class1", "Shard2"), false},
{"Partial match role", authorization.Roles("anotherRole")[0], conv.CasbinRoles("ro*"), false},
{"Partial match role", authorization.Roles("role")[0], conv.CasbinRoles("ro*"), true},
{"Partial match collection", authorization.CollectionsMetadata("Class1")[0], conv.CasbinCollections("Cla*"), true},
{"Partial match shard", authorization.ShardsMetadata("Class1", "Shard1")[0], conv.CasbinShards("Class1", "Sha*"), true},
{"Partial match collection", authorization.CollectionsMetadata("Class1")[0], conv.CasbinSchema("Cla*", ""), true},
{"Partial match shard", authorization.ShardsMetadata("Class1", "Shard1")[0], conv.CasbinSchema("Class1", "Sha*"), true},
{"Partial match object", authorization.Objects("Class1", "Shard1", "Object1"), conv.CasbinObjects("Class1", "Shard1", "Obj*"), true},
{"Special character mismatch", authorization.Objects("Class1", "Shard1", "Object1"), "data/collections/Class1/shards/Shard1/objects/Object1!", false},
{"Mismatched object", authorization.Objects("Class1", "Shard1", "Object1"), conv.CasbinObjects("Class1", "Shard1", "Object2"), false},
Expand Down
6 changes: 3 additions & 3 deletions usecases/auth/authorization/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,15 248,15 @@ func ShardsMetadata(class string, shards ...string) []string {
}

if len(shards) == 0 || (len(shards) == 1 && (shards[0] == "" || shards[0] == "*")) {
return []string{fmt.Sprintf("meta/collections/%s/shards/*/*", class)}
return []string{fmt.Sprintf("meta/collections/%s/shards/*", class)}
}

resources := make([]string, len(shards))
for idx := range shards {
if shards[idx] == "" {
resources[idx] = fmt.Sprintf("meta/collections/%s/shards/*/*", class)
resources[idx] = fmt.Sprintf("meta/collections/%s/shards/*", class)
} else {
resources[idx] = fmt.Sprintf("meta/collections/%s/shards/%s/*", class, shards[idx])
resources[idx] = fmt.Sprintf("meta/collections/%s/shards/%s", class, shards[idx])
}
}

Expand Down
12 changes: 6 additions & 6 deletions usecases/auth/authorization/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 89,12 @@ func TestShards(t *testing.T) {
shards []string
expected []string
}{
{"No class, no shards", "", []string{}, []string{"meta/collections/*/shards/*/*"}},
{"Class, no shards", "class1", []string{}, []string{"meta/collections/class1/shards/*/*"}},
{"No class, single shard", "", []string{"shard1"}, []string{"meta/collections/*/shards/shard1/*"}},
{"Class, single shard", "class1", []string{"shard1"}, []string{"meta/collections/class1/shards/shard1/*"}},
{"Class, multiple shards", "class1", []string{"shard1", "shard2"}, []string{"meta/collections/class1/shards/shard1/*", "meta/collections/class1/shards/shard2/*"}},
{"Class, empty shard", "class1", []string{"shard1", ""}, []string{"meta/collections/class1/shards/shard1/*", "meta/collections/class1/shards/*/*"}},
{"No class, no shards", "", []string{}, []string{"meta/collections/*/shards/*"}},
{"Class, no shards", "class1", []string{}, []string{"meta/collections/class1/shards/*"}},
{"No class, single shard", "", []string{"shard1"}, []string{"meta/collections/*/shards/shard1"}},
{"Class, single shard", "class1", []string{"shard1"}, []string{"meta/collections/class1/shards/shard1"}},
{"Class, multiple shards", "class1", []string{"shard1", "shard2"}, []string{"meta/collections/class1/shards/shard1", "meta/collections/class1/shards/shard2"}},
{"Class, empty shard", "class1", []string{"shard1", ""}, []string{"meta/collections/class1/shards/shard1", "meta/collections/class1/shards/*"}},
}

for _, tt := range tests {
Expand Down
Loading