Browse Source

Added batch authorization API;

tags/1.1.0
huanghaiquan 5 years ago
parent
commit
85021535a6
8 changed files with 150 additions and 76 deletions
  1. +19
    -14
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/handles/UserAuthorizeOperationHandle.java
  2. +2
    -2
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserAuthorizeOperation.java
  3. +2
    -2
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/UserAuthorize.java
  4. +17
    -20
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/UserAuthorizeOpTemplate.java
  5. +1
    -1
      source/ledger/ledger-model/src/test/resources/ledger.init
  6. +44
    -37
      source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDKDemo_RegisterUser.java
  7. +64
    -0
      source/test/test-integration/src/test/resources/ledger_init_test.init
  8. +1
    -0
      source/utils/utils-common/src/main/java/com/jd/blockchain/utils/ArrayUtils.java

+ 19
- 14
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/handles/UserAuthorizeOperationHandle.java View File

@@ -18,6 +18,7 @@ import com.jd.blockchain.ledger.core.OperationHandleContext;
import com.jd.blockchain.ledger.core.SecurityContext; import com.jd.blockchain.ledger.core.SecurityContext;
import com.jd.blockchain.ledger.core.SecurityPolicy; import com.jd.blockchain.ledger.core.SecurityPolicy;
import com.jd.blockchain.ledger.core.TransactionRequestExtension; import com.jd.blockchain.ledger.core.TransactionRequestExtension;
import com.jd.blockchain.utils.Bytes;


public class UserAuthorizeOperationHandle extends AbstractLedgerOperationHandle<UserAuthorizeOperation> { public class UserAuthorizeOperationHandle extends AbstractLedgerOperationHandle<UserAuthorizeOperation> {
public UserAuthorizeOperationHandle() { public UserAuthorizeOperationHandle() {
@@ -49,21 +50,25 @@ public class UserAuthorizeOperationHandle extends AbstractLedgerOperationHandle<
} }
} }
} }
UserRoles ur = urSettings.getUserRoles(urcfg.getUserAddress());
if (ur == null) {
RolesPolicy policy = urcfg.getPolicy();
if (policy == null) {
policy = RolesPolicy.UNION;
}
urSettings.addUserRoles(urcfg.getUserAddress(), policy, validRoles);
} else {
ur.addRoles(validRoles);
ur.removeRoles(urcfg.getUnauthorizedRoles());
for (Bytes address : urcfg.getUserAddresses()) {
UserRoles ur = urSettings.getUserRoles(address);
if (ur == null) {
// 这是新的授权;
RolesPolicy policy = urcfg.getPolicy();
if (policy == null) {
policy = RolesPolicy.UNION;
}
urSettings.addUserRoles(address, policy, validRoles);
} else {
// 更改之前的授权;
ur.addRoles(validRoles);
ur.removeRoles(urcfg.getUnauthorizedRoles());


// 如果请求中设置了策略,才进行更新;
RolesPolicy policy = urcfg.getPolicy();
if (policy != null) {
ur.setPolicy(policy);
// 如果请求中设置了策略,才进行更新;
RolesPolicy policy = urcfg.getPolicy();
if (policy != null) {
ur.setPolicy(policy);
}
} }
} }
} }


+ 2
- 2
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserAuthorizeOperation.java View File

