Skip to content

Commit

Permalink
feat: implement UpdatableAdapter and add tests (#73)
Browse files Browse the repository at this point in the history
  • Loading branch information
Muluo-cyan authored May 10, 2024
1 parent 37f90e8 commit d3e66e8
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 1 deletion.
44 changes: 43 additions & 1 deletion src/main/java/org/casbin/adapter/JDBCBaseAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.casbin.jcasbin.persist.Adapter;
import org.casbin.jcasbin.persist.BatchAdapter;
import org.casbin.jcasbin.persist.Helper;
import org.casbin.jcasbin.persist.UpdatableAdapter;

import javax.sql.DataSource;
import java.sql.*;
Expand All @@ -49,7 +50,7 @@ public String[] toStringArray() {
* JDBCAdapter is the JDBC adapter for jCasbin.
* It can load policy from JDBC supported database or save policy to it.
*/
abstract class JDBCBaseAdapter implements Adapter, BatchAdapter {
abstract class JDBCBaseAdapter implements Adapter, BatchAdapter, UpdatableAdapter {
protected static final String DEFAULT_TABLE_NAME = "casbin_rule";
protected static final boolean DEFAULT_REMOVE_POLICY_FAILED = false;
protected static final boolean DEFAULT_AUTO_CREATE_TABLE = true;
Expand Down Expand Up @@ -480,6 +481,47 @@ public void removeFilteredPolicy(String sec, String ptype, int fieldIndex, Strin
});
}

/**
* updatePolicy updates a policy rule from the current policy.
*/
@Override
public void updatePolicy(String sec, String ptype, List<String> oldRule, List<String> newRule) {
if (CollectionUtils.isEmpty(oldRule) || CollectionUtils.isEmpty(newRule)) {
return;
}

String sql = renderActualSql("INSERT INTO casbin_rule (ptype,v0,v1,v2,v3,v4,v5) VALUES(?,?,?,?,?,?,?)");


Failsafe.with(retryPolicy).run(ctx -> {
if (ctx.isRetry()) {
retry(ctx);
}
conn.setAutoCommit(false);
removePolicy(sec, ptype, oldRule);
try (PreparedStatement ps = conn.prepareStatement(sql)) {
CasbinRule line = this.savePolicyLine(ptype, newRule);

ps.setString(1, line.ptype);
ps.setString(2, line.v0);
ps.setString(3, line.v1);
ps.setString(4, line.v2);
ps.setString(5, line.v3);
ps.setString(6, line.v4);
ps.setString(7, line.v5);
ps.executeUpdate();
conn.commit();
} catch (SQLException e) {
conn.rollback();

e.printStackTrace();
throw e;
} finally {
conn.setAutoCommit(true);
}
});
}

/**
* Close the Connection.
*/
Expand Down
33 changes: 33 additions & 0 deletions src/test/java/org/casbin/adapter/JDBCAdapterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -257,4 +257,37 @@ public void testRemovePolicy() throws Exception {
asList("data2_admin", "data2", "read"),
asList("data2_admin", "data2", "write")));
}

@Test
public void testUpdatePolicy() throws Exception {
JDBCAdapter adapter = new MySQLAdapterCreator().create();

// Because the DB is empty at first,
// so we need to load the policy from the file adapter (.CSV) first.
Enforcer e = new Enforcer("examples/rbac_model.conf", "examples/rbac_policy.csv");

// This is a trick to save the current policy to the DB.
// We can't call e.savePolicy() because the adapter in the enforcer is still the file adapter.
// The current policy means the policy in the jCasbin enforcer (aka in memory).
adapter.savePolicy(e.getModel());

e.clearPolicy();
testGetPolicy(e, asList());

e = new Enforcer("examples/rbac_model.conf", adapter);
testGetPolicy(e, asList(
asList("alice", "data1", "read"),
asList("bob", "data2", "write"),
asList("data2_admin", "data2", "read"),
asList("data2_admin", "data2", "write")));

adapter.updatePolicy("p", "p", asList("bob", "data2", "write"), asList("alice", "data2", "read"));
e = new Enforcer("examples/rbac_model.conf", adapter);
testGetPolicy(e, asList(
asList("alice", "data1", "read"),
asList("data2_admin", "data2", "read"),
asList("data2_admin", "data2", "write"),
asList("alice", "data2", "read")));

}
}

0 comments on commit d3e66e8

Please sign in to comment.