move orbit-db-access-controller tests here

This commit is contained in:
tabcat 2021-09-27 15:18:35 -05:00
parent 6151cdff18
commit c9fcb75f9b
21 changed files with 9509 additions and 801 deletions

8236
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -47,6 +47,7 @@
"cpy-cli": "^3.1.1",
"cross-env": "^7.0.2",
"fs-extra": "^9.0.1",
"ganache-cli": "^6.12.2",
"go-ipfs": "^0.10.0-rc1",
"ipfs": "^0.59.0",
"ipfsd-ctl": "^10.0.3",
@ -67,6 +68,7 @@
"rimraf": "^3.0.2",
"standard": "^14.3.4",
"validate-maintainers": "^1.2.2",
"web3": "^1.5.3",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10"
},
@ -77,7 +79,7 @@
"examples:browser-webpack": "open-cli examples/browser/browser-webpack-example/index.html",
"lint:docs": "remark -qf -u validate-links .",
"test:all": "npm run test:browser-multiple-tabs && npm run test",
"test": "cross-env TEST=all mocha",
"test": "cross-env TEST=all mocha && cross-env TEST=all mocha ./test/access-controllers --exit",
"test:browser-multiple-tabs": "npm run build:dist && cpy dist/orbitdb.min.js ./test/browser --rename=orbitdb.js && cpy node_modules/ipfs/index.min.js ./test/browser --rename=ipfs.js && cpy node_modules/orbit-db-identity-provider/dist/index-browser.min.js ./test/browser --rename=identities.js && cpy node_modules/ipfs-log/dist/ipfslog.min.js ./test/browser && mocha ./test/browser/concurrent.spec.js",
"build": "npm run build:es5 && npm run build:debug && npm run build:dist && npm run build:examples && npm run build:docs/toc",
"build:examples": "webpack --config conf/webpack.example.config.js --sort-modules-by size",

View File

@ -0,0 +1,6 @@
'use strict'
module.exports = {
exit: true,
recursive: true,
slow: 1000
}

View File

@ -0,0 +1,174 @@
{
"contractName": "Access",
"abi": [
{
"constant": true,
"inputs": [
{
"name": "",
"type": "address"
},
{
"name": "",
"type": "bytes32"
}
],
"name": "capabilities",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "OGAdmin",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"name": "user",
"type": "address"
},
{
"indexed": false,
"name": "capability",
"type": "bytes32"
}
],
"name": "CapabilityGranted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"name": "user",
"type": "address"
},
{
"indexed": false,
"name": "capability",
"type": "bytes32"
}
],
"name": "CapabilityRevoked",
"type": "event"
},
{
"constant": false,
"inputs": [
{
"name": "newAdmin",
"type": "address"
}
],
"name": "grantAdminStatus",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "adminToRemove",
"type": "address"
}
],
"name": "revokeAdminStatus",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "user",
"type": "address"
},
{
"name": "capability",
"type": "bytes32"
}
],
"name": "grantCapability",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "user",
"type": "address"
},
{
"name": "capability",
"type": "bytes32"
}
],
"name": "revokeCapability",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "user",
"type": "address"
},
{
"name": "capability",
"type": "bytes32"
}
],
"name": "isPermitted",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
}
],
"bytecode": "0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060018060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550610822806100b76000396000f3fe608060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063106bab8c146100885780631faad3c4146100fb578063228e3f9b14610152578063330506d9146101ad5780637caac39814610208578063e21c478314610259578063fa62a1ff146102cc575b600080fd5b34801561009457600080fd5b506100e1600480360360408110156100ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061031d565b604051808215151515815260200191505060405180910390f35b34801561010757600080fd5b5061011061034c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561015e57600080fd5b506101ab6004803603604081101561017557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610371565b005b3480156101b957600080fd5b50610206600480360360408110156101d057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506104a3565b005b34801561021457600080fd5b506102576004803603602081101561022b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506105d5565b005b34801561026557600080fd5b506102b26004803603604081101561027c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610689565b604051808215151515815260200191505060405180910390f35b3480156102d857600080fd5b5061031b600480360360208110156102ef57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610745565b005b60026020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60011515600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515141561049f576000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002060006101000a81548160ff0219169083151502179055507f6cc46c13bf9ecc309370a9150165239f833c3742128d77220c49cb4915a07bc78282604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15b5050565b60011515600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514156105d1576001600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002060006101000a81548160ff0219169083151502179055507faf409f79c52d1fc6127b156de998c22b9c6cf6d4f0f58e934e62f983c4dc82bf8282604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15b5050565b60011515600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514156106865760018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b50565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff168061073d5750600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002060009054906101000a900460ff165b905092915050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156107f3576000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b5056fea165627a7a7230582009cc4036faa4edfffcc9ba31cfc8caab65942780eb1dedaa2459f3514b30db5d0029",
"deployedBytecode": "0x608060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063106bab8c146100885780631faad3c4146100fb578063228e3f9b14610152578063330506d9146101ad5780637caac39814610208578063e21c478314610259578063fa62a1ff146102cc575b600080fd5b34801561009457600080fd5b506100e1600480360360408110156100ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061031d565b604051808215151515815260200191505060405180910390f35b34801561010757600080fd5b5061011061034c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561015e57600080fd5b506101ab6004803603604081101561017557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610371565b005b3480156101b957600080fd5b50610206600480360360408110156101d057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506104a3565b005b34801561021457600080fd5b506102576004803603602081101561022b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506105d5565b005b34801561026557600080fd5b506102b26004803603604081101561027c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610689565b604051808215151515815260200191505060405180910390f35b3480156102d857600080fd5b5061031b600480360360208110156102ef57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610745565b005b60026020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60011515600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515141561049f576000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002060006101000a81548160ff0219169083151502179055507f6cc46c13bf9ecc309370a9150165239f833c3742128d77220c49cb4915a07bc78282604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15b5050565b60011515600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514156105d1576001600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002060006101000a81548160ff0219169083151502179055507faf409f79c52d1fc6127b156de998c22b9c6cf6d4f0f58e934e62f983c4dc82bf8282604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15b5050565b60011515600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514156106865760018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b50565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff168061073d5750600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002060009054906101000a900460ff165b905092915050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156107f3576000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b5056fea165627a7a7230582009cc4036faa4edfffcc9ba31cfc8caab65942780eb1dedaa2459f3514b30db5d0029",
"sourceMap": "25:1342:0:-;;;185:93;8:9:-1;5:2;;;30:1;27;20:12;5:2;185:93:0;227:10;217:7;;:20;;;;;;;;;;;;;;;;;;267:4;247:5;:17;253:10;247:17;;;;;;;;;;;;;;;;:24;;;;;;;;;;;;;;;;;;25:1342;;;;;;",
"deployedSourceMap": "25:1342:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;112:66;;8:9:-1;5:2;;;30:1;27;20:12;5:2;112:66:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;112:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47:22;;8:9:-1;5:2;;;30:1;27;20:12;5:2;47:22:0;;;;;;;;;;;;;;;;;;;;;;;;;;;978:230;;8:9:-1;5:2;;;30:1;27;20:12;5:2;978:230:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;978:230:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;744:228;;8:9:-1;5:2;;;30:1;27;20:12;5:2;744:228:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;744:228:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;434:145;;8:9:-1;5:2;;;30:1;27;20:12;5:2;434:145:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;434:145:0;;;;;;;;;;;;;;;;;;;;;;1214:151;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1214:151:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;1214:151:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;585:153;;8:9:-1;5:2;;;30:1;27;20:12;5:2;585:153:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;585:153:0;;;;;;;;;;;;;;;;;;;;;;112:66;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;47:22::-;;;;;;;;;;;;;:::o;978:230::-;1079:4;1058:25;;:5;:17;1064:10;1058:17;;;;;;;;;;;;;;;;;;;;;;;;;:25;;;1055:147;;;1132:5;1099:12;:18;1112:4;1099:18;;;;;;;;;;;;;;;:30;1118:10;1099:30;;;;;;;;;;;;:38;;;;;;;;;;;;;;;;;;1156:35;1174:4;1180:10;1156:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;1055:147;978:230;;:::o;744:228::-;844:4;823:25;;:5;:17;829:10;823:17;;;;;;;;;;;;;;;;;;;;;;;;;:25;;;820:146;;;897:4;864:12;:18;877:4;864:18;;;;;;;;;;;;;;;:30;883:10;864:30;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;920:35;938:4;944:10;920:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;820:146;744:228;;:::o;434:145::-;520:4;499:25;;:5;:17;505:10;499:17;;;;;;;;;;;;;;;;;;;;;;;;;:25;;;495:78;;;558:4;540:5;:15;546:8;540:15;;;;;;;;;;;;;;;;:22;;;;;;;;;;;;;;;;;;495:78;434:145;:::o;1214:151::-;1290:4;1313:5;:11;1319:4;1313:11;;;;;;;;;;;;;;;;;;;;;;;;;:45;;;;1328:12;:18;1341:4;1328:18;;;;;;;;;;;;;;;:30;1347:10;1328:30;;;;;;;;;;;;;;;;;;;;;1313:45;1306:52;;1214:151;;;;:::o;585:153::-;670:7;;;;;;;;;;;656:21;;:10;:21;;;652:80;;;716:5;693;:20;699:13;693:20;;;;;;;;;;;;;;;;:28;;;;;;;;;;;;;;;;;;652:80;585:153;:::o",
"source": "pragma solidity ^0.5.0;\n\ncontract Access {\n address public OGAdmin;\n mapping (address => bool) admin;\n mapping (address => mapping (bytes32 => bool)) public capabilities;\n\n constructor () public {\n OGAdmin = msg.sender;\n admin[msg.sender] = true;\n }\n\n event CapabilityGranted(address user, bytes32 capability);\n\n event CapabilityRevoked(\n address user,\n bytes32 capability\n );\n\n function grantAdminStatus(address newAdmin) public {\n if (admin[msg.sender] == true) {\n admin[newAdmin] = true;\n }\n }\n\n function revokeAdminStatus(address adminToRemove) public {\n if (msg.sender == OGAdmin) {\n admin[adminToRemove] = false;\n }\n }\n\n function grantCapability(address user, bytes32 capability) public {\n if(admin[msg.sender] == true) {\n capabilities[user][capability] = true;\n emit CapabilityGranted(user, capability);\n }\n }\n\n function revokeCapability(address user, bytes32 capability) public {\n if(admin[msg.sender] == true) {\n capabilities[user][capability] = false;\n emit CapabilityRevoked(user, capability);\n }\n }\n\n function isPermitted(address user, bytes32 capability) public view returns (bool) {\n return admin[user] || capabilities[user][capability];\n }\n}\n"
}

