Skip to content
This repository was archived by the owner on Mar 8, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .travis/before-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ sudo rm /usr/local/bin/docker-compose
curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose
chmod +x docker-compose
sudo mv docker-compose /usr/local/bin
echo "Docker-compose version: "
echo "Docker-compose version: "
docker-compose --version

# Update docker
Expand All @@ -22,7 +22,7 @@ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get install docker-ce
echo "Docker version: "
echo "Docker version: "
docker --version

# Grab the parent (root) directory.
Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
"packages": [
"packages/*"
],
"version": "0.8.2",
"version": "0.9.0",
"hoist": true
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
},
"name": "composer",
"description": "You must install [Lerna](https://lernajs.io) to build this multi-package repository.",
"version": "0.8.2",
"version": "0.9.0",
"main": "index.js",
"private": true,
"scripts": {
Expand Down
8 changes: 4 additions & 4 deletions packages/composer-admin/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "composer-admin",
"version": "0.8.2",
"version": "0.9.0",
"description": "Hyperledger Composer Admin, code that manages business networks deployed to Hyperledger Fabric",
"engines": {
"node": ">=6",
Expand Down Expand Up @@ -42,9 +42,9 @@
"sinon-as-promised": "^4.0.2"
},
"dependencies": {
"composer-common": "^0.8.2",
"composer-connector-hlf": "^0.8.2",
"composer-connector-hlfv1": "^0.8.2"
"composer-common": "^0.9.0",
"composer-connector-hlf": "^0.9.0",
"composer-connector-hlfv1": "^0.9.0"
},
"license-check-config": {
"src": [
Expand Down
10 changes: 5 additions & 5 deletions packages/composer-cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "composer-cli",
"version": "0.8.2",
"version": "0.9.0",
"description": "Hyperledger Composer command line interfaces (CLIs)",
"engines": {
"node": ">=6",
Expand Down Expand Up @@ -42,10 +42,10 @@
"dependencies": {
"chalk": "^1.1.3",
"cli-table": "^0.3.1",
"composer-admin": "^0.8.2",
"composer-client": "^0.8.2",
"composer-common": "^0.8.2",
"composer-rest-server": "^0.8.2",
"composer-admin": "^0.9.0",
"composer-client": "^0.9.0",
"composer-common": "^0.9.0",
"composer-rest-server": "^0.9.0",
"homedir": "^0.6.0",
"npm-paths": "^0.1.3",
"nunjucks": "^3.0.0",
Expand Down
8 changes: 4 additions & 4 deletions packages/composer-client/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "composer-client",
"version": "0.8.2",
"version": "0.9.0",
"description": "The node.js client library for Hyperledger Composer, a development framework for Hyperledger Fabric",
"engines": {
"node": ">=6",
Expand Down Expand Up @@ -42,9 +42,9 @@
"logError": true
},
"dependencies": {
"composer-common": "^0.8.2",
"composer-connector-hlf": "^0.8.2",
"composer-connector-hlfv1": "^0.8.2",
"composer-common": "^0.9.0",
"composer-connector-hlf": "^0.9.0",
"composer-connector-hlfv1": "^0.9.0",
"uuid": "^3.0.1"
},
"devDependencies": {
Expand Down
1 change: 1 addition & 0 deletions packages/composer-common/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ module.exports.Sort = require('./lib/query/sort');
module.exports.TransactionDeclaration = require('./lib/introspect/transactiondeclaration');
module.exports.TypescriptVisitor = require('./lib/codegen/fromcto/typescript/typescriptvisitor');
module.exports.Util = require('./lib/util');
module.exports.ModelUtil = require('./lib/modelutil');
module.exports.Wallet = require('./lib/wallet');
module.exports.Where = require('./lib/query/where');
module.exports.Writer = require('./lib/codegen/writer.js');
Expand Down
12 changes: 11 additions & 1 deletion packages/composer-common/lib/acl/aclrule.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,17 +112,27 @@ class AclRule {
const foundVerbs = {};
this.verbs.forEach((verb) => {
if (foundVerbs[verb]) {
throw new Error(`The verb '${verb}' has been specified more than once in the ACL rule '${this.name}'`);
throw new IllegalModelException(`The verb '${verb}' has been specified more than once in the ACL rule '${this.name}'`);
}
foundVerbs[verb] = true;
});

if(this.participant) {
this.participant.validate();

let participantClassDeclaration = this.participant.getClassDeclaration();
if (participantClassDeclaration && participantClassDeclaration.constructor.name !== 'ParticipantDeclaration') {
throw new IllegalModelException(`The participant '${participantClassDeclaration.getName()}' must be a participant`);
}
}

if(this.transaction) {
this.transaction.validate();

let transactionClassDeclaration = this.transaction.getClassDeclaration();
if (transactionClassDeclaration && transactionClassDeclaration.constructor.name !== 'TransactionDeclaration') {
throw new IllegalModelException(`The transaction '${transactionClassDeclaration.getName()}' must be a transaction`);
}
}

if(this.predicate) {
Expand Down
75 changes: 24 additions & 51 deletions packages/composer-common/lib/acl/modelbinding.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,70 +142,43 @@ class ModelBinding {

/**
* Semantic validation of the structure of this ModelBinding.
* <p>
* Algorithm:
* </p>
* <ul>
* <li>If we have a variableName, then qualifiedName cannot be a namespace
* <li>If we have an instanceId, then qualifiedName cannot be a namespace
* </ul>
* <pre>
* We assume we have ns.class.property and try to resolve the class in ns
* - On success
* -- Check that the property exists
* - On failure
* -- Try to resolve ns.class
* -- On failure
* --- If instanceId and variableName are null
* --- Try to resolve ns
* </pre>
*
* @throws {IllegalModelException}
* @private
*/
validate() {
const mm = this.getAclRule().getAclFile().getModelManager();

// assume qualifiedName is ns.class.property
const nsDotClass = ModelUtil.getNamespace(this.qualifiedName);
const ns = ModelUtil.getNamespace(nsDotClass);
const className = ModelUtil.getShortName(nsDotClass);
const propertyName = ModelUtil.getShortName(this.qualifiedName);
const modelFile = mm.getModelFile(ns);
const ns = ModelUtil.getNamespace(this.qualifiedName);
if (ModelUtil.isRecursiveWildcardName(this.qualifiedName)) {
const namespaces = mm.getNamespaces();

if(modelFile) {
const classDeclaration = modelFile.getLocalType(className);
if(!classDeclaration) {
throw new Error('Failed to find class ' + nsDotClass);
}
this.classDeclaration = classDeclaration;
const property = classDeclaration.getProperty(propertyName);
if(!property) {
throw new Error('Failed to find property ' + this.qualifiedName);
if (namespaces.findIndex(function (element, index, array) {
return (ns === element || element.startsWith(ns + '.'));
})=== -1) {
throw new IllegalModelException('Failed to find namespace ' + this.qualifiedName);
}
}
else {
// assume qualifiedName is ns.class
const ns = ModelUtil.getNamespace(this.qualifiedName);
const className = ModelUtil.getShortName(this.qualifiedName);
} else if (ModelUtil.isWildcardName(this.qualifiedName)) {
const modelFile = mm.getModelFile(ns);

if(modelFile) {
const classDeclaration = modelFile.getLocalType(className);
if(!classDeclaration) {
throw new Error('Failed to find class ' + this.qualifiedName);
}
this.classDeclaration = classDeclaration;
if(!modelFile) {
throw new IllegalModelException('Failed to find namespace ' + this.qualifiedName);
}
else if(this.instanceId === null && this.variableName === null) {
// assume namespace
const modelFile = mm.getModelFile(this.qualifiedName);
if(!modelFile) {
throw new Error('Failed to find namespace ' + this.qualifiedName);
}
} else {
const modelFile = mm.getModelFile(ns);

if(!modelFile) {
throw new IllegalModelException('Failed to find namespace ' + ns);
}
else {
throw new Error('Failed to resolve ' + this.qualifiedName);

const className = ModelUtil.getShortName(this.qualifiedName);
const classDeclaration = modelFile.getLocalType(className);

if(!classDeclaration) {
throw new IllegalModelException('Failed to find class ' + this.qualifiedName);
}

this.classDeclaration = classDeclaration;
}
}

Expand Down
16 changes: 11 additions & 5 deletions packages/composer-common/lib/acl/parser.pegjs
Original file line number Diff line number Diff line change
Expand Up @@ -1424,8 +1424,12 @@ InstanceId
return id;
}

Glob
= '.**'
/ '.*'

Binding
= qualifiedName:QualifiedName instanceId:InstanceId?
= qualifiedName:QualifiedName instanceId:InstanceId
{
return {
type: "Binding",
Expand All @@ -1436,17 +1440,18 @@ Binding
}

BindingNoInstance
= qualifiedName:QualifiedName
= qualifiedName:(QualifiedName Glob?)
{
return {
type: "BindingNoInstance",
qualifiedName: qualifiedName,
qualifiedName: qualifiedName.join(''),
location: location()
};
}

Noun
= Binding
/ BindingNoInstance

NounNoInstance
= BindingNoInstance
Expand Down Expand Up @@ -1486,8 +1491,9 @@ AllVerb = 'ALL'
Verbs = AllVerb / BasicVerbList

Participant
= 'ANY' /
Binding
= 'ANY'
/ Binding
/ BindingNoInstance

Predicate
= "(" __ test:$Expression __ ")" __
Expand Down
46 changes: 41 additions & 5 deletions packages/composer-common/lib/modelutil.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,51 @@ class ModelUtil {
}

/**
* Returns true if the specified name is a wildcard.
* Returns true if the specified name is a wildcard
* @param {string} fqn - the source string
* @return {boolean} true if the specified name is a wildcard.
* @return {boolean} true if the specified name is a wildcard
* @private
*/
static isWildcardName(fqn) {
return ModelUtil.getShortName(fqn) === '*';
}

/**
* Returns true if the specified name is a recusive wildcard
* @param {string} fqn - the source string
* @return {boolean} true if the specified name is a recusive wildcard
* @private
*/
static isRecursiveWildcardName(fqn) {
return ModelUtil.getShortName(fqn) === '**';
}

/**
* Returns true if a type matches the required fully qualified name. The required
* name may be a wildcard or recursive wildcard
* @param {Typed} type - the type to test
* @param {string} fqn - required fully qualified name
* @return {boolean} true if the specified type and namespace match
* @private
*/
static isMatchingType(type, fqn) {
let ns = ModelUtil.getNamespace(fqn);
let typeNS = type.getNamespace();

if (type.instanceOf(fqn)) {
// matching type or subtype
} else if (ModelUtil.isWildcardName(fqn) && typeNS === ns) {
// matching namespace
} else if (ModelUtil.isRecursiveWildcardName(fqn) && (typeNS + '.').startsWith(ns + '.')) {
// matching recursive namespace
} else {
// does not match
return false;
}

return true;
}

/**
* Returns the namespace for a the fully qualified name of a type
* @param {string} fqn - the fully qualified identifier of a type
Expand All @@ -76,13 +112,13 @@ class ModelUtil {

/**
* Returns true if the type is a primitive type
* @param {string} type - the name of the type
* @param {string} typeName - the name of the type
* @return {boolean} - true if the type is a primitive
* @private
*/
static isPrimitiveType(type) {
static isPrimitiveType(typeName) {
const primitiveTypes = ['Boolean', 'String', 'DateTime', 'Double', 'Integer', 'Long'];
return (primitiveTypes.indexOf(type) >= 0);
return (primitiveTypes.indexOf(typeName) >= 0);
}

/**
Expand Down
1 change: 0 additions & 1 deletion packages/composer-common/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@

"modelutil-getnamespace-nofnq": "FQN is invalid.",


"resourcevalidator-notresourceorconcept": "Model violation in instance {resourceId} class {classFQN} has value {invalidValue} expected a Resource or a Concept.",
"resourcevalidator-notrelationship": "Model violation in instance {resourceId} class {classFQN} has value {invalidValue} expected a Relationship.",
"resourcevalidator-fieldtypeviolation": "Model violation in instance {resourceId} field {propertyName} has value {value} ({typeOfValue}) expected type {fieldType}",
Expand Down
2 changes: 1 addition & 1 deletion packages/composer-common/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "composer-common",
"version": "0.8.2",
"version": "0.9.0",
"description": "Hyperledger Composer Common, code that is common across client, admin and runtime.",
"engines": {
"node": ">=6",
Expand Down
Loading