Repository: casbin/casbin
Pull request #607 (2020-09-18 12:17:19)

feat: Add CasbinJsGetPermissionForUserSynced for SyncedEnforcer
Signed-off-by: 00LT00 <lightning@zerokirin.online>

Fix: https://github.com/casbin/casbin/issues/568


Patch:
diff --git a/README.md b/README.md
index 142ed62..6e512bc 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ Casbin
 [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/casbin/lobby)
 [![Sourcegraph](https://sourcegraph.com/github.com/casbin/casbin/-/badge.svg)](https://sourcegraph.com/github.com/casbin/casbin?badge)
 
-**News**: still worry about how to write the correct Casbin policy? ``Casbin online editor`` is coming to help! Try it at: https://casbin.org/editor/
+**News**: still worry about how to write the correct Casbin policy? ``Casbin online editor`` is coming to help! Try it at: http://casbin.org/editor/
 
 ![casbin Logo](casbin-logo.png)
 
diff --git a/enforcer_synced.go b/enforcer_synced.go
index 52f03f9..41fedd6 100644
--- a/enforcer_synced.go
+++ b/enforcer_synced.go
@@ -418,3 +418,46 @@ func (e *SyncedEnforcer) AddNamedPolicies(ptype string, rules [][]string) (bool,
 	defer e.m.Unlock()
 	return e.Enforcer.AddNamedPolicies(ptype, rules)
 }
+
+// GetImplicitPermissionsForUser gets implicit permissions for a user or role.
+// Compared to GetPermissionsForUser(), this function retrieves permissions for inherited roles.
+// For example:
+// p, admin, data1, read
+// p, alice, data2, read
+// g, alice, admin
+//
+// GetPermissionsForUser("alice") can only get: [["alice", "data2", "read"]].
+// But GetImplicitPermissionsForUser("alice") will get: [["admin", "data1", "read"], ["alice", "data2", "read"]].
+func (e *SyncedEnforcer) GetImplicitPermissionsForUser(user string, domain ...string) ([][]string, error) {
+	e.m.Lock()
+	defer e.m.Unlock()
+	return e.Enforcer.GetImplicitPermissionsForUser(user, domain...)
+}
+
+// GetImplicitRolesForUser gets implicit roles that a user has.
+// Compared to GetRolesForUser(), this function retrieves indirect roles besides direct roles.
+// For example:
+// g, alice, role:admin
+// g, role:admin, role:user
+//
+// GetRolesForUser("alice") can only get: ["role:admin"].
+// But GetImplicitRolesForUser("alice") will get: ["role:admin", "role:user"].
+func (e *SyncedEnforcer) GetImplicitRolesForUser(name string, domain ...string) ([]string, error) {
+	e.m.Lock()
+	defer e.m.Unlock()
+	return e.Enforcer.GetImplicitRolesForUser(name, domain...)
+}
+
+// GetImplicitUsersForPermission gets implicit users for a permission.
+// For example:
+// p, admin, data1, read
+// p, bob, data1, read
+// g, alice, admin
+//
+// GetImplicitUsersForPermission("data1", "read") will get: ["alice", "bob"].
+// Note: only users will be returned, roles (2nd arg in "g") will be excluded.
+func (e *SyncedEnforcer) GetImplicitUsersForPermission(permission ...string) ([]string, error) {
+	e.m.Lock()
+	defer e.m.Unlock()
+	return e.Enforcer.GetImplicitUsersForPermission(permission...)
+}
diff --git a/frontend.go b/frontend.go
index ce37aaa..c53ca46 100644
--- a/frontend.go
+++ b/frontend.go
@@ -18,7 +18,7 @@ import (
 	"encoding/json"
 )
 
-func CasbinJsGetPermissionForUser(e *Enforcer, user string) ([]byte, error) {
+func CasbinJsGetPermissionForUser(e IEnforcer, user string) ([]byte, error) {
 	policy, err := e.GetImplicitPermissionsForUser(user)
 	if err != nil {
 		return nil, err


Test patch:
diff --git a/frontend_test.go b/frontend_test.go
index 2766879..92c6186 100644
--- a/frontend_test.go
+++ b/frontend_test.go
@@ -91,3 +91,14 @@ func TestCasbinJsGetPermissionForUser(t *testing.T) {
 		t.Errorf("Someone can have a non-existing action (rm -rf)")
 	}
 }
+
+func TestCasbinJsGetPermissionForUser2(t *testing.T) {
+	e, err := NewSyncedEnforcer("examples/rbac_model.conf", "examples/rbac_policy.csv")
+	if err != nil {
+		panic(err)
+	}
+	_, err = CasbinJsGetPermissionForUser(e, "alice") // make sure CasbinJsGetPermissionForUser can be used with a SyncedEnforcer.
+	if err != nil {
+		t.Errorf("Test error: %s", err)
+	}
+}