Browse Source

Completed user-role authorization model;

tags/1.1.0
huanghaiquan 5 years ago
parent
commit
7bc81950f2
14 changed files with 546 additions and 237 deletions
  1. +1
    -1
      source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java
  2. +71
    -7
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAdminAccount.java
  3. +2
    -2
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerSecurityManager.java
  4. +0
    -2
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PermissionService.java
  5. +0
    -21
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PrivilegeDataSet.java
  6. +2
    -2
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PrivilegeSet.java
  7. +0
    -175
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RoleDataSet.java
  8. +270
    -0
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeDataSet.java
  9. +107
    -0
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeSettings.java
  10. +4
    -4
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivileges.java
  11. +22
    -17
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleDataSet.java
  12. +53
    -0
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleSettings.java
  13. +3
    -3
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoles.java
  14. +11
    -3
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerMetadata_V2.java

+ 1
- 1
source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java View File

@@ -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;


+ 71
- 7
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAdminAccount.java View File

@@ -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;
}
}
}

+ 2
- 2
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerSecurityManager.java View File

@@ -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!");
}


+ 0
- 2
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PermissionService.java View File

@@ -1,7 +1,5 @@
package com.jd.blockchain.ledger.core;

import java.util.SortedSet;

public interface PermissionService {
boolean checkLedgerPermission();


+ 0
- 21
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PrivilegeDataSet.java View File

@@ -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);
// }
//
//}

source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilege.java → source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PrivilegeSet.java View File

@@ -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();

+ 0
- 175
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RoleDataSet.java View File

@@ -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;
}

}

+ 270
- 0
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeDataSet.java View File

@@ -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());
}

}

+ 107
- 0
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeSettings.java View File

@@ -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();

}

source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeAuthorization.java → source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivileges.java View File

@@ -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;

+ 22
- 17
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleDataSet.java View File

@@ -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;
}


+ 53
- 0
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleSettings.java View File

@@ -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();

}

source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRolesAuthorization.java → source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoles.java View File

@@ -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();

+ 11
- 3
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerMetadata_V2.java View File

@@ -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();

}

Loading…
Cancel
Save