View File

@ -0,0 +1,124 @@
{
"contractName": "PayDeposit",
"abi": [
{
"constant": true,
"inputs": [],
"name": "OGAdmin",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "address"
}
],
"name": "paid",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"constant": false,
"inputs": [
{
"name": "newAdmin",
"type": "address"
}
],
"name": "grantAdminStatus",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "adminToRemove",
"type": "address"
}
],
"name": "revokeAdminStatus",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "user",
"type": "address"
}
],
"name": "payDeposit",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "user",
"type": "address"
}
],
"name": "expireDeposit",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "user",
"type": "address"
}
],
"name": "hasPaidDeposit",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
}
],
"bytecode": "0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060018060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061068b806100b76000396000f3fe608060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680631faad3c4146100885780632c679d63146100df57806354dae7801461013057806359f3ef05146101995780637caac398146101ea578063a340cf791461023b578063fa62a1ff146102a4575b600080fd5b34801561009457600080fd5b5061009d6102f5565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156100eb57600080fd5b5061012e6004803603602081101561010257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061031a565b005b34801561013c57600080fd5b5061017f6004803603602081101561015357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506103cf565b604051808215151515815260200191505060405180910390f35b3480156101a557600080fd5b506101e8600480360360208110156101bc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610425565b005b3480156101f657600080fd5b506102396004803603602081101561020d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506104da565b005b34801561024757600080fd5b5061028a6004803603602081101561025e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061058e565b604051808215151515815260200191505060405180910390f35b3480156102b057600080fd5b506102f3600480360360208110156102c757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506105ae565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60011515600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514156103cc576000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b50565b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b60011515600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514156104d7576001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b50565b60011515600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515141561058b5760018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b50565b60026020528060005260406000206000915054906101000a900460ff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561065c576000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b5056fea165627a7a72305820d6f5392496318abaff5d492d31c15fee1934106beb9aa461d99727d9d77955cb0029",
"deployedBytecode": "0x608060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680631faad3c4146100885780632c679d63146100df57806354dae7801461013057806359f3ef05146101995780637caac398146101ea578063a340cf791461023b578063fa62a1ff146102a4575b600080fd5b34801561009457600080fd5b5061009d6102f5565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156100eb57600080fd5b5061012e6004803603602081101561010257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061031a565b005b34801561013c57600080fd5b5061017f6004803603602081101561015357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506103cf565b604051808215151515815260200191505060405180910390f35b3480156101a557600080fd5b506101e8600480360360208110156101bc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610425565b005b3480156101f657600080fd5b506102396004803603602081101561020d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506104da565b005b34801561024757600080fd5b5061028a6004803603602081101561025e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061058e565b604051808215151515815260200191505060405180910390f35b3480156102b057600080fd5b506102f3600480360360208110156102c757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506105ae565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60011515600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514156103cc576000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b50565b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b60011515600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514156104d7576001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b50565b60011515600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515141561058b5760018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b50565b60026020528060005260406000206000915054906101000a900460ff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561065c576000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b5056fea165627a7a72305820d6f5392496318abaff5d492d31c15fee1934106beb9aa461d99727d9d77955cb0029",
"sourceMap": "25:919:2:-;;;160:93;8:9:-1;5:2;;;30:1;27;20:12;5:2;160:93:2;202:10;192:7;;:20;;;;;;;;;;;;;;;;;;242:4;222:5;:17;228:10;222:17;;;;;;;;;;;;;;;;:24;;;;;;;;;;;;;;;;;;25:919;;;;;;",
"deployedSourceMap": "25:919:2:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51:22;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51:22:2;;;;;;;;;;;;;;;;;;;;;;;;;;;704:133;;8:9:-1;5:2;;;30:1;27;20:12;5:2;704:133:2;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;704:133:2;;;;;;;;;;;;;;;;;;;;;;843:99;;8:9:-1;5:2;;;30:1;27;20:12;5:2;843:99:2;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;843:99:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;569:129;;8:9:-1;5:2;;;30:1;27;20:12;5:2;569:129:2;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;569:129:2;;;;;;;;;;;;;;;;;;;;;;259:145;;8:9:-1;5:2;;;30:1;27;20:12;5:2;259:145:2;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;259:145:2;;;;;;;;;;;;;;;;;;;;;;116:37;;8:9:-1;5:2;;;30:1;27;20:12;5:2;116:37:2;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;116:37:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;410:153;;8:9:-1;5:2;;;30:1;27;20:12;5:2;410:153:2;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;410:153:2;;;;;;;;;;;;;;;;;;;;;;51:22;;;;;;;;;;;;;:::o;704:133::-;782:4;761:25;;:5;:17;767:10;761:17;;;;;;;;;;;;;;;;;;;;;;;;;:25;;;758:73;;;815:5;802:4;:10;807:4;802:10;;;;;;;;;;;;;;;;:18;;;;;;;;;;;;;;;;;;758:73;704:133;:::o;843:99::-;902:4;925;:10;930:4;925:10;;;;;;;;;;;;;;;;;;;;;;;;;918:17;;843:99;;;:::o;569:129::-;644:4;623:25;;:5;:17;629:10;623:17;;;;;;;;;;;;;;;;;;;;;;;;;:25;;;620:72;;;677:4;664;:10;669:4;664:10;;;;;;;;;;;;;;;;:17;;;;;;;;;;;;;;;;;;620:72;569:129;:::o;259:145::-;345:4;324:25;;:5;:17;330:10;324:17;;;;;;;;;;;;;;;;;;;;;;;;;:25;;;320:78;;;383:4;365:5;:15;371:8;365:15;;;;;;;;;;;;;;;;:22;;;;;;;;;;;;;;;;;;320:78;259:145;:::o;116:37::-;;;;;;;;;;;;;;;;;;;;;;:::o;410:153::-;495:7;;;;;;;;;;;481:21;;:10;:21;;;477:80;;;541:5;518;:20;524:13;518:20;;;;;;;;;;;;;;;;:28;;;;;;;;;;;;;;;;;;477:80;410:153;:::o",
"source": "pragma solidity ^0.5.0;\n\ncontract PayDeposit {\n address public OGAdmin;\n mapping (address => bool) admin;\n mapping (address => bool) public paid;\n\n constructor () public {\n OGAdmin = msg.sender;\n admin[msg.sender] = true;\n }\n\n function grantAdminStatus(address newAdmin) public {\n if (admin[msg.sender] == true) {\n admin[newAdmin] = true;\n }\n }\n\n function revokeAdminStatus(address adminToRemove) public {\n if (msg.sender == OGAdmin) {\n admin[adminToRemove] = false;\n }\n }\n\n function payDeposit(address user) public {\n if(admin[msg.sender] == true) {\n paid[user] = true;\n }\n }\n\n function expireDeposit(address user) public {\n if(admin[msg.sender] == true) {\n paid[user] = false;\n }\n }\n\n function hasPaidDeposit(address user) public view returns (bool) {\n return paid[user];\n }\n}\n"
}

