@@ -60,7 +60,7 @@ public interface DataCodes { | |||
public static final int ENUM_LEDGER_PERMISSION = 0x402; | |||
public static final int ENUM_MULTI_ROLES_POLICY = 0x403; | |||
public static final int ROLE_PRIVILEGE = 0x410; | |||
public static final int PRIVILEGE_SET = 0x410; | |||
public static final int ROLE_SET = 0x411; | |||
@@ -1,7 +1,5 @@ | |||
package com.jd.blockchain.ledger.core; | |||
import com.jd.blockchain.ledger.LedgerMetadata; | |||
import com.jd.blockchain.ledger.LedgerSettings; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
@@ -13,6 +11,9 @@ import com.jd.blockchain.crypto.HashFunction; | |||
import com.jd.blockchain.ledger.LedgerAdminInfo; | |||
import com.jd.blockchain.ledger.LedgerException; | |||
import com.jd.blockchain.ledger.LedgerInitSetting; | |||
import com.jd.blockchain.ledger.LedgerMetadata; | |||
import com.jd.blockchain.ledger.LedgerMetadata_V2; | |||
import com.jd.blockchain.ledger.LedgerSettings; | |||
import com.jd.blockchain.ledger.ParticipantNode; | |||
import com.jd.blockchain.storage.service.ExPolicyKVStorage; | |||
import com.jd.blockchain.storage.service.ExPolicyKVStorage.ExPolicy; | |||
@@ -31,11 +32,13 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||
public static final String LEDGER_META_PREFIX = "MTA" + LedgerConsts.KEY_SEPERATOR; | |||
public static final String LEDGER_PARTICIPANT_PREFIX = "PAR" + LedgerConsts.KEY_SEPERATOR; | |||
public static final String LEDGER_SETTING_PREFIX = "SET" + LedgerConsts.KEY_SEPERATOR; | |||
public static final String LEDGER_PRIVILEGE_PREFIX = "PRL" + LedgerConsts.KEY_SEPERATOR; | |||
public static final String ROLE_PRIVILEGE_PREFIX = "RPV" + LedgerConsts.KEY_SEPERATOR; | |||
public static final String USER_ROLE_PREFIX = "URO" + LedgerConsts.KEY_SEPERATOR; | |||
private final Bytes metaPrefix; | |||
private final Bytes settingPrefix; | |||
private final Bytes privilegePrefix; | |||
private final Bytes rolePrivilegePrefix; | |||
private final Bytes userRolePrefix; | |||
private LedgerMetadata origMetadata; | |||
@@ -56,6 +59,10 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||
*/ | |||
private ParticipantDataSet participants; | |||
private RolePrivilegeDataSet rolePrivileges; | |||
private UserRoleDataSet userRoles; | |||
/** | |||
* 账本参数配置; | |||
*/ | |||
@@ -82,6 +89,14 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||
return readonly; | |||
} | |||
public RolePrivilegeSettings getRolePrivileges() { | |||
return rolePrivileges; | |||
} | |||
public UserRoleSettings getUserRoles() { | |||
return userRoles; | |||
} | |||
/** | |||
* 初始化账本的管理账户; | |||
* | |||
@@ -99,7 +114,8 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||
VersioningKVStorage versioningStorage) { | |||
this.metaPrefix = Bytes.fromString(keyPrefix + LEDGER_META_PREFIX); | |||
this.settingPrefix = Bytes.fromString(keyPrefix + LEDGER_SETTING_PREFIX); | |||
this.privilegePrefix = Bytes.fromString(keyPrefix + LEDGER_PRIVILEGE_PREFIX); | |||
this.rolePrivilegePrefix = Bytes.fromString(keyPrefix + ROLE_PRIVILEGE_PREFIX); | |||
this.userRolePrefix = Bytes.fromString(keyPrefix + USER_ROLE_PREFIX); | |||
ParticipantNode[] parties = initSetting.getConsensusParticipants(); | |||
if (parties.length == 0) { | |||
@@ -134,6 +150,14 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||
this.participants.addConsensusParticipant(p); | |||
} | |||
String rolePrivilegePrefix = keyPrefix + ROLE_PRIVILEGE_PREFIX; | |||
this.rolePrivileges = new RolePrivilegeDataSet(this.settings.getCryptoSetting(), rolePrivilegePrefix, | |||
exPolicyStorage, versioningStorage); | |||
String userRolePrefix = keyPrefix + USER_ROLE_PREFIX; | |||
this.userRoles = new UserRoleDataSet(this.settings.getCryptoSetting(), userRolePrefix, exPolicyStorage, | |||
versioningStorage); | |||
// 初始化其它属性; | |||
this.storage = exPolicyStorage; | |||
this.readonly = false; | |||
@@ -143,7 +167,8 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||
VersioningKVStorage versioningKVStorage, boolean readonly) { | |||
this.metaPrefix = Bytes.fromString(keyPrefix + LEDGER_META_PREFIX); | |||
this.settingPrefix = Bytes.fromString(keyPrefix + LEDGER_SETTING_PREFIX); | |||
this.privilegePrefix = Bytes.fromString(keyPrefix + LEDGER_PRIVILEGE_PREFIX); | |||
this.rolePrivilegePrefix = Bytes.fromString(keyPrefix + ROLE_PRIVILEGE_PREFIX); | |||
this.userRolePrefix = Bytes.fromString(keyPrefix + USER_ROLE_PREFIX); | |||
this.storage = kvStorage; | |||
this.readonly = readonly; | |||
this.origMetadata = loadAndVerifyMetadata(adminAccountHash); | |||
@@ -167,6 +192,14 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||
String partiPrefix = keyPrefix + LEDGER_PARTICIPANT_PREFIX; | |||
this.participants = new ParticipantDataSet(metadata.getParticipantsHash(), previousSettings.getCryptoSetting(), | |||
partiPrefix, kvStorage, versioningKVStorage, readonly); | |||
String rolePrivilegePrefix = keyPrefix + ROLE_PRIVILEGE_PREFIX; | |||
this.rolePrivileges = new RolePrivilegeDataSet(metadata.getRolePrivilegesHash(), | |||
previousSettings.getCryptoSetting(), rolePrivilegePrefix, kvStorage, versioningKVStorage, readonly); | |||
String userRolePrefix = keyPrefix + USER_ROLE_PREFIX; | |||
this.userRoles = new UserRoleDataSet(metadata.getUserRolesHash(), previousSettings.getCryptoSetting(), | |||
userRolePrefix, kvStorage, versioningKVStorage, readonly); | |||
} | |||
private LedgerSettings loadAndVerifySettings(HashDigest settingsHash) { | |||
@@ -304,6 +337,15 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||
participants.commit(); | |||
metadata.setParticipantsHash(participants.getRootHash()); | |||
// 计算并更新角色权限集合的根哈希; | |||
rolePrivileges.commit(); | |||
metadata.setRolePrivilegesHash(rolePrivileges.getRootHash()); | |||
// 计算并更新用户角色授权集合的根哈希; | |||
userRoles.commit(); | |||
metadata.setUserRolesHash(userRoles.getRootHash()); | |||
// 当前区块上下文的密码参数设置的哈希函数; | |||
HashFunction hashFunc = Crypto.getHashFunction(previousSettings.getCryptoSetting().getHashAlgorithm()); | |||
// 计算并更新参数配置的哈希; | |||
@@ -367,7 +409,7 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||
metadata = new LedgerMetadataImpl(origMetadata); | |||
} | |||
public static class LedgerMetadataImpl implements LedgerMetadata { | |||
public static class LedgerMetadataImpl implements LedgerMetadata_V2 { | |||
private byte[] seed; | |||
@@ -377,6 +419,10 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||
private HashDigest settingsHash; | |||
private HashDigest rolePrivilegesHash; | |||
private HashDigest userRolesHash; | |||
public LedgerMetadataImpl() { | |||
} | |||
@@ -402,6 +448,16 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||
return participantsHash; | |||
} | |||
@Override | |||
public HashDigest getRolePrivilegesHash() { | |||
return rolePrivilegesHash; | |||
} | |||
@Override | |||
public HashDigest getUserRolesHash() { | |||
return userRolesHash; | |||
} | |||
public void setSeed(byte[] seed) { | |||
this.seed = seed; | |||
} | |||
@@ -413,6 +469,14 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||
public void setParticipantsHash(HashDigest participantsHash) { | |||
this.participantsHash = participantsHash; | |||
} | |||
public void setRolePrivilegesHash(HashDigest rolePrivilegesHash) { | |||
this.rolePrivilegesHash = rolePrivilegesHash; | |||
} | |||
public void setUserRolesHash(HashDigest userRolesHash) { | |||
this.userRolesHash = userRolesHash; | |||
} | |||
} | |||
} |
@@ -22,11 +22,11 @@ public class LedgerSecurityManager { | |||
throw new IllegalStateException("Not implemented!"); | |||
} | |||
public RolePrivilegeAuthorization setRole(String role, LedgerPrivilege privilege) { | |||
public RolePrivileges setRole(String role, LedgerPrivilege privilege) { | |||
throw new IllegalStateException("Not implemented!"); | |||
} | |||
public RolePrivilegeAuthorization getRole(String role) { | |||
public RolePrivileges getRole(String role) { | |||
throw new IllegalStateException("Not implemented!"); | |||
} | |||
@@ -1,7 +1,5 @@ | |||
package com.jd.blockchain.ledger.core; | |||
import java.util.SortedSet; | |||
public interface PermissionService { | |||
boolean checkLedgerPermission(); | |||
@@ -1,21 +0,0 @@ | |||
//package com.jd.blockchain.ledger.core; | |||
// | |||
//import com.jd.blockchain.crypto.hash.HashDigest; | |||
//import com.jd.blockchain.ledger.data.DigitalSignatureBlob; | |||
// | |||
//import my.utils.io.ExistentialKVStorage; | |||
//import my.utils.io.VersioningKVStorage; | |||
// | |||
//public class PrivilegeDataSet extends GenericMerkleDataSet<Authorization, AuthorizationVO> { | |||
// | |||
// public PrivilegeDataSet(CryptoSetting setting, ExistentialKVStorage merkleTreeStorage, VersioningKVStorage dataStorage) { | |||
// this(null, setting, merkleTreeStorage, dataStorage, false); | |||
// } | |||
// | |||
// public PrivilegeDataSet(HashDigest rootHash, CryptoSetting setting, ExistentialKVStorage merkleTreeStorage, | |||
// VersioningKVStorage dataStorage, boolean readonly) { | |||
// super(rootHash, setting, merkleTreeStorage, dataStorage, readonly, Authorization.class, AuthorizationVO.class, | |||
// DigitalSignatureBlob.class); | |||
// } | |||
// | |||
//} |
@@ -11,8 +11,8 @@ import com.jd.blockchain.consts.DataCodes; | |||
* @author huanghaiquan | |||
* | |||
*/ | |||
@DataContract(code = DataCodes.ROLE_PRIVILEGE, name = "ROLE-PRIVILEGE") | |||
public interface RolePrivilege { | |||
@DataContract(code = DataCodes.PRIVILEGE_SET, name = "PRIVILEGE-SET") | |||
public interface PrivilegeSet { | |||
@DataField(order = 1, primitiveType = PrimitiveType.BYTES) | |||
LedgerPrivilege getLedgerPrivilege(); |
@@ -1,175 +0,0 @@ | |||
package com.jd.blockchain.ledger.core; | |||
import com.jd.blockchain.binaryproto.BinaryProtocol; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.ledger.CryptoSetting; | |||
import com.jd.blockchain.ledger.LedgerException; | |||
import com.jd.blockchain.storage.service.ExPolicyKVStorage; | |||
import com.jd.blockchain.storage.service.VersioningKVEntry; | |||
import com.jd.blockchain.storage.service.VersioningKVStorage; | |||
import com.jd.blockchain.utils.Bytes; | |||
import com.jd.blockchain.utils.Transactional; | |||
public class RoleDataSet implements Transactional, MerkleProvable { | |||
/** | |||
* 角色名称的最大 Unicode 字符数; | |||
*/ | |||
public static final int MAX_ROLE_NAME_LENGTH = 20; | |||
private MerkleDataSet dataset; | |||
public RoleDataSet(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exPolicyStorage, | |||
VersioningKVStorage verStorage) { | |||
dataset = new MerkleDataSet(cryptoSetting, prefix, exPolicyStorage, verStorage); | |||
} | |||
public RoleDataSet(HashDigest merkleRootHash, CryptoSetting cryptoSetting, String prefix, | |||
ExPolicyKVStorage exPolicyStorage, VersioningKVStorage verStorage, boolean readonly) { | |||
dataset = new MerkleDataSet(merkleRootHash, cryptoSetting, prefix, exPolicyStorage, verStorage, readonly); | |||
} | |||
@Override | |||
public HashDigest getRootHash() { | |||
return dataset.getRootHash(); | |||
} | |||
@Override | |||
public MerkleProof getProof(Bytes key) { | |||
return dataset.getProof(key); | |||
} | |||
@Override | |||
public boolean isUpdated() { | |||
return dataset.isUpdated(); | |||
} | |||
@Override | |||
public void commit() { | |||
dataset.commit(); | |||
} | |||
@Override | |||
public void cancel() { | |||
dataset.cancel(); | |||
} | |||
public long getRoleCount() { | |||
return dataset.getDataCount(); | |||
} | |||
/** | |||
* 加入新的角色授权; <br> | |||
* | |||
* 如果指定的角色已经存在,则引发 {@link LedgerException} 异常; | |||
* | |||
* @param roleName 角色名称;不能超过 {@link #MAX_ROLE_NAME_LENGTH} 个 Unicode 字符; | |||
* @param ledgerPrivilege | |||
* @param txPrivilege | |||
*/ | |||
public void addRoleAuthorization(String roleName, LedgerPrivilege ledgerPrivilege, | |||
TransactionPrivilege txPrivilege) { | |||
RolePrivilegeAuthorization roleAuth = new RolePrivilegeAuthorization(roleName, -1, ledgerPrivilege, txPrivilege); | |||
long nv = innerSetRoleAuthorization(roleAuth); | |||
if (nv < 0) { | |||
throw new LedgerException("Role[" + roleName + "] already exist!"); | |||
} | |||
} | |||
/** | |||
* 设置角色授权; <br> | |||
* 如果版本校验不匹配,则返回 -1; | |||
* | |||
* @param roleAuth | |||
* @return | |||
*/ | |||
public long innerSetRoleAuthorization(RolePrivilegeAuthorization roleAuth) { | |||
if (roleAuth.getRoleName().length() > MAX_ROLE_NAME_LENGTH) { | |||
throw new LedgerException("Too long role name!"); | |||
} | |||
Bytes key = encodeKey(roleAuth.getRoleName()); | |||
byte[] privilegeBytes = BinaryProtocol.encode(roleAuth, RolePrivilege.class); | |||
return dataset.setValue(key, privilegeBytes, roleAuth.getVersion()); | |||
} | |||
/** | |||
* 更新角色授权; <br> | |||
* 如果指定的角色不存在,或者版本不匹配,则引发 {@link LedgerException} 异常; | |||
* | |||
* @param participant | |||
*/ | |||
public void updateRoleAuthorization(RolePrivilegeAuthorization roleAuth) { | |||
long nv = innerSetRoleAuthorization(roleAuth); | |||
if (nv < 0) { | |||
throw new LedgerException("Update to RoleAuthorization[" + roleAuth.getRoleName() | |||
+ "] failed due to wrong version[" + roleAuth.getVersion() + "] !"); | |||
} | |||
} | |||
/** | |||
* 授权角色指定的权限; <br> | |||
* 如果角色不存在,则返回 -1; | |||
* | |||
* @param participant | |||
*/ | |||
public long authorizePermissions(String roleName, LedgerPermission... permissions) { | |||
RolePrivilegeAuthorization roleAuth = getRoleAuthorization(roleName); | |||
if (roleAuth == null) { | |||
return -1; | |||
} | |||
roleAuth.getLedgerPrivilege().enable(permissions); | |||
return innerSetRoleAuthorization(roleAuth); | |||
} | |||
/** | |||
* 授权角色指定的权限; <br> | |||
* 如果角色不存在,则返回 -1; | |||
* | |||
* @param participant | |||
*/ | |||
public long authorizePermissions(String roleName, TransactionPermission... permissions) { | |||
RolePrivilegeAuthorization roleAuth = getRoleAuthorization(roleName); | |||
if (roleAuth == null) { | |||
return -1; | |||
} | |||
roleAuth.getTransactionPrivilege().enable(permissions); | |||
return innerSetRoleAuthorization(roleAuth); | |||
} | |||
private Bytes encodeKey(String address) { | |||
// return id + ""; | |||
return Bytes.fromString(address); | |||
} | |||
/** | |||
* 查询角色授权; | |||
* | |||
* <br> | |||
* 如果不存在,则返回 null; | |||
* | |||
* @param address | |||
* @return | |||
*/ | |||
public RolePrivilegeAuthorization getRoleAuthorization(String roleName) { | |||
// 只返回最新版本; | |||
Bytes key = encodeKey(roleName); | |||
VersioningKVEntry kv = dataset.getDataEntry(key); | |||
if (kv == null) { | |||
return null; | |||
} | |||
RolePrivilege privilege = BinaryProtocol.decode(kv.getValue()); | |||
return new RolePrivilegeAuthorization(roleName, kv.getVersion(), privilege); | |||
} | |||
public RolePrivilegeAuthorization[] getRoleAuthorizations() { | |||
VersioningKVEntry[] kvEntries = dataset.getLatestDataEntries(0, (int) dataset.getDataCount()); | |||
RolePrivilegeAuthorization[] pns = new RolePrivilegeAuthorization[kvEntries.length]; | |||
RolePrivilege privilege; | |||
for (int i = 0; i < pns.length; i++) { | |||
privilege = BinaryProtocol.decode(kvEntries[i].getValue()); | |||
pns[i] = new RolePrivilegeAuthorization(kvEntries[i].getKey().toUTF8String(), kvEntries[i].getVersion(), privilege); | |||
} | |||
return pns; | |||
} | |||
} |
@@ -0,0 +1,270 @@ | |||
package com.jd.blockchain.ledger.core; | |||
import com.jd.blockchain.binaryproto.BinaryProtocol; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.ledger.CryptoSetting; | |||
import com.jd.blockchain.ledger.LedgerException; | |||
import com.jd.blockchain.storage.service.ExPolicyKVStorage; | |||
import com.jd.blockchain.storage.service.VersioningKVEntry; | |||
import com.jd.blockchain.storage.service.VersioningKVStorage; | |||
import com.jd.blockchain.utils.Bytes; | |||
import com.jd.blockchain.utils.Transactional; | |||
public class RolePrivilegeDataSet implements Transactional, MerkleProvable, RolePrivilegeSettings { | |||
/** | |||
* 角色名称的最大 Unicode 字符数; | |||
*/ | |||
public static final int MAX_ROLE_NAME_LENGTH = 20; | |||
private MerkleDataSet dataset; | |||
public RolePrivilegeDataSet(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exPolicyStorage, | |||
VersioningKVStorage verStorage) { | |||
dataset = new MerkleDataSet(cryptoSetting, prefix, exPolicyStorage, verStorage); | |||
} | |||
public RolePrivilegeDataSet(HashDigest merkleRootHash, CryptoSetting cryptoSetting, String prefix, | |||
ExPolicyKVStorage exPolicyStorage, VersioningKVStorage verStorage, boolean readonly) { | |||
dataset = new MerkleDataSet(merkleRootHash, cryptoSetting, prefix, exPolicyStorage, verStorage, readonly); | |||
} | |||
@Override | |||
public HashDigest getRootHash() { | |||
return dataset.getRootHash(); | |||
} | |||
@Override | |||
public MerkleProof getProof(Bytes key) { | |||
return dataset.getProof(key); | |||
} | |||
@Override | |||
public boolean isUpdated() { | |||
return dataset.isUpdated(); | |||
} | |||
@Override | |||
public void commit() { | |||
dataset.commit(); | |||
} | |||
@Override | |||
public void cancel() { | |||
dataset.cancel(); | |||
} | |||
@Override | |||
public long getRoleCount() { | |||
return dataset.getDataCount(); | |||
} | |||
/** | |||
* 加入新的角色授权; <br> | |||
* | |||
* 如果指定的角色已经存在,则引发 {@link LedgerException} 异常; | |||
* | |||
* @param roleName 角色名称;不能超过 {@link #MAX_ROLE_NAME_LENGTH} 个 Unicode 字符; | |||
* @param ledgerPrivilege | |||
* @param txPrivilege | |||
*/ | |||
@Override | |||
public void addRolePrivilege(String roleName, LedgerPrivilege ledgerPrivilege, TransactionPrivilege txPrivilege) { | |||
RolePrivileges roleAuth = new RolePrivileges(roleName, -1, ledgerPrivilege, | |||
txPrivilege); | |||
long nv = setRolePrivilege(roleAuth); | |||
if (nv < 0) { | |||
throw new LedgerException("Role[" + roleName + "] already exist!"); | |||
} | |||
} | |||
/** | |||
* 设置角色授权; <br> | |||
* 如果版本校验不匹配,则返回 -1; | |||
* | |||
* @param roleAuth | |||
* @return | |||
*/ | |||
private long setRolePrivilege(RolePrivileges roleAuth) { | |||
if (roleAuth.getRoleName().length() > MAX_ROLE_NAME_LENGTH) { | |||
throw new LedgerException("Too long role name!"); | |||
} | |||
Bytes key = encodeKey(roleAuth.getRoleName()); | |||
byte[] privilegeBytes = BinaryProtocol.encode(roleAuth, PrivilegeSet.class); | |||
return dataset.setValue(key, privilegeBytes, roleAuth.getVersion()); | |||
} | |||
/** | |||
* 更新角色授权; <br> | |||
* 如果指定的角色不存在,或者版本不匹配,则引发 {@link LedgerException} 异常; | |||
* | |||
* @param participant | |||
*/ | |||
@Override | |||
public void updateRolePrivilege(RolePrivileges roleAuth) { | |||
long nv = setRolePrivilege(roleAuth); | |||
if (nv < 0) { | |||
throw new LedgerException("Update to RoleAuthorization[" + roleAuth.getRoleName() | |||
+ "] failed due to wrong version[" + roleAuth.getVersion() + "] !"); | |||
} | |||
} | |||
/** | |||
* 授权角色指定的权限; <br> | |||
* 如果角色不存在,则返回 -1; | |||
* | |||
* @param roleName 角色; | |||
* @param permissions 权限列表; | |||
* @return | |||
*/ | |||
@Override | |||
public long enablePermissions(String roleName, LedgerPermission... permissions) { | |||
RolePrivileges roleAuth = getRolePrivilege(roleName); | |||
if (roleAuth == null) { | |||
return -1; | |||
} | |||
roleAuth.getLedgerPrivilege().enable(permissions); | |||
return setRolePrivilege(roleAuth); | |||
} | |||
/** | |||
* 授权角色指定的权限; <br> | |||
* 如果角色不存在,则返回 -1; | |||
* | |||
* @param roleName 角色; | |||
* @param permissions 权限列表; | |||
* @return | |||
*/ | |||
@Override | |||
public long enablePermissions(String roleName, TransactionPermission... permissions) { | |||
RolePrivileges roleAuth = getRolePrivilege(roleName); | |||
if (roleAuth == null) { | |||
return -1; | |||
} | |||
roleAuth.getTransactionPrivilege().enable(permissions); | |||
return setRolePrivilege(roleAuth); | |||
} | |||
/** | |||
* 禁止角色指定的权限; <br> | |||
* 如果角色不存在,则返回 -1; | |||
* | |||
* @param roleName 角色; | |||
* @param permissions 权限列表; | |||
* @return | |||
*/ | |||
@Override | |||
public long disablePermissions(String roleName, LedgerPermission... permissions) { | |||
RolePrivileges roleAuth = getRolePrivilege(roleName); | |||
if (roleAuth == null) { | |||
return -1; | |||
} | |||
roleAuth.getLedgerPrivilege().disable(permissions); | |||
return setRolePrivilege(roleAuth); | |||
} | |||
/** | |||
* 禁止角色指定的权限; <br> | |||
* 如果角色不存在,则返回 -1; | |||
* | |||
* @param roleName 角色; | |||
* @param permissions 权限列表; | |||
* @return | |||
*/ | |||
@Override | |||
public long disablePermissions(String roleName, TransactionPermission... permissions) { | |||
RolePrivileges roleAuth = getRolePrivilege(roleName); | |||
if (roleAuth == null) { | |||
return -1; | |||
} | |||
roleAuth.getTransactionPrivilege().disable(permissions); | |||
return setRolePrivilege(roleAuth); | |||
} | |||
/** | |||
* 授权角色指定的权限; <br> | |||
* 如果角色不存在,则返回 -1; | |||
* | |||
* @param roleName | |||
* @param ledgerPermissions | |||
* @param txPermissions | |||
* @return | |||
*/ | |||
@Override | |||
public long enablePermissions(String roleName, LedgerPermission[] ledgerPermissions, | |||
TransactionPermission[] txPermissions) { | |||
RolePrivileges roleAuth = getRolePrivilege(roleName); | |||
if (roleAuth == null) { | |||
return -1; | |||
} | |||
roleAuth.getLedgerPrivilege().enable(ledgerPermissions); | |||
roleAuth.getTransactionPrivilege().enable(txPermissions); | |||
return setRolePrivilege(roleAuth); | |||
} | |||
/** | |||
* 禁用角色指定的权限; <br> | |||
* 如果角色不存在,则返回 -1; | |||
* | |||
* @param roleName | |||
* @param ledgerPermissions | |||
* @param txPermissions | |||
* @return | |||
*/ | |||
@Override | |||
public long disablePermissions(String roleName, LedgerPermission[] ledgerPermissions, | |||
TransactionPermission[] txPermissions) { | |||
RolePrivileges roleAuth = getRolePrivilege(roleName); | |||
if (roleAuth == null) { | |||
return -1; | |||
} | |||
roleAuth.getLedgerPrivilege().disable(ledgerPermissions); | |||
roleAuth.getTransactionPrivilege().disable(txPermissions); | |||
return setRolePrivilege(roleAuth); | |||
} | |||
private Bytes encodeKey(String address) { | |||
// return id + ""; | |||
return Bytes.fromString(address); | |||
} | |||
/** | |||
* 查询角色授权; | |||
* | |||
* <br> | |||
* 如果不存在,则返回 null; | |||
* | |||
* @param address | |||
* @return | |||
*/ | |||
@Override | |||
public RolePrivileges getRolePrivilege(String roleName) { | |||
// 只返回最新版本; | |||
Bytes key = encodeKey(roleName); | |||
VersioningKVEntry kv = dataset.getDataEntry(key); | |||
if (kv == null) { | |||
return null; | |||
} | |||
PrivilegeSet privilege = BinaryProtocol.decode(kv.getValue()); | |||
return new RolePrivileges(roleName, kv.getVersion(), privilege); | |||
} | |||
@Override | |||
public RolePrivileges[] getRolePrivileges(int index, int count) { | |||
VersioningKVEntry[] kvEntries = dataset.getLatestDataEntries(index, count); | |||
RolePrivileges[] pns = new RolePrivileges[kvEntries.length]; | |||
PrivilegeSet privilege; | |||
for (int i = 0; i < pns.length; i++) { | |||
privilege = BinaryProtocol.decode(kvEntries[i].getValue()); | |||
pns[i] = new RolePrivileges(kvEntries[i].getKey().toUTF8String(), kvEntries[i].getVersion(), | |||
privilege); | |||
} | |||
return pns; | |||
} | |||
@Override | |||
public RolePrivileges[] getRolePrivileges() { | |||
return getRolePrivileges(0, (int) getRoleCount()); | |||
} | |||
} |
@@ -0,0 +1,107 @@ | |||
package com.jd.blockchain.ledger.core; | |||
import com.jd.blockchain.ledger.LedgerException; | |||
public interface RolePrivilegeSettings { | |||
long getRoleCount(); | |||
/** | |||
* 加入新的角色授权; <br> | |||
* | |||
* 如果指定的角色已经存在,则引发 {@link LedgerException} 异常; | |||
* | |||
* @param roleName 角色名称;不能超过 {@link #MAX_ROLE_NAME_LENGTH} 个 Unicode 字符; | |||
* @param ledgerPrivilege | |||
* @param txPrivilege | |||
*/ | |||
void addRolePrivilege(String roleName, LedgerPrivilege ledgerPrivilege, TransactionPrivilege txPrivilege); | |||
/** | |||
* 更新角色授权; <br> | |||
* 如果指定的角色不存在,或者版本不匹配,则引发 {@link LedgerException} 异常; | |||
* | |||
* @param participant | |||
*/ | |||
void updateRolePrivilege(RolePrivileges roleAuth); | |||
/** | |||
* 授权角色指定的权限; <br> | |||
* 如果角色不存在,则返回 -1; | |||
* | |||
* @param roleName 角色; | |||
* @param permissions 权限列表; | |||
* @return | |||
*/ | |||
long enablePermissions(String roleName, LedgerPermission... permissions); | |||
/** | |||
* 授权角色指定的权限; <br> | |||
* 如果角色不存在,则返回 -1; | |||
* | |||
* @param roleName 角色; | |||
* @param permissions 权限列表; | |||
* @return | |||
*/ | |||
long enablePermissions(String roleName, TransactionPermission... permissions); | |||
/** | |||
* 禁止角色指定的权限; <br> | |||
* 如果角色不存在,则返回 -1; | |||
* | |||
* @param roleName 角色; | |||
* @param permissions 权限列表; | |||
* @return | |||
*/ | |||
long disablePermissions(String roleName, LedgerPermission... permissions); | |||
/** | |||
* 禁止角色指定的权限; <br> | |||
* 如果角色不存在,则返回 -1; | |||
* | |||
* @param roleName 角色; | |||
* @param permissions 权限列表; | |||
* @return | |||
*/ | |||
long disablePermissions(String roleName, TransactionPermission... permissions); | |||
/** | |||
* 授权角色指定的权限; <br> | |||
* 如果角色不存在,则返回 -1; | |||
* | |||
* @param roleName | |||
* @param ledgerPermissions | |||
* @param txPermissions | |||
* @return | |||
*/ | |||
long enablePermissions(String roleName, LedgerPermission[] ledgerPermissions, | |||
TransactionPermission[] txPermissions); | |||
/** | |||
* 禁用角色指定的权限; <br> | |||
* 如果角色不存在,则返回 -1; | |||
* | |||
* @param roleName | |||
* @param ledgerPermissions | |||
* @param txPermissions | |||
* @return | |||
*/ | |||
long disablePermissions(String roleName, LedgerPermission[] ledgerPermissions, | |||
TransactionPermission[] txPermissions); | |||
/** | |||
* 查询角色授权; | |||
* | |||
* <br> | |||
* 如果不存在,则返回 null; | |||
* | |||
* @param address | |||
* @return | |||
*/ | |||
RolePrivileges getRolePrivilege(String roleName); | |||
RolePrivileges[] getRolePrivileges(int index, int count); | |||
RolePrivileges[] getRolePrivileges(); | |||
} |
@@ -6,7 +6,7 @@ package com.jd.blockchain.ledger.core; | |||
* @author huanghaiquan | |||
* | |||
*/ | |||
public class RolePrivilegeAuthorization implements RolePrivilege { | |||
public class RolePrivileges implements PrivilegeSet { | |||
private String roleName; | |||
@@ -16,21 +16,21 @@ public class RolePrivilegeAuthorization implements RolePrivilege { | |||
private TransactionPrivilege txPrivilege; | |||
public RolePrivilegeAuthorization(String roleName, long version) { | |||
public RolePrivileges(String roleName, long version) { | |||
this.roleName = roleName; | |||
this.version = version; | |||
this.ledgerPrivilege = new LedgerPrivilege(); | |||
this.txPrivilege = new TransactionPrivilege(); | |||
} | |||
public RolePrivilegeAuthorization(String roleName, long version, RolePrivilege privilege) { | |||
public RolePrivileges(String roleName, long version, PrivilegeSet privilege) { | |||
this.roleName = roleName; | |||
this.version = version; | |||
this.ledgerPrivilege = privilege.getLedgerPrivilege(); | |||
this.txPrivilege = privilege.getTransactionPrivilege(); | |||
} | |||
public RolePrivilegeAuthorization(String roleName, long version, LedgerPrivilege ledgerPrivilege, TransactionPrivilege txPrivilege) { | |||
public RolePrivileges(String roleName, long version, LedgerPrivilege ledgerPrivilege, TransactionPrivilege txPrivilege) { | |||
this.roleName = roleName; | |||
this.version = version; | |||
this.ledgerPrivilege = ledgerPrivilege; |
@@ -10,7 +10,7 @@ import com.jd.blockchain.storage.service.VersioningKVStorage; | |||
import com.jd.blockchain.utils.Bytes; | |||
import com.jd.blockchain.utils.Transactional; | |||
public class UserRoleDataSet implements Transactional, MerkleProvable { | |||
public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleSettings { | |||
/** | |||
* 角色名称的最大 Unicode 字符数; | |||
@@ -54,6 +54,7 @@ public class UserRoleDataSet implements Transactional, MerkleProvable { | |||
dataset.cancel(); | |||
} | |||
@Override | |||
public long getRoleCount() { | |||
return dataset.getDataCount(); | |||
} | |||
@@ -67,10 +68,11 @@ public class UserRoleDataSet implements Transactional, MerkleProvable { | |||
* @param rolesPolicy | |||
* @param roles | |||
*/ | |||
@Override | |||
public void addUserRoles(Bytes userAddress, RolesPolicy rolesPolicy, String... roles) { | |||
UserRolesAuthorization roleAuth = new UserRolesAuthorization(userAddress, -1, rolesPolicy); | |||
UserRoles roleAuth = new UserRoles(userAddress, -1, rolesPolicy); | |||
roleAuth.addRoles(roles); | |||
long nv = innerSetUserRolesAuthorization(roleAuth); | |||
long nv = setUserRolesAuthorization(roleAuth); | |||
if (nv < 0) { | |||
throw new LedgerException("Roles authorization of User[" + userAddress + "] already exists!"); | |||
} | |||
@@ -83,7 +85,7 @@ public class UserRoleDataSet implements Transactional, MerkleProvable { | |||
* @param userRoles | |||
* @return | |||
*/ | |||
public long innerSetUserRolesAuthorization(UserRolesAuthorization userRoles) { | |||
private long setUserRolesAuthorization(UserRoles userRoles) { | |||
byte[] rolesetBytes = BinaryProtocol.encode(userRoles, RoleSet.class); | |||
return dataset.setValue(userRoles.getUserAddress(), rolesetBytes, userRoles.getVersion()); | |||
} | |||
@@ -94,8 +96,9 @@ public class UserRoleDataSet implements Transactional, MerkleProvable { | |||
* | |||
* @param userRoles | |||
*/ | |||
public void updateUserRolesAuthorization(UserRolesAuthorization userRoles) { | |||
long nv = innerSetUserRolesAuthorization(userRoles); | |||
@Override | |||
public void updateUserRoles(UserRoles userRoles) { | |||
long nv = setUserRolesAuthorization(userRoles); | |||
if (nv < 0) { | |||
throw new LedgerException("Update to roles of user[" + userRoles.getUserAddress() | |||
+ "] failed due to wrong version[" + userRoles.getVersion() + "] !"); | |||
@@ -111,14 +114,15 @@ public class UserRoleDataSet implements Transactional, MerkleProvable { | |||
* @param roles 角色列表; | |||
* @return | |||
*/ | |||
@Override | |||
public long setRoles(Bytes userAddress, RolesPolicy policy, String... roles) { | |||
UserRolesAuthorization userRoles = getUserRolesAuthorization(userAddress); | |||
UserRoles userRoles = getUserRoles(userAddress); | |||
if (userRoles == null) { | |||
userRoles = new UserRolesAuthorization(userAddress, -1, policy); | |||
userRoles = new UserRoles(userAddress, -1, policy); | |||
} | |||
userRoles.setPolicy(policy); | |||
userRoles.setRoles(roles); | |||
return innerSetUserRolesAuthorization(userRoles); | |||
return setUserRolesAuthorization(userRoles); | |||
} | |||
/** | |||
@@ -130,24 +134,25 @@ public class UserRoleDataSet implements Transactional, MerkleProvable { | |||
* @param address | |||
* @return | |||
*/ | |||
public UserRolesAuthorization getUserRolesAuthorization(Bytes userAddress) { | |||
@Override | |||
public UserRoles getUserRoles(Bytes userAddress) { | |||
// 只返回最新版本; | |||
VersioningKVEntry kv = dataset.getDataEntry(userAddress); | |||
if (kv == null) { | |||
return null; | |||
} | |||
RoleSet roleSet = BinaryProtocol.decode(kv.getValue()); | |||
return new UserRolesAuthorization(userAddress, kv.getVersion(), roleSet); | |||
return new UserRoles(userAddress, kv.getVersion(), roleSet); | |||
} | |||
public RolePrivilegeAuthorization[] getRoleAuthorizations() { | |||
@Override | |||
public UserRoles[] getRoleAuthorizations() { | |||
VersioningKVEntry[] kvEntries = dataset.getLatestDataEntries(0, (int) dataset.getDataCount()); | |||
RolePrivilegeAuthorization[] pns = new RolePrivilegeAuthorization[kvEntries.length]; | |||
RolePrivilege privilege; | |||
UserRoles[] pns = new UserRoles[kvEntries.length]; | |||
RoleSet roleset; | |||
for (int i = 0; i < pns.length; i++) { | |||
privilege = BinaryProtocol.decode(kvEntries[i].getValue()); | |||
pns[i] = new RolePrivilegeAuthorization(kvEntries[i].getKey().toUTF8String(), kvEntries[i].getVersion(), | |||
privilege); | |||
roleset = BinaryProtocol.decode(kvEntries[i].getValue()); | |||
pns[i] = new UserRoles(kvEntries[i].getKey(), kvEntries[i].getVersion(), roleset); | |||
} | |||
return pns; | |||
} | |||
@@ -0,0 +1,53 @@ | |||
package com.jd.blockchain.ledger.core; | |||
import com.jd.blockchain.ledger.LedgerException; | |||
import com.jd.blockchain.utils.Bytes; | |||
public interface UserRoleSettings { | |||
long getRoleCount(); | |||
/** | |||
* 加入新的用户角色授权; <br> | |||
* | |||
* 如果该用户的授权已经存在,则引发 {@link LedgerException} 异常; | |||
* | |||
* @param userAddress | |||
* @param rolesPolicy | |||
* @param roles | |||
*/ | |||
void addUserRoles(Bytes userAddress, RolesPolicy rolesPolicy, String... roles); | |||
/** | |||
* 更新用户角色授权; <br> | |||
* 如果指定用户的授权不存在,或者版本不匹配,则引发 {@link LedgerException} 异常; | |||
* | |||
* @param userRoles | |||
*/ | |||
void updateUserRoles(UserRoles userRoles); | |||
/** | |||
* 设置用户的角色; <br> | |||
* 如果用户的角色授权不存在,则创建新的授权; | |||
* | |||
* @param userAddress 用户; | |||
* @param policy 角色策略; | |||
* @param roles 角色列表; | |||
* @return | |||
*/ | |||
long setRoles(Bytes userAddress, RolesPolicy policy, String... roles); | |||
/** | |||
* 查询角色授权; | |||
* | |||
* <br> | |||
* 如果不存在,则返回 null; | |||
* | |||
* @param address | |||
* @return | |||
*/ | |||
UserRoles getUserRoles(Bytes userAddress); | |||
UserRoles[] getRoleAuthorizations(); | |||
} |
@@ -5,7 +5,7 @@ import java.util.TreeSet; | |||
import com.jd.blockchain.utils.Bytes; | |||
public class UserRolesAuthorization implements RoleSet { | |||
public class UserRoles implements RoleSet { | |||
private Bytes userAddress; | |||
@@ -15,14 +15,14 @@ public class UserRolesAuthorization implements RoleSet { | |||
private long version; | |||
public UserRolesAuthorization(Bytes userAddress, long version, RolesPolicy policy) { | |||
public UserRoles(Bytes userAddress, long version, RolesPolicy policy) { | |||
this.userAddress = userAddress; | |||
this.version = version; | |||
this.policy = policy; | |||
this.roles = new TreeSet<String>(); | |||
} | |||
public UserRolesAuthorization(Bytes userAddress, long version, RoleSet roleSet) { | |||
public UserRoles(Bytes userAddress, long version, RoleSet roleSet) { | |||
this.userAddress = userAddress; | |||
this.version = version; | |||
this.policy = roleSet.getPolicy(); |
@@ -8,7 +8,7 @@ import com.jd.blockchain.crypto.HashDigest; | |||
/** | |||
* {@link LedgerMetadata_V2} 是 {@link LedgerMetadata} 的升级版本,新增加了 | |||
* {@link #getPrivilegeHash()} 属性; | |||
* {@link #getRolePrivilegesHash()} 属性; | |||
* | |||
* @author huanghaiquan | |||
* | |||
@@ -17,11 +17,19 @@ import com.jd.blockchain.crypto.HashDigest; | |||
public interface LedgerMetadata_V2 extends LedgerMetadata { | |||
/** | |||
* 加入新的版本; | |||
* 角色权限集合的根哈希;; | |||
* | |||
* @return | |||
*/ | |||
@DataField(order = 4, primitiveType = PrimitiveType.BYTES) | |||
HashDigest getPrivilegeHash(); | |||
HashDigest getRolePrivilegesHash(); | |||
/** | |||
* 用户角色授权集合的根哈希; | |||
* | |||
* @return | |||
*/ | |||
@DataField(order = 5, primitiveType = PrimitiveType.BYTES) | |||
HashDigest getUserRolesHash(); | |||
} |