Skip to content

Commit 58903b0

Browse files
authored
feat: adds the missing AddGroupingPoliciesEx and AddNamedGroupingPoliciesEx APIs to sync jCasbin with Go Casbin (#463)
1 parent 747eb33 commit 58903b0

File tree

4 files changed

+220
-0
lines changed

4 files changed

+220
-0
lines changed

src/main/java/org/casbin/jcasbin/main/ManagementEnforcer.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,56 @@ public boolean addNamedGroupingPolicies(String ptype, String[][] rules) {
645645
return addNamedGroupingPolicies(ptype, Arrays.stream(rules).map(Arrays::asList).collect(Collectors.toList()));
646646
}
647647

648+
/**
649+
* addGroupingPoliciesEx adds role inheritance rules to the current policy.
650+
* If the rule already exists, the rule will not be added.
651+
* But unlike AddGroupingPolicies, other non-existent rules are added instead of returning false directly
652+
*
653+
* @param rules the "g" policy rules, ptype "g" is implicitly used.
654+
* @return succeeds or not.
655+
*/
656+
public boolean addGroupingPoliciesEx(List<List<String>> rules) {
657+
return addNamedGroupingPoliciesEx("g", rules);
658+
}
659+
660+
/**
661+
* addGroupingPoliciesEx adds role inheritance rules to the current policy.
662+
* If the rule already exists, the rule will not be added.
663+
* But unlike AddGroupingPolicies, other non-existent rules are added instead of returning false directly
664+
*
665+
* @param rules the "g" policy rules, ptype "g" is implicitly used.
666+
* @return succeeds or not.
667+
*/
668+
public boolean addGroupingPoliciesEx(String[][] rules) {
669+
return addGroupingPoliciesEx(Arrays.stream(rules).map(Arrays::asList).collect(Collectors.toList()));
670+
}
671+
672+
/**
673+
* addNamedGroupingPoliciesEx adds named role inheritance rules to the current policy.
674+
* If the rule already exists, the rule will not be added.
675+
* But unlike AddNamedGroupingPolicies, other non-existent rules are added instead of returning false directly
676+
*
677+
* @param ptype the policy type, can be "g", "g2", "g3", ..
678+
* @param rules the "g" policy rules.
679+
* @return succeeds or not.
680+
*/
681+
public boolean addNamedGroupingPoliciesEx(String ptype, List<List<String>> rules) {
682+
return addPolicies("g", ptype, rules, true);
683+
}
684+
685+
/**
686+
* addNamedGroupingPoliciesEx adds named role inheritance rules to the current policy.
687+
* If the rule already exists, the rule will not be added.
688+
* But unlike AddNamedGroupingPolicies, other non-existent rules are added instead of returning false directly
689+
*
690+
* @param ptype the policy type, can be "g", "g2", "g3", ..
691+
* @param rules the "g" policy rules.
692+
* @return succeeds or not.
693+
*/
694+
public boolean addNamedGroupingPoliciesEx(String ptype, String[][] rules) {
695+
return addNamedGroupingPoliciesEx(ptype, Arrays.stream(rules).map(Arrays::asList).collect(Collectors.toList()));
696+
}
697+
648698
/**
649699
* removeGroupingPolicy removes a role inheritance rule from the current policy.
650700
*

src/main/java/org/casbin/jcasbin/main/SyncedEnforcer.java

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,60 @@ public boolean addNamedGroupingPolicies(String ptype, String[][] rules) {
941941
return runSynchronized(() -> super.addNamedGroupingPolicies(ptype, rules), READ_WRITE_LOCK.writeLock());
942942
}
943943

944+
/**
945+
* addGroupingPoliciesEx adds role inheritance rules to the current policy.
946+
* If the rule already exists, the rule will not be added.
947+
* But unlike AddGroupingPolicies, other non-existent rules are added instead of returning false directly
948+
*
949+
* @param rules the "g" policy rules, ptype "g" is implicitly used.
950+
* @return succeeds or not.
951+
*/
952+
@Override
953+
public boolean addGroupingPoliciesEx(List<List<String>> rules) {
954+
return runSynchronized(() -> super.addGroupingPoliciesEx(rules), READ_WRITE_LOCK.writeLock());
955+
}
956+
957+
/**
958+
* addGroupingPoliciesEx adds role inheritance rules to the current policy.
959+
* If the rule already exists, the rule will not be added.
960+
* But unlike AddGroupingPolicies, other non-existent rules are added instead of returning false directly
961+
*
962+
* @param rules the "g" policy rules, ptype "g" is implicitly used.
963+
* @return succeeds or not.
964+
*/
965+
@Override
966+
public boolean addGroupingPoliciesEx(String[][] rules) {
967+
return runSynchronized(() -> super.addGroupingPoliciesEx(rules), READ_WRITE_LOCK.writeLock());
968+
}
969+
970+
/**
971+
* addNamedGroupingPoliciesEx adds named role inheritance rules to the current policy.
972+
* If the rule already exists, the rule will not be added.
973+
* But unlike AddNamedGroupingPolicies, other non-existent rules are added instead of returning false directly
974+
*
975+
* @param ptype the policy type, can be "g", "g2", "g3", ..
976+
* @param rules the "g" policy rules.
977+
* @return succeeds or not.
978+
*/
979+
@Override
980+
public boolean addNamedGroupingPoliciesEx(String ptype, List<List<String>> rules) {
981+
return runSynchronized(() -> super.addNamedGroupingPoliciesEx(ptype, rules), READ_WRITE_LOCK.writeLock());
982+
}
983+
984+
/**
985+
* addNamedGroupingPoliciesEx adds named role inheritance rules to the current policy.
986+
* If the rule already exists, the rule will not be added.
987+
* But unlike AddNamedGroupingPolicies, other non-existent rules are added instead of returning false directly
988+
*
989+
* @param ptype the policy type, can be "g", "g2", "g3", ..
990+
* @param rules the "g" policy rules.
991+
* @return succeeds or not.
992+
*/
993+
@Override
994+
public boolean addNamedGroupingPoliciesEx(String ptype, String[][] rules) {
995+
return runSynchronized(() -> super.addNamedGroupingPoliciesEx(ptype, rules), READ_WRITE_LOCK.writeLock());
996+
}
997+
944998
/**
945999
* removeGroupingPolicy removes a role inheritance rule from the current policy.
9461000
*

src/test/java/org/casbin/jcasbin/main/ManagementAPIUnitTest.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,66 @@ public void testModifyGroupingPolicyAPI() {
216216
testGetUsers(e, "data3_admin", asList("eve"));
217217
}
218218

219+
@Test
220+
public void testModifyGroupingPolicyAPIEx() {
221+
Enforcer e = new Enforcer("examples/rbac_model.conf", "examples/rbac_policy.csv");
222+
223+
// Initial state: alice has role data2_admin
224+
testGetRoles(e, "alice", asList("data2_admin"));
225+
226+
String[][] groupingRules = {
227+
{"alice", "data2_admin"}, // This rule already exists
228+
{"bob", "data1_admin"}, // This is new
229+
{"eve", "data3_admin"} // This is new
230+
};
231+
232+
// Test addGroupingPoliciesEx - should add only new rules (bob and eve), not fail on existing (alice)
233+
boolean result = e.addGroupingPoliciesEx(groupingRules);
234+
Assert.assertTrue("addGroupingPoliciesEx should return true", result);
235+
testGetRoles(e, "alice", asList("data2_admin"));
236+
testGetRoles(e, "bob", asList("data1_admin"));
237+
testGetRoles(e, "eve", asList("data3_admin"));
238+
239+
// Clean up for next test
240+
e.removeGroupingPolicy("bob", "data1_admin");
241+
e.removeGroupingPolicy("eve", "data3_admin");
242+
243+
// Test with List<List<String>>
244+
List<List<String>> groupingRulesList = asList(
245+
asList("alice", "data2_admin"), // Already exists
246+
asList("bob", "data1_admin"), // New
247+
asList("ham", "data4_admin") // New
248+
);
249+
250+
result = e.addGroupingPoliciesEx(groupingRulesList);
251+
Assert.assertTrue("addGroupingPoliciesEx with List should return true", result);
252+
testGetRoles(e, "alice", asList("data2_admin"));
253+
testGetRoles(e, "bob", asList("data1_admin"));
254+
testGetRoles(e, "ham", asList("data4_admin"));
255+
256+
// Clean up
257+
e.removeGroupingPolicy("bob", "data1_admin");
258+
e.removeGroupingPolicy("ham", "data4_admin");
259+
260+
// Test addNamedGroupingPoliciesEx with List<List<String>>
261+
result = e.addNamedGroupingPoliciesEx("g", groupingRulesList);
262+
Assert.assertTrue("addNamedGroupingPoliciesEx with List should return true", result);
263+
testGetRoles(e, "alice", asList("data2_admin"));
264+
testGetRoles(e, "bob", asList("data1_admin"));
265+
testGetRoles(e, "ham", asList("data4_admin"));
266+
267+
// Clean up
268+
e.removeGroupingPolicy("bob", "data1_admin");
269+
e.removeGroupingPolicy("ham", "data4_admin");
270+
271+
// Test addNamedGroupingPoliciesEx with String[][]
272+
result = e.addNamedGroupingPoliciesEx("g", groupingRules);
273+
Assert.assertTrue("addNamedGroupingPoliciesEx with String[][] should return true", result);
274+
testGetRoles(e, "alice", asList("data2_admin"));
275+
testGetRoles(e, "bob", asList("data1_admin"));
276+
testGetRoles(e, "eve", asList("data3_admin"));
277+
}
278+
219279
@Test
220280
public void should_throwsNullPointException_when_setAviatorEvaluator_given_nullInstance() {
221281
// given

src/test/java/org/casbin/jcasbin/main/SyncedManagementAPIUnitTest.java

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,60 @@ public void testModifyGroupingPolicyAPI() {
138138
testGetUsers(e, "data2_admin", asList());
139139
testGetUsers(e, "data3_admin", asList("eve"));
140140
}
141+
142+
@Test
143+
public void testModifyGroupingPolicyAPIEx() {
144+
Enforcer e = new SyncedEnforcer("examples/rbac_model.conf", "examples/rbac_policy.csv");
145+
146+
// Initial state: alice has role data2_admin
147+
testGetRoles(e, "alice", asList("data2_admin"));
148+
149+
String[][] groupingRules = {
150+
{"alice", "data2_admin"}, // This rule already exists
151+
{"bob", "data1_admin"}, // This is new
152+
{"eve", "data3_admin"} // This is new
153+
};
154+
155+
// Test addGroupingPoliciesEx - should add only new rules (bob and eve), not fail on existing (alice)
156+
e.addGroupingPoliciesEx(groupingRules);
157+
testGetRoles(e, "alice", asList("data2_admin"));
158+
testGetRoles(e, "bob", asList("data1_admin"));
159+
testGetRoles(e, "eve", asList("data3_admin"));
160+
161+
// Clean up for next test
162+
e.removeGroupingPolicy("bob", "data1_admin");
163+
e.removeGroupingPolicy("eve", "data3_admin");
164+
165+
// Test with List<List<String>>
166+
List<List<String>> groupingRulesList = asList(
167+
asList("alice", "data2_admin"), // Already exists
168+
asList("bob", "data1_admin"), // New
169+
asList("ham", "data4_admin") // New
170+
);
171+
172+
e.addGroupingPoliciesEx(groupingRulesList);
173+
testGetRoles(e, "alice", asList("data2_admin"));
174+
testGetRoles(e, "bob", asList("data1_admin"));
175+
testGetRoles(e, "ham", asList("data4_admin"));
176+
177+
// Clean up
178+
e.removeGroupingPolicy("bob", "data1_admin");
179+
e.removeGroupingPolicy("ham", "data4_admin");
180+
181+
// Test addNamedGroupingPoliciesEx with List<List<String>>
182+
e.addNamedGroupingPoliciesEx("g", groupingRulesList);
183+
testGetRoles(e, "alice", asList("data2_admin"));
184+
testGetRoles(e, "bob", asList("data1_admin"));
185+
testGetRoles(e, "ham", asList("data4_admin"));
186+
187+
// Clean up
188+
e.removeGroupingPolicy("bob", "data1_admin");
189+
e.removeGroupingPolicy("ham", "data4_admin");
190+
191+
// Test addNamedGroupingPoliciesEx with String[][]
192+
e.addNamedGroupingPoliciesEx("g", groupingRules);
193+
testGetRoles(e, "alice", asList("data2_admin"));
194+
testGetRoles(e, "bob", asList("data1_admin"));
195+
testGetRoles(e, "eve", asList("data3_admin"));
196+
}
141197
}

0 commit comments

Comments
 (0)