View File

@ -0,0 +1,142 @@
'use strict'
const assert = require('assert')
const rmrf = require('rimraf')
const Web3 = require('web3')
const OrbitDB = require('../../src/OrbitDB.js')
const IdentityProvider = require('orbit-db-identity-provider')
const Keystore = require('orbit-db-keystore')
const AccessControllers = require('orbit-db-access-controllers')
const ContractAccessController = require('orbit-db-access-controllers/src/contract-access-controller.js')
const ganache = require('ganache-cli')
const { abi, bytecode } = require('./Access')
// Include test utilities
const {
config,
startIpfs,
stopIpfs,
testAPIs
} = require('orbit-db-test-utils')
const dbPath1 = './orbitdb/tests/orbitdb-access-controller/1'
const dbPath2 = './orbitdb/tests/orbitdb-access-controller/2'
Object.keys(testAPIs).forEach(API => {
describe(`orbit-db - Access Controller Handlers (${API})`, function () {
this.timeout(config.timeout)
let web3, contract, ipfsd1, ipfsd2, ipfs1, ipfs2, id1, id2
let orbitdb1, orbitdb2
before(async () => {
rmrf.sync(dbPath1)
rmrf.sync(dbPath2)
ipfsd1 = await startIpfs(API, config.daemon1)
ipfsd2 = await startIpfs(API, config.daemon2)
ipfs1 = ipfsd1.api
ipfs2 = ipfsd2.api
const keystore1 = new Keystore(dbPath1 + '/keys')
const keystore2 = new Keystore(dbPath2 + '/keys')
id1 = await IdentityProvider.createIdentity({ id: 'A', keystore: keystore1 })
id2 = await IdentityProvider.createIdentity({ id: 'B', keystore: keystore2 })
orbitdb1 = await OrbitDB.createInstance(ipfs1, {
AccessControllers: AccessControllers,
directory: dbPath1,
identity: id1
})
orbitdb2 = await OrbitDB.createInstance(ipfs2, {
AccessControllers: AccessControllers,
directory: dbPath2,
identity: id2
})
})
after(async () => {
if (orbitdb1) { await orbitdb1.stop() }
if (orbitdb2) { await orbitdb2.stop() }
if (ipfsd1) { await stopIpfs(ipfsd1) }
if (ipfsd2) { await stopIpfs(ipfsd2) }
})
describe('isSupported', function () {
it('supports default access controllers', () => {
assert.strictEqual(AccessControllers.isSupported('ipfs'), true)
assert.strictEqual(AccessControllers.isSupported('orbitdb'), true)
})
it('doesn\'t support smart contract access controller by default', () => {
assert.strictEqual(AccessControllers.isSupported(ContractAccessController.type), false)
})
})
describe('addAccessController', function () {
it('supports added access controller', () => {
const options = {
AccessController: ContractAccessController,
web3: web3,
abi: abi
}
AccessControllers.addAccessController(options)
assert.strictEqual(AccessControllers.isSupported(ContractAccessController.type), true)
})
})
describe('create access controllers', function () {
let options = {
AccessController: ContractAccessController
}
before(async () => {
web3 = new Web3(ganache.provider())
const accounts = await web3.eth.getAccounts()
contract = await new web3.eth.Contract(abi)
.deploy({ data: bytecode })
.send({ from: accounts[0], gas: '1000000' })
options = Object.assign({}, options, { web3, abi, contractAddress: contract._address, defaultAccount: accounts[0] })
AccessControllers.addAccessController(options)
})
it('throws an error if AccessController is not defined', async () => {
let err
try {
AccessControllers.addAccessController({})
} catch (e) {
err = e.toString()
}
assert.strictEqual(err, 'Error: AccessController class needs to be given as an option')
})
it('throws an error if AccessController doesn\'t define type', async () => {
let err
try {
AccessControllers.addAccessController({ AccessController: {} })
} catch (e) {
err = e.toString()
}
assert.strictEqual(err, 'Error: Given AccessController class needs to implement: static get type() { /* return a string */}.')
})
it('creates a custom access controller', async () => {
const type = ContractAccessController.type
const acManifestHash = await AccessControllers.create(orbitdb1, type, options)
assert.notStrictEqual(acManifestHash, null)
const ac = await AccessControllers.resolve(orbitdb1, acManifestHash, options)
assert.strictEqual(ac.type, type)
})
it('removes the custom access controller', async () => {
AccessControllers.removeAccessController(ContractAccessController.type)
assert.strictEqual(AccessControllers.isSupported(ContractAccessController.type), false)
})
})
})
})

View File

