diff --git a/source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java b/source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java index 9e76d988..f27c5258 100644 --- a/source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java +++ b/source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java @@ -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; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAdminAccount.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAdminAccount.java index 1e494766..d1522ea5 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAdminAccount.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAdminAccount.java @@ -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; + } } } \ No newline at end of file diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerSecurityManager.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerSecurityManager.java index fc8151f3..c9cbf359 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerSecurityManager.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerSecurityManager.java @@ -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!"); } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PermissionService.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PermissionService.java index b3b9a7c2..78be086b 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PermissionService.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PermissionService.java @@ -1,7 +1,5 @@ package com.jd.blockchain.ledger.core; -import java.util.SortedSet; - public interface PermissionService { boolean checkLedgerPermission(); diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PrivilegeDataSet.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PrivilegeDataSet.java deleted file mode 100644 index 9bdc3f3b..00000000 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PrivilegeDataSet.java +++ /dev/null @@ -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 { -// -// 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); -// } -// -//} \ No newline at end of file diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilege.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PrivilegeSet.java similarity index 83% rename from source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilege.java rename to source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PrivilegeSet.java index e40649b2..aa22efd2 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilege.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PrivilegeSet.java @@ -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(); diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RoleDataSet.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RoleDataSet.java deleted file mode 100644 index 6fb3ee65..00000000 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RoleDataSet.java +++ /dev/null @@ -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(); - } - - /** - * 加入新的角色授权;
- * - * 如果指定的角色已经存在,则引发 {@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!"); - } - } - - /** - * 设置角色授权;
- * 如果版本校验不匹配,则返回 -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()); - } - - /** - * 更新角色授权;
- * 如果指定的角色不存在,或者版本不匹配,则引发 {@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() + "] !"); - } - } - - /** - * 授权角色指定的权限;
- * 如果角色不存在,则返回 -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); - } - - /** - * 授权角色指定的权限;
- * 如果角色不存在,则返回 -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); - } - - /** - * 查询角色授权; - * - *
- * 如果不存在,则返回 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; - } - -} diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeDataSet.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeDataSet.java new file mode 100644 index 00000000..327a4d3f --- /dev/null +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeDataSet.java @@ -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(); + } + + /** + * 加入新的角色授权;
+ * + * 如果指定的角色已经存在,则引发 {@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!"); + } + } + + /** + * 设置角色授权;
+ * 如果版本校验不匹配,则返回 -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()); + } + + /** + * 更新角色授权;
+ * 如果指定的角色不存在,或者版本不匹配,则引发 {@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() + "] !"); + } + } + + /** + * 授权角色指定的权限;
+ * 如果角色不存在,则返回 -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); + } + + /** + * 授权角色指定的权限;
+ * 如果角色不存在,则返回 -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); + } + + /** + * 禁止角色指定的权限;
+ * 如果角色不存在,则返回 -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); + } + + /** + * 禁止角色指定的权限;
+ * 如果角色不存在,则返回 -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); + } + + /** + * 授权角色指定的权限;
+ * 如果角色不存在,则返回 -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); + } + + /** + * 禁用角色指定的权限;
+ * 如果角色不存在,则返回 -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); + } + + /** + * 查询角色授权; + * + *
+ * 如果不存在,则返回 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()); + } + +} diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeSettings.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeSettings.java new file mode 100644 index 00000000..d900e002 --- /dev/null +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeSettings.java @@ -0,0 +1,107 @@ +package com.jd.blockchain.ledger.core; + +import com.jd.blockchain.ledger.LedgerException; + +public interface RolePrivilegeSettings { + + long getRoleCount(); + + /** + * 加入新的角色授权;
+ * + * 如果指定的角色已经存在,则引发 {@link LedgerException} 异常; + * + * @param roleName 角色名称;不能超过 {@link #MAX_ROLE_NAME_LENGTH} 个 Unicode 字符; + * @param ledgerPrivilege + * @param txPrivilege + */ + void addRolePrivilege(String roleName, LedgerPrivilege ledgerPrivilege, TransactionPrivilege txPrivilege); + + /** + * 更新角色授权;
+ * 如果指定的角色不存在,或者版本不匹配,则引发 {@link LedgerException} 异常; + * + * @param participant + */ + void updateRolePrivilege(RolePrivileges roleAuth); + + /** + * 授权角色指定的权限;
+ * 如果角色不存在,则返回 -1; + * + * @param roleName 角色; + * @param permissions 权限列表; + * @return + */ + long enablePermissions(String roleName, LedgerPermission... permissions); + + /** + * 授权角色指定的权限;
+ * 如果角色不存在,则返回 -1; + * + * @param roleName 角色; + * @param permissions 权限列表; + * @return + */ + long enablePermissions(String roleName, TransactionPermission... permissions); + + /** + * 禁止角色指定的权限;
+ * 如果角色不存在,则返回 -1; + * + * @param roleName 角色; + * @param permissions 权限列表; + * @return + */ + long disablePermissions(String roleName, LedgerPermission... permissions); + + /** + * 禁止角色指定的权限;
+ * 如果角色不存在,则返回 -1; + * + * @param roleName 角色; + * @param permissions 权限列表; + * @return + */ + long disablePermissions(String roleName, TransactionPermission... permissions); + + /** + * 授权角色指定的权限;
+ * 如果角色不存在,则返回 -1; + * + * @param roleName + * @param ledgerPermissions + * @param txPermissions + * @return + */ + long enablePermissions(String roleName, LedgerPermission[] ledgerPermissions, + TransactionPermission[] txPermissions); + + /** + * 禁用角色指定的权限;
+ * 如果角色不存在,则返回 -1; + * + * @param roleName + * @param ledgerPermissions + * @param txPermissions + * @return + */ + long disablePermissions(String roleName, LedgerPermission[] ledgerPermissions, + TransactionPermission[] txPermissions); + + /** + * 查询角色授权; + * + *
+ * 如果不存在,则返回 null; + * + * @param address + * @return + */ + RolePrivileges getRolePrivilege(String roleName); + + RolePrivileges[] getRolePrivileges(int index, int count); + + RolePrivileges[] getRolePrivileges(); + +} \ No newline at end of file diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeAuthorization.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivileges.java similarity index 77% rename from source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeAuthorization.java rename to source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivileges.java index b73f940c..e2c4f8a5 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeAuthorization.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivileges.java @@ -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; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleDataSet.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleDataSet.java index e4ddb63e..36b6b633 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleDataSet.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleDataSet.java @@ -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; } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleSettings.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleSettings.java new file mode 100644 index 00000000..d720aa59 --- /dev/null +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleSettings.java @@ -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(); + + /** + * 加入新的用户角色授权;
+ * + * 如果该用户的授权已经存在,则引发 {@link LedgerException} 异常; + * + * @param userAddress + * @param rolesPolicy + * @param roles + */ + void addUserRoles(Bytes userAddress, RolesPolicy rolesPolicy, String... roles); + + /** + * 更新用户角色授权;
+ * 如果指定用户的授权不存在,或者版本不匹配,则引发 {@link LedgerException} 异常; + * + * @param userRoles + */ + void updateUserRoles(UserRoles userRoles); + + /** + * 设置用户的角色;
+ * 如果用户的角色授权不存在,则创建新的授权; + * + * @param userAddress 用户; + * @param policy 角色策略; + * @param roles 角色列表; + * @return + */ + long setRoles(Bytes userAddress, RolesPolicy policy, String... roles); + + /** + * 查询角色授权; + * + *
+ * 如果不存在,则返回 null; + * + * @param address + * @return + */ + UserRoles getUserRoles(Bytes userAddress); + + UserRoles[] getRoleAuthorizations(); + +} \ No newline at end of file diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRolesAuthorization.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoles.java similarity index 86% rename from source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRolesAuthorization.java rename to source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoles.java index bc038827..57ec2110 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRolesAuthorization.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoles.java @@ -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(); } - 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(); diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerMetadata_V2.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerMetadata_V2.java index 1fbe075e..01ce182f 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerMetadata_V2.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerMetadata_V2.java @@ -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(); }