mirror of
https://github.com/amark/gun.git
synced 2025-11-25 15:06:12 +00:00
Improve SEA: .auth, .certify, check.pub (#1130)
* Improve SEA.certify - Improve certify() logic - "Blacklist" renamed to "block". BLACK LIVES MATTER! - Fix user.is.alias, now it doesn't contain full pair any more. * SEA.certify wire logic tests The "block" (former "blacklist") feature is not working yet (due to a bug in gun) * skip certify block feature unit test
This commit is contained in:
parent
89c5286a52
commit
63b0043076
33
sea.js
33
sea.js
@ -674,23 +674,21 @@
|
|||||||
// This is to certify that a group of "certificants" can "put" anything at a group of matched "paths" to the certificate authority's graph
|
// This is to certify that a group of "certificants" can "put" anything at a group of matched "paths" to the certificate authority's graph
|
||||||
SEA.certify = SEA.certify || (async (certificants, policy = {}, authority, cb, opt = {}) => { try {
|
SEA.certify = SEA.certify || (async (certificants, policy = {}, authority, cb, opt = {}) => { try {
|
||||||
/*
|
/*
|
||||||
|
The Certify Protocol was made out of love by a Vietnamese code enthusiast. Vietnamese people around the world deserve respect!
|
||||||
IMPORTANT: A Certificate is like a Signature. No one knows who (authority) created/signed a cert until you put it into their graph.
|
IMPORTANT: A Certificate is like a Signature. No one knows who (authority) created/signed a cert until you put it into their graph.
|
||||||
"certificants": '*' or a String (Bob.pub) || an Object that contains "pub" as a key || an array of [object || string]. These people will have the rights.
|
"certificants": '*' or a String (Bob.pub) || an Object that contains "pub" as a key || an array of [object || string]. These people will have the rights.
|
||||||
"policy": A string ('inbox'), or a RAD/LEX object {'*': 'inbox'}, or an Array of RAD/LEX objects or strings. RAD/LEX object can contain key "?" with indexOf("*") > -1 to force key equals certificant pub. This rule is used to check against soul+'/'+key using Gun.text.match or String.match.
|
"policy": A string ('inbox'), or a RAD/LEX object {'*': 'inbox'}, or an Array of RAD/LEX objects or strings. RAD/LEX object can contain key "?" with indexOf("*") > -1 to force key equals certificant pub. This rule is used to check against soul+'/'+key using Gun.text.match or String.match.
|
||||||
"authority": Key pair or priv of the certificate authority.
|
"authority": Key pair or priv of the certificate authority.
|
||||||
"cb": A callback function after all things are done.
|
"cb": A callback function after all things are done.
|
||||||
"opt": If opt.expiry (a timestamp) is set, SEA won't sync data after opt.expiry. If opt.blacklist is set, SEA will look for blacklist before syncing.
|
"opt": If opt.expiry (a timestamp) is set, SEA won't sync data after opt.expiry. If opt.block is set, SEA will look for block before syncing.
|
||||||
*/
|
*/
|
||||||
console.log('SEA.certify() is an early experimental community supported method that may change API behavior without warning in any future version.')
|
console.log('SEA.certify() is an early experimental community supported method that may change API behavior without warning in any future version.')
|
||||||
|
|
||||||
certificants = (() => {
|
certificants = (() => {
|
||||||
var data = []
|
var data = []
|
||||||
if (certificants) {
|
if (certificants) {
|
||||||
if ((typeof certificants === 'string' || Array.isArray(certificants)) && certificants.indexOf('*') !== -1) return '*'
|
if ((typeof certificants === 'string' || Array.isArray(certificants)) && certificants.indexOf('*') > -1) return '*'
|
||||||
if (typeof certificants === 'string') {
|
if (typeof certificants === 'string') return certificants
|
||||||
return certificants
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.isArray(certificants)) {
|
if (Array.isArray(certificants)) {
|
||||||
if (certificants.length === 1 && certificants[0]) return typeof certificants[0] === 'object' && certificants[0].pub ? certificants[0].pub : typeof certificants[0] === 'string' ? certificants[0] : null
|
if (certificants.length === 1 && certificants[0]) return typeof certificants[0] === 'object' && certificants[0].pub ? certificants[0].pub : typeof certificants[0] === 'string' ? certificants[0] : null
|
||||||
certificants.map(certificant => {
|
certificants.map(certificant => {
|
||||||
@ -702,7 +700,7 @@
|
|||||||
if (typeof certificants === 'object' && certificants.pub) return certificants.pub
|
if (typeof certificants === 'object' && certificants.pub) return certificants.pub
|
||||||
return data.length > 0 ? data : null
|
return data.length > 0 ? data : null
|
||||||
}
|
}
|
||||||
return null
|
return
|
||||||
})()
|
})()
|
||||||
|
|
||||||
if (!certificants) return console.log("No certificant found.")
|
if (!certificants) return console.log("No certificant found.")
|
||||||
@ -710,8 +708,11 @@
|
|||||||
const expiry = opt.expiry && (typeof opt.expiry === 'number' || typeof opt.expiry === 'string') ? parseFloat(opt.expiry) : null
|
const expiry = opt.expiry && (typeof opt.expiry === 'number' || typeof opt.expiry === 'string') ? parseFloat(opt.expiry) : null
|
||||||
const readPolicy = (policy || {}).read ? policy.read : null
|
const readPolicy = (policy || {}).read ? policy.read : null
|
||||||
const writePolicy = (policy || {}).write ? policy.write : typeof policy === 'string' || Array.isArray(policy) || policy["+"] || policy["#"] || policy["."] || policy["="] || policy["*"] || policy[">"] || policy["<"] ? policy : null
|
const writePolicy = (policy || {}).write ? policy.write : typeof policy === 'string' || Array.isArray(policy) || policy["+"] || policy["#"] || policy["."] || policy["="] || policy["*"] || policy[">"] || policy["<"] ? policy : null
|
||||||
const readBlacklist = ((opt || {}).blacklist || {}).read && (typeof opt.blacklist.read === 'string' || opt.blacklist.read['#']) ? opt.blacklist.read : null
|
// The "blacklist" feature is now renamed to "block". Why ? BECAUSE BLACK LIVES MATTER!
|
||||||
const writeBlacklist = typeof (opt || {}).blacklist === 'string' || (((opt || {}).blacklist || {}).write || {})['#'] ? opt.blacklist : ((opt || {}).blacklist || {}).write && (typeof opt.blacklist.write === 'string' || opt.blacklist.write['#']) ? opt.blacklist.write : null
|
// We can now use 3 keys: block, blacklist, ban
|
||||||
|
const block = (opt || {}).block || (opt || {}).blacklist || (opt || {}).ban || {}
|
||||||
|
const readBlock = block.read && (typeof block.read === 'string' || (block.read || {})['#']) ? block.read : null
|
||||||
|
const writeBlock = typeof block === 'string' ? block : block.write && (typeof block.write === 'string' || block.write['#']) ? block.write : null
|
||||||
|
|
||||||
if (!readPolicy && !writePolicy) return console.log("No policy found.")
|
if (!readPolicy && !writePolicy) return console.log("No policy found.")
|
||||||
|
|
||||||
@ -721,8 +722,8 @@
|
|||||||
...(expiry ? {e: expiry} : {}), // inject expiry if possible
|
...(expiry ? {e: expiry} : {}), // inject expiry if possible
|
||||||
...(readPolicy ? {r: readPolicy } : {}), // "r" stands for read, which means read permission.
|
...(readPolicy ? {r: readPolicy } : {}), // "r" stands for read, which means read permission.
|
||||||
...(writePolicy ? {w: writePolicy} : {}), // "w" stands for write, which means write permission.
|
...(writePolicy ? {w: writePolicy} : {}), // "w" stands for write, which means write permission.
|
||||||
...(readBlacklist ? {rb: readBlacklist} : {}), // inject READ blacklist if possible
|
...(readBlock ? {rb: readBlock} : {}), // inject READ block if possible
|
||||||
...(writeBlacklist ? {wb: writeBlacklist} : {}), // inject WRITE blacklist if possible
|
...(writeBlock ? {wb: writeBlock} : {}), // inject WRITE block if possible
|
||||||
})
|
})
|
||||||
|
|
||||||
const certificate = await SEA.sign(data, authority, null, {raw:1})
|
const certificate = await SEA.sign(data, authority, null, {raw:1})
|
||||||
@ -1025,7 +1026,7 @@
|
|||||||
at = user._ = root.get('~'+pair.pub)._;
|
at = user._ = root.get('~'+pair.pub)._;
|
||||||
at.opt = upt;
|
at.opt = upt;
|
||||||
// add our credentials in-memory only to our root user instance
|
// add our credentials in-memory only to our root user instance
|
||||||
user.is = {pub: pair.pub, epub: pair.epub, alias: alias || pair};
|
user.is = {pub: pair.pub, epub: pair.epub, alias: alias || pair.pub};
|
||||||
at.sea = act.pair;
|
at.sea = act.pair;
|
||||||
cat.ing = false;
|
cat.ing = false;
|
||||||
try{if(pass && u == (obj_ify(cat.root.graph['~'+pair.pub].auth)||'')[':']){ opt.shuffle = opt.change = pass; } }catch(e){} // migrate UTF8 & Shuffle!
|
try{if(pass && u == (obj_ify(cat.root.graph['~'+pair.pub].auth)||'')[':']){ opt.shuffle = opt.change = pass; } }catch(e){} // migrate UTF8 & Shuffle!
|
||||||
@ -1368,12 +1369,12 @@
|
|||||||
if ((String.match(path, lex['#']) && String.match(key, lex['.'])) || (!lex['.'] && String.match(path, lex['#'])) || (!lex['#'] && String.match(key, lex['.'])) || String.match((path ? path + '/' + key : key), lex['#'] || lex)) {
|
if ((String.match(path, lex['#']) && String.match(key, lex['.'])) || (!lex['.'] && String.match(path, lex['#'])) || (!lex['#'] && String.match(key, lex['.'])) || String.match((path ? path + '/' + key : key), lex['#'] || lex)) {
|
||||||
// is Certificant forced to present in Path
|
// is Certificant forced to present in Path
|
||||||
if (lex['+'] && lex['+'].indexOf('*') > -1 && path && path.indexOf(certificant) == -1 && key.indexOf(certificant) == -1) return no(`Path "${path}" or key "${key}" must contain string "${certificant}".`)
|
if (lex['+'] && lex['+'].indexOf('*') > -1 && path && path.indexOf(certificant) == -1 && key.indexOf(certificant) == -1) return no(`Path "${path}" or key "${key}" must contain string "${certificant}".`)
|
||||||
// path is allowed, but is there any WRITE blacklist? Check it out
|
// path is allowed, but is there any WRITE block? Check it out
|
||||||
if (data.wb && (typeof data.wb === 'string' || ((data.wb || {})['#']))) { // "data.wb" = path to the WRITE blacklist
|
if (data.wb && (typeof data.wb === 'string' || ((data.wb || {})['#']))) { // "data.wb" = path to the WRITE block
|
||||||
var root = at.$.back(-1)
|
var root = eve.as.root.$.back(-1)
|
||||||
if (typeof data.wb === 'string' && '~' !== data.wb.slice(0, 1)) root = root.get('~' + pub)
|
if (typeof data.wb === 'string' && '~' !== data.wb.slice(0, 1)) root = root.get('~' + pub)
|
||||||
return root.get(data.wb).get(certificant).once(value => {
|
return root.get(data.wb).get(certificant).once(value => {
|
||||||
if (value && (value === 1 || value === true)) return no("Certificant blacklisted.")
|
if (value && (value === 1 || value === true)) return no(`Certificant ${certificant} blocked.`)
|
||||||
return cb(data)
|
return cb(data)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -551,6 +551,14 @@ describe('SEA', function(){
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('node', function(){
|
||||||
|
var u;
|
||||||
|
if(''+u === typeof process){ return }
|
||||||
|
console.log("REMEMBER TO RUN mocha test/sea/nodeauth !!!!");
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
describe('CERTIFY', function () {
|
describe('CERTIFY', function () {
|
||||||
var gun = Gun()
|
var gun = Gun()
|
||||||
var user = gun.user()
|
var user = gun.user()
|
||||||
@ -692,57 +700,45 @@ describe('SEA', function(){
|
|||||||
})
|
})
|
||||||
}())})
|
}())})
|
||||||
|
|
||||||
it.skip('Certify: Advanced - Blacklist', function(done){(async function(){
|
it.skip('Certify: Advanced - Block', function(done){(async function(){
|
||||||
var alice = await SEA.pair()
|
var alice = await SEA.pair()
|
||||||
var dave = await SEA.pair()
|
var dave = await SEA.pair()
|
||||||
var bob = await SEA.pair()
|
var bob = await SEA.pair()
|
||||||
var cert = await SEA.certify(bob, {"*": "private"}, alice, null, {
|
var cert = await SEA.certify(bob, {"*": "private"}, alice, null, {
|
||||||
expiry: Gun.state() + 5000, // expires in 5 seconds
|
expiry: Gun.state() + 5000, // expires in 5 seconds
|
||||||
blacklist: 'blacklist' // path to blacklist in Alice's graph
|
block: 'block' // path to block in Alice's graph
|
||||||
})
|
})
|
||||||
console.log(111111);
|
|
||||||
// Alice points her blacklist to Dave's graph
|
|
||||||
user.leave()
|
|
||||||
user.auth(alice, async () => {
|
|
||||||
console.log("meeeeoooooow");
|
|
||||||
var ref = gun.get('~'+dave.pub+'/blacklist');
|
|
||||||
await user.get('blacklist').put(ref);
|
|
||||||
user.leave()
|
|
||||||
console.log(2222222);
|
|
||||||
|
|
||||||
// Dave logins, he adds Bob to his blacklist, which is connected to the certificate that Alice issued for Bob
|
// Alice points her block to Dave's graph
|
||||||
user.auth(dave, async () => {
|
await user.auth(alice)
|
||||||
await user.get('blacklist').get(bob.pub).put(true)
|
if (user.is) {
|
||||||
user.leave()
|
await user.get('block').put({'#': '~'+dave.pub+'/block'});
|
||||||
console.log(333333);
|
await user.leave()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dave logins, he adds Bob to his block, which is connected to the certificate that Alice issued for Bob
|
||||||
|
await user.auth(dave)
|
||||||
|
if (user.is) {
|
||||||
|
await user.get('block').get(bob.pub).put(true)
|
||||||
|
await user.leave()
|
||||||
|
}
|
||||||
|
|
||||||
// Bob logins and tries to hack Alice
|
// Bob logins and tries to hack Alice
|
||||||
user.auth(bob, async () => {
|
await user.auth(bob)
|
||||||
console.log(4444444);
|
if (user.is) {
|
||||||
var data = Gun.state().toString(36)
|
var data = Gun.state().toString(36)
|
||||||
gun.get("~" + alice.pub)
|
gun.get("~" + alice.pub)
|
||||||
.get("private")
|
.get("private")
|
||||||
.get("asdf")
|
.get("asdf")
|
||||||
.get("qwerty")
|
.get("qwerty")
|
||||||
.put(data, ack => {
|
.put(data, ack => {
|
||||||
console.log(555555);
|
|
||||||
expect(ack.err).to.be.ok()
|
expect(ack.err).to.be.ok()
|
||||||
user.leave()
|
user.leave()
|
||||||
done()
|
done()
|
||||||
}, { opt: { cert } })
|
}, { opt: { cert } })
|
||||||
})
|
}
|
||||||
})
|
|
||||||
})
|
|
||||||
}())})
|
}())})
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('node', function(){
|
|
||||||
var u;
|
|
||||||
if(''+u === typeof process){ return }
|
|
||||||
console.log("REMEMBER TO RUN mocha test/sea/nodeauth !!!!");
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user