@ -0,0 +1,267 @@
'use strict'
const assert = require('assert')
const rmrf = require('rimraf')
const OrbitDB = require('../../src/OrbitDB.js')
const IdentityProvider = require('orbit-db-identity-provider')
const EthIdentityProvider = require('orbit-db-identity-provider/src/ethereum-identity-provider')
const Keystore = require('orbit-db-keystore')
const AccessControllers = require('orbit-db-access-controllers')
const ContractAccessController = require('orbit-db-access-controllers/src/contract-access-controller')
const DepositContractAccessController = require('orbit-db-access-controllers/src/deposit-contract-access-controller')
const ganache = require('ganache-cli')
const Web3 = require('web3')
const io = require('orbit-db-io')
// Include test utilities
const {
config,
startIpfs,
stopIpfs,
testAPIs
} = require('orbit-db-test-utils')
const dbPath1 = './orbitdb/tests/contract-access-controller-integration/1'
const dbPath2 = './orbitdb/tests/contract-access-controller-integration/2'
const accessControllers = [
{
AccessController: ContractAccessController,
contract: require('./Access')
},
{
AccessController: DepositContractAccessController,
contract: require('./PayDeposit')
}
]
Object.keys(testAPIs).forEach(API => {
describe(`orbit-db - ContractAccessController Integration (${API})`, function () {
this.timeout(config.timeout)
let ipfsd1, ipfsd2, ipfs1, ipfs2, id1, id2
let orbitdb1, orbitdb2
let web3, accounts
before(async () => {
rmrf.sync(dbPath1)
rmrf.sync(dbPath2)
ipfsd1 = await startIpfs(API, config.daemon1)
ipfsd2 = await startIpfs(API, config.daemon2)
ipfs1 = ipfsd1.api
ipfs2 = ipfsd2.api
const keystore1 = new Keystore(dbPath1 + '/keys')
const keystore2 = new Keystore(dbPath2 + '/keys')
IdentityProvider.addIdentityProvider(EthIdentityProvider)
id1 = await IdentityProvider.createIdentity({ type: 'ethereum', keystore: keystore1 })
id2 = await IdentityProvider.createIdentity({ type: 'ethereum', keystore: keystore2 })
web3 = new Web3(ganache.provider())
accounts = await web3.eth.getAccounts()
accessControllers.forEach(ac => AccessControllers.addAccessController(ac))
orbitdb1 = await OrbitDB.createInstance(ipfs1, {
AccessControllers: AccessControllers,
directory: dbPath1,
identity: id1
})
orbitdb2 = await OrbitDB.createInstance(ipfs2, {
AccessControllers: AccessControllers,
directory: dbPath2,
identity: id2
})
})
after(async () => {
if (orbitdb1) {
await orbitdb1.stop()
}
if (orbitdb2) {
await orbitdb2.stop()
}
if (ipfsd1) {
await stopIpfs(ipfsd1)
}
if (ipfsd2) {
await stopIpfs(ipfsd2)
}
})
describe('OrbitDB Integration', function () {
accessControllers.forEach(async (ac, i) => {
let db, db2
let dbManifest, acManifest, access
let contract
before(async () => {
contract = await new web3.eth.Contract(ac.contract.abi)
.deploy({ data: ac.contract.bytecode })
.send({ from: accounts[i], gas: '1000000' })
// DB creator needs to provide ac-type, abi and contract-address
db = await orbitdb1.feed('AABB', {
identity: id1,
accessController: {
type: ac.AccessController.type,
web3: web3,
abi: ac.contract.abi,
contractAddress: contract._address,
defaultAccount: accounts[i]
}
})
// DB peer needs to provide web3 instance
db2 = await orbitdb2.feed(db.address, {
identity: id2,
accessController: {
web3: web3,
defaultAccount: accounts[(i + 1) % accessControllers.length] // peer owns different eth-account
}
})
await db2.load()
dbManifest = await io.read(ipfs1, db.address.root)
const hash = dbManifest.accessController.split('/').pop()
acManifest = await io.read(ipfs1, hash)
access = await io.read(ipfs1, acManifest.params.address)
})
it('makes database use the correct access controller', async () => {
assert.strictEqual(access.contractAddress, db.access.address)
})
it('saves database manifest file locally', async () => {
assert.notStrictEqual(dbManifest, null)
})
it('saves access controller manifest file locally', async () => {
assert.notStrictEqual(acManifest, null)
})
describe('database manifest', () => {
it('has correct name', async () => {
assert.strictEqual(dbManifest.name, 'AABB')
})
it('has correct type', async () => {
assert.strictEqual(dbManifest.type, 'feed')
})
it('has correct address', async () => {
assert.notStrictEqual(dbManifest.accessController, null)
assert.strictEqual(dbManifest.accessController.indexOf('/ipfs'), 0)
})
})
describe('access controller manifest', () => {
it('has correct type', async () => {
assert.strictEqual(acManifest.type, ac.AccessController.type)
})
it('has correct address', async () => {
assert.strictEqual(access.contractAddress.indexOf('0x'), 0)
assert.strictEqual(access.contractAddress, db.access.address)
})
})
describe('access controls', () => {
it('throws error if key not permitted to write', async () => {
let err
try {
await db.add('hello?') // should throw error
assert.strictEqual('Should not end here', false)
} catch (e) {
err = e.toString()
}
assert.strictEqual(err, `Error: Could not append entry, key "${id1.id}" is not allowed to write to the log`)
})
it('granting access enables to write to the database', async () => {
await db.access.grant('write', id1.id)
const doChanges = () => {
return new Promise((resolve, reject) => {
try {
db2.events.once('replicated', () => {
// FIXME: timeout to get rid of the "libp2p node not started yet" errors
setTimeout(() => resolve(), 1000)
})
db.add('hello!')
} catch (e) {
reject(e)
}
})
}
// Try adding something again
await doChanges()
const res1 = await db.iterator().collect().map(e => e.payload.value)
const res2 = await db2.iterator().collect().map(e => e.payload.value)
assert.deepStrictEqual(res1, ['hello!'])
assert.deepStrictEqual(res2, ['hello!'])
})
it('can\'t grant access if not admin', async () => {
await db2.access.grant('write', id2.id)
const canAppend = await db2.access.canAppend({ identity: id2 }, id2.provider)
assert.strictEqual(canAppend, false)
})
it('can\'t revoke access if not admin', async () => {
await db2.access.revoke('write', id1.id)
const canAppend = await db2.access.canAppend({ identity: id1 }, id1.provider)
assert.strictEqual(canAppend, true)
})
it('can check permissions without defaultAccount set', async () => {
db2.access.defaultAccount = null
const canAppend = await db2.access.canAppend({ identity: id1 }, id1.provider)
assert.strictEqual(canAppend, true)
})
it('can\'t change permissions without from address if no defaultAccount set', async () => {
let err
db2.access.defaultAccount = null
try {
await db2.access.grant('write', id2.id)
} catch (e) {
err = e.toString()
}
assert.strictEqual(err, 'Error: No "from" address specified in neither the given options, nor the default options.')
})
it('can change permissions by passing in from address', async () => {
let err
db2.access.defaultAccount = null
try {
await db2.access.grant('write', id2.id, { from: accounts[i] }) // from address can grant/revoke access
} catch (e) {
err = e.toString()
}
assert.strictEqual(err, undefined)
const canAppend = await db2.access.canAppend({ identity: id2 }, id2.provider)
assert.strictEqual(canAppend, true)
})
it('revoking access disables ability to write to the database', async () => {
let err
try {
// Revoke user's access
await db.access.revoke('write', id2.id)
await db2.add('hello?')
} catch (e) {
err = e.toString()
}
assert.strictEqual(err, `Error: Could not append entry, key "${id2.id}" is not allowed to write to the log`)
})
})
})
})
})
})

View File

@ -0,0 +1,183 @@
'use strict'
const assert = require('assert')
const rmrf = require('rimraf')
const OrbitDB = require('../../src/OrbitDB.js')
const IdentityProvider = require('orbit-db-identity-provider')
const EthIdentityProvider = require('orbit-db-identity-provider/src/ethereum-identity-provider')
const Keystore = require('orbit-db-keystore')
const ContractAccessController = require('orbit-db-access-controllers/src/contract-access-controller')
const DepositContractAccessController = require('orbit-db-access-controllers/src/deposit-contract-access-controller')
const AccessControllers = require('orbit-db-access-controllers')
const Web3 = require('web3')
const ganache = require('ganache-cli')
const io = require('orbit-db-io')
// Include test utilities
const {
config,
startIpfs,
stopIpfs,
testAPIs
} = require('orbit-db-test-utils')
const dbPath1 = './orbitdb/tests/contract-access-controller/1'
const dbPath2 = './orbitdb/tests/contract-access-controller/2'
const accessControllers = [
{
AccessController: ContractAccessController,
contract: require('./Access')
},
{
AccessController: DepositContractAccessController,
contract: require('./PayDeposit')
}
]
Object.keys(testAPIs).forEach(API => {
describe(`orbit-db - ContractAccessController (${API})`, function () {
this.timeout(config.timeout)
let ipfsd1, ipfsd2, ipfs1, ipfs2, id1, id2
let orbitdb1, orbitdb2
let web3, accounts
before(async () => {
rmrf.sync(dbPath1)
rmrf.sync(dbPath2)
ipfsd1 = await startIpfs(API, config.daemon1)
ipfsd2 = await startIpfs(API, config.daemon2)
ipfs1 = ipfsd1.api
ipfs2 = ipfsd2.api
const keystore1 = new Keystore(dbPath1 + '/keys')
const keystore2 = new Keystore(dbPath2 + '/keys')
IdentityProvider.addIdentityProvider(EthIdentityProvider)
id1 = await IdentityProvider.createIdentity({ type: EthIdentityProvider.type, keystore: keystore1 })
id2 = await IdentityProvider.createIdentity({ type: EthIdentityProvider.type, keystore: keystore2 })
web3 = new Web3(ganache.provider())
accounts = await web3.eth.getAccounts()
orbitdb1 = await OrbitDB.createInstance(ipfs1, {
AccessControllers: AccessControllers,
directory: dbPath1,
identity: id1
})
orbitdb2 = await OrbitDB.createInstance(ipfs2, {
AccessControllers: AccessControllers,
directory: dbPath2,
identity: id2
})
})
after(async () => {
if (orbitdb1) {
await orbitdb1.stop()
}
if (orbitdb2) {
await orbitdb2.stop()
}
if (ipfsd1) {
await stopIpfs(ipfsd1)
}
if (ipfsd2) {
await stopIpfs(ipfsd2)
}
})
describe('Constructor', function () {
accessControllers.forEach(async (ac, i) => {
let accessController, contract
before(async () => {
contract = await new web3.eth.Contract(ac.contract.abi)
.deploy({ data: ac.contract.bytecode })
.send({ from: accounts[i], gas: '1000000' })
accessController = await ac.AccessController.create(orbitdb1, {
type: ac.AccessController.type,
web3: web3,
abi: ac.contract.abi,
contractAddress: contract._address,
defaultAccount: accounts[i]
})
await accessController.load()
})
it('creates an access controller', () => {
assert.notStrictEqual(accessController, null)
assert.notStrictEqual(accessController, undefined)
})
it('sets the controller type', () => {
assert.strictEqual(accessController.type, ac.AccessController.type)
})
it('grants access to key', async () => {
const mockEntry = {
identity: id1
// ...
// doesn't matter what we put here, only identity is used for the check
}
await accessController.grant('write', id1.id)
const canAppend = await accessController.canAppend(mockEntry, id1.provider)
assert.strictEqual(canAppend, true)
})
it('grants access to multiple keys', async () => {
const canAppend1 = await accessController.canAppend({ identity: orbitdb1.identity }, orbitdb1.identity.provider)
const canAppend2 = await accessController.canAppend({ identity: orbitdb2.identity }, orbitdb2.identity.provider)
await accessController.grant('write', orbitdb2.identity.id)
const canAppend3 = await accessController.canAppend({ identity: orbitdb2.identity }, orbitdb2.identity.provider)
assert.strictEqual(canAppend1, true)
assert.strictEqual(canAppend2, false)
assert.strictEqual(canAppend3, true)
})
describe('save and load', function () {
let accessController, manifest
before(async () => {
accessController = await ac.AccessController.create(orbitdb1, {
type: ac.AccessController.type,
web3: web3,
abi: ac.contract.abi,
contractAddress: contract._address,
defaultAccount: accounts[i]
})
manifest = await accessController.save()
const access = await io.read(ipfs1, manifest.address)
accessController = await ac.AccessController.create(orbitdb1, {
type: ac.AccessController.type,
web3: web3,
abi: JSON.parse(access.abi),
contractAddress: access.contractAddress,
defaultAccount: accounts[i]
})
await accessController.load(manifest.address)
})
it('has correct capabalities', async () => {
const canAppend1 = await accessController.canAppend({ identity: orbitdb1.identity }, orbitdb1.identity.provider)
const canAppend2 = await accessController.canAppend({ identity: orbitdb2.identity }, orbitdb2.identity.provider)
const canAppend3 = await accessController.canAppend({ identity: { id: 'someotherid' } }, orbitdb1.identity.provider)
assert.strictEqual(canAppend1, true)
assert.strictEqual(canAppend2, true)
assert.strictEqual(canAppend3, false)
})
})
})
})
})
})

