Browse Source

Completed dataset definitions about roles and user-roles assignment;

tags/1.1.0
huanghaiquan 5 years ago
parent
commit
89bd2d87af
17 changed files with 636 additions and 137 deletions
  1. +8
    -2
      source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java
  2. +26
    -31
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AbstractPrivilege.java
  3. +1
    -1
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerPermission.java
  4. +3
    -0
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerPrivilege.java
  5. +2
    -2
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerSecurityManager.java
  6. +21
    -0
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataSet.java
  7. +0
    -27
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/Role.java
  8. +175
    -0
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RoleDataSet.java
  9. +10
    -55
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilege.java
  10. +66
    -0
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeAuthorization.java
  11. +23
    -0
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RoleSet.java
  12. +40
    -0
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolesPolicy.java
  13. +5
    -5
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/TransactionPermission.java
  14. +17
    -0
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/TransactionPrivilege.java
  15. +0
    -14
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/TxPrivilege.java
  16. +155
    -0
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleDataSet.java
  17. +84
    -0
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRolesAuthorization.java

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

@@ -56,8 +56,14 @@ public interface DataCodes {
public static final int TX_OP_RESULT = 0x360;

// enum types of permissions;
public static final int ENUM_TX_PERMISSIONS = 0x401;
public static final int ENUM_LEDGER_PERMISSIONS = 0x402;
public static final int ENUM_TX_PERMISSION = 0x401;
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 ROLE_SET = 0x411;

// contract types of metadata;
public static final int METADATA = 0x600;


+ 26
- 31
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AbstractPrivilege.java View File

@@ -12,52 +12,47 @@ import com.jd.blockchain.utils.io.BytesSerializable;
*/
public abstract class AbstractPrivilege<E extends Enum<?>> implements Privilege<E>, BytesSerializable {

private BitSet permissions;
private BitSet permissionBits;
public AbstractPrivilege() {
permissionBits = new BitSet();
}

public AbstractPrivilege(byte[] codeBytes) {
permissions = BitSet.valueOf(codeBytes);
permissionBits = BitSet.valueOf(codeBytes);
}

public boolean isEnable(E permission) {
return permissions.get(getCodeIndex(permission));
return permissionBits.get(getCodeIndex(permission));
}

public void enable(E permission) {
permissions.set(getCodeIndex(permission));
permissionBits.set(getCodeIndex(permission));
}

public void disable(E permission) {
permissions.clear(getCodeIndex(permission));
permissionBits.clear(getCodeIndex(permission));
}
@SuppressWarnings("unchecked")
public void enable(E... permissions) {
for (E p : permissions) {
permissionBits.set(getCodeIndex(p));
}
}
@SuppressWarnings("unchecked")
public void disable(E... permissions) {
for (E p : permissions) {
permissionBits.clear(getCodeIndex(p));
}
}

// private int getCodeIndex(E permission) {
// return permission.CODE & 0xFF;
// }

protected abstract int getCodeIndex(E permission);

@Override
public byte[] toBytes() {
return permissions.toByteArray();
}

// public boolean[] getPermissionStates() {
// LedgerPermission[] PMs = LedgerPermission.values();
//
// LedgerPermission maxPermission = Arrays.stream(PMs).max(new Comparator<LedgerPermission>() {
// @Override
// public int compare(LedgerPermission o1, LedgerPermission o2) {
// return getCodeIndex(o1) - getCodeIndex(o2);
// }
// }).get();
//
// boolean[] states = new boolean[getCodeIndex(maxPermission) + 1];
// int idx = -1;
// for (LedgerPermission pm : PMs) {
// idx = getCodeIndex(pm);
// states[idx] = permissions.get(idx);
// }
//
// return states;
// }
return permissionBits.toByteArray();
}

}

+ 1
- 1
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerPermission.java View File

