Skip to content

Commit 2ea99d3

Browse files
authored
Merge pull request #45 from tangyang9464/master
feat: add UpdateFilteredPolicies method
2 parents 6fc8c43 + 5678dab commit 2ea99d3

File tree

4 files changed

+188
-1
lines changed

4 files changed

+188
-1
lines changed

adapter.go

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,3 +486,119 @@ func (a *Adapter) UpdatePolicies(sec string, ptype string, oldRules, newRules []
486486

487487
return session.Commit()
488488
}
489+
490+
func (a *Adapter) UpdateFilteredPolicies(sec string, ptype string, newPolicies [][]string, fieldIndex int, fieldValues ...string) ([][]string, error) {
491+
// UpdateFilteredPolicies deletes old rules and adds new rules.
492+
line := &CasbinRule{}
493+
494+
line.PType = ptype
495+
if fieldIndex <= 0 && 0 < fieldIndex+len(fieldValues) {
496+
line.V0 = fieldValues[0-fieldIndex]
497+
}
498+
if fieldIndex <= 1 && 1 < fieldIndex+len(fieldValues) {
499+
line.V1 = fieldValues[1-fieldIndex]
500+
}
501+
if fieldIndex <= 2 && 2 < fieldIndex+len(fieldValues) {
502+
line.V2 = fieldValues[2-fieldIndex]
503+
}
504+
if fieldIndex <= 3 && 3 < fieldIndex+len(fieldValues) {
505+
line.V3 = fieldValues[3-fieldIndex]
506+
}
507+
if fieldIndex <= 4 && 4 < fieldIndex+len(fieldValues) {
508+
line.V4 = fieldValues[4-fieldIndex]
509+
}
510+
if fieldIndex <= 5 && 5 < fieldIndex+len(fieldValues) {
511+
line.V5 = fieldValues[5-fieldIndex]
512+
}
513+
514+
newP := make([]CasbinRule, 0, len(newPolicies))
515+
oldP := make([]CasbinRule, 0)
516+
for _, newRule := range newPolicies {
517+
newP = append(newP, *a.genPolicyLine(ptype, newRule))
518+
}
519+
tx := a.engine.NewSession()
520+
defer tx.Close()
521+
522+
if err := tx.Begin(); err != nil {
523+
return nil, err
524+
}
525+
526+
for i := range newP {
527+
str, args := line.queryString()
528+
if err := tx.Where(str, args...).Find(&oldP); err != nil {
529+
return nil, tx.Rollback()
530+
}
531+
if _, err := tx.Where(str.(string), args...).Delete(CasbinRule{}); err != nil {
532+
return nil, tx.Rollback()
533+
}
534+
if _, err := tx.Insert(&newP[i]); err != nil {
535+
return nil, tx.Rollback()
536+
}
537+
}
538+
539+
// return deleted rulues
540+
oldPolicies := make([][]string, 0)
541+
for _, v := range oldP {
542+
oldPolicy := v.toStringPolicy()
543+
oldPolicies = append(oldPolicies, oldPolicy)
544+
}
545+
return oldPolicies, tx.Commit()
546+
}
547+
548+
func (c *CasbinRule) toStringPolicy() []string {
549+
policy := make([]string, 0)
550+
if c.PType != "" {
551+
policy = append(policy, c.PType)
552+
}
553+
if c.V0 != "" {
554+
policy = append(policy, c.V0)
555+
}
556+
if c.V1 != "" {
557+
policy = append(policy, c.V1)
558+
}
559+
if c.V2 != "" {
560+
policy = append(policy, c.V2)
561+
}
562+
if c.V3 != "" {
563+
policy = append(policy, c.V3)
564+
}
565+
if c.V4 != "" {
566+
policy = append(policy, c.V4)
567+
}
568+
if c.V5 != "" {
569+
policy = append(policy, c.V5)
570+
}
571+
return policy
572+
}
573+
574+
func (c *CasbinRule) queryString() (interface{}, []interface{}) {
575+
queryArgs := []interface{}{c.PType}
576+
577+
queryStr := "p_type = ?"
578+
if c.V0 != "" {
579+
queryStr += " and v0 = ?"
580+
queryArgs = append(queryArgs, c.V0)
581+
}
582+
if c.V1 != "" {
583+
queryStr += " and v1 = ?"
584+
queryArgs = append(queryArgs, c.V1)
585+
}
586+
if c.V2 != "" {
587+
queryStr += " and v2 = ?"
588+
queryArgs = append(queryArgs, c.V2)
589+
}
590+
if c.V3 != "" {
591+
queryStr += " and v3 = ?"
592+
queryArgs = append(queryArgs, c.V3)
593+
}
594+
if c.V4 != "" {
595+
queryStr += " and v4 = ?"
596+
queryArgs = append(queryArgs, c.V4)
597+
}
598+
if c.V5 != "" {
599+
queryStr += " and v5 = ?"
600+
queryArgs = append(queryArgs, c.V5)
601+
}
602+
603+
return queryStr, queryArgs
604+
}

adapter_test.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package xormadapter
1616