View File

@ -0,0 +1,156 @@
'use strict'
const assert = require('assert')
const rmrf = require('rimraf')
const OrbitDB = require('../../src/OrbitDB.js')
const IdentityProvider = require('orbit-db-identity-provider')
const Keystore = require('orbit-db-keystore')
const AccessControllers = require('orbit-db-access-controllers')
const io = require('orbit-db-io')
// Include test utilities
const {
config,
startIpfs,
stopIpfs,
testAPIs
} = require('orbit-db-test-utils')
const dbPath1 = './orbitdb/tests/orbitdb-access-controller-integration/1'
const dbPath2 = './orbitdb/tests/orbitdb-access-controller-integration/2'
Object.keys(testAPIs).forEach(API => {
describe(`orbit-db - IPFSAccessController Integration (${API})`, function () {
this.timeout(config.timeout)
let ipfsd1, ipfsd2, ipfs1, ipfs2, id1, id2
let orbitdb1, orbitdb2
before(async () => {
rmrf.sync(dbPath1)
rmrf.sync(dbPath2)
ipfsd1 = await startIpfs(API, config.daemon1)
ipfsd2 = await startIpfs(API, config.daemon2)
ipfs1 = ipfsd1.api
ipfs2 = ipfsd2.api
const keystore1 = new Keystore(dbPath1 + '/keys')
const keystore2 = new Keystore(dbPath2 + '/keys')
id1 = await IdentityProvider.createIdentity({ id: 'A', keystore: keystore1 })
id2 = await IdentityProvider.createIdentity({ id: 'B', keystore: keystore2 })
orbitdb1 = await OrbitDB.createInstance(ipfs1, {
AccessControllers: AccessControllers,
directory: dbPath1,
identity: id1
})
orbitdb2 = await OrbitDB.createInstance(ipfs2, {
AccessControllers: AccessControllers,
directory: dbPath2,
identity: id2
})
})
after(async () => {
if (orbitdb1) { await orbitdb1.stop() }
if (orbitdb2) { await orbitdb2.stop() }
if (ipfsd1) { await stopIpfs(ipfsd1) }
if (ipfsd2) { await stopIpfs(ipfsd2) }
})
describe('OrbitDB Integration', function () {
let db, db2
let dbManifest, acManifest
before(async () => {
db = await orbitdb1.feed('AABB', {
identity: id1,
accessController: {
type: 'ipfs',
write: [id1.id]
}
})
db2 = await orbitdb2.feed(db.address, {
identity: id2
})
await db2.load()
dbManifest = await io.read(ipfs1, db.address.root)
const hash = dbManifest.accessController.split('/').pop()
acManifest = await io.read(ipfs1, hash)
})
it('has the correct access rights after creating the database', async () => {
assert.deepStrictEqual(db.access.write, [id1.id])
})
it('makes database use the correct access controller', async () => {
const { address } = await db.access.save()
assert.strictEqual(acManifest.params.address, address)
})
it('saves database manifest file locally', async () => {
assert.notStrictEqual(dbManifest, null)
})
it('saves access controller manifest file locally', async () => {
assert.notStrictEqual(acManifest, null)
})
it('has correct type', async () => {
assert.strictEqual(acManifest.type, 'ipfs')
})
describe('database manifest', () => {
it('has correct name', async () => {
assert.strictEqual(dbManifest.name, 'AABB')
})
it('has correct type', async () => {
assert.strictEqual(dbManifest.type, 'feed')
})
it('has correct address', async () => {
assert.notStrictEqual(dbManifest.accessController, null)
assert.strictEqual(dbManifest.accessController.indexOf('/ipfs'), 0)
})
})
describe('access controls', () => {
it('allows to write if user has write access', async () => {
let err
try {
await db.add('hello?')
} catch (e) {
err = e.toString()
}
const res = await db.iterator().collect().map(e => e.payload.value)
assert.strictEqual(err, undefined)
assert.deepStrictEqual(res, ['hello?'])
})
it('doesn\'t allow to write without write access', async () => {
let err
try {
await db2.add('hello!!')
assert.strictEqual('Should not end here', false)
} catch (e) {
err = e
}
const res = await db2.iterator().collect().map(e => e.payload.value)
assert.strictEqual(err.message, `Could not append entry, key "${db2.identity.id}" is not allowed to write to the log`)
assert.deepStrictEqual(res.includes(e => e === 'hello!!'), false)
})
})
})
})
// TODO: use two separate peers for testing the AC
// TODO: add tests for revocation correctness with a database (integration tests)
})

View File

@ -0,0 +1,130 @@
'use strict'
const assert = require('assert')
const rmrf = require('rimraf')
const OrbitDB = require('../../src/OrbitDB.js')
const IdentityProvider = require('orbit-db-identity-provider')
const Keystore = require('orbit-db-keystore')
const IPFSAccessController = require('orbit-db-access-controllers/src/ipfs-access-controller')
const AccessControllers = require('orbit-db-access-controllers')
// Include test utilities
const {
config,
startIpfs,
stopIpfs,
testAPIs
} = require('orbit-db-test-utils')
const dbPath1 = './orbitdb/tests/ipfs-access-controller/1'
const dbPath2 = './orbitdb/tests/ipfs-access-controller/2'
Object.keys(testAPIs).forEach(API => {
describe(`orbit-db - IPFSAccessController (${API})`, function () {
this.timeout(config.timeout)
let ipfsd1, ipfsd2, ipfs1, ipfs2, id1, id2
let orbitdb1, orbitdb2
before(async () => {
rmrf.sync(dbPath1)
rmrf.sync(dbPath2)
ipfsd1 = await startIpfs(API, config.daemon1)
ipfsd2 = await startIpfs(API, config.daemon2)
ipfs1 = ipfsd1.api
ipfs2 = ipfsd2.api
const keystore1 = new Keystore(dbPath1 + '/keys')
const keystore2 = new Keystore(dbPath2 + '/keys')
id1 = await IdentityProvider.createIdentity({ id: 'A', keystore: keystore1 })
id2 = await IdentityProvider.createIdentity({ id: 'B', keystore: keystore2 })
orbitdb1 = await OrbitDB.createInstance(ipfs1, {
AccessControllers: AccessControllers,
directory: dbPath1,
identity: id1
})
orbitdb2 = await OrbitDB.createInstance(ipfs2, {
AccessControllers: AccessControllers,
directory: dbPath2,
identity: id2
})
})
after(async () => {
if (orbitdb1) {
await orbitdb1.stop()
}
if (orbitdb2) {
await orbitdb2.stop()
}
if (ipfsd1) {
await stopIpfs(ipfsd1)
}
if (ipfsd2) {
await stopIpfs(ipfsd2)
}
})
describe('Constructor', function () {
let accessController
before(async () => {
accessController = await IPFSAccessController.create(orbitdb1, {
write: [id1.id]
})
})
it('creates an access controller', () => {
assert.notStrictEqual(accessController, null)
assert.notStrictEqual(accessController, undefined)
})
it('sets the controller type', () => {
assert.strictEqual(accessController.type, 'ipfs')
})
it('has IPFS instance', async () => {
const peerId1 = await accessController._ipfs.id()
const peerId2 = await ipfs1.id()
assert.strictEqual(peerId1.id, peerId2.id)
})
it('sets default capabilities', async () => {
assert.deepStrictEqual(accessController.write, [id1.id])
})
it('allows owner to append after creation', async () => {
const mockEntry = {
identity: id1,
v: 1
// ...
// doesn't matter what we put here, only identity is used for the check
}
const canAppend = await accessController.canAppend(mockEntry, id1.provider)
assert.strictEqual(canAppend, true)
})
})
describe('save and load', function () {
let accessController, manifest
before(async () => {
accessController = await IPFSAccessController.create(orbitdb1, {
write: ['A', 'B', id1.id]
})
manifest = await accessController.save()
await accessController.load(manifest.address)
})
it('has correct capabalities', async () => {
assert.deepStrictEqual(accessController.write, ['A', 'B', id1.id])
})
})
})
})

