use of com.jd.blockchain.ledger.core.UserAccountSet in project jdchain-core by blockchain-jd-com.
the class LedgerSecurityManagerTest method testGetSecurityPolicy.
@Test
public void testGetSecurityPolicy() {
MemoryKVStorage testStorage = new MemoryKVStorage();
// 定义不同角色用户的 keypair;
final BlockchainKeypair kpManager = BlockchainKeyGenerator.getInstance().generate();
final BlockchainKeypair kpEmployee = BlockchainKeyGenerator.getInstance().generate();
final BlockchainKeypair kpDevoice = BlockchainKeyGenerator.getInstance().generate();
final BlockchainKeypair kpPlatform = BlockchainKeyGenerator.getInstance().generate();
// 定义角色和权限;
final String ROLE_ADMIN = "ID_ADMIN";
final String ROLE_OPERATOR = "OPERATOR";
final String ROLE_DATA_COLLECTOR = "DATA_COLLECTOR";
final String ROLE_PLATFORM = "PLATFORM";
// 定义管理员角色的权限:【账本权限只允许:注册用户、注册数据账户】【交易权限只允许:调用账本直接操作】
final Privileges PRIVILEGES_ADMIN = Privileges.configure().enable(LedgerPermission.REGISTER_USER, LedgerPermission.REGISTER_DATA_ACCOUNT).enable(TransactionPermission.DIRECT_OPERATION);
// 定义操作员角色的权限:【账本权限只允许:写入数据账户】【交易权限只允许:调用合约】
final Privileges PRIVILEGES_OPERATOR = Privileges.configure().enable(LedgerPermission.WRITE_DATA_ACCOUNT).enable(TransactionPermission.CONTRACT_OPERATION);
// 定义数据收集器角色的权限:【账本权限只允许:写入数据账户】【交易权限只允许:调用账本直接操作】
final Privileges PRIVILEGES_DATA_COLLECTOR = Privileges.configure().enable(LedgerPermission.WRITE_DATA_ACCOUNT).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[] employeeRoles = new String[] { ROLE_OPERATOR };
String[] devoiceRoles = new String[] { ROLE_DATA_COLLECTOR };
String[] platformRoles = new String[] { ROLE_PLATFORM };
UserRoleDatasetEditor 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();
ParticipantCollection partisQuery = Mockito.mock(ParticipantCollection.class);
UserAccountSet usersQuery = Mockito.mock(UserAccountSet.class);
// 创建安全管理器;
LedgerSecurityManager securityManager = new LedgerSecurityManagerImpl(rolePrivilegeDataset, userRolesDataset, partisQuery, usersQuery);
// 定义终端用户列表;终端用户一起共同具有 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.getSecurityPolicy(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.isEndpointEnable(p, MultiIDsPolicy.AT_LEAST_ONE));
} else {
assertFalse(policy.isEndpointEnable(p, MultiIDsPolicy.AT_LEAST_ONE));
}
if (p == LedgerPermission.APPROVE_TX) {
// 共识参与方只有 PLATFORM 角色的权限:核准交易;
assertTrue(policy.isNodeEnable(p, MultiIDsPolicy.AT_LEAST_ONE));
} else {
assertFalse(policy.isNodeEnable(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.isEndpointEnable(p, MultiIDsPolicy.AT_LEAST_ONE));
} else {
assertFalse(policy.isEndpointEnable(p, MultiIDsPolicy.AT_LEAST_ONE));
}
assertFalse(policy.isNodeEnable(p, MultiIDsPolicy.AT_LEAST_ONE));
}
}
use of com.jd.blockchain.ledger.core.UserAccountSet in project jdchain-core by blockchain-jd-com.
the class LedgerManagerTest method testLedgerInit.
@Test
public void testLedgerInit() {
// 创建账本初始化配置;
LedgerInitSetting initSetting = createLedgerInitSetting();
// 采用基于内存的 Storage;
MemoryKVStorage storage = new MemoryKVStorage();
// 新建账本;
LedgerEditor ldgEdt = LedgerInitializer.createLedgerEditor(initSetting, storage);
// 创建一个模拟的创世交易;
TransactionRequest genesisTxReq = LedgerTestUtils.createLedgerInitTxRequest_SHA256(participants);
// 记录交易,注册用户;
LedgerTransactionContext txCtx = ldgEdt.newTransaction(genesisTxReq);
LedgerDataSetEditor ldgDS = (LedgerDataSetEditor) txCtx.getDataset();
BlockchainKeypair userKP = BlockchainKeyGenerator.getInstance().generate();
UserAccount userAccount = ldgDS.getUserAccountSet().register(userKP.getAddress(), userKP.getPubKey());
userAccount.setProperty("Name", "孙悟空", -1);
userAccount.setProperty("Age", "10000", -1);
System.out.println("UserAddress=" + userAccount.getAddress());
// 提交交易结果;
TransactionResult tx = txCtx.commit(TransactionState.SUCCESS);
assertEquals(genesisTxReq.getTransactionHash(), tx.getTransactionHash());
assertEquals(0, tx.getBlockHeight());
// 生成区块;
LedgerBlock genesisBlock = ldgEdt.prepare();
HashDigest ledgerHash = genesisBlock.getHash();
assertEquals(0, genesisBlock.getHeight());
assertNotNull(genesisBlock.getHash());
assertNull(genesisBlock.getPreviousHash());
// 创世区块的账本hash 为null;创世区块本身的哈希就代表了账本的哈希;
assertNull(genesisBlock.getLedgerHash());
// 提交数据,写入存储;
ldgEdt.commit();
assertNull(genesisBlock.getLedgerHash());
assertNotNull(genesisBlock.getHash());
// 重新加载并校验结果;
LedgerManager reloadLedgerManager = new LedgerManager();
LedgerRepository reloadLedgerRepo = reloadLedgerManager.register(ledgerHash, storage, LedgerDataStructure.MERKLE_TREE);
HashDigest genesisHash = reloadLedgerRepo.getBlockHash(0);
assertEquals(ledgerHash, genesisHash);
LedgerBlock latestBlock = reloadLedgerRepo.getLatestBlock();
assertEquals(0, latestBlock.getHeight());
assertEquals(ledgerHash, latestBlock.getHash());
// 创世区块的账本hash 为null;创世区块本身的哈希就代表了账本的哈希;
assertNull(latestBlock.getLedgerHash());
LedgerEditor editor1 = reloadLedgerRepo.createNextBlock();
CryptoSetting cryptoSetting = reloadLedgerRepo.getAdminInfo().getSettings().getCryptoSetting();
TxBuilder txBuilder = new TxBuilder(ledgerHash, cryptoSetting.getHashAlgorithm());
BlockchainKeypair dataKey = BlockchainKeyGenerator.getInstance().generate();
txBuilder.dataAccounts().register(dataKey.getIdentity());
TransactionRequestBuilder txReqBuilder = txBuilder.prepareRequest();
DigitalSignature dgtsign = txReqBuilder.signAsEndpoint(userKP);
TransactionRequest txRequest = txReqBuilder.buildRequest();
LedgerTransactionContext txCtx1 = editor1.newTransaction(txRequest);
((DataAccountSetEditor) (txCtx1.getDataset().getDataAccountSet())).register(dataKey.getAddress(), dataKey.getPubKey(), null);
txCtx1.commit(TransactionState.SUCCESS);
LedgerBlock block1 = editor1.prepare();
editor1.commit();
assertEquals(1, block1.getHeight());
assertNotNull(block1.getHash());
assertEquals(genesisHash, block1.getPreviousHash());
assertEquals(ledgerHash, block1.getLedgerHash());
latestBlock = reloadLedgerRepo.getLatestBlock();
assertEquals(1, latestBlock.getHeight());
assertEquals(block1.getHash(), latestBlock.getHash());
showStorageKeys(storage);
reloadLedgerManager = new LedgerManager();
reloadLedgerRepo = reloadLedgerManager.register(ledgerHash, storage, LedgerDataStructure.MERKLE_TREE);
latestBlock = reloadLedgerRepo.getLatestBlock();
assertEquals(1, latestBlock.getHeight());
assertEquals(block1.getHash(), latestBlock.getHash());
DataAccountSet dataAccountSet = reloadLedgerRepo.getDataAccountSet(latestBlock);
UserAccountSet userAccountSet = reloadLedgerRepo.getUserAccountSet(latestBlock);
ContractAccountSet contractAccountSet = reloadLedgerRepo.getContractAccountSet(latestBlock);
}
use of com.jd.blockchain.ledger.core.UserAccountSet in project jdchain-core by blockchain-jd-com.
the class LedgerQueryController method getUserCount.
@RequestMapping(method = RequestMethod.GET, path = GET_USER_COUNT_ON_BLOCK_HASH)
@Override
public long getUserCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, @PathVariable(name = "blockHash") HashDigest blockHash) {
LedgerQuery ledger = ledgerService.getLedger(ledgerHash);
LedgerBlock block = ledger.getBlock(blockHash);
if (null == block) {
return 0;
}
UserAccountSet userAccountSet = ledger.getUserAccountSet(block);
return userAccountSet.getTotal();
}
use of com.jd.blockchain.ledger.core.UserAccountSet in project jdchain-core by blockchain-jd-com.
the class LedgerQueryController method getUsers.
/**
* get more users by fromIndex and count;
*
* @param ledgerHash
* @param fromIndex
* @param count
* @return
*/
@RequestMapping(method = RequestMethod.GET, path = GET_USER_SEQUENCE)
@Override
public BlockchainIdentity[] getUsers(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, @RequestParam(name = "fromIndex", required = false, defaultValue = "0") int fromIndex, @RequestParam(name = "count", required = false, defaultValue = "-1") int count) {
LedgerQuery ledger = ledgerService.getLedger(ledgerHash);
LedgerBlock block = ledger.getLatestBlock();
UserAccountSet userAccountSet = ledger.getUserAccountSet(block);
QueryArgs queryArgs = QueryUtils.calFromIndexAndCountDescend(fromIndex, count, (int) userAccountSet.getTotal());
SkippingIterator<BlockchainIdentity> it = userAccountSet.identityIterator();
it.skip(queryArgs.getFrom());
return it.next(queryArgs.getCount(), BlockchainIdentity.class);
}
use of com.jd.blockchain.ledger.core.UserAccountSet in project jdchain-core by blockchain-jd-com.
the class LedgerQueryController method getUserTotalCount.
@RequestMapping(method = RequestMethod.GET, path = GET_TOTAL_USER_COUNT)
@Override
public long getUserTotalCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash) {
LedgerQuery ledger = ledgerService.getLedger(ledgerHash);
LedgerBlock block = ledger.getLatestBlock();
UserAccountSet userAccountSet = ledger.getUserAccountSet(block);
return userAccountSet.getTotal();
}
Aggregations