@@ -6,8 +6,15 @@ import com.jd.blockchain.utils.Bytes; | |||||
public interface LedgerSecurityManager { | public interface LedgerSecurityManager { | ||||
String DEFAULT_ROLE = "_DEFAULT"; | |||||
String DEFAULT_ROLE = "DEFAULT"; | |||||
SecurityPolicy getSecurityPolicy(Set<Bytes> endpoints, Set<Bytes> nodes); | |||||
/** | |||||
* 创建一项与指定的终端用户和节点参与方相关的安全策略; | |||||
* | |||||
* @param endpoints 终端用户的地址列表; | |||||
* @param nodes 节点参与方的地址列表; | |||||
* @return 一项安全策略; | |||||
*/ | |||||
SecurityPolicy createSecurityPolicy(Set<Bytes> endpoints, Set<Bytes> nodes); | |||||
} | } |
@@ -29,8 +29,9 @@ public class LedgerSecurityManagerImpl implements LedgerSecurityManager { | |||||
private UserRoleSettings userRolesSettings; | private UserRoleSettings userRolesSettings; | ||||
//用户的权限配置 | |||||
private Map<Bytes, UserRolesPrivileges> userPrivilegesCache = new ConcurrentHashMap<>(); | private Map<Bytes, UserRolesPrivileges> userPrivilegesCache = new ConcurrentHashMap<>(); | ||||
private Map<Bytes, UserRoles> userRolesCache = new ConcurrentHashMap<>(); | private Map<Bytes, UserRoles> userRolesCache = new ConcurrentHashMap<>(); | ||||
private Map<String, RolePrivileges> rolesPrivilegeCache = new ConcurrentHashMap<>(); | private Map<String, RolePrivileges> rolesPrivilegeCache = new ConcurrentHashMap<>(); | ||||
@@ -40,8 +41,7 @@ public class LedgerSecurityManagerImpl implements LedgerSecurityManager { | |||||
} | } | ||||
@Override | @Override | ||||
public SecurityPolicy getSecurityPolicy(Set<Bytes> endpoints, Set<Bytes> nodes) { | |||||
public SecurityPolicy createSecurityPolicy(Set<Bytes> endpoints, Set<Bytes> nodes) { | |||||
Map<Bytes, UserRolesPrivileges> endpointPrivilegeMap = new HashMap<>(); | Map<Bytes, UserRolesPrivileges> endpointPrivilegeMap = new HashMap<>(); | ||||
Map<Bytes, UserRolesPrivileges> nodePrivilegeMap = new HashMap<>(); | Map<Bytes, UserRolesPrivileges> nodePrivilegeMap = new HashMap<>(); | ||||
@@ -90,7 +90,7 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { | |||||
TransactionRequestExtension reqExt = new TransactionRequestExtensionImpl(request); | TransactionRequestExtension reqExt = new TransactionRequestExtensionImpl(request); | ||||
// 初始化交易的用户安全策略; | // 初始化交易的用户安全策略; | ||||
SecurityPolicy securityPolicy = securityManager.getSecurityPolicy(reqExt.getEndpointAddresses(), | |||||
SecurityPolicy securityPolicy = securityManager.createSecurityPolicy(reqExt.getEndpointAddresses(), | |||||
reqExt.getNodeAddresses()); | reqExt.getNodeAddresses()); | ||||
SecurityContext.setContextUsersPolicy(securityPolicy); | SecurityContext.setContextUsersPolicy(securityPolicy); | ||||
@@ -200,7 +200,7 @@ public class ContractInvokingTest { | |||||
when(securityPolicy.isEnableToNodes(any(LedgerPermission.class), any())).thenReturn(true); | when(securityPolicy.isEnableToNodes(any(LedgerPermission.class), any())).thenReturn(true); | ||||
when(securityPolicy.isEnableToNodes(any(TransactionPermission.class), any())).thenReturn(true); | when(securityPolicy.isEnableToNodes(any(TransactionPermission.class), any())).thenReturn(true); | ||||
when(securityManager.getSecurityPolicy(any(), any())).thenReturn(securityPolicy); | |||||
when(securityManager.createSecurityPolicy(any(), any())).thenReturn(securityPolicy); | |||||
return securityManager; | return securityManager; | ||||
} | } | ||||
@@ -1,5 +1,6 @@ | |||||
package test.com.jd.blockchain.ledger.core; | package test.com.jd.blockchain.ledger.core; | ||||
import static org.junit.Assert.assertEquals; | |||||
import static org.junit.Assert.assertFalse; | import static org.junit.Assert.assertFalse; | ||||
import static org.junit.Assert.assertTrue; | import static org.junit.Assert.assertTrue; | ||||
@@ -18,10 +19,8 @@ import com.jd.blockchain.ledger.BlockchainKeypair; | |||||
import com.jd.blockchain.ledger.CryptoSetting; | import com.jd.blockchain.ledger.CryptoSetting; | ||||
import com.jd.blockchain.ledger.LedgerPermission; | import com.jd.blockchain.ledger.LedgerPermission; | ||||
import com.jd.blockchain.ledger.Privileges; | import com.jd.blockchain.ledger.Privileges; | ||||
import com.jd.blockchain.ledger.RolePrivilegeSettings; | |||||
import com.jd.blockchain.ledger.RolesPolicy; | import com.jd.blockchain.ledger.RolesPolicy; | ||||
import com.jd.blockchain.ledger.TransactionPermission; | import com.jd.blockchain.ledger.TransactionPermission; | ||||
import com.jd.blockchain.ledger.UserRoleSettings; | |||||
import com.jd.blockchain.ledger.core.CryptoConfig; | import com.jd.blockchain.ledger.core.CryptoConfig; | ||||
import com.jd.blockchain.ledger.core.LedgerSecurityManager; | import com.jd.blockchain.ledger.core.LedgerSecurityManager; | ||||
import com.jd.blockchain.ledger.core.LedgerSecurityManagerImpl; | import com.jd.blockchain.ledger.core.LedgerSecurityManagerImpl; | ||||
@@ -56,30 +55,18 @@ public class LedgerSecurityManagerTest { | |||||
CRYPTO_SETTINGS = cryptoConfig; | CRYPTO_SETTINGS = cryptoConfig; | ||||
} | } | ||||
private RolePrivilegeSettings initRoles(MemoryKVStorage testStorage, String[] roles, Privileges[] privilege) { | |||||
private RolePrivilegeDataset createRolePrivilegeDataset(MemoryKVStorage testStorage) { | |||||
String prefix = "role-privilege/"; | String prefix = "role-privilege/"; | ||||
RolePrivilegeDataset rolePrivilegeDataset = new RolePrivilegeDataset(CRYPTO_SETTINGS, prefix, testStorage, | RolePrivilegeDataset rolePrivilegeDataset = new RolePrivilegeDataset(CRYPTO_SETTINGS, prefix, testStorage, | ||||
testStorage); | testStorage); | ||||
for (int i = 0; i < roles.length; i++) { | |||||
rolePrivilegeDataset.addRolePrivilege(roles[i], privilege[i]); | |||||
} | |||||
rolePrivilegeDataset.commit(); | |||||
return rolePrivilegeDataset; | return rolePrivilegeDataset; | ||||
} | } | ||||
private UserRoleSettings initUserRoless(MemoryKVStorage testStorage, Bytes[] userAddresses, RolesPolicy[] policies, | |||||
String[][] roles) { | |||||
private UserRoleDataset createUserRoleDataset(MemoryKVStorage testStorage) { | |||||
String prefix = "user-roles/"; | String prefix = "user-roles/"; | ||||
UserRoleDataset userRolesDataset = new UserRoleDataset(CRYPTO_SETTINGS, prefix, testStorage, testStorage); | UserRoleDataset userRolesDataset = new UserRoleDataset(CRYPTO_SETTINGS, prefix, testStorage, testStorage); | ||||
for (int i = 0; i < userAddresses.length; i++) { | |||||
userRolesDataset.addUserRoles(userAddresses[i], policies[i], roles[i]); | |||||
} | |||||
userRolesDataset.commit(); | |||||
return userRolesDataset; | return userRolesDataset; | ||||
} | } | ||||
@@ -87,55 +74,102 @@ public class LedgerSecurityManagerTest { | |||||
public void testGetSecurityPolicy() { | public void testGetSecurityPolicy() { | ||||
MemoryKVStorage testStorage = new MemoryKVStorage(); | MemoryKVStorage testStorage = new MemoryKVStorage(); | ||||
// 定义不同角色用户的 keypair; | |||||
final BlockchainKeypair kpManager = BlockchainKeyGenerator.getInstance().generate(); | final BlockchainKeypair kpManager = BlockchainKeyGenerator.getInstance().generate(); | ||||
final BlockchainKeypair kpEmployee = BlockchainKeyGenerator.getInstance().generate(); | final BlockchainKeypair kpEmployee = BlockchainKeyGenerator.getInstance().generate(); | ||||
final BlockchainKeypair kpDevoice = BlockchainKeyGenerator.getInstance().generate(); | final BlockchainKeypair kpDevoice = BlockchainKeyGenerator.getInstance().generate(); | ||||
final Map<Bytes, BlockchainKeypair> endpoints = new HashMap<>(); | |||||
endpoints.put(kpManager.getAddress(), kpManager); | |||||
endpoints.put(kpEmployee.getAddress(), kpEmployee); | |||||
final Map<Bytes, BlockchainKeypair> nodes = new HashMap<>(); | |||||
nodes.put(kpDevoice.getAddress(), kpDevoice); | |||||
final BlockchainKeypair kpPlatform = BlockchainKeyGenerator.getInstance().generate(); | |||||
// 定义角色和权限; | |||||
final String ROLE_ADMIN = "ID_ADMIN"; | final String ROLE_ADMIN = "ID_ADMIN"; | ||||
final String ROLE_OPERATOR = "OPERATOR"; | final String ROLE_OPERATOR = "OPERATOR"; | ||||
final String ROLE_DATA_COLLECTOR = "DATA_COLLECTOR"; | final String ROLE_DATA_COLLECTOR = "DATA_COLLECTOR"; | ||||
final String ROLE_PLATFORM = "PLATFORM"; | |||||
// 定义管理员角色的权限:【账本权限只允许:注册用户、注册数据账户】【交易权限只允许:调用账本直接操作】 | |||||
final Privileges PRIVILEGES_ADMIN = Privileges.configure() | final Privileges PRIVILEGES_ADMIN = Privileges.configure() | ||||
.enable(LedgerPermission.REGISTER_USER, LedgerPermission.REGISTER_DATA_ACCOUNT) | .enable(LedgerPermission.REGISTER_USER, LedgerPermission.REGISTER_DATA_ACCOUNT) | ||||
.enable(TransactionPermission.DIRECT_OPERATION, TransactionPermission.CONTRACT_OPERATION); | |||||
.enable(TransactionPermission.DIRECT_OPERATION); | |||||
final Privileges PRIVILEGES_OPERATOR = Privileges.configure() | |||||
.enable(LedgerPermission.WRITE_DATA_ACCOUNT, LedgerPermission.APPROVE_TX) | |||||
// 定义操作员角色的权限:【账本权限只允许:写入数据账户】【交易权限只允许:调用合约】 | |||||
final Privileges PRIVILEGES_OPERATOR = Privileges.configure().enable(LedgerPermission.WRITE_DATA_ACCOUNT) | |||||
.enable(TransactionPermission.CONTRACT_OPERATION); | .enable(TransactionPermission.CONTRACT_OPERATION); | ||||
// 定义数据收集器角色的权限:【账本权限只允许:写入数据账户】【交易权限只允许:调用账本直接操作】 | |||||
final Privileges PRIVILEGES_DATA_COLLECTOR = Privileges.configure().enable(LedgerPermission.WRITE_DATA_ACCOUNT) | final Privileges PRIVILEGES_DATA_COLLECTOR = Privileges.configure().enable(LedgerPermission.WRITE_DATA_ACCOUNT) | ||||
.enable(TransactionPermission.CONTRACT_OPERATION); | |||||
RolePrivilegeSettings rolePrivilegeSettings = initRoles(testStorage, | |||||
new String[] { ROLE_ADMIN, ROLE_OPERATOR, ROLE_DATA_COLLECTOR }, | |||||
new Privileges[] { PRIVILEGES_ADMIN, PRIVILEGES_OPERATOR, PRIVILEGES_DATA_COLLECTOR }); | |||||
.enable(TransactionPermission.DIRECT_OPERATION); | |||||
// 定义平台角色的权限:【账本权限只允许:签署合约】 (只允许作为节点签署交易,不允许作为终端发起交易指令) | |||||
final Privileges PRIVILEGES_PLATFORM = Privileges.configure().enable(LedgerPermission.APPROVE_TX); | |||||
RolePrivilegeDataset rolePrivilegeDataset = createRolePrivilegeDataset(testStorage); | |||||
long v = rolePrivilegeDataset.addRolePrivilege(ROLE_ADMIN, PRIVILEGES_ADMIN); | |||||
assertTrue(v > -1); | |||||
v = rolePrivilegeDataset.addRolePrivilege(ROLE_OPERATOR, PRIVILEGES_OPERATOR); | |||||
assertTrue(v > -1); | |||||
v = rolePrivilegeDataset.addRolePrivilege(ROLE_DATA_COLLECTOR, PRIVILEGES_DATA_COLLECTOR); | |||||
assertTrue(v > -1); | |||||
v = rolePrivilegeDataset.addRolePrivilege(ROLE_PLATFORM, PRIVILEGES_PLATFORM); | |||||
assertTrue(v > -1); | |||||
rolePrivilegeDataset.commit(); | |||||
// 为用户分配角色; | |||||
String[] managerRoles = new String[] { ROLE_ADMIN, ROLE_OPERATOR }; | String[] managerRoles = new String[] { ROLE_ADMIN, ROLE_OPERATOR }; | ||||
String[] employeeRoles = new String[] { ROLE_OPERATOR }; | String[] employeeRoles = new String[] { ROLE_OPERATOR }; | ||||
String[] devoiceRoles = new String[] { ROLE_DATA_COLLECTOR }; | String[] devoiceRoles = new String[] { ROLE_DATA_COLLECTOR }; | ||||
UserRoleSettings userRolesSettings = initUserRoless(testStorage, | |||||
new Bytes[] { kpManager.getAddress(), kpEmployee.getAddress(), kpDevoice.getAddress() }, | |||||
new RolesPolicy[] { RolesPolicy.UNION, RolesPolicy.UNION, RolesPolicy.UNION }, | |||||
new String[][] { managerRoles, employeeRoles, devoiceRoles }); | |||||
LedgerSecurityManager securityManager = new LedgerSecurityManagerImpl(rolePrivilegeSettings, userRolesSettings); | |||||
SecurityPolicy policy = securityManager.getSecurityPolicy(endpoints.keySet(), nodes.keySet()); | |||||
assertTrue(policy.isEnableToEndpoints(LedgerPermission.REGISTER_USER, MultiIdsPolicy.AT_LEAST_ONE)); | |||||
assertTrue(policy.isEnableToEndpoints(LedgerPermission.REGISTER_DATA_ACCOUNT, MultiIdsPolicy.AT_LEAST_ONE)); | |||||
assertTrue(policy.isEnableToEndpoints(LedgerPermission.WRITE_DATA_ACCOUNT, MultiIdsPolicy.AT_LEAST_ONE)); | |||||
assertTrue(policy.isEnableToEndpoints(LedgerPermission.APPROVE_TX, MultiIdsPolicy.AT_LEAST_ONE)); | |||||
assertFalse(policy.isEnableToEndpoints(LedgerPermission.REGISTER_USER, MultiIdsPolicy.ALL)); | |||||
assertFalse(policy.isEnableToEndpoints(LedgerPermission.AUTHORIZE_ROLES, MultiIdsPolicy.AT_LEAST_ONE)); | |||||
String[] platformRoles = new String[] { ROLE_PLATFORM }; | |||||
UserRoleDataset userRolesDataset = createUserRoleDataset(testStorage); | |||||
userRolesDataset.addUserRoles(kpManager.getAddress(), RolesPolicy.UNION, managerRoles); | |||||
userRolesDataset.addUserRoles(kpEmployee.getAddress(), RolesPolicy.UNION, employeeRoles); | |||||
userRolesDataset.addUserRoles(kpDevoice.getAddress(), RolesPolicy.UNION, devoiceRoles); | |||||
userRolesDataset.addUserRoles(kpPlatform.getAddress(), RolesPolicy.UNION, platformRoles); | |||||
userRolesDataset.commit(); | |||||
// 创建安全管理器; | |||||
LedgerSecurityManager securityManager = new LedgerSecurityManagerImpl(rolePrivilegeDataset, userRolesDataset); | |||||
// 定义终端用户列表;终端用户一起共同具有 ADMIN、OPERATOR 角色; | |||||
final Map<Bytes, BlockchainKeypair> endpoints = new HashMap<>(); | |||||
endpoints.put(kpManager.getAddress(), kpManager); | |||||
endpoints.put(kpEmployee.getAddress(), kpEmployee); | |||||
// 定义节点参与方列表; | |||||
final Map<Bytes, BlockchainKeypair> nodes = new HashMap<>(); | |||||
nodes.put(kpPlatform.getAddress(), kpPlatform); | |||||
// 创建一项与指定的终端用户和节点参与方相关的安全策略; | |||||
SecurityPolicy policy = securityManager.createSecurityPolicy(endpoints.keySet(), nodes.keySet()); | |||||
// 校验安全策略的正确性; | |||||
LedgerPermission[] ledgerPermissions = LedgerPermission.values(); | |||||
for (LedgerPermission p : ledgerPermissions) { | |||||
// 终端节点有 ADMIN 和 OPERATOR 两种角色的合并权限; | |||||
if (p == LedgerPermission.REGISTER_USER || p == LedgerPermission.REGISTER_DATA_ACCOUNT | |||||
|| p == LedgerPermission.WRITE_DATA_ACCOUNT) { | |||||
assertTrue(policy.isEnableToEndpoints(p, MultiIdsPolicy.AT_LEAST_ONE)); | |||||
} else { | |||||
assertFalse(policy.isEnableToEndpoints(p, MultiIdsPolicy.AT_LEAST_ONE)); | |||||
} | |||||
if (p == LedgerPermission.APPROVE_TX) { | |||||
// 共识参与方只有 PLATFORM 角色的权限:核准交易; | |||||
assertTrue(policy.isEnableToNodes(p, MultiIdsPolicy.AT_LEAST_ONE)); | |||||
} else { | |||||
assertFalse(policy.isEnableToNodes(p, MultiIdsPolicy.AT_LEAST_ONE)); | |||||
} | |||||
} | |||||
TransactionPermission[] transactionPermissions = TransactionPermission.values(); | |||||
for (TransactionPermission p : transactionPermissions) { | |||||
// 终端节点有 ADMIN 和 OPERATOR 两种角色的合并权限; | |||||
if (p == TransactionPermission.DIRECT_OPERATION || p == TransactionPermission.CONTRACT_OPERATION) { | |||||
assertTrue(policy.isEnableToEndpoints(p, MultiIdsPolicy.AT_LEAST_ONE)); | |||||
} else { | |||||
assertFalse(policy.isEnableToEndpoints(p, MultiIdsPolicy.AT_LEAST_ONE)); | |||||
} | |||||
assertFalse(policy.isEnableToNodes(p, MultiIdsPolicy.AT_LEAST_ONE)); | |||||
} | |||||
} | } | ||||
} | } |
@@ -125,7 +125,7 @@ public class TransactionBatchProcessorTest { | |||||
when(securityPolicy.isEnableToNodes(any(LedgerPermission.class), any())).thenReturn(true); | when(securityPolicy.isEnableToNodes(any(LedgerPermission.class), any())).thenReturn(true); | ||||
when(securityPolicy.isEnableToNodes(any(TransactionPermission.class), any())).thenReturn(true); | when(securityPolicy.isEnableToNodes(any(TransactionPermission.class), any())).thenReturn(true); | ||||
when(securityManager.getSecurityPolicy(any(), any())).thenReturn(securityPolicy); | |||||
when(securityManager.createSecurityPolicy(any(), any())).thenReturn(securityPolicy); | |||||
return securityManager; | return securityManager; | ||||
} | } | ||||
@@ -45,7 +45,9 @@ public enum LedgerPermission { | |||||
/** | /** | ||||
* 参与方核准交易;<br> | * 参与方核准交易;<br> | ||||
* | * | ||||
* 如果不具备此项权限,则无法作为网关节点接入并签署由终端提交的交易; | |||||
* 如果不具备此项权限,则无法作为节点签署由终端提交的交易; | |||||
* <p> | |||||
* 只对交易请求的节点签名列表{@link TransactionRequest#getNodeSignatures()}的用户产生影响; | |||||
*/ | */ | ||||
APPROVE_TX((byte) 0x06), | APPROVE_TX((byte) 0x06), | ||||
@@ -11,17 +11,37 @@ import com.jd.blockchain.utils.io.BytesSerializable; | |||||
* | * | ||||
*/ | */ | ||||
public class PrivilegeBitset<E extends Enum<?>> implements Privilege<E>, BytesSerializable { | public class PrivilegeBitset<E extends Enum<?>> implements Privilege<E>, BytesSerializable { | ||||
// 加入前缀位,可避免序列化时输出空的字节数组; | |||||
private static final boolean[] PREFIX = { false, false, false, true, false, false, false, true }; | |||||
private static final int OFFSET = PREFIX.length; | |||||
private static final int MAX_SIZE = 256 - PREFIX.length; | |||||
private BitSet permissionBits; | private BitSet permissionBits; | ||||
private CodeIndexer<E> codeIndexer; | private CodeIndexer<E> codeIndexer; | ||||
public PrivilegeBitset(CodeIndexer<E> codeIndexer) { | public PrivilegeBitset(CodeIndexer<E> codeIndexer) { | ||||
this(new BitSet(), codeIndexer); | |||||
this.permissionBits = new BitSet(); | |||||
this.codeIndexer = codeIndexer; | |||||
// 设置前缀; | |||||
for (int i = 0; i < PREFIX.length; i++) { | |||||
permissionBits.set(i, PREFIX[i]); | |||||
} | |||||
} | } | ||||
public PrivilegeBitset(byte[] codeBytes, CodeIndexer<E> codeIndexer) { | public PrivilegeBitset(byte[] codeBytes, CodeIndexer<E> codeIndexer) { | ||||
this(BitSet.valueOf(codeBytes), codeIndexer); | |||||
if (codeBytes.length > MAX_SIZE) { | |||||
throw new IllegalArgumentException( | |||||
"The size of code bytes specified to PrivilegeBitset exceed the max size[" + MAX_SIZE + "]!"); | |||||
} | |||||
this.permissionBits = BitSet.valueOf(codeBytes); | |||||
this.codeIndexer = codeIndexer; | |||||
// 校验前缀; | |||||
for (int i = 0; i < PREFIX.length; i++) { | |||||
if (permissionBits.get(i) != PREFIX[i]) { | |||||
throw new IllegalArgumentException("The code bytes is not match the privilege prefix code!"); | |||||
} | |||||
} | |||||
} | } | ||||
private PrivilegeBitset(BitSet bits, CodeIndexer<E> codeIndexer) { | private PrivilegeBitset(BitSet bits, CodeIndexer<E> codeIndexer) { | ||||
@@ -30,28 +50,28 @@ public class PrivilegeBitset<E extends Enum<?>> implements Privilege<E>, BytesSe | |||||
} | } | ||||
public boolean isEnable(E permission) { | public boolean isEnable(E permission) { | ||||
return permissionBits.get(codeIndexer.getCodeIndex(permission)); | |||||
return permissionBits.get(index(permission)); | |||||
} | } | ||||
public void enable(E permission) { | public void enable(E permission) { | ||||
permissionBits.set(codeIndexer.getCodeIndex(permission)); | |||||
permissionBits.set(index(permission)); | |||||
} | } | ||||
public void disable(E permission) { | public void disable(E permission) { | ||||
permissionBits.clear(codeIndexer.getCodeIndex(permission)); | |||||
permissionBits.clear(index(permission)); | |||||
} | } | ||||
@SuppressWarnings("unchecked") | @SuppressWarnings("unchecked") | ||||
public void enable(E... permissions) { | public void enable(E... permissions) { | ||||
for (E p : permissions) { | for (E p : permissions) { | ||||
permissionBits.set(codeIndexer.getCodeIndex(p)); | |||||
permissionBits.set(index(p)); | |||||
} | } | ||||
} | } | ||||
@SuppressWarnings("unchecked") | @SuppressWarnings("unchecked") | ||||
public void disable(E... permissions) { | public void disable(E... permissions) { | ||||
for (E p : permissions) { | for (E p : permissions) { | ||||
permissionBits.clear(codeIndexer.getCodeIndex(p)); | |||||
permissionBits.clear(index(p)); | |||||
} | } | ||||
} | } | ||||
@@ -72,6 +92,7 @@ public class PrivilegeBitset<E extends Enum<?>> implements Privilege<E>, BytesSe | |||||
/** | /** | ||||
* 把指定的权限合并到当前的权限中; <br> | * 把指定的权限合并到当前的权限中; <br> | ||||
* | |||||
* @param privileges | * @param privileges | ||||
* @param offset | * @param offset | ||||
* @param count | * @param count | ||||
@@ -115,6 +136,10 @@ public class PrivilegeBitset<E extends Enum<?>> implements Privilege<E>, BytesSe | |||||
return new PrivilegeBitset<E>((BitSet) permissionBits.clone(), codeIndexer); | return new PrivilegeBitset<E>((BitSet) permissionBits.clone(), codeIndexer); | ||||
} | } | ||||
private int index(E permission) { | |||||
return OFFSET + codeIndexer.getCodeIndex(permission); | |||||
} | |||||
static interface CodeIndexer<E extends Enum<?>> { | static interface CodeIndexer<E extends Enum<?>> { | ||||
int getCodeIndex(E permission); | int getCodeIndex(E permission); | ||||
} | } | ||||
@@ -0,0 +1,92 @@ | |||||
package test.com.jd.blockchain.ledger; | |||||
import static org.junit.Assert.*; | |||||
import org.junit.Test; | |||||
import com.jd.blockchain.binaryproto.BinaryProtocol; | |||||
import com.jd.blockchain.ledger.LedgerPermission; | |||||
import com.jd.blockchain.ledger.PrivilegeSet; | |||||
import com.jd.blockchain.ledger.Privileges; | |||||
import com.jd.blockchain.ledger.TransactionPermission; | |||||
public class PrivilegesTest { | |||||
@Test | |||||
public void test() { | |||||
// 正常情形; | |||||
{ | |||||
Privileges privileges = Privileges.configure() | |||||
.enable(LedgerPermission.REGISTER_USER, LedgerPermission.APPROVE_TX) | |||||
.enable(TransactionPermission.DIRECT_OPERATION); | |||||
byte[] bytes = BinaryProtocol.encode(privileges, PrivilegeSet.class); | |||||
PrivilegeSet decodePrivileges = BinaryProtocol.decode(bytes); | |||||
assertNotNull(decodePrivileges.getLedgerPrivilege()); | |||||
assertNotNull(decodePrivileges.getTransactionPrivilege()); | |||||
for (LedgerPermission p : LedgerPermission.values()) { | |||||
if (p == LedgerPermission.REGISTER_USER || p == LedgerPermission.APPROVE_TX) { | |||||
assertTrue(decodePrivileges.getLedgerPrivilege().isEnable(p)); | |||||
} else { | |||||
assertFalse(decodePrivileges.getLedgerPrivilege().isEnable(p)); | |||||
} | |||||
} | |||||
for (TransactionPermission p : TransactionPermission.values()) { | |||||
if (p == TransactionPermission.DIRECT_OPERATION) { | |||||
assertTrue(decodePrivileges.getTransactionPrivilege().isEnable(p)); | |||||
} else { | |||||
assertFalse(decodePrivileges.getTransactionPrivilege().isEnable(p)); | |||||
} | |||||
} | |||||
} | |||||
// 只定义账本权限的情形; | |||||
{ | |||||
Privileges privileges = Privileges.configure().enable(LedgerPermission.REGISTER_USER, | |||||
LedgerPermission.APPROVE_TX); | |||||
byte[] bytes = BinaryProtocol.encode(privileges, PrivilegeSet.class); | |||||
PrivilegeSet decodePrivileges = BinaryProtocol.decode(bytes); | |||||
assertNotNull(decodePrivileges.getLedgerPrivilege()); | |||||
assertNotNull(decodePrivileges.getTransactionPrivilege()); | |||||
for (LedgerPermission p : LedgerPermission.values()) { | |||||
if (p == LedgerPermission.REGISTER_USER || p == LedgerPermission.APPROVE_TX) { | |||||
assertTrue(decodePrivileges.getLedgerPrivilege().isEnable(p)); | |||||
} else { | |||||
assertFalse(decodePrivileges.getLedgerPrivilege().isEnable(p)); | |||||
} | |||||
} | |||||
for (TransactionPermission p : TransactionPermission.values()) { | |||||
assertFalse(decodePrivileges.getTransactionPrivilege().isEnable(p)); | |||||
} | |||||
} | |||||
// 只定义交易权限的情形; | |||||
{ | |||||
Privileges privileges = Privileges.configure().enable(TransactionPermission.CONTRACT_OPERATION); | |||||
byte[] bytes = BinaryProtocol.encode(privileges, PrivilegeSet.class); | |||||
PrivilegeSet decodePrivileges = BinaryProtocol.decode(bytes); | |||||
assertNotNull(decodePrivileges.getLedgerPrivilege()); | |||||
assertNotNull(decodePrivileges.getTransactionPrivilege()); | |||||
for (LedgerPermission p : LedgerPermission.values()) { | |||||
assertFalse(decodePrivileges.getLedgerPrivilege().isEnable(p)); | |||||
} | |||||
for (TransactionPermission p : TransactionPermission.values()) { | |||||
if (p == TransactionPermission.CONTRACT_OPERATION) { | |||||
assertTrue(decodePrivileges.getTransactionPrivilege().isEnable(p)); | |||||
} else { | |||||
assertFalse(decodePrivileges.getTransactionPrivilege().isEnable(p)); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} |