View File

@ -0,0 +1,228 @@
'use strict'
const assert = require('assert')
const rmrf = require('rimraf')
const OrbitDB = require('../../src/OrbitDB.js')
const IdentityProvider = require('orbit-db-identity-provider')
const Keystore = require('orbit-db-keystore')
const AccessControllers = require('orbit-db-access-controllers')
const io = require('orbit-db-io')
// Include test utilities
const {
config,
startIpfs,
stopIpfs,
testAPIs
} = require('orbit-db-test-utils')
const dbPath1 = './orbitdb/tests/orbitdb-access-controller-integration/1'
const dbPath2 = './orbitdb/tests/orbitdb-access-controller-integration/2'
Object.keys(testAPIs).forEach(API => {
describe(`orbit-db - OrbitDBAccessController Integration (${API})`, function () {
this.timeout(config.timeout)
let ipfsd1, ipfsd2, ipfs1, ipfs2, id1, id2
let orbitdb1, orbitdb2
before(async () => {
rmrf.sync(dbPath1)
rmrf.sync(dbPath2)
ipfsd1 = await startIpfs(API, config.daemon1)
ipfsd2 = await startIpfs(API, config.daemon2)
ipfs1 = ipfsd1.api
ipfs2 = ipfsd2.api
const keystore1 = new Keystore(dbPath1 + '/keys')
const keystore2 = new Keystore(dbPath2 + '/keys')
id1 = await IdentityProvider.createIdentity({ id: 'A', keystore: keystore1 })
id2 = await IdentityProvider.createIdentity({ id: 'B', keystore: keystore2 })
orbitdb1 = await OrbitDB.createInstance(ipfs1, {
AccessControllers: AccessControllers,
directory: dbPath1,
identity: id1
})
orbitdb2 = await OrbitDB.createInstance(ipfs2, {
AccessControllers: AccessControllers,
directory: dbPath2,
identity: id2
})
})
after(async () => {
if (orbitdb1) {
await orbitdb1.stop()
}
if (orbitdb2) {
await orbitdb2.stop()
}
if (ipfsd1) {
await stopIpfs(ipfsd1)
}
if (ipfsd2) {
await stopIpfs(ipfsd2)
}
})
describe('OrbitDB Integration', function () {
let db, db2
let dbManifest, acManifest
before(async () => {
db = await orbitdb1.feed('AABB', {
identity: id1,
accessController: {
type: 'orbitdb',
write: [id1.id]
}
})
db2 = await orbitdb2.feed(db.address, { identity: id2 })
await db2.load()
dbManifest = await io.read(ipfs1, db.address.root)
const hash = dbManifest.accessController.split('/').pop()
acManifest = await io.read(ipfs1, hash)
})
it('has the correct access rights after creating the database', async () => {
assert.deepStrictEqual(db.access.capabilities, {
admin: new Set([id1.id]),
write: new Set([id1.id])
})
})
it('makes database use the correct access controller', async () => {
assert.strictEqual(acManifest.params.address, db.access._db.address.toString())
})
it('saves database manifest file locally', async () => {
assert.notStrictEqual(dbManifest, null)
})
it('saves access controller manifest file locally', async () => {
assert.notStrictEqual(acManifest, null)
})
describe('database manifest', () => {
it('has correct name', async () => {
assert.strictEqual(dbManifest.name, 'AABB')
})
it('has correct type', async () => {
assert.strictEqual(dbManifest.type, 'feed')
})
it('has correct address', async () => {
assert.notStrictEqual(dbManifest.accessController, null)
assert.strictEqual(dbManifest.accessController.indexOf('/ipfs'), 0)
})
})
describe('access controller manifest', () => {
it('has correct type', async () => {
assert.strictEqual(acManifest.type, 'orbitdb')
})
it('has correct address', async () => {
assert.strictEqual(acManifest.params.address.indexOf('/orbitdb'), 0)
assert.strictEqual(acManifest.params.address.split('/').pop(), '_access')
})
})
describe('access controls', () => {
it('granting access enables to write to the database', async () => {
let err
try {
await db2.add('hello?')
assert.strictEqual('Should not end here', false)
} catch (e) {
err = e.toString()
}
assert.strictEqual(err, `Error: Could not append entry, key "${db2.identity.id}" is not allowed to write to the log`)
const doChanges = () => {
return new Promise((resolve, reject) => {
try {
// Wait for the second user's AC to notify it was updated
db2.access.once('updated', async () => {
// Wait for the first user's db to replicate the update
db.events.once('replicated', () => {
// FIXME: timeout to get rid of the "libp2p node not started yet" errors
setTimeout(() => resolve(), 1000)
})
// Try adding something again
await db2.add('hello!')
})
// Give access to the second user
db.access.grant('write', id2.id)
} catch (e) {
reject(e)
}
})
}
await doChanges()
const res1 = await db.iterator().collect().map(e => e.payload.value)
const res2 = await db2.iterator().collect().map(e => e.payload.value)
assert.deepStrictEqual(res1, ['hello!'])
assert.deepStrictEqual(res2, ['hello!'])
})
it('can\'t grant access if doesn\'t have write access', async () => {
let err
try {
await db2.access.grant('write', id2.id)
} catch (e) {
err = e.toString()
}
assert.strictEqual(err, `Error: Could not append entry, key "${db2.identity.id}" is not allowed to write to the log`)
})
it('can\'t revoke access if doesn\'t have write access', async () => {
let err
try {
await db2.access.revoke('write', id1.id)
} catch (e) {
err = e.toString()
}
assert.strictEqual(err, `Error: Could not append entry, key "${db2.identity.id}" is not allowed to write to the log`)
})
it('revoking access disables ability to write to the database', async () => {
const getError = () => {
return new Promise((resolve, reject) => {
try {
// Wait for the second user's AC to notify it was updated
db2.access.once('updated', async () => {
let err
try {
// Try adding something again
await db2.add('hello?')
} catch (e) {
err = e.toString()
}
resolve(err)
})
// Revoke user's access
db.access.revoke('write', id2.id)
} catch (e) {
reject(e)
}
})
}
const err = await getError()
assert.strictEqual(err, `Error: Could not append entry, key "${db2.identity.id}" is not allowed to write to the log`)
})
})
})
})
// TODO: use two separate peers for testing the AC
// TODO: add tests for revocation correctness with a database (integration tests)
})

View File