1717
import (
18+
"github.com/casbin/casbin/v2/util"
1819
"log"
1920
"strings"
2021
"testing"
@@ -300,6 +301,71 @@ func testUpdatePolicies(t *testing.T, driverName string, dataSourceName string,
300301
testGetPolicy(t, e, [][]string{{"bob", "data1", "read"}, {"bob", "data2", "write"}, {"data2_admin", "data2", "read"}, {"data2_admin", "data2", "write"}})
301302
}
302303

304+
func testUpdateFilteredPolicies(t *testing.T, driverName string, dataSourceName string, dbSpecified ...bool) {
305+
// Initialize some policy in DB.
306+
initPolicy(t, driverName, dataSourceName, dbSpecified...)
307+
// Note: you don't need to look at the above code
308+
// if you already have a working DB with policy inside.
309+
310+
// Now the DB has policy, so we can provide a normal use case.
311+
// Create an adapter and an enforcer.
312+
// NewEnforcer() will load the policy automatically.
313+
a, _ := NewAdapter(driverName, dataSourceName, dbSpecified...)
314+
e, _ := casbin.NewEnforcer("examples/rbac_model.conf")
315+
316+
// Now set the adapter
317+
e.SetAdapter(a)
318+
319+
e.UpdateFilteredPolicies([][]string{{"alice", "data1", "write"}}, 0, "alice", "data1", "read")
320+
e.UpdateFilteredPolicies([][]string{{"bob", "data2", "read"}}, 0, "bob", "data2", "write")
321+
e.LoadPolicy()
322+
testGetPolicyWithoutOrder(t, e, [][]string{{"alice", "data1", "write"}, {"data2_admin", "data2", "read"}, {"data2_admin", "data2", "write"}, {"bob", "data2", "read"}})
323+
}
324+
325+
func testGetPolicyWithoutOrder(t *testing.T, e *casbin.Enforcer, res [][]string) {
326+
myRes := e.GetPolicy()
327+
log.Print("Policy: ", myRes)
328+
329+
if !arrayEqualsWithoutOrder(myRes, res) {
330+
t.Error("Policy: ", myRes, ", supposed to be ", res)
331+
}
332+
}
333+
334+
func arrayEqualsWithoutOrder(a [][]string, b [][]string) bool {
335+
if len(a) != len(b) {
336+
return false
337+
}
338+
339+
mapA := make(map[int]string)
340+
mapB := make(map[int]string)
341+
order := make(map[int]struct{})
342+
l := len(a)
343+
344+
for i := 0; i < l; i++ {
345+
mapA[i] = util.ArrayToString(a[i])
346+
mapB[i] = util.ArrayToString(b[i])
347+
}
348+
349+
for i := 0; i < l; i++ {
350+
for j := 0; j < l; j++ {
351+
if _, ok := order[j]; ok {
352+
if j == l-1 {
353+
return false
354+
} else {
355+
continue
356+
}
357+
}
358+
if mapA[i] == mapB[j] {
359+
order[j] = struct{}{}
360+
break
361+
} else if j == l-1 {
362+
return false
363+
}
364+
}
365+
}
366+
return true
367+
}
368+
303369
func TestAdapters(t *testing.T) {
304370
// You can also use the following way to use an existing DB "abc":
305371
// testSaveLoad(t, "mysql", "root:@tcp(127.0.0.1:3306)/abc", true)
@@ -320,4 +386,7 @@ func TestAdapters(t *testing.T) {
320386

321387
testUpdatePolicies(t, "mysql", "root:@tcp(127.0.0.1:3306)/")
322388
testUpdatePolicies(t, "postgres", "user=postgres password=postgres host=127.0.0.1 port=5432 sslmode=disable")
389+
390+
testUpdateFilteredPolicies(t, "mysql", "root:@tcp(127.0.0.1:3306)/")
391+
testUpdateFilteredPolicies(t, "postgres", "user=postgres password=postgres host=127.0.0.1 port=5432 sslmode=disable")
323392
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/casbin/xorm-adapter/v2
33
go 1.12
44

55
require (
6-
github.com/casbin/casbin/v2 v2.25.5
6+
github.com/casbin/casbin/v2 v2.28.3
77
github.com/go-sql-driver/mysql v1.5.0
88
github.com/lib/pq v1.8.0
99
xorm.io/xorm v1.0.3

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBK
66
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
77
github.com/casbin/casbin/v2 v2.25.5 h1:TPKaoGu1gqAVJtQ2MaTfdHn2zgnCaulLylbNXbY6TYo=
88
github.com/casbin/casbin/v2 v2.25.5/go.mod h1:wUgota0cQbTXE6Vd+KWpg41726jFRi7upxio0sR+Xd0=
9+
github.com/casbin/casbin/v2 v2.28.3 h1:iHxxEsNHwSciRoYh+54etVUA8AXKS9OKzNy6/39UWvY=
10+
github.com/casbin/casbin/v2 v2.28.3/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg=
911
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
1012
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
1113
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=

0 commit comments

Comments
 (0)