@@ -26,8 +26,8 @@ public interface UserAuthorizeOperation extends Operation {
* *
* @return * @return
*/ */
@DataField(order = 0, primitiveType = PrimitiveType.BYTES)
Bytes getUserAddress();
@DataField(order = 0, primitiveType = PrimitiveType.BYTES, list = true)
Bytes[] getUserAddresses();
/** /**
* 要更新的多角色权限策略; * 要更新的多角色权限策略;


+ 2
- 2
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/UserAuthorize.java View File

@@ -5,8 +5,8 @@ import com.jd.blockchain.utils.Bytes;


public interface UserAuthorize { public interface UserAuthorize {


UserRolesAuthorizer forUser(BlockchainIdentity userId);
UserRolesAuthorizer forUser(BlockchainIdentity... userId);


UserRolesAuthorizer forUser(Bytes userAddress);
UserRolesAuthorizer forUser(Bytes... userAddress);


} }

+ 17
- 20
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/UserAuthorizeOpTemplate.java View File

@@ -1,9 +1,8 @@
package com.jd.blockchain.transaction; package com.jd.blockchain.transaction;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set; import java.util.Set;
import com.jd.blockchain.binaryproto.DataContractRegistry; import com.jd.blockchain.binaryproto.DataContractRegistry;
@@ -21,8 +20,8 @@ public class UserAuthorizeOpTemplate implements UserAuthorizer, UserAuthorizeOpe
DataContractRegistry.register(UserRegisterOperation.class); DataContractRegistry.register(UserRegisterOperation.class);
} }
private Map<Bytes, UserRolesAuthorization> userAuthMap = Collections
.synchronizedMap(new LinkedHashMap<Bytes, UserRolesAuthorization>());
private Set<UserRolesAuthorization> userAuthMap = Collections
.synchronizedSet(new LinkedHashSet<UserRolesAuthorization>());
public UserAuthorizeOpTemplate() { public UserAuthorizeOpTemplate() {
} }
@@ -32,7 +31,7 @@ public class UserAuthorizeOpTemplate implements UserAuthorizer, UserAuthorizeOpe
@Override @Override
public UserRolesAuthorization[] getUserRolesAuthorizations() { public UserRolesAuthorization[] getUserRolesAuthorizations() {
return ArrayUtils.toArray(userAuthMap.values(), UserRolesAuthorization.class);
return ArrayUtils.toArray(userAuthMap, UserRolesAuthorization.class);
} }
@Override @Override
@@ -41,35 +40,33 @@ public class UserAuthorizeOpTemplate implements UserAuthorizer, UserAuthorizeOpe
} }
@Override @Override
public UserRolesAuthorizer forUser(Bytes userAddress) {
UserRolesAuthorization userRolesAuth = userAuthMap.get(userAddress);
if (userRolesAuth == null) {
userRolesAuth = new UserRolesAuthorization(userAddress);
userAuthMap.put(userAddress, userRolesAuth);
}
public UserRolesAuthorizer forUser(Bytes... userAddresses) {
UserRolesAuthorization userRolesAuth = new UserRolesAuthorization(userAddresses);
userAuthMap.add(userRolesAuth);
return userRolesAuth; return userRolesAuth;
} }
@Override @Override
public UserRolesAuthorizer forUser(BlockchainIdentity userId) {
return forUser(userId.getAddress());
public UserRolesAuthorizer forUser(BlockchainIdentity... userIds) {
Bytes[] addresses = Arrays.stream(userIds).map(p -> p.getAddress()).toArray(Bytes[]::new);
return forUser(addresses);
} }
private class UserRolesAuthorization implements UserRolesAuthorizer, UserRolesEntry { private class UserRolesAuthorization implements UserRolesAuthorizer, UserRolesEntry {
private Bytes userAddress;
private Bytes[] userAddress;
private RolesPolicy policy = RolesPolicy.UNION; private RolesPolicy policy = RolesPolicy.UNION;
private Set<String> authRoles = new LinkedHashSet<String>(); private Set<String> authRoles = new LinkedHashSet<String>();
private Set<String> unauthRoles = new LinkedHashSet<String>(); private Set<String> unauthRoles = new LinkedHashSet<String>();
private UserRolesAuthorization(Bytes userAddress) {
private UserRolesAuthorization(Bytes[] userAddress) {
this.userAddress = userAddress; this.userAddress = userAddress;
} }
@Override @Override
public Bytes getUserAddress() {
public Bytes[] getUserAddresses() {
return userAddress; return userAddress;
} }
@@ -119,13 +116,13 @@ public class UserAuthorizeOpTemplate implements UserAuthorizer, UserAuthorizeOpe
} }
@Override @Override
public UserRolesAuthorizer forUser(BlockchainIdentity userId) {
return UserAuthorizeOpTemplate.this.forUser(userId);
public UserRolesAuthorizer forUser(BlockchainIdentity... userIds) {
return UserAuthorizeOpTemplate.this.forUser(userIds);
} }
@Override @Override
public UserRolesAuthorizer forUser(Bytes userAddress) {
return UserAuthorizeOpTemplate.this.forUser(userAddress);
public UserRolesAuthorizer forUser(Bytes... userAddresses) {
return UserAuthorizeOpTemplate.this.forUser(userAddresses);
} }
} }
} }

+ 1
- 1
source/ledger/ledger-model/src/test/resources/ledger.init View File

@@ -65,7 +65,7 @@ com.jd.blockchain.crypto.service.sm.SMCryptoService
crypto.verify-hash=true crypto.verify-hash=true


#哈希算法; #哈希算法;
crypto.hash-algorithm=SHA256;
crypto.hash-algorithm=SHA256




#参与方的个数,后续以 cons_parti.id 分别标识每一个参与方的配置; #参与方的个数,后续以 cons_parti.id 分别标识每一个参与方的配置;


+ 44
- 37
source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDKDemo_RegisterUser.java View File

@@ -20,60 +20,67 @@ import com.jd.blockchain.utils.ConsoleUtils;


/** /**
* 注册用户 * 注册用户
*
* @author shaozhuguang * @author shaozhuguang
* @create 2018/10/18 * @create 2018/10/18
* @since 1.0.0 * @since 1.0.0
*/ */


public class SDKDemo_RegisterUser { public class SDKDemo_RegisterUser {
public static void main(String[] args) {
public static void main(String[] args) {


String GATEWAY_IPADDR = "127.0.0.1";
int GATEWAY_PORT = 8081;
if (args != null && args.length == 2) {
GATEWAY_IPADDR = args[0];
GATEWAY_PORT = Integer.parseInt(args[1]);
}
String GATEWAY_IPADDR = "127.0.0.1";
int GATEWAY_PORT = 8081;
if (args != null && args.length == 2) {
GATEWAY_IPADDR = args[0];
GATEWAY_PORT = Integer.parseInt(args[1]);
}


// 注册相关class
DataContractRegistry.register(TransactionContent.class);
DataContractRegistry.register(TransactionContentBody.class);
DataContractRegistry.register(TransactionRequest.class);
DataContractRegistry.register(NodeRequest.class);
DataContractRegistry.register(EndpointRequest.class);
DataContractRegistry.register(TransactionResponse.class);
// 注册相关class
DataContractRegistry.register(TransactionContent.class);
DataContractRegistry.register(TransactionContentBody.class);
DataContractRegistry.register(TransactionRequest.class);
DataContractRegistry.register(NodeRequest.class);
DataContractRegistry.register(EndpointRequest.class);
DataContractRegistry.register(TransactionResponse.class);


PrivKey privKey = SDKDemo_Params.privkey1;
PubKey pubKey = SDKDemo_Params.pubKey1;
PrivKey privKey = SDKDemo_Params.privkey1;
PubKey pubKey = SDKDemo_Params.pubKey1;


BlockchainKeypair CLIENT_CERT = new BlockchainKeypair(SDKDemo_Params.pubKey0, SDKDemo_Params.privkey0);
BlockchainKeypair CLIENT_CERT = new BlockchainKeypair(SDKDemo_Params.pubKey0, SDKDemo_Params.privkey0);


boolean SECURE = false;
GatewayServiceFactory serviceFactory = GatewayServiceFactory.connect(GATEWAY_IPADDR, GATEWAY_PORT, SECURE,
CLIENT_CERT);
BlockchainService service = serviceFactory.getBlockchainService();
boolean SECURE = false;
GatewayServiceFactory serviceFactory = GatewayServiceFactory.connect(GATEWAY_IPADDR, GATEWAY_PORT, SECURE,
CLIENT_CERT);
BlockchainService service = serviceFactory.getBlockchainService();


HashDigest[] ledgerHashs = service.getLedgerHashs();
// 在本地定义注册账号的 TX;
TransactionTemplate txTemp = service.newTransaction(ledgerHashs[0]);
HashDigest[] ledgerHashs = service.getLedgerHashs();
// 在本地定义注册账号的 TX;
TransactionTemplate txTemp = service.newTransaction(ledgerHashs[0]);


//existed signer
AsymmetricKeypair keyPair = new BlockchainKeypair(pubKey, privKey);
// existed signer
AsymmetricKeypair keyPair = new BlockchainKeypair(pubKey, privKey);


BlockchainKeypair user = BlockchainKeyGenerator.getInstance().generate();
BlockchainKeypair user = BlockchainKeyGenerator.getInstance().generate();


// 注册
txTemp.users().register(user.getIdentity());
// 注册
txTemp.users().register(user.getIdentity());


// TX 准备就绪;
PreparedTransaction prepTx = txTemp.prepare();
// 定义角色权限;
txTemp.security().roles().configure("MANAGER")
.enable(LedgerPermission.REGISTER_USER, LedgerPermission.REGISTER_DATA_ACCOUNT)
.enable(TransactionPermission.CONTRACT_OPERATION);
txTemp.security().authorziations().forUser(user.getIdentity()).authorize("MANAGER");


// 使用私钥进行签名;
prepTx.sign(keyPair);
// TX 准备就绪
PreparedTransaction prepTx = txTemp.prepare();


// 提交交易
TransactionResponse transactionResponse = prepTx.commit();
// 使用私钥进行签名
prepTx.sign(keyPair);


ConsoleUtils.info("register user complete, result is [%s]", transactionResponse.isSuccess());
}
// 提交交易;
TransactionResponse transactionResponse = prepTx.commit();

ConsoleUtils.info("register user complete, result is [%s]", transactionResponse.isSuccess());
}
} }

+ 64
- 0
source/test/test-integration/src/test/resources/ledger_init_test.init View File

@@ -8,6 +8,48 @@ ledger.name=TEST-LEDGER
#声明的账本创建时间;格式为 “yyyy-MM-dd HH:mm:ss.SSSZ”,表示”年-月-日 时:分:秒:毫秒时区“;例如:“2019-08-01 14:26:58.069+0800”,其中,+0800 表示时区是东8区 #声明的账本创建时间;格式为 “yyyy-MM-dd HH:mm:ss.SSSZ”,表示”年-月-日 时:分:秒:毫秒时区“;例如:“2019-08-01 14:26:58.069+0800”,其中,+0800 表示时区是东8区
created-time=2019-08-01 14:26:58.069+0800 created-time=2019-08-01 14:26:58.069+0800


#-----------------------------------------------
# 初始的角色名称列表;可选项;
# 角色名称不区分大小写,最长不超过20个字符;多个角色名称之间用半角的逗点“,”分隔;
# 系统会预置一个默认角色“DEFAULT”,所有未指定角色的用户都以赋予该角色的权限;若初始化时未配置默认角色的权限,则为默认角色分配所有权限;
#
# 注:如果声明了角色,但未声明角色对应的权限清单,这会忽略该角色的初始化;
#
security.roles=DEFAULT, ADMIN, MANAGER, GUEST

# 赋予角色的账本权限清单;可选项;
# 可选的权限如下;
# AUTHORIZE_ROLES, SET_CONSENSUS, SET_CRYPTO, REGISTER_PARTICIPANT,
# REGISTER_USER, REGISTER_DATA_ACCOUNT, REGISTER_CONTRACT, UPGRADE_CONTRACT,
# SET_USER_ATTRIBUTES, WRITE_DATA_ACCOUNT,
# APPROVE_TX, CONSENSUS_TX
# 多项权限之间用逗点“,”分隔;
#
security.role.DEFAULT.ledger-privileges=REGISTER_USER, REGISTER_DATA_ACCOUNT

# 赋予角色的交易权限清单;可选项;
# 可选的权限如下;
# DIRECT_OPERATION, CONTRACT_OPERATION
# 多项权限之间用逗点“,”分隔;
#
security.role.DEFAULT.tx-privileges=DIRECT_OPERATION, CONTRACT_OPERATION

# 其它角色的配置示例;
# 系统管理员角色:只能操作全局性的参数配置和用户注册,只能执行直接操作指令;
security.role.ADMIN.ledger-privileges=CONFIGURE_ROLES, AUTHORIZE_USER_ROLES, SET_CONSENSUS, SET_CRYPTO, REGISTER_PARTICIPANT, REGISTER_USER
security.role.ADMIN.tx-privileges=DIRECT_OPERATION

# 业务主管角色:只能够执行账本数据相关的操作,包括注册用户、注册数据账户、注册合约、升级合约、写入数据等;能够执行直接操作指令和调用合约;
security.role.MANAGER.ledger-privileges=CONFIGURE_ROLES, AUTHORIZE_USER_ROLES, REGISTER_USER, REGISTER_DATA_ACCOUNT, REGISTER_CONTRACT, UPGRADE_CONTRACT, SET_USER_ATTRIBUTES, WRITE_DATA_ACCOUNT,
security.role.MANAGER.tx-privileges=DIRECT_OPERATION, CONTRACT_OPERATION

# 访客角色:不具备任何的账本权限,只有数据读取的操作;也只能够通过调用合约来读取数据;
security.role.GUEST.ledger-privileges=
security.role.GUEST.tx-privileges=CONTRACT_OPERATION



#-----------------------------------------------
#共识服务提供者;必须; #共识服务提供者;必须;
consensus.service-provider=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider consensus.service-provider=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider


@@ -18,6 +60,12 @@ consensus.conf=classpath:bftsmart.config
crypto.service-providers=com.jd.blockchain.crypto.service.classic.ClassicCryptoService, \ crypto.service-providers=com.jd.blockchain.crypto.service.classic.ClassicCryptoService, \
com.jd.blockchain.crypto.service.sm.SMCryptoService com.jd.blockchain.crypto.service.sm.SMCryptoService


#从存储中加载账本数据时,是否校验哈希;可选;
crypto.verify-hash=true

#哈希算法;
crypto.hash-algorithm=SHA256

#参与方的个数,后续以 cons_parti.id 分别标识每一个参与方的配置; #参与方的个数,后续以 cons_parti.id 分别标识每一个参与方的配置;
cons_parti.count=4 cons_parti.count=4


@@ -27,6 +75,10 @@ cons_parti.0.name=jd.com
cons_parti.0.pubkey-path=keys/jd-com.pub cons_parti.0.pubkey-path=keys/jd-com.pub
#第0个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; #第0个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数;
cons_parti.0.pubkey=3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9 cons_parti.0.pubkey=3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9
#第0个参与方的角色清单;可选项;
cons_parti.0.roles=ADMIN, MANAGER
#第0个参与方的角色权限策略,可选值有:UNION(并集),INTERSECT(交集);可选项;
cons_parti.0.roles-policy=UNION
#第0个参与方的共识服务的主机地址; #第0个参与方的共识服务的主机地址;
cons_parti.0.consensus.host=127.0.0.1 cons_parti.0.consensus.host=127.0.0.1
#第0个参与方的共识服务的端口; #第0个参与方的共识服务的端口;
@@ -46,6 +98,10 @@ cons_parti.1.name=at.com
cons_parti.1.pubkey-path=keys/at-com.pub cons_parti.1.pubkey-path=keys/at-com.pub
#第1个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; #第1个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数;
cons_parti.1.pubkey=3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX cons_parti.1.pubkey=3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX
#第1个参与方的角色清单;可选项;
cons_parti.1.roles=MANAGER
#第1个参与方的角色权限策略,可选值有:UNION(并集),INTERSECT(交集);可选项;
cons_parti.1.roles-policy=UNION
#第1个参与方的共识服务的主机地址; #第1个参与方的共识服务的主机地址;
cons_parti.1.consensus.host=127.0.0.1 cons_parti.1.consensus.host=127.0.0.1
#第1个参与方的共识服务的端口; #第1个参与方的共识服务的端口;
@@ -65,6 +121,10 @@ cons_parti.2.name=bt.com
cons_parti.2.pubkey-path=keys/bt-com.pub cons_parti.2.pubkey-path=keys/bt-com.pub
#第2个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; #第2个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数;
cons_parti.2.pubkey=3snPdw7i7PZi6TStiyc6mzjprnNhgs2atSGNS8wPYzhbKaUWGFJt7x cons_parti.2.pubkey=3snPdw7i7PZi6TStiyc6mzjprnNhgs2atSGNS8wPYzhbKaUWGFJt7x
#第2个参与方的角色清单;可选项;
cons_parti.2.roles=MANAGER
#第2个参与方的角色权限策略,可选值有:UNION(并集),INTERSECT(交集);可选项;
cons_parti.2.roles-policy=UNION
#第2个参与方的共识服务的主机地址; #第2个参与方的共识服务的主机地址;
cons_parti.2.consensus.host=127.0.0.1 cons_parti.2.consensus.host=127.0.0.1
#第2个参与方的共识服务的端口; #第2个参与方的共识服务的端口;
@@ -84,6 +144,10 @@ cons_parti.3.name=xt.com
cons_parti.3.pubkey-path=keys/xt-com.pub cons_parti.3.pubkey-path=keys/xt-com.pub
#第3个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; #第3个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数;
cons_parti.3.pubkey=3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk cons_parti.3.pubkey=3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk
#第3个参与方的角色清单;可选项;
cons_parti.3.roles=GUEST
#第3个参与方的角色权限策略,可选值有:UNION(并集),INTERSECT(交集);可选项;
cons_parti.3.roles-policy=INTERSECT
#第3个参与方的共识服务的主机地址; #第3个参与方的共识服务的主机地址;
cons_parti.3.consensus.host=127.0.0.1 cons_parti.3.consensus.host=127.0.0.1
#第3个参与方的共识服务的端口; #第3个参与方的共识服务的端口;


+ 1
- 0
source/utils/utils-common/src/main/java/com/jd/blockchain/utils/ArrayUtils.java View File

@@ -9,6 +9,7 @@ import java.util.*;
*/ */
public abstract class ArrayUtils { public abstract class ArrayUtils {
private ArrayUtils() { private ArrayUtils() {
} }
public static <T> T[] singleton(T obj, Class<T> clazz) { public static <T> T[] singleton(T obj, Class<T> clazz) {


Loading…
Cancel
Save