@ -0,0 +1,338 @@
'use strict'
const assert = require('assert')
const rmrf = require('rimraf')
const OrbitDB = require('../../src/OrbitDB.js')
const IdentityProvider = require('orbit-db-identity-provider')
const Keystore = require('orbit-db-keystore')
const OrbitDBAccessController = require('orbit-db-access-controllers/src/orbitdb-access-controller')
const AccessControllers = require('orbit-db-access-controllers')
// Include test utilities
const {
config,
startIpfs,
stopIpfs,
testAPIs
} = require('orbit-db-test-utils')
const dbPath1 = './orbitdb/tests/orbitdb-access-controller/1'
const dbPath2 = './orbitdb/tests/orbitdb-access-controller/2'
Object.keys(testAPIs).forEach(API => {
describe(`orbit-db - OrbitDBAccessController (${API})`, function () {
this.timeout(config.timeout)
let ipfsd1, ipfsd2, ipfs1, ipfs2, id1, id2
let orbitdb1, orbitdb2
before(async () => {
rmrf.sync(dbPath1)
rmrf.sync(dbPath2)
ipfsd1 = await startIpfs(API, config.daemon1)
ipfsd2 = await startIpfs(API, config.daemon2)
ipfs1 = ipfsd1.api
ipfs2 = ipfsd2.api
const keystore1 = new Keystore(dbPath1 + '/keys')
const keystore2 = new Keystore(dbPath2 + '/keys')
id1 = await IdentityProvider.createIdentity({ id: 'A', keystore: keystore1 })
id2 = await IdentityProvider.createIdentity({ id: 'B', keystore: keystore2 })
orbitdb1 = await OrbitDB.createInstance(ipfs1, {
AccessControllers: AccessControllers,
directory: dbPath1,
identity: id1
})
orbitdb2 = await OrbitDB.createInstance(ipfs2, {
AccessControllers: AccessControllers,
directory: dbPath2,
identity: id2
})
})
after(async () => {
if (orbitdb1) {
await orbitdb1.stop()
}
if (orbitdb2) {
await orbitdb2.stop()
}
if (ipfsd1) {
await stopIpfs(ipfsd1)
}
if (ipfsd2) {
await stopIpfs(ipfsd2)
}
})
describe('Constructor', function () {
let accessController
before(async () => {
accessController = await OrbitDBAccessController.create(orbitdb1)
})
it('creates an access controller', () => {
assert.notStrictEqual(accessController, null)
assert.notStrictEqual(accessController, undefined)
})
it('sets the controller type', () => {
assert.strictEqual(accessController.type, 'orbitdb')
})
it('has OrbitDB instance', async () => {
assert.notStrictEqual(accessController._orbitdb, null)
assert.strictEqual(accessController._orbitdb.id, orbitdb1.id)
})
it('has IPFS instance', async () => {
const peerId1 = await accessController._orbitdb._ipfs.id()
const peerId2 = await ipfs1.id()
assert.strictEqual(peerId1.id, peerId2.id)
})
it('sets default capabilities', async () => {
assert.deepStrictEqual(accessController.capabilities, {
admin: new Set([id1.id])
})
})
it('allows owner to append after creation', async () => {
const mockEntry = {
identity: id1
// ...
// doesn't matter what we put here, only identity is used for the check
}
const canAppend = await accessController.canAppend(mockEntry, id1.provider)
assert.strictEqual(canAppend, true)
})
})
describe('grant', function () {
let accessController
before(async () => {
accessController = new OrbitDBAccessController(orbitdb1)
await accessController.load('testdb/add')
})
it('loads the root access controller from IPFS', () => {
assert.strictEqual(accessController._db.access.type, 'ipfs')
assert.deepStrictEqual(accessController._db.access.write, [id1.id])
})
it('adds a capability', async () => {
try {
await accessController.grant('write', id1.id)
} catch (e) {
assert(e, null)
}
assert.deepStrictEqual(accessController.capabilities, {
admin: new Set([id1.id]),
write: new Set([id1.id])
})
})
it('adds more capabilities', async () => {
try {
await accessController.grant('read', 'ABCD')
await accessController.grant('delete', 'ABCD')
} catch (e) {
assert.strictEqual(e, null)
}
assert.deepStrictEqual(accessController.capabilities, {
admin: new Set([id1.id]),
write: new Set([id1.id]),
read: new Set(['ABCD']),
delete: new Set(['ABCD'])
})
})
it('emit \'updated\' event when a capability was added', async () => {
return new Promise((resolve, reject) => {
accessController.on('updated', () => {
try {
assert.deepStrictEqual(accessController.capabilities, {
admin: new Set([id1.id]),
write: new Set([id1.id]),
read: new Set(['ABCD', 'AXES']),
delete: new Set(['ABCD'])
})
resolve()
} catch (e) {
reject(e)
}
})
accessController.grant('read', 'AXES')
})
})
it('can append after acquiring capability', async () => {
try {
await accessController.grant('write', id1.id)
await accessController.grant('write', id2.id)
} catch (e) {
assert(e, null)
}
const mockEntry1 = {
identity: id1
}
const mockEntry2 = {
identity: id2
}
const canAppend1 = await accessController.canAppend(mockEntry1, id1.provider)
const canAppend2 = await accessController.canAppend(mockEntry2, id2.provider)
assert.strictEqual(canAppend1, true)
assert.strictEqual(canAppend2, true)
})
})
describe('revoke', function () {
let accessController
before(async () => {
accessController = new OrbitDBAccessController(orbitdb1)
await accessController.load('testdb/remove')
})
it('removes a capability', async () => {
try {
await accessController.grant('write', id1.id)
await accessController.grant('write', 'AABB')
await accessController.revoke('write', 'AABB')
} catch (e) {
assert.strictEqual(e, null)
}
assert.deepStrictEqual(accessController.capabilities, {
admin: new Set([id1.id]),
write: new Set([id1.id])
})
})
it('can remove the creator\'s write access', async () => {
try {
await accessController.revoke('write', id1.id)
} catch (e) {
assert.strictEqual(e, null)
}
assert.deepStrictEqual(accessController.capabilities, {
admin: new Set([id1.id])
})
})
it('can\'t remove the creator\'s admin access', async () => {
try {
await accessController.revoke('admin', id1.id)
} catch (e) {
assert.strictEqual(e, null)
}
assert.deepStrictEqual(accessController.capabilities, {
admin: new Set([id1.id])
})
})
it('removes more capabilities', async () => {
try {
await accessController.grant('read', 'ABCD')
await accessController.grant('delete', 'ABCD')
await accessController.grant('write', id1.id)
await accessController.revoke('read', 'ABCDE')
await accessController.revoke('delete', 'ABCDE')
} catch (e) {
assert.strictEqual(e, null)
}
assert.deepStrictEqual(accessController.capabilities, {
admin: new Set([id1.id]),
delete: new Set(['ABCD']),
read: new Set(['ABCD']),
write: new Set([id1.id])
})
})
it('can\'t append after revoking capability', async () => {
try {
await accessController.grant('write', id2.id)
await accessController.revoke('write', id2.id)
} catch (e) {
assert(e, null)
}
const mockEntry1 = {
identity: id1
}
const mockEntry2 = {
identity: id2
}
const canAppend = await accessController.canAppend(mockEntry1, id1.provider)
const noAppend = await accessController.canAppend(mockEntry2, id2.provider)
assert.strictEqual(canAppend, true)
assert.strictEqual(noAppend, false)
})
it('emits \'updated\' event when a capability was removed', async () => {
await accessController.grant('admin', 'cats')
await accessController.grant('admin', 'dogs')
return new Promise((resolve, reject) => {
accessController.on('updated', () => {
try {
assert.deepStrictEqual(accessController.capabilities, {
admin: new Set([id1.id, 'dogs']),
delete: new Set(['ABCD']),
read: new Set(['ABCD']),
write: new Set([id1.id])
})
resolve()
} catch (e) {
reject(e)
}
})
accessController.revoke('admin', 'cats')
})
})
})
describe('save and load', function () {
let accessController, dbName
before(async () => {
dbName = 'testdb-load-' + new Date().getTime()
accessController = new OrbitDBAccessController(orbitdb1)
await accessController.load(dbName)
await accessController.grant('write', 'A')
await accessController.grant('write', 'B')
await accessController.grant('write', 'C')
await accessController.grant('write', 'C') // double entry
await accessController.grant('another', 'AA')
await accessController.grant('another', 'BB')
await accessController.revoke('another', 'AA')
await accessController.grant('admin', id1.id)
return new Promise((resolve) => {
// Test that the access controller emits 'updated' after it was loaded
accessController.on('updated', () => resolve())
accessController.load(accessController.address)
})
})
it('has the correct database address for the internal db', async () => {
const addr = accessController._db.address.toString().split('/')
assert.strictEqual(addr[addr.length - 1], '_access')
assert.strictEqual(addr[addr.length - 2], dbName)
})
it('has correct capabalities', async () => {
assert.deepStrictEqual(accessController.get('admin'), new Set([id1.id]))
assert.deepStrictEqual(accessController.get('write'), new Set(['A', 'B', 'C']))
assert.deepStrictEqual(accessController.get('another'), new Set(['BB']))
})
})
})
// TODO: use two separate peers for testing the AC
// TODO: add tests for revocation correctness with a database (integration tests)
})

