@@ -8,12 +8,4 @@ | |||
<version>1.1.0-SNAPSHOT</version> | |||
</parent> | |||
<artifactId>base</artifactId> | |||
<dependencies> | |||
<dependency> | |||
<groupId>org.slf4j</groupId> | |||
<artifactId>slf4j-api</artifactId> | |||
</dependency> | |||
</dependencies> | |||
</project> |
@@ -75,7 +75,6 @@ | |||
<dependency> | |||
<groupId>commons-io</groupId> | |||
<artifactId>commons-io</artifactId> | |||
<version>${commons-io.version}</version> | |||
</dependency> | |||
<dependency> | |||
@@ -98,18 +97,13 @@ | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-web</artifactId> | |||
<exclusions> | |||
<exclusion> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-logging</artifactId> | |||
</exclusion> | |||
</exclusions> | |||
</dependency> | |||
<dependency> | |||
<!-- <dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-log4j2</artifactId> | |||
</dependency> | |||
</dependency> --> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
@@ -1,7 +1,9 @@ | |||
package com.jd.blockchain.ledger.core; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
import java.util.Map.Entry; | |||
import java.util.concurrent.ConcurrentHashMap; | |||
import org.springframework.stereotype.Component; | |||
@@ -10,26 +12,31 @@ import com.jd.blockchain.ledger.core.handles.ContractCodeDeployOperationHandle; | |||
import com.jd.blockchain.ledger.core.handles.DataAccountKVSetOperationHandle; | |||
import com.jd.blockchain.ledger.core.handles.DataAccountRegisterOperationHandle; | |||
import com.jd.blockchain.ledger.core.handles.JVMContractEventSendOperationHandle; | |||
import com.jd.blockchain.ledger.core.handles.RolesConfigureOperationHandle; | |||
import com.jd.blockchain.ledger.core.handles.UserAuthorizeOperationHandle; | |||
import com.jd.blockchain.ledger.core.handles.UserRegisterOperationHandle; | |||
@Component | |||
public class DefaultOperationHandleRegisteration implements OperationHandleRegisteration { | |||
private List<OperationHandle> opHandles = new ArrayList<>(); | |||
private static Map<Class<?>, OperationHandle> DEFAULT_HANDLES = new HashMap<>(); | |||
public DefaultOperationHandleRegisteration() { | |||
initDefaultHandles(); | |||
private Map<Class<?>, OperationHandle> handles = new ConcurrentHashMap<>(); | |||
private Map<Class<?>, OperationHandle> cacheMapping = new ConcurrentHashMap<>(); | |||
static { | |||
addDefaultHandle(new RolesConfigureOperationHandle()); | |||
addDefaultHandle(new UserAuthorizeOperationHandle()); | |||
addDefaultHandle(new DataAccountKVSetOperationHandle()); | |||
addDefaultHandle(new DataAccountRegisterOperationHandle()); | |||
addDefaultHandle(new UserRegisterOperationHandle()); | |||
addDefaultHandle(new ContractCodeDeployOperationHandle()); | |||
addDefaultHandle(new JVMContractEventSendOperationHandle()); | |||
} | |||
/** | |||
* 针对不采用bean依赖注入的方式来处理; | |||
*/ | |||
private void initDefaultHandles() { | |||
opHandles.add(new DataAccountKVSetOperationHandle()); | |||
opHandles.add(new DataAccountRegisterOperationHandle()); | |||
opHandles.add(new UserRegisterOperationHandle()); | |||
opHandles.add(new ContractCodeDeployOperationHandle()); | |||
opHandles.add(new JVMContractEventSendOperationHandle()); | |||
private static void addDefaultHandle(OperationHandle handle) { | |||
DEFAULT_HANDLES.put(handle.getOperationType(), handle); | |||
} | |||
/** | |||
@@ -37,9 +44,32 @@ public class DefaultOperationHandleRegisteration implements OperationHandleRegis | |||
* | |||
* @param handle | |||
*/ | |||
public void insertAsTopPriority(OperationHandle handle) { | |||
opHandles.remove(handle); | |||
opHandles.add(0, handle); | |||
public void registerHandle(OperationHandle handle) { | |||
handles.put(handle.getOperationType(), handle); | |||
} | |||
private OperationHandle getRegisteredHandle(Class<?> operationType) { | |||
OperationHandle hdl = handles.get(operationType); | |||
if (hdl == null) { | |||
for (Entry<Class<?>, OperationHandle> entry : handles.entrySet()) { | |||
if (entry.getKey().isAssignableFrom(operationType)) { | |||
hdl = entry.getValue(); | |||
} | |||
} | |||
} | |||
return hdl; | |||
} | |||
private OperationHandle getDefaultHandle(Class<?> operationType) { | |||
OperationHandle hdl = DEFAULT_HANDLES.get(operationType); | |||
if (hdl == null) { | |||
for (Entry<Class<?>, OperationHandle> entry : DEFAULT_HANDLES.entrySet()) { | |||
if (entry.getKey().isAssignableFrom(operationType)) { | |||
hdl = entry.getValue(); | |||
} | |||
} | |||
} | |||
return hdl; | |||
} | |||
/* | |||
@@ -51,12 +81,19 @@ public class DefaultOperationHandleRegisteration implements OperationHandleRegis | |||
*/ | |||
@Override | |||
public OperationHandle getHandle(Class<?> operationType) { | |||
for (OperationHandle handle : opHandles) { | |||
if (handle.support(operationType)) { | |||
return handle; | |||
OperationHandle hdl = cacheMapping.get(operationType); | |||
if (hdl != null) { | |||
return hdl; | |||
} | |||
hdl = getRegisteredHandle(operationType); | |||
if (hdl == null) { | |||
hdl = getDefaultHandle(operationType); | |||
if (hdl == null) { | |||
throw new LedgerException("Unsupported operation type[" + operationType.getName() + "]!"); | |||
} | |||
} | |||
throw new LedgerException("Unsupported operation type[" + operationType.getName() + "]!"); | |||
cacheMapping.put(operationType, hdl); | |||
return hdl; | |||
} | |||
} |
@@ -16,7 +16,7 @@ import com.jd.blockchain.ledger.LedgerMetadata_V2; | |||
import com.jd.blockchain.ledger.LedgerSettings; | |||
import com.jd.blockchain.ledger.ParticipantNode; | |||
import com.jd.blockchain.ledger.RolePrivilegeSettings; | |||
import com.jd.blockchain.ledger.UserRoleSettings; | |||
import com.jd.blockchain.ledger.UserRolesSettings; | |||
import com.jd.blockchain.storage.service.ExPolicyKVStorage; | |||
import com.jd.blockchain.storage.service.ExPolicyKVStorage.ExPolicy; | |||
import com.jd.blockchain.storage.service.VersioningKVStorage; | |||
@@ -105,7 +105,7 @@ public class LedgerAdminDataset implements Transactional, LedgerAdminInfo { | |||
} | |||
@Override | |||
public UserRoleSettings getUserRoles() { | |||
public UserRolesSettings getUserRoles() { | |||
return userRoles; | |||
} | |||
@@ -14,7 +14,7 @@ import com.jd.blockchain.ledger.RolePrivilegeSettings; | |||
import com.jd.blockchain.ledger.RolePrivileges; | |||
import com.jd.blockchain.ledger.RolesPolicy; | |||
import com.jd.blockchain.ledger.TransactionPermission; | |||
import com.jd.blockchain.ledger.UserRoleSettings; | |||
import com.jd.blockchain.ledger.UserRolesSettings; | |||
import com.jd.blockchain.ledger.UserRoles; | |||
import com.jd.blockchain.utils.Bytes; | |||
@@ -28,7 +28,7 @@ public class LedgerSecurityManagerImpl implements LedgerSecurityManager { | |||
private RolePrivilegeSettings rolePrivilegeSettings; | |||
private UserRoleSettings userRolesSettings; | |||
private UserRolesSettings userRolesSettings; | |||
// 用户的权限配置 | |||
private Map<Bytes, UserRolesPrivileges> userPrivilegesCache = new ConcurrentHashMap<>(); | |||
@@ -36,7 +36,7 @@ public class LedgerSecurityManagerImpl implements LedgerSecurityManager { | |||
private Map<Bytes, UserRoles> userRolesCache = new ConcurrentHashMap<>(); | |||
private Map<String, RolePrivileges> rolesPrivilegeCache = new ConcurrentHashMap<>(); | |||
public LedgerSecurityManagerImpl(RolePrivilegeSettings rolePrivilegeSettings, UserRoleSettings userRolesSettings) { | |||
public LedgerSecurityManagerImpl(RolePrivilegeSettings rolePrivilegeSettings, UserRolesSettings userRolesSettings) { | |||
this.rolePrivilegeSettings = rolePrivilegeSettings; | |||
this.userRolesSettings = userRolesSettings; | |||
} | |||
@@ -11,7 +11,7 @@ public interface OperationHandle { | |||
* @param operationType | |||
* @return | |||
*/ | |||
boolean support(Class<?> operationType); | |||
Class<?> getOperationType(); | |||
/** | |||
* 同步解析和执行操作; | |||
@@ -283,4 +283,10 @@ public class RolePrivilegeDataset implements Transactional, MerkleProvable, Role | |||
public boolean isReadonly() { | |||
return dataset.isReadonly(); | |||
} | |||
@Override | |||
public boolean contains(String roleName) { | |||
Bytes key = encodeKey(roleName); | |||
return dataset.getVersion(key) > -1; | |||
} | |||
} |
@@ -1,5 +1,7 @@ | |||
package com.jd.blockchain.ledger.core; | |||
import java.util.Collection; | |||
import com.jd.blockchain.binaryproto.BinaryProtocol; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.ledger.AuthorizationException; | |||
@@ -7,8 +9,8 @@ import com.jd.blockchain.ledger.CryptoSetting; | |||
import com.jd.blockchain.ledger.LedgerException; | |||
import com.jd.blockchain.ledger.RoleSet; | |||
import com.jd.blockchain.ledger.RolesPolicy; | |||
import com.jd.blockchain.ledger.UserRoleSettings; | |||
import com.jd.blockchain.ledger.UserRoles; | |||
import com.jd.blockchain.ledger.UserRolesSettings; | |||
import com.jd.blockchain.storage.service.ExPolicyKVStorage; | |||
import com.jd.blockchain.storage.service.VersioningKVEntry; | |||
import com.jd.blockchain.storage.service.VersioningKVStorage; | |||
@@ -21,7 +23,7 @@ import com.jd.blockchain.utils.Transactional; | |||
* @author huanghaiquan | |||
* | |||
*/ | |||
public class UserRoleDataset implements Transactional, MerkleProvable, UserRoleSettings { | |||
public class UserRoleDataset implements Transactional, MerkleProvable, UserRolesSettings { | |||
private MerkleDataSet dataset; | |||
@@ -84,6 +86,25 @@ public class UserRoleDataset implements Transactional, MerkleProvable, UserRoleS | |||
} | |||
} | |||
/** | |||
* 加入新的用户角色授权; <br> | |||
* | |||
* 如果该用户的授权已经存在,则引发 {@link LedgerException} 异常; | |||
* | |||
* @param userAddress | |||
* @param rolesPolicy | |||
* @param roles | |||
*/ | |||
@Override | |||
public void addUserRoles(Bytes userAddress, RolesPolicy rolesPolicy, Collection<String> roles) { | |||
UserRoles roleAuth = new UserRoles(userAddress, -1, rolesPolicy); | |||
roleAuth.addRoles(roles); | |||
long nv = setUserRolesAuthorization(roleAuth); | |||
if (nv < 0) { | |||
throw new AuthorizationException("Roles authorization of User[" + userAddress + "] already exists!"); | |||
} | |||
} | |||
/** | |||
* 设置用户角色授权; <br> | |||
* 如果版本校验不匹配,则返回 -1; | |||
@@ -32,9 +32,14 @@ public abstract class AbstractLedgerOperationHandle<T extends Operation> impleme | |||
this.SUPPORTED_OPERATION_TYPE = supportedOperationType; | |||
} | |||
// @Override | |||
// public final boolean support(Class<?> operationType) { | |||
// return SUPPORTED_OPERATION_TYPE.isAssignableFrom(operationType); | |||
// } | |||
@Override | |||
public final boolean support(Class<?> operationType) { | |||
return SUPPORTED_OPERATION_TYPE.isAssignableFrom(operationType); | |||
public Class<?> getOperationType() { | |||
return SUPPORTED_OPERATION_TYPE; | |||
} | |||
@Override | |||
@@ -22,11 +22,11 @@ import com.jd.blockchain.ledger.core.SecurityPolicy; | |||
import com.jd.blockchain.ledger.core.TransactionRequestExtension; | |||
@Service | |||
public abstract class AbtractContractEventHandle implements OperationHandle { | |||
public abstract class AbtractContractEventSendOperationHandle implements OperationHandle { | |||
@Override | |||
public boolean support(Class<?> operationType) { | |||
return ContractEventSendOperation.class.isAssignableFrom(operationType); | |||
public Class<?> getOperationType() { | |||
return ContractEventSendOperation.class; | |||
} | |||
@Override |
@@ -1,13 +1,13 @@ | |||
package com.jd.blockchain.ledger.core.handles; | |||
import static com.jd.blockchain.utils.BaseConstant.CONTRACT_SERVICE_PROVIDER; | |||
import com.jd.blockchain.contract.engine.ContractCode; | |||
import com.jd.blockchain.contract.engine.ContractEngine; | |||
import com.jd.blockchain.contract.engine.ContractServiceProviders; | |||
import com.jd.blockchain.ledger.core.ContractAccount; | |||
import static com.jd.blockchain.utils.BaseConstant.CONTRACT_SERVICE_PROVIDER; | |||
public class JVMContractEventSendOperationHandle extends AbtractContractEventHandle { | |||
public class JVMContractEventSendOperationHandle extends AbtractContractEventSendOperationHandle { | |||
private static final ContractEngine JVM_ENGINE; | |||
@@ -0,0 +1,49 @@ | |||
package com.jd.blockchain.ledger.core.handles; | |||
import com.jd.blockchain.ledger.LedgerPermission; | |||
import com.jd.blockchain.ledger.RolePrivilegeSettings; | |||
import com.jd.blockchain.ledger.RolePrivileges; | |||
import com.jd.blockchain.ledger.RolesConfigureOperation; | |||
import com.jd.blockchain.ledger.RolesConfigureOperation.RolePrivilegeEntry; | |||
import com.jd.blockchain.ledger.core.LedgerDataset; | |||
import com.jd.blockchain.ledger.core.LedgerService; | |||
import com.jd.blockchain.ledger.core.MultiIdsPolicy; | |||
import com.jd.blockchain.ledger.core.OperationHandleContext; | |||
import com.jd.blockchain.ledger.core.SecurityContext; | |||
import com.jd.blockchain.ledger.core.SecurityPolicy; | |||
import com.jd.blockchain.ledger.core.TransactionRequestExtension; | |||
public class RolesConfigureOperationHandle extends AbstractLedgerOperationHandle<RolesConfigureOperation> { | |||
public RolesConfigureOperationHandle() { | |||
super(RolesConfigureOperation.class); | |||
} | |||
@Override | |||
protected void doProcess(RolesConfigureOperation operation, LedgerDataset newBlockDataset, | |||
TransactionRequestExtension request, LedgerDataset previousBlockDataset, | |||
OperationHandleContext handleContext, LedgerService ledgerService) { | |||
// 权限校验; | |||
SecurityPolicy securityPolicy = SecurityContext.getContextUsersPolicy(); | |||
securityPolicy.checkEndpoints(LedgerPermission.CONFIGURE_ROLES, MultiIdsPolicy.AT_LEAST_ONE); | |||
// 操作账本; | |||
RolePrivilegeEntry[] rpcfgs = operation.getRoles(); | |||
RolePrivilegeSettings rpSettings = newBlockDataset.getAdminDataset().getRolePrivileges(); | |||
if (rpcfgs != null) { | |||
for (RolePrivilegeEntry rpcfg : rpcfgs) { | |||
RolePrivileges rp = rpSettings.getRolePrivilege(rpcfg.getRoleName()); | |||
if (rp == null) { | |||
rpSettings.addRolePrivilege(rpcfg.getRoleName(), rpcfg.getEnableLedgerPermissions(), | |||
rpcfg.getEnableTransactionPermissions()); | |||
} else { | |||
rp.enable(rpcfg.getEnableLedgerPermissions()); | |||
rp.enable(rpcfg.getEnableTransactionPermissions()); | |||
rp.disable(rpcfg.getDisableLedgerPermissions()); | |||
rp.disable(rpcfg.getDisableTransactionPermissions()); | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -0,0 +1,72 @@ | |||
package com.jd.blockchain.ledger.core.handles; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import com.jd.blockchain.ledger.LedgerPermission; | |||
import com.jd.blockchain.ledger.RolePrivilegeSettings; | |||
import com.jd.blockchain.ledger.RolesPolicy; | |||
import com.jd.blockchain.ledger.UserAuthorizeOperation; | |||
import com.jd.blockchain.ledger.UserAuthorizeOperation.UserRolesEntry; | |||
import com.jd.blockchain.ledger.UserRoles; | |||
import com.jd.blockchain.ledger.UserRolesSettings; | |||
import com.jd.blockchain.ledger.core.LedgerDataset; | |||
import com.jd.blockchain.ledger.core.LedgerService; | |||
import com.jd.blockchain.ledger.core.MultiIdsPolicy; | |||
import com.jd.blockchain.ledger.core.OperationHandleContext; | |||
import com.jd.blockchain.ledger.core.SecurityContext; | |||
import com.jd.blockchain.ledger.core.SecurityPolicy; | |||
import com.jd.blockchain.ledger.core.TransactionRequestExtension; | |||
public class UserAuthorizeOperationHandle extends AbstractLedgerOperationHandle<UserAuthorizeOperation> { | |||
public UserAuthorizeOperationHandle() { | |||
super(UserAuthorizeOperation.class); | |||
} | |||
@Override | |||
protected void doProcess(UserAuthorizeOperation operation, LedgerDataset newBlockDataset, | |||
TransactionRequestExtension request, LedgerDataset previousBlockDataset, | |||
OperationHandleContext handleContext, LedgerService ledgerService) { | |||
// 权限校验; | |||
SecurityPolicy securityPolicy = SecurityContext.getContextUsersPolicy(); | |||
securityPolicy.checkEndpoints(LedgerPermission.CONFIGURE_ROLES, MultiIdsPolicy.AT_LEAST_ONE); | |||
// 操作账本; | |||
UserRolesEntry[] urcfgs = operation.getUserRolesAuthorizations(); | |||
UserRolesSettings urSettings = newBlockDataset.getAdminDataset().getUserRoles(); | |||
RolePrivilegeSettings rolesSettings = newBlockDataset.getAdminDataset().getRolePrivileges(); | |||
if (urcfgs != null) { | |||
for (UserRolesEntry urcfg : urcfgs) { | |||
// | |||
String[] authRoles = urcfg.getAuthorizedRoles(); | |||
List<String> validRoles = new ArrayList<String>(); | |||
if (authRoles != null) { | |||
for (String r : authRoles) { | |||
if (rolesSettings.contains(r)) { | |||
validRoles.add(r); | |||
} | |||
} | |||
} | |||
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()); | |||
// 如果请求中设置了策略,才进行更新; | |||
RolesPolicy policy = urcfg.getPolicy(); | |||
if (policy != null) { | |||
ur.setPolicy(policy); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -1,13 +1,12 @@ | |||
package com.jd.blockchain.ledger.core.serialize; | |||
import java.lang.reflect.Type; | |||
import com.alibaba.fastjson.serializer.JSONSerializer; | |||
import com.alibaba.fastjson.serializer.ObjectSerializer; | |||
import com.alibaba.fastjson.serializer.SerializeWriter; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.ledger.LedgerBlock; | |||
import java.lang.reflect.Type; | |||
public class LedgerBlockSerializer implements ObjectSerializer { | |||
@Override | |||
@@ -8,10 +8,10 @@ import com.jd.blockchain.contract.engine.ContractCode; | |||
import com.jd.blockchain.contract.jvm.AbstractContractCode; | |||
import com.jd.blockchain.contract.jvm.ContractDefinition; | |||
import com.jd.blockchain.ledger.core.ContractAccount; | |||
import com.jd.blockchain.ledger.core.handles.AbtractContractEventHandle; | |||
import com.jd.blockchain.ledger.core.handles.AbtractContractEventSendOperationHandle; | |||
import com.jd.blockchain.utils.Bytes; | |||
public class ContractInvokingHandle extends AbtractContractEventHandle { | |||
public class ContractInvokingHandle extends AbtractContractEventSendOperationHandle { | |||
private Map<Bytes, ContractCode> contractInstances = new ConcurrentHashMap<Bytes, ContractCode>(); | |||
@@ -61,7 +61,7 @@ public class ContractInvokingTest { | |||
// 注册合约处理器; | |||
DefaultOperationHandleRegisteration opReg = new DefaultOperationHandleRegisteration(); | |||
opReg.insertAsTopPriority(contractInvokingHandle); | |||
opReg.registerHandle(contractInvokingHandle); | |||
// 发布指定地址合约 | |||
deploy(ledgerRepo, ledgerManager, opReg, ledgerHash, contractKey); | |||
@@ -30,7 +30,7 @@ import com.jd.blockchain.ledger.RolePrivilegeSettings; | |||
import com.jd.blockchain.ledger.RolePrivileges; | |||
import com.jd.blockchain.ledger.RolesPolicy; | |||
import com.jd.blockchain.ledger.TransactionPermission; | |||
import com.jd.blockchain.ledger.UserRoleSettings; | |||
import com.jd.blockchain.ledger.UserRolesSettings; | |||
import com.jd.blockchain.ledger.UserRoles; | |||
import com.jd.blockchain.ledger.core.CryptoConfig; | |||
import com.jd.blockchain.ledger.core.LedgerAdminDataset; | |||
@@ -92,7 +92,7 @@ public class LedgerAdminDatasetTest { | |||
testStorage); | |||
ledgerAdminDataset.getRolePrivileges().addRolePrivilege("DEFAULT", | |||
new LedgerPermission[] { LedgerPermission.AUTHORIZE_ROLES, LedgerPermission.REGISTER_USER, | |||
new LedgerPermission[] { LedgerPermission.CONFIGURE_ROLES, LedgerPermission.REGISTER_USER, | |||
LedgerPermission.APPROVE_TX }, | |||
new TransactionPermission[] { TransactionPermission.DIRECT_OPERATION, | |||
TransactionPermission.CONTRACT_OPERATION }); | |||
@@ -225,7 +225,7 @@ public class LedgerAdminDatasetTest { | |||
} | |||
private void verifyRealoadingRoleAuthorizations(LedgerAdminInfo actualAccount, | |||
RolePrivilegeSettings expRolePrivilegeSettings, UserRoleSettings expUserRoleSettings) { | |||
RolePrivilegeSettings expRolePrivilegeSettings, UserRolesSettings expUserRoleSettings) { | |||
// 验证基本信息; | |||
RolePrivilegeSettings actualRolePrivileges = actualAccount.getRolePrivileges(); | |||
RolePrivileges[] expRPs = expRolePrivilegeSettings.getRolePrivileges(); | |||
@@ -239,7 +239,7 @@ public class LedgerAdminDatasetTest { | |||
assertArrayEquals(expRP.getTransactionPrivilege().toBytes(), actualRP.getTransactionPrivilege().toBytes()); | |||
} | |||
UserRoleSettings actualUserRoleSettings = actualAccount.getUserRoles(); | |||
UserRolesSettings actualUserRoleSettings = actualAccount.getUserRoles(); | |||
UserRoles[] expUserRoles = expUserRoleSettings.getUserRoles(); | |||
assertEquals(expUserRoles.length, actualUserRoleSettings.getUserCount()); | |||
@@ -10,7 +10,7 @@ public interface LedgerAdminInfo { | |||
ParticipantNode[] getParticipants(); | |||
UserRoleSettings getUserRoles(); | |||
UserRolesSettings getUserRoles(); | |||
RolePrivilegeSettings getRolePrivileges(); | |||
@@ -15,57 +15,61 @@ import com.jd.blockchain.consts.DataCodes; | |||
public enum LedgerPermission { | |||
/** | |||
* 授权角色权限;<br> | |||
* 包括:创建角色、设置角色的权限代码、分配用户角色; | |||
* 配置角色的权限;<br> | |||
*/ | |||
AUTHORIZE_ROLES((byte) 0x01), | |||
CONFIGURE_ROLES((byte) 0x01), | |||
/** | |||
* 授权用户角色;<br> | |||
*/ | |||
AUTHORIZE_USER_ROLES((byte) 0x02), | |||
/** | |||
* 设置共识协议;<br> | |||
*/ | |||
SET_CONSENSUS((byte) 0x02), | |||
SET_CONSENSUS((byte) 0x03), | |||
/** | |||
* 设置密码体系;<br> | |||
*/ | |||
SET_CRYPTO((byte) 0x03), | |||
SET_CRYPTO((byte) 0x04), | |||
/** | |||
* 注册参与方;<br> | |||
*/ | |||
REGISTER_PARTICIPANT((byte) 0x04), | |||
REGISTER_PARTICIPANT((byte) 0x05), | |||
/** | |||
* 注册用户;<br> | |||
* | |||
* 如果不具备此项权限,则无法注册用户; | |||
*/ | |||
REGISTER_USER((byte) 0x05), | |||
REGISTER_USER((byte) 0x11), | |||
/** | |||
* 注册数据账户;<br> | |||
*/ | |||
REGISTER_DATA_ACCOUNT((byte) 0x06), | |||
REGISTER_DATA_ACCOUNT((byte) 0x12), | |||
/** | |||
* 注册合约;<br> | |||
*/ | |||
REGISTER_CONTRACT((byte) 0x07), | |||
REGISTER_CONTRACT((byte) 0x13), | |||
/** | |||
* 升级合约 | |||
*/ | |||
UPGRADE_CONTRACT((byte) 0x08), | |||
UPGRADE_CONTRACT((byte) 0x14), | |||
/** | |||
* 设置用户属性;<br> | |||
*/ | |||
SET_USER_ATTRIBUTES((byte) 0x09), | |||
SET_USER_ATTRIBUTES((byte) 0x15), | |||
/** | |||
* 写入数据账户;<br> | |||
*/ | |||
WRITE_DATA_ACCOUNT((byte) 0x0A), | |||
WRITE_DATA_ACCOUNT((byte) 0x16), | |||
/** | |||
* 参与方核准交易;<br> | |||
@@ -74,16 +78,14 @@ public enum LedgerPermission { | |||
* <p> | |||
* 只对交易请求的节点签名列表{@link TransactionRequest#getNodeSignatures()}的用户产生影响; | |||
*/ | |||
APPROVE_TX((byte) 0x0B), | |||
APPROVE_TX((byte) 0x0C), | |||
/** | |||
* 参与方共识交易;<br> | |||
* | |||
* 如果不具备此项权限,则无法作为共识节点接入并对交易进行共识; | |||
*/ | |||
CONSENSUS_TX((byte) 0x0C); | |||
CONSENSUS_TX((byte) 0x0D); | |||
@EnumField(type = PrimitiveType.INT8) | |||
public final byte CODE; | |||
@@ -155,4 +155,6 @@ public interface RolePrivilegeSettings { | |||
long disablePermissions(String roleName, LedgerPermission[] ledgerPermissions, | |||
TransactionPermission[] txPermissions); | |||
boolean contains(String r); | |||
} |
@@ -1,5 +1,6 @@ | |||
package com.jd.blockchain.ledger; | |||
import java.util.Collection; | |||
import java.util.Set; | |||
import java.util.TreeSet; | |||
@@ -72,6 +73,24 @@ public class UserRoles implements RoleSet { | |||
} | |||
} | |||
public void addRoles(Collection<String> roles) { | |||
for (String r : roles) { | |||
this.roles.add(r); | |||
} | |||
} | |||
public void removeRoles(String... roles) { | |||
for (String r : roles) { | |||
this.roles.remove(r); | |||
} | |||
} | |||
public void removeRoles(Collection<String> roles) { | |||
for (String r : roles) { | |||
this.roles.remove(r); | |||
} | |||
} | |||
/** | |||
* 设置角色集合;<br> | |||
* 注意,这不是追加;现有的不在参数指定范围的角色将被移除; | |||
@@ -1,8 +1,10 @@ | |||
package com.jd.blockchain.ledger; | |||
import java.util.Collection; | |||
import com.jd.blockchain.utils.Bytes; | |||
public interface UserRoleSettings { | |||
public interface UserRolesSettings { | |||
/** | |||
* 单一用户可被授权的角色数量的最大值; | |||
@@ -51,6 +53,17 @@ public interface UserRoleSettings { | |||
* @param roles | |||
*/ | |||
void addUserRoles(Bytes userAddress, RolesPolicy rolesPolicy, String... roles); | |||
/** | |||
* 加入新的用户角色授权; <br> | |||
* | |||
* 如果该用户的授权已经存在,则引发 {@link LedgerException} 异常; | |||
* | |||
* @param userAddress | |||
* @param rolesPolicy | |||
* @param roles | |||
*/ | |||
void addUserRoles(Bytes userAddress, RolesPolicy rolesPolicy, Collection<String> roles); | |||
/** | |||
* 更新用户角色授权; <br> |
@@ -54,18 +54,12 @@ | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-web</artifactId> | |||
<exclusions> | |||
<exclusion> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-logging</artifactId> | |||
</exclusion> | |||
</exclusions> | |||
</dependency> | |||
<dependency> | |||
<!-- <dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-log4j2</artifactId> | |||
</dependency> | |||
</dependency> --> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
@@ -8,11 +8,6 @@ | |||
<artifactId>spring-boot-starter-parent</artifactId> | |||
<version>2.0.6.RELEASE</version> | |||
</parent> | |||
<!--<parent> --> | |||
<!--<groupId>org.sonatype.oss</groupId> --> | |||
<!--<artifactId>oss-parent</artifactId> --> | |||
<!--<version>7</version> --> | |||
<!--</parent> --> | |||
<groupId>com.jd.blockchain</groupId> | |||
<artifactId>jdchain-root</artifactId> | |||
@@ -45,9 +40,6 @@ | |||
<explorer.version>0.7.0.RELEASE</explorer.version> | |||
<ump-explorer.version>1.0.0-SNAPSHOT</ump-explorer.version> | |||
<commons-io.version>2.4</commons-io.version> | |||
<!-- <spring.framework.version>4.3.4.RELEASE</spring.framework.version> --> | |||
<!-- <spring.mongo.version>1.9.3.RELEASE</spring.mongo.version> <spring.dao.version>2.0.8</spring.dao.version> | |||
<spring.security.version>4.2.0.RELEASE</spring.security.version> --> | |||
<mongo.driver.version>3.3.0</mongo.driver.version> | |||
<shiro.version>1.2.2</shiro.version> | |||
<aspectj.version>1.8.8</aspectj.version> | |||
@@ -85,6 +77,10 @@ | |||
</properties> | |||
<dependencies> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-logging</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>junit</groupId> | |||
<artifactId>junit</artifactId> | |||
@@ -54,7 +54,7 @@ public class AssetContractImpl implements EventProcessingAware, AssetContract { | |||
KVDataObject currTotal = (KVDataObject) kvEntries[0]; | |||
long newTotal = currTotal.longValue() + amount; | |||
eventContext.getLedger().dataAccount(ASSET_ADDRESS).setInt64(KEY_TOTAL, newTotal, currTotal.getVersion()); | |||
// 分配到持有者账户; | |||
KVDataObject holderAmount = (KVDataObject) kvEntries[1]; | |||
long newHodlerAmount = holderAmount.longValue() + amount; | |||
@@ -72,18 +72,18 @@ | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-web</artifactId> | |||
<exclusions> | |||
<!-- <exclusions> | |||
<exclusion> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-logging</artifactId> | |||
</exclusion> | |||
</exclusions> | |||
</exclusions> --> | |||
</dependency> | |||
<dependency> | |||
<!-- <dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-log4j2</artifactId> | |||
</dependency> | |||
</dependency> --> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
@@ -96,15 +96,18 @@ public class LedgerInitPropertiesTest { | |||
TransactionPermission.CONTRACT_OPERATION }, roleDefault.getTransactionPermissions()); | |||
RoleInitData roleAdmin = rolesInitDatas.get("ADMIN"); | |||
assertArrayEquals(new LedgerPermission[] { LedgerPermission.AUTHORIZE_ROLES, LedgerPermission.SET_CONSENSUS, | |||
LedgerPermission.SET_CRYPTO, LedgerPermission.REGISTER_PARTICIPANT, | |||
LedgerPermission.REGISTER_USER }, roleAdmin.getLedgerPermissions()); | |||
assertArrayEquals( | |||
new LedgerPermission[] { LedgerPermission.CONFIGURE_ROLES, LedgerPermission.AUTHORIZE_USER_ROLES, | |||
LedgerPermission.SET_CONSENSUS, LedgerPermission.SET_CRYPTO, | |||
LedgerPermission.REGISTER_PARTICIPANT, LedgerPermission.REGISTER_USER }, | |||
roleAdmin.getLedgerPermissions()); | |||
assertArrayEquals(new TransactionPermission[] { TransactionPermission.DIRECT_OPERATION }, | |||
roleAdmin.getTransactionPermissions()); | |||
RoleInitData roleManager = rolesInitDatas.get("MANAGER"); | |||
assertArrayEquals( | |||
new LedgerPermission[] { LedgerPermission.REGISTER_USER, LedgerPermission.REGISTER_DATA_ACCOUNT, | |||
new LedgerPermission[] { LedgerPermission.CONFIGURE_ROLES, LedgerPermission.AUTHORIZE_USER_ROLES, | |||
LedgerPermission.REGISTER_USER, LedgerPermission.REGISTER_DATA_ACCOUNT, | |||
LedgerPermission.REGISTER_CONTRACT, LedgerPermission.UPGRADE_CONTRACT, | |||
LedgerPermission.SET_USER_ATTRIBUTES, LedgerPermission.WRITE_DATA_ACCOUNT }, | |||
roleManager.getLedgerPermissions()); | |||
@@ -127,7 +130,7 @@ public class LedgerInitPropertiesTest { | |||
// 验证参与方信息; | |||
assertEquals(4, initProps.getConsensusParticipantCount()); | |||
ConsensusParticipantConfig part0 = initProps.getConsensusParticipant(0); | |||
assertEquals("jd.com", part0.getName()); | |||
PubKey pubKey0 = KeyGenCommand.decodePubKey("3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9"); | |||
@@ -135,26 +138,25 @@ public class LedgerInitPropertiesTest { | |||
assertEquals("127.0.0.1", part0.getInitializerAddress().getHost()); | |||
assertEquals(8800, part0.getInitializerAddress().getPort()); | |||
assertEquals(true, part0.getInitializerAddress().isSecure()); | |||
assertArrayEquals(new String[] {"ADMIN", "MANAGER"}, part0.getRoles()); | |||
assertArrayEquals(new String[] { "ADMIN", "MANAGER" }, part0.getRoles()); | |||
assertEquals(RolesPolicy.UNION, part0.getRolesPolicy()); | |||
ConsensusParticipantConfig part1 = initProps.getConsensusParticipant(1); | |||
assertEquals(false, part1.getInitializerAddress().isSecure()); | |||
PubKey pubKey1 = KeyGenCommand.decodePubKey("3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX"); | |||
assertEquals(pubKey1, part1.getPubKey()); | |||
assertArrayEquals(new String[] { "MANAGER"}, part1.getRoles()); | |||
assertArrayEquals(new String[] { "MANAGER" }, part1.getRoles()); | |||
assertEquals(RolesPolicy.UNION, part1.getRolesPolicy()); | |||
ConsensusParticipantConfig part2 = initProps.getConsensusParticipant(2); | |||
assertEquals("7VeRAr3dSbi1xatq11ZcF7sEPkaMmtZhV9shonGJWk9T4pLe", part2.getPubKey().toBase58()); | |||
assertArrayEquals(new String[] { "MANAGER"}, part2.getRoles()); | |||
assertArrayEquals(new String[] { "MANAGER" }, part2.getRoles()); | |||
assertEquals(RolesPolicy.UNION, part2.getRolesPolicy()); | |||
ConsensusParticipantConfig part3 = initProps.getConsensusParticipant(3); | |||
PubKey pubKey3 = KeyGenCommand.decodePubKey("3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk"); | |||
assertEquals(pubKey3, part3.getPubKey()); | |||
assertArrayEquals(new String[] { "GUEST"}, part3.getRoles()); | |||
assertArrayEquals(new String[] { "GUEST" }, part3.getRoles()); | |||
assertEquals(RolesPolicy.INTERSECT, part3.getRolesPolicy()); | |||
} finally { | |||
@@ -37,11 +37,11 @@ security.role.DEFAULT.tx-privileges=DIRECT_OPERATION, CONTRACT_OPERATION | |||
# 其它角色的配置示例; | |||
# 系统管理员角色:只能操作全局性的参数配置和用户注册,只能执行直接操作指令; | |||
security.role.ADMIN.ledger-privileges=AUTHORIZE_ROLES, SET_CONSENSUS, SET_CRYPTO, REGISTER_PARTICIPANT, REGISTER_USER | |||
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=REGISTER_USER, REGISTER_DATA_ACCOUNT, REGISTER_CONTRACT, UPGRADE_CONTRACT, SET_USER_ATTRIBUTES, WRITE_DATA_ACCOUNT, | |||
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 | |||
# 访客角色:不具备任何的账本权限,只有数据读取的操作;也只能够通过调用合约来读取数据; | |||
@@ -57,18 +57,19 @@ import com.jd.blockchain.ledger.TransactionState; | |||
import com.jd.blockchain.ledger.UserInfo; | |||
import com.jd.blockchain.ledger.UserRegisterOperation; | |||
import com.jd.blockchain.ledger.core.CryptoConfig; | |||
import com.jd.blockchain.ledger.core.DefaultOperationHandleRegisteration; | |||
import com.jd.blockchain.ledger.core.LedgerDataset; | |||
import com.jd.blockchain.ledger.core.LedgerEditor; | |||
import com.jd.blockchain.ledger.core.LedgerManager; | |||
import com.jd.blockchain.ledger.core.LedgerQueryService; | |||
import com.jd.blockchain.ledger.core.LedgerRepository; | |||
import com.jd.blockchain.ledger.core.LedgerSecurityManager; | |||
import com.jd.blockchain.ledger.core.OperationHandleRegisteration; | |||
import com.jd.blockchain.ledger.core.SecurityPolicy; | |||
import com.jd.blockchain.ledger.core.TransactionBatchProcessor; | |||
import com.jd.blockchain.mocker.config.MockerConstant; | |||
import com.jd.blockchain.mocker.config.PresetAnswerPrompter; | |||
import com.jd.blockchain.mocker.handler.MockerContractExeHandle; | |||
import com.jd.blockchain.mocker.handler.MockerOperationHandleRegister; | |||
import com.jd.blockchain.mocker.proxy.ContractProxy; | |||
import com.jd.blockchain.service.TransactionBatchResultHandle; | |||
import com.jd.blockchain.storage.service.DbConnectionFactory; | |||
@@ -91,7 +92,7 @@ public class MockerNodeContext implements BlockchainQueryService { | |||
private DbConnectionFactory dbConnFactory = new MemoryDBConnFactory(); | |||
private MockerOperationHandleRegister opHandler = new MockerOperationHandleRegister(); | |||
private DefaultOperationHandleRegisteration opHandler = new DefaultOperationHandleRegisteration(); | |||
private MockerContractExeHandle contractExeHandle = new MockerContractExeHandle(); | |||
@@ -194,7 +195,7 @@ public class MockerNodeContext implements BlockchainQueryService { | |||
contractExeHandle.initLedger(ledgerManager, ledgerHash); | |||
opHandler.registerHandler(contractExeHandle); | |||
opHandler.registerHandle(contractExeHandle); | |||
return this; | |||
} | |||
@@ -73,8 +73,8 @@ public class MockerContractExeHandle implements OperationHandle { | |||
} | |||
@Override | |||
public boolean support(Class<?> operationType) { | |||
return ContractEventSendOperation.class.isAssignableFrom(operationType); | |||
public Class<?> getOperationType() { | |||
return ContractEventSendOperation.class; | |||
} | |||
public void initLedger(LedgerManager ledgerManager, HashDigest ledgerHash) { | |||
@@ -1,54 +1,54 @@ | |||
package com.jd.blockchain.mocker.handler; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import com.jd.blockchain.ledger.LedgerException; | |||
import com.jd.blockchain.ledger.core.OperationHandle; | |||
import com.jd.blockchain.ledger.core.OperationHandleRegisteration; | |||
import com.jd.blockchain.ledger.core.handles.ContractCodeDeployOperationHandle; | |||
import com.jd.blockchain.ledger.core.handles.DataAccountKVSetOperationHandle; | |||
import com.jd.blockchain.ledger.core.handles.DataAccountRegisterOperationHandle; | |||
import com.jd.blockchain.ledger.core.handles.UserRegisterOperationHandle; | |||
public class MockerOperationHandleRegister implements OperationHandleRegisteration { | |||
private List<OperationHandle> opHandles = new ArrayList<>(); | |||
public MockerOperationHandleRegister() { | |||
initDefaultHandles(); | |||
} | |||
/** | |||
* 针对不采用bean依赖注入的方式来处理; | |||
*/ | |||
private void initDefaultHandles(){ | |||
opHandles.add(new DataAccountKVSetOperationHandle()); | |||
opHandles.add(new DataAccountRegisterOperationHandle()); | |||
opHandles.add(new UserRegisterOperationHandle()); | |||
opHandles.add(new ContractCodeDeployOperationHandle()); | |||
// opHandles.add(new ContractEventSendOperationHandle()); | |||
} | |||
public List<OperationHandle> getOpHandles() { | |||
return opHandles; | |||
} | |||
public void registerHandler(OperationHandle operationHandle) { | |||
opHandles.add(operationHandle); | |||
} | |||
public void removeHandler(OperationHandle operationHandle) { | |||
opHandles.remove(operationHandle); | |||
} | |||
@Override | |||
public OperationHandle getHandle(Class<?> operationType) { | |||
for (OperationHandle handle : opHandles) { | |||
if (handle.support(operationType)) { | |||
return handle; | |||
} | |||
} | |||
throw new LedgerException("Unsupported operation type[" + operationType.getName() + "]!"); | |||
} | |||
} | |||
//package com.jd.blockchain.mocker.handler; | |||
// | |||
//import java.util.ArrayList; | |||
//import java.util.List; | |||
// | |||
//import com.jd.blockchain.ledger.LedgerException; | |||
//import com.jd.blockchain.ledger.core.OperationHandle; | |||
//import com.jd.blockchain.ledger.core.OperationHandleRegisteration; | |||
//import com.jd.blockchain.ledger.core.handles.ContractCodeDeployOperationHandle; | |||
//import com.jd.blockchain.ledger.core.handles.DataAccountKVSetOperationHandle; | |||
//import com.jd.blockchain.ledger.core.handles.DataAccountRegisterOperationHandle; | |||
//import com.jd.blockchain.ledger.core.handles.UserRegisterOperationHandle; | |||
// | |||
//public class MockerOperationHandleRegister implements OperationHandleRegisteration { | |||
// | |||
// private List<OperationHandle> opHandles = new ArrayList<>(); | |||
// | |||
// public MockerOperationHandleRegister() { | |||
// initDefaultHandles(); | |||
// } | |||
// | |||
// /** | |||
// * 针对不采用bean依赖注入的方式来处理; | |||
// */ | |||
// private void initDefaultHandles(){ | |||
// opHandles.add(new DataAccountKVSetOperationHandle()); | |||
// opHandles.add(new DataAccountRegisterOperationHandle()); | |||
// opHandles.add(new UserRegisterOperationHandle()); | |||
// opHandles.add(new ContractCodeDeployOperationHandle()); | |||
//// opHandles.add(new ContractEventSendOperationHandle()); | |||
// } | |||
// | |||
// public List<OperationHandle> getOpHandles() { | |||
// return opHandles; | |||
// } | |||
// | |||
// public void registerHandler(OperationHandle operationHandle) { | |||
// opHandles.add(operationHandle); | |||
// } | |||
// | |||
// public void removeHandler(OperationHandle operationHandle) { | |||
// opHandles.remove(operationHandle); | |||
// } | |||
// | |||
// @Override | |||
// public OperationHandle getHandle(Class<?> operationType) { | |||
// for (OperationHandle handle : opHandles) { | |||
// if (handle.support(operationType)) { | |||
// return handle; | |||
// } | |||
// } | |||
// throw new LedgerException("Unsupported operation type[" + operationType.getName() + "]!"); | |||
// } | |||
//} |
@@ -51,7 +51,7 @@ public class StringUtils { | |||
*/ | |||
public static String[] splitToArray(String str, String delimiter, boolean trimElement, boolean ignoreEmptyElement) { | |||
if (str == null) { | |||
return null; | |||
return EMPTY_ARRAY; | |||
} | |||
if (trimElement) { | |||
str = str.trim(); | |||