@@ -11,7 +11,7 @@ import com.jd.blockchain.consts.DataCodes;
* @author huanghaiquan
*
*/
@EnumContract(code = DataCodes.ENUM_LEDGER_PERMISSIONS)
@EnumContract(code = DataCodes.ENUM_LEDGER_PERMISSION)
public enum LedgerPermission {

/**


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

@@ -8,6 +8,9 @@ package com.jd.blockchain.ledger.core;
*/
public class LedgerPrivilege extends AbstractPrivilege<LedgerPermission> {

public LedgerPrivilege() {
}
public LedgerPrivilege(byte[] codeBytes) {
super(codeBytes);
}


+ 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 Role setRole(String role, LedgerPrivilege privilege) {
public RolePrivilegeAuthorization setRole(String role, LedgerPrivilege privilege) {
throw new IllegalStateException("Not implemented!");
}

public Role getRole(String role) {
public RolePrivilegeAuthorization getRole(String role) {
throw new IllegalStateException("Not implemented!");
}


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

@@ -149,6 +149,22 @@ public class MerkleDataSet implements Transactional, MerkleProvable {
}
return values;
}
public VersioningKVEntry[] getLatestDataEntries(int fromIndex, int count) {
if (count > LedgerConsts.MAX_LIST_COUNT) {
throw new IllegalArgumentException("Count exceed the upper limit[" + LedgerConsts.MAX_LIST_COUNT + "]!");
}
if (fromIndex < 0 || (fromIndex + count) > merkleTree.getDataCount()) {
throw new IllegalArgumentException("Index out of bound!");
}
VersioningKVEntry[] values = new VersioningKVEntry[count];
for (int i = 0; i < count; i++) {
MerkleDataNode dataNode = merkleTree.getData(fromIndex + i);
Bytes dataKey = encodeDataKey(dataNode.getKey());
values[i] = valueStorage.getEntry(dataKey, dataNode.getVersion());
}
return values;
}
/**
* get the data at the specific index;
@@ -404,6 +420,11 @@ public class MerkleDataSet implements Transactional, MerkleProvable {
return getDataEntry(Bytes.fromString(key));
}
/**
*
* @param key
* @return Null if the key doesn't exist!
*/
public VersioningKVEntry getDataEntry(Bytes key) {
long latestVersion = getMerkleVersion(key);
if (latestVersion < 0) {


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

@@ -1,27 +0,0 @@
package com.jd.blockchain.ledger.core;

public class Role {
private String name;
private long version;
private LedgerPrivilege privilege;

public String getName() {
return name;
}

public long getVersion() {
return version;
}

public LedgerPrivilege getPrivilege() {
return privilege;
}
}

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

@@ -0,0 +1,175 @@
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;
}

}

+ 10
- 55
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilege.java View File

@@ -1,10 +1,9 @@
package com.jd.blockchain.ledger.core;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import com.jd.blockchain.utils.io.BytesEncoding;
import com.jd.blockchain.utils.io.BytesSerializable;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;

/**
* 表示赋予角色的特权码;
@@ -12,57 +11,13 @@ import com.jd.blockchain.utils.io.BytesSerializable;
* @author huanghaiquan
*
*/
public class RolePrivilege implements BytesSerializable {

// 权限码的数量;目前有2种:账本权限 + 交易权限;
private static final int SEGMENT_COUNT = 2;

private LedgerPrivilege ledgerPrivilege;

private TxPrivilege txPrivilege;

public Privilege<TxPermission> getTxPrivilege() {
return txPrivilege;
}

public Privilege<LedgerPermission> getLedgerPrivilege() {
return ledgerPrivilege;
}

public RolePrivilege(byte[] priviledgeCodes) {
byte[][] bytesSegments = decodeBytes(priviledgeCodes);
ledgerPrivilege = new LedgerPrivilege(bytesSegments[0]);
txPrivilege = new TxPrivilege(bytesSegments[1]);
}

private byte[] encodeBytes(byte[]... bytes) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
// write one byte;
out.write(bytes.length);
for (int i = 0; i < bytes.length; i++) {
BytesEncoding.writeInTiny(bytes[i], out);
}
return out.toByteArray();
}
@DataContract(code = DataCodes.ROLE_PRIVILEGE, name = "ROLE-PRIVILEGE")
public interface RolePrivilege {

private byte[][] decodeBytes(byte[] bytes) {
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
// read one byte;
int len = in.read();
if (len < 1 || len > SEGMENT_COUNT) {
throw new IllegalStateException("Decoded illegal privilege bytes!");
}
byte[][] bytesSegments = new byte[len][];
for (int i = 0; i < bytesSegments.length; i++) {
bytesSegments[i] = BytesEncoding.readInTiny(in);
}
return bytesSegments;
}
@DataField(order = 1, primitiveType = PrimitiveType.BYTES)
LedgerPrivilege getLedgerPrivilege();

@Override
public byte[] toBytes() {
// 保持和解码时一致的顺序;
return encodeBytes(ledgerPrivilege.toBytes(), txPrivilege.toBytes());
}
@DataField(order = 1, primitiveType = PrimitiveType.BYTES)
TransactionPrivilege getTransactionPrivilege();

}

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

@@ -0,0 +1,66 @@
package com.jd.blockchain.ledger.core;

/**
* 对角色的授权;
*
* @author huanghaiquan
*
*/
public class RolePrivilegeAuthorization implements RolePrivilege {

private String roleName;

private long version;

private LedgerPrivilege ledgerPrivilege;

private TransactionPrivilege txPrivilege;

public RolePrivilegeAuthorization(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) {
this.roleName = roleName;
this.version = version;
this.ledgerPrivilege = privilege.getLedgerPrivilege();
this.txPrivilege = privilege.getTransactionPrivilege();
}

public RolePrivilegeAuthorization(String roleName, long version, LedgerPrivilege ledgerPrivilege, TransactionPrivilege txPrivilege) {
this.roleName = roleName;
this.version = version;
this.ledgerPrivilege = ledgerPrivilege;
this.txPrivilege = txPrivilege;
}

public String getRoleName() {
return roleName;
}

public long getVersion() {
return version;
}

@Override
public LedgerPrivilege getLedgerPrivilege() {
return ledgerPrivilege;
}

public void setLedgerPrivilege(LedgerPrivilege ledgerPrivilege) {
this.ledgerPrivilege = ledgerPrivilege;
}

@Override
public TransactionPrivilege getTransactionPrivilege() {
return txPrivilege;
}

public void setTransactionPrivilege(TransactionPrivilege txPrivilege) {
this.txPrivilege = txPrivilege;
}

}

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

@@ -0,0 +1,23 @@
package com.jd.blockchain.ledger.core;

import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;

/**
* 角色集;
*
* @author huanghaiquan
*
*/
@DataContract(code = DataCodes.ROLE_SET)
public interface RoleSet {

@DataField(order = 1, refEnum = true)
RolesPolicy getPolicy();

@DataField(order = 2, primitiveType = PrimitiveType.TEXT, list = true)
String[] getRoles();

}

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

@@ -0,0 +1,40 @@
package com.jd.blockchain.ledger.core;

import com.jd.blockchain.binaryproto.EnumContract;
import com.jd.blockchain.binaryproto.EnumField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;

/**
* 多角色策略;<br>
*
* 表示如何处理一个对象被赋予多个角色时的综合权限;
*
* @author huanghaiquan
*
*/
@EnumContract(code = DataCodes.ENUM_MULTI_ROLES_POLICY, name = "USER-ROLE-POLICY")
public enum RolesPolicy {

/**
* 合并权限;<br>
*
* 综合权限是所有角色权限的并集,即任何一个角色的权限都被继承;
*/
UNION((byte) 0),

/**
* 交叉权限;<br>
*
* 综合权限是所有角色权限的交集,即只有全部角色共同拥有的权限才会被继承;
*/
INTERSECT((byte) 1);

@EnumField(type = PrimitiveType.INT8)
public final byte CODE;

private RolesPolicy(byte code) {
this.CODE = code;
}

}

source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/TxPermission.java → source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/TransactionPermission.java View File

@@ -11,23 +11,23 @@ import com.jd.blockchain.consts.DataCodes;
* @author huanghaiquan
*
*/
@EnumContract(code = DataCodes.ENUM_TX_PERMISSIONS)
public enum TxPermission {
@EnumContract(code = DataCodes.ENUM_TX_PERMISSION)
public enum TransactionPermission {

/**
* 交易中包含指令操作;
*/
COMMAND((byte) 0x01),
DIRECT_OPERATION((byte) 0x01),

/**
* 交易中包含合约操作;
*/
CONTRACT((byte) 0x02);
CONTRACT_OPERATION((byte) 0x02);

@EnumField(type = PrimitiveType.INT8)
public final byte CODE;

private TxPermission(byte code) {
private TransactionPermission(byte code) {
this.CODE = code;
}


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

@@ -0,0 +1,17 @@
package com.jd.blockchain.ledger.core;

public class TransactionPrivilege extends AbstractPrivilege<TransactionPermission> {

public TransactionPrivilege() {
}

public TransactionPrivilege(byte[] codeBytes) {
super(codeBytes);
}

@Override
protected int getCodeIndex(TransactionPermission permission) {
return permission.CODE & 0xFF;
}

}

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

@@ -1,14 +0,0 @@
package com.jd.blockchain.ledger.core;

public class TxPrivilege extends AbstractPrivilege<TxPermission> {

public TxPrivilege(byte[] codeBytes) {
super(codeBytes);
}

@Override
protected int getCodeIndex(TxPermission permission) {
return permission.CODE & 0xFF;
}

}

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

@@ -0,0 +1,155 @@
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 UserRoleDataSet implements Transactional, MerkleProvable {

/**
* 角色名称的最大 Unicode 字符数;
*/
public static final int MAX_ROLE_NAME_LENGTH = 20;

private MerkleDataSet dataset;

public UserRoleDataSet(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exPolicyStorage,
VersioningKVStorage verStorage) {
dataset = new MerkleDataSet(cryptoSetting, prefix, exPolicyStorage, verStorage);
}

public UserRoleDataSet(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 userAddress
* @param rolesPolicy
* @param roles
*/
public void addUserRoles(Bytes userAddress, RolesPolicy rolesPolicy, String... roles) {
UserRolesAuthorization roleAuth = new UserRolesAuthorization(userAddress, -1, rolesPolicy);
roleAuth.addRoles(roles);
long nv = innerSetUserRolesAuthorization(roleAuth);
if (nv < 0) {
throw new LedgerException("Roles authorization of User[" + userAddress + "] already exists!");
}
}

/**
* 设置用户角色授权; <br>
* 如果版本校验不匹配,则返回 -1;
*
* @param userRoles
* @return
*/
public long innerSetUserRolesAuthorization(UserRolesAuthorization userRoles) {
byte[] rolesetBytes = BinaryProtocol.encode(userRoles, RoleSet.class);
return dataset.setValue(userRoles.getUserAddress(), rolesetBytes, userRoles.getVersion());
}

/**
* 更新用户角色授权; <br>
* 如果指定用户的授权不存在,或者版本不匹配,则引发 {@link LedgerException} 异常;
*
* @param userRoles
*/
public void updateUserRolesAuthorization(UserRolesAuthorization userRoles) {
long nv = innerSetUserRolesAuthorization(userRoles);
if (nv < 0) {
throw new LedgerException("Update to roles of user[" + userRoles.getUserAddress()
+ "] failed due to wrong version[" + userRoles.getVersion() + "] !");
}
}

/**
* 设置用户的角色; <br>
* 如果用户的角色授权不存在,则创建新的授权;
*
* @param userAddress 用户;
* @param policy 角色策略;
* @param roles 角色列表;
* @return
*/
public long setRoles(Bytes userAddress, RolesPolicy policy, String... roles) {
UserRolesAuthorization userRoles = getUserRolesAuthorization(userAddress);
if (userRoles == null) {
userRoles = new UserRolesAuthorization(userAddress, -1, policy);
}
userRoles.setPolicy(policy);
userRoles.setRoles(roles);
return innerSetUserRolesAuthorization(userRoles);
}

/**
* 查询角色授权;
*
* <br>
* 如果不存在,则返回 null;
*
* @param address
* @return
*/
public UserRolesAuthorization getUserRolesAuthorization(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);
}

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

}

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

@@ -0,0 +1,84 @@
package com.jd.blockchain.ledger.core;

import java.util.Set;
import java.util.TreeSet;

import com.jd.blockchain.utils.Bytes;

public class UserRolesAuthorization implements RoleSet {

private Bytes userAddress;

private RolesPolicy policy;

private Set<String> roles;

private long version;

public UserRolesAuthorization(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) {
this.userAddress = userAddress;
this.version = version;
this.policy = roleSet.getPolicy();
this.roles = initRoles(roleSet.getRoles());

}

private Set<String> initRoles(String[] roles) {
TreeSet<String> roleset = new TreeSet<String>();
if (roles != null) {
for (String r : roles) {
roleset.add(r);
}
}
return roleset;
}

public Bytes getUserAddress() {
return userAddress;
}

@Override
public RolesPolicy getPolicy() {
return policy;
}

public void setPolicy(RolesPolicy policy) {
this.policy = policy;
}

public int getRoleCount() {
return roles.size();
}

@Override
public String[] getRoles() {
return roles.toArray(new String[roles.size()]);
}

public long getVersion() {
return version;
}

public void addRoles(String... roles) {
for (String r : roles) {
this.roles.add(r);
}
}

/**
* 设置角色集合;<br>
* 注意,这不是追加;现有的不在参数指定范围的角色将被移除;
*
* @param roles
*/
public void setRoles(String[] roles) {

}
}

Loading…
Cancel
Save