View File

@ -0,0 +1,75 @@
module.exports = {
timeout: 30000,
dbname: 'orbit-db-tests',
defaultIpfsConfig: {
start: true,
EXPERIMENTAL: {
pubsub: true
},
config: {
Addresses: {
API: '/ip4/127.0.0.1/tcp/0',
Swarm: ['/ip4/0.0.0.0/tcp/0'],
Gateway: '/ip4/0.0.0.0/tcp/0'
},
Bootstrap: [],
Discovery: {
MDNS: {
Enabled: true,
Interval: 1
},
webRTCStar: {
Enabled: false
}
}
}
},
daemon1: {
repo: './ipfs/orbitdb/tests/daemon1',
start: true,
EXPERIMENTAL: {
pubsub: true
},
config: {
Addresses: {
API: '/ip4/127.0.0.1/tcp/0',
Swarm: ['/ip4/0.0.0.0/tcp/0'],
Gateway: '/ip4/0.0.0.0/tcp/0'
},
Bootstrap: [],
Discovery: {
MDNS: {
Enabled: true,
Interval: 1
},
webRTCStar: {
Enabled: false
}
}
}
},
daemon2: {
repo: './ipfs/orbitdb/tests/daemon2',
start: true,
EXPERIMENTAL: {
pubsub: true
},
config: {
Addresses: {
API: '/ip4/127.0.0.1/tcp/0',
Swarm: ['/ip4/0.0.0.0/tcp/0'],
Gateway: '/ip4/0.0.0.0/tcp/0'
},
Bootstrap: [],
Discovery: {
MDNS: {
Enabled: true,
Interval: 1
},
webRTCStar: {
Enabled: false
}
}
}
}
}

View File

@ -0,0 +1,10 @@
'use strict'
const connectIpfsNodes = async (ipfs1, ipfs2) => {
const id1 = await ipfs1.id()
const id2 = await ipfs2.id()
await ipfs1.swarm.connect(id2.addresses[0])
await ipfs2.swarm.connect(id1.addresses[0])
}
module.exports = connectIpfsNodes

View File

@ -0,0 +1,53 @@
const EC = require('elliptic').ec
const ec = new EC('secp256k1')
/**
* A custom keystore example
*/
class CustomTestKeystore {
constructor (signer) {
this.createKey()
}
createKey () {
const key = ec.genKeyPair()
this.key = ec.keyPair({
pub: key.getPublic('hex'),
priv: key.getPrivate('hex'),
privEnc: 'hex',
pubEnc: 'hex'
})
return this.key
}
getKey () {
return this.key
}
// TODO: check if this is really in use
generateKey () {
return Promise.resolve(this.createKey())
}
importPublicKey (key) {
return Promise.resolve(ec.keyFromPublic(key, 'hex'))
}
importPrivateKey (key) {
return Promise.resolve(ec.keyFromPrivate(key, 'hex'))
}
sign (key, data) {
const sig = ec.sign(data, key)
return Promise.resolve(sig.toDER('hex'))
}
verify (signature, key, data) {
let res = false
res = ec.verify(data, signature, key)
return Promise.resolve(res)
}
}
module.exports = new CustomTestKeystore()

View File

@ -0,0 +1,8 @@
exports.config = require('./config.js')
exports.testAPIs = require('./test-apis')
exports.startIpfs = require('./start-ipfs')
exports.stopIpfs = require('./stop-ipfs')
exports.waitForPeers = require('./wait-for-peers')
exports.connectPeers = require('./connect-peers')
exports.MemStore = require('./mem-store')
exports.CustomTestKeystore = require('./custom-test-keystore')

View File

@ -0,0 +1,70 @@
'use strict'
const multihashing = require('multihashing-async')
const mh = require('multihashes')
const defaultHashAlg = 'sha2-256'
// 'use strict'
// const ImmutableDB = require('./immutabledb-interface')
const createMultihash = (data, hashAlg) => {
return new Promise((resolve, reject) => {
multihashing(data, hashAlg || defaultHashAlg, (err, multihash) => {
if (err) { return reject(err) }
resolve(mh.toB58String(multihash))
})
})
}
// const LRU = require('lru')
// const ImmutableDB = require('./immutabledb-interface')
// const createMultihash = require('./create-multihash')
/* Memory store using an LRU cache */
class MemStore {
constructor () {
this._store = {}// new LRU(1000)
}
async put (value) {
const data = value// new Buffer(JSON.stringify(value))
const hash = await createMultihash(data)
// console.log(this._store)
// this._store.set(hash, data)
if (!this._store) this._store = {}
// console.log(this._store)
// console.log(hash, data)
this._store[hash] = data
// return hash
return {
toJSON: () => {
return {
data: value,
multihash: hash
}
}
}
}
async get (key) {
// if (data) {
// const value = JSON.parse(data)
// return value
// }
// return data
return {
toJSON: () => {
return {
data: this._store[key],
multihash: key
}
}
}
}
}
module.exports = MemStore

View File

@ -0,0 +1,43 @@
'use strict'
const IPFSFactory = require('ipfsd-ctl')
const testAPIs = require('./test-apis')
/**
* Start an IPFS instance
* @param {Object} config [IPFS configuration to use]
* @return {[Promise<IPFS>]} [IPFS instance]
*/
const startIpfs = (type, config = {}) => {
return new Promise((resolve, reject) => {
if (!testAPIs[type]) {
reject(new Error(`Wanted API type ${JSON.stringify(type)} is unknown. Available types: ${Object.keys(testAPIs).join(', ')}`))
}
// If we're starting a process, pass command line arguments to it
if (!config.args) {
config.args = ['--enable-pubsub-experiment']
}
// Spawn an IPFS daemon (type defined in)
IPFSFactory
.create(testAPIs[type])
.spawn(config, async (err, ipfsd) => {
if (err) {
reject(err)
}
// Monkey patch _peerInfo to the ipfs api/instance
// to make js-ipfs-api compatible with js-ipfs
// TODO: Get IPFS id via coherent API call (without it being asynchronous)
if (!ipfsd.api._peerInfo) {
const { id } = await ipfsd.api.id()
ipfsd.api._peerInfo = { id: { _idB58String: id } }
}
resolve(ipfsd)
})
})
}
module.exports = startIpfs

View File

@ -0,0 +1,17 @@
'use strict'
/**
* Stop an IPFS or ipfsd-ctl instance
* @param {Object} config [IPFS ipfsd-ctl to stop]
* @return {None}
*/
const stopIpfs = (ipfs) => {
return new Promise((resolve, reject) => {
ipfs.stop((err) => {
if (err) { reject(err) }
resolve()
})
})
}
module.exports = stopIpfs

View File

@ -0,0 +1,30 @@
const IPFS = require('ipfs')
/**
* IPFS daemons to run the tests with.
*/
// Available daemon types are defined in:
// https://github.com/ipfs/js-ipfsd-ctl#ipfsfactory---const-f--ipfsfactorycreateoptions
const jsIpfs = {
'js-ipfs': {
type: 'proc',
exec: IPFS
}
}
const goIpfs = {
'go-ipfs': {
type: 'go'
}
}
// By default, we run tests against js-ipfs.
let testAPIs = Object.assign({}, jsIpfs)
// Setting env variable 'TEST=all' will make tests run with js-ipfs and go-ipfs.
// Setting env variable 'TEST=go' will make tests run with go-ipfs.
// Eg. 'TEST=go mocha' runs tests with go-ipfs
if (process.env.TEST === 'all') { testAPIs = Object.assign({}, testAPIs, goIpfs) } else if (process.env.TEST === 'go') { testAPIs = Object.assign({}, goIpfs) }
module.exports = testAPIs

View File

@ -0,0 +1,16 @@
'use strict'
const waitForPeers = (ipfs, peersToWait, topic, callback) => {
return new Promise((resolve, reject) => {
const i = setInterval(async () => {
const peers = await ipfs.pubsub.peers(topic)
const hasAllPeers = peersToWait.map((e) => peers.includes(e)).filter((e) => e === false).length === 0
if (hasAllPeers) {
clearInterval(i)
resolve()
}
}, 500)
})
}
module.exports = waitForPeers