Repository: casbin/casbin
Pull request #535 (2020-07-18 02:27:24)

feat: make enforcer.ClearPolicy different with Model.ClearPolicy
Signed-off-by: Cheng JIANG <jiang.cheng@vip.163.com>


Patch:
diff --git a/effect/default_effector.go b/effect/default_effector.go
index 5ecfd58..f359573 100644
--- a/effect/default_effector.go
+++ b/effect/default_effector.go
@@ -24,15 +24,15 @@ func NewDefaultEffector() *DefaultEffector {
 	return &e
 }
 
-func (e *DefaultEffector) NewStream(expr string, cap int) (EffectorStream) {
-	if !(cap>0) {
+func (e *DefaultEffector) NewStream(expr string, cap int) EffectorStream {
+	if !(cap > 0) {
 		panic("cap should be greater than 0")
 	}
 
 	var res bool
-	if expr=="some(where (p_eft == allow))" || expr=="some(where (p_eft == allow)) && !some(where (p_eft == deny))" || expr=="priority(p_eft) || deny" {
+	if expr == "some(where (p_eft == allow))" || expr == "some(where (p_eft == allow)) && !some(where (p_eft == deny))" || expr == "priority(p_eft) || deny" {
 		res = false
-	} else if expr=="!some(where (p_eft == deny))" {
+	} else if expr == "!some(where (p_eft == deny))" {
 		res = true
 	} else {
 		panic("unsupported effect: " + expr)
@@ -41,4 +41,5 @@ func (e *DefaultEffector) NewStream(expr string, cap int) (EffectorStream) {
 	des := &DefaultEffectorStream{false, res, expr, 0, cap, make([]int, 0)}
 
 	return des
-}
\ No newline at end of file
+}
+
diff --git a/effect/default_effector_stream.go b/effect/default_effector_stream.go
index 3870927..8703e1e 100644
--- a/effect/default_effector_stream.go
+++ b/effect/default_effector_stream.go
@@ -3,10 +3,10 @@ package effect
 // DefaultEffectorStream is the default implementation of interface EffectorStream.
 type DefaultEffectorStream struct {
 	done bool
-	res bool
+	res  bool
 	expr string
-	idx int
-	cap int
+	idx  int
+	cap  int
 	expl []int
 }
 
@@ -60,10 +60,10 @@ func (s *DefaultEffectorStream) PushEffect(eft Effect) bool {
 		pushIndex(hasPolicy, &s.expl, s.idx)
 	}
 
-	if s.idx + 1 == s.cap {
+	if s.idx+1 == s.cap {
 		s.done = true
 	}
 	s.idx++
-	
+
 	return s.done
 }
diff --git a/effect/effector.go b/effect/effector.go
index c6c7402..6edffce 100644
--- a/effect/effector.go
+++ b/effect/effector.go
@@ -26,5 +26,5 @@ const (
 
 // Effector is the interface for Casbin effectors.
 type Effector interface {
-	NewStream(expr string, cap int) (EffectorStream)
+	NewStream(expr string, cap int) EffectorStream
 }
diff --git a/effect/effector_stream.go b/effect/effector_stream.go
index f78d6a4..5a1efc4 100644
--- a/effect/effector_stream.go
+++ b/effect/effector_stream.go
@@ -5,4 +5,5 @@ type EffectorStream interface {
 	Next() bool
 	Explain() []int
 	PushEffect(eft Effect) bool
-}
\ No newline at end of file
+}
+
diff --git a/enforcer.go b/enforcer.go
index 8516ac4..80ca4c8 100644
--- a/enforcer.go
+++ b/enforcer.go
@@ -237,8 +237,11 @@ func (e *Enforcer) SetEffector(eft effect.Effector) {
 }
 
 // ClearPolicy clears all policy.
-func (e *Enforcer) ClearPolicy() {
+func (e *Enforcer) ClearPolicy() error {
+	// TODO: implement ClearPolicy in adapter and move model.ClearPolicy after adapter.ClearPolicy
 	e.model.ClearPolicy()
+
+	return e.adapter.SavePolicy(e.model)
 }
 
 // LoadPolicy reloads the policy from file/database.
diff --git a/enforcer_interface.go b/enforcer_interface.go
index 39aca3b..d5ecd2b 100644
--- a/enforcer_interface.go
+++ b/enforcer_interface.go
@@ -42,7 +42,7 @@ type IEnforcer interface {
 	GetRoleManager() rbac.RoleManager
 	SetRoleManager(rm rbac.RoleManager)
 	SetEffector(eft effect.Effector)
-	ClearPolicy()
+	ClearPolicy() error
 	LoadPolicy() error
 	LoadFilteredPolicy(filter interface{}) error
 	IsFiltered() bool
diff --git a/enforcer_synced.go b/enforcer_synced.go
index b7bd218..9df5d83 100644
--- a/enforcer_synced.go
+++ b/enforcer_synced.go
@@ -46,15 +46,15 @@ func NewSyncedEnforcer(params ...interface{}) (*SyncedEnforcer, error) {
 	return e, nil
 }
 
-// IsAudoLoadingRunning check if SyncedEnforcer is auto loading policies
-func (e *SyncedEnforcer) IsAudoLoadingRunning() bool {
+// IsAudoLoadRunning check if SyncedEnforcer is auto loading policies
+func (e *SyncedEnforcer) IsAudoLoadRunning() bool {
 	return atomic.LoadInt32(&(e.autoLoadRunning)) != 0
 }
 
 // StartAutoLoadPolicy starts a go routine that will every specified duration call LoadPolicy
 func (e *SyncedEnforcer) StartAutoLoadPolicy(d time.Duration) {
 	// Don't start another goroutine if there is already one running
-	if e.IsAudoLoadingRunning() {
+	if e.IsAudoLoadRunning() {
 		return
 	}
 	atomic.StoreInt32(&(e.autoLoadRunning), int32(1))
@@ -84,7 +84,7 @@ func (e *SyncedEnforcer) StartAutoLoadPolicy(d time.Duration) {
 
 // StopAutoLoadPolicy causes the go routine to exit.
 func (e *SyncedEnforcer) StopAutoLoadPolicy() {
-	if e.IsAudoLoadingRunning() {
+	if e.IsAudoLoadRunning() {
 		e.stopAutoLoad <- struct{}{}
 	}
 }
@@ -96,10 +96,10 @@ func (e *SyncedEnforcer) SetWatcher(watcher persist.Watcher) error {
 }
 
 // ClearPolicy clears all policy.
-func (e *SyncedEnforcer) ClearPolicy() {
+func (e *SyncedEnforcer) ClearPolicy() error {
 	e.m.Lock()
 	defer e.m.Unlock()
-	e.Enforcer.ClearPolicy()
+	return e.Enforcer.ClearPolicy()
 }
 
 // LoadPolicy reloads the policy from file/database.
@@ -371,8 +371,7 @@ func (e *SyncedEnforcer) RemoveFilteredNamedGroupingPolicy(ptype string, fieldIn
 
 // AddFunction adds a customized function.
 func (e *SyncedEnforcer) AddFunction(name string, function govaluate.ExpressionFunction) {
-	e.m.Lock()
-	defer e.m.Unlock()
+	// FuncionMap uses sync.Map so it's totally thread-safe
 	e.Enforcer.AddFunction(name, function)
 }
 


Test patch:
diff --git a/enforcer_synced_test.go b/enforcer_synced_test.go
index 14ccb13..0c9a025 100644
--- a/enforcer_synced_test.go
+++ b/enforcer_synced_test.go
@@ -47,13 +47,13 @@ func TestSync(t *testing.T) {
 func TestStopAutoLoadPolicy(t *testing.T) {
 	e, _ := NewSyncedEnforcer("examples/basic_model.conf", "examples/basic_policy.csv")
 	e.StartAutoLoadPolicy(5 * time.Millisecond)
-	if !e.IsAudoLoadingRunning() {
+	if !e.IsAudoLoadRunning() {
 		t.Error("auto load is not running")
 	}
 	e.StopAutoLoadPolicy()
 	// Need a moment, to exit goroutine
 	time.Sleep(10 * time.Millisecond)
-	if e.IsAudoLoadingRunning() {
+	if e.IsAudoLoadRunning() {
 		t.Error("auto load is still running")
 	}
 }
diff --git a/enforcer_test.go b/enforcer_test.go
index 7170f5c..1f3b253 100644
--- a/enforcer_test.go
+++ b/enforcer_test.go
@@ -230,7 +230,7 @@ func TestSavePolicy(t *testing.T) {
 func TestClearPolicy(t *testing.T) {
 	e, _ := NewEnforcer("examples/rbac_model.conf", "examples/rbac_policy.csv")
 
-	e.ClearPolicy()
+	e.GetModel().ClearPolicy()
 }
 
 func TestEnableEnforce(t *testing.T) {
diff --git a/rbac_api_test.go b/rbac_api_test.go
index 24a8ced..b12d370 100644
--- a/rbac_api_test.go
+++ b/rbac_api_test.go
@@ -295,7 +295,7 @@ func TestImplicitUserAPI(t *testing.T) {
 	testGetImplicitUsers(t, e, []string{"alice"}, "data2", "read")
 	testGetImplicitUsers(t, e, []string{"alice", "bob"}, "data2", "write")
 
-	e.ClearPolicy()
+	e.GetModel().ClearPolicy()
 	_, _ = e.AddPolicy("admin", "data1", "read")
 	_, _ = e.AddPolicy("bob", "data1", "read")
 	_, _ = e.AddGroupingPolicy("alice", "admin")