mirror of
https://github.com/orbitdb/orbitdb.git
synced 2025-03-30 15:08:28 +00:00

* docs: Correctly print out db query results. * test: Remove concurrent. * test: Remove unimplemented and 3rd party AC tests. * test: Remove unimplemented and 3rd party identity tests. * docs: Move jsdoc config to conf directory. * Point package.json main at index.js to access all exported functions. * test: Identities storage pointing at wrong location. * refactor: Identities is configurable when creating an OrbitDB instance.
278 lines
8.2 KiB
JavaScript
278 lines
8.2 KiB
JavaScript
import { strictEqual, deepStrictEqual, notStrictEqual } from 'assert'
|
|
import rmrf from 'rimraf'
|
|
import OrbitDB from '../../src/orbitdb.js'
|
|
import * as IPFS from 'ipfs-core'
|
|
import Keystore from '../../src/key-store.js'
|
|
import Identities from '../../src/identities/identities.js'
|
|
import OrbitDBAccessController from '../../src/access-controllers/orbitdb.js'
|
|
import config from '../config.js'
|
|
import connectPeers from '../utils/connect-nodes.js'
|
|
|
|
const dbPath1 = './orbitdb/tests/orbitdb-access-controller/1'
|
|
const dbPath2 = './orbitdb/tests/orbitdb-access-controller/2'
|
|
|
|
describe('OrbitDBAccessController', function () {
|
|
this.timeout(config.timeout)
|
|
|
|
let ipfs1, ipfs2
|
|
let orbitdb1, orbitdb2
|
|
let identities1, identities2, testIdentity1, testIdentity2
|
|
|
|
before(async () => {
|
|
ipfs1 = await IPFS.create({ ...config.daemon1, repo: './ipfs1' })
|
|
ipfs2 = await IPFS.create({ ...config.daemon2, repo: './ipfs2' })
|
|
await connectPeers(ipfs1, ipfs2)
|
|
|
|
const keystore1 = await Keystore({ path: dbPath1 + '/keys' })
|
|
const keystore2 = await Keystore({ path: dbPath2 + '/keys' })
|
|
|
|
identities1 = await Identities({ ipfs: ipfs1, keystore: keystore1 })
|
|
identities2 = await Identities({ ipfs: ipfs2, keystore: keystore2 })
|
|
|
|
testIdentity1 = await identities1.createIdentity({ id: 'userA' })
|
|
testIdentity2 = await identities2.createIdentity({ id: 'userB' })
|
|
|
|
orbitdb1 = await OrbitDB({ ipfs: ipfs1, identities: identities1, id: 'userA', directory: dbPath1 })
|
|
orbitdb2 = await OrbitDB({ ipfs: ipfs2, identities: identities2, id: 'userB', directory: dbPath2 })
|
|
})
|
|
|
|
after(async () => {
|
|
if (orbitdb1) {
|
|
await orbitdb1.stop()
|
|
}
|
|
|
|
if (orbitdb2) {
|
|
await orbitdb2.stop()
|
|
}
|
|
|
|
if (ipfs1) {
|
|
await ipfs1.stop()
|
|
}
|
|
|
|
if (ipfs2) {
|
|
await ipfs2.stop()
|
|
}
|
|
|
|
await rmrf('./orbitdb')
|
|
await rmrf('./ipfs1')
|
|
await rmrf('./ipfs2')
|
|
})
|
|
|
|
describe('Default write access', function () {
|
|
let accessController
|
|
|
|
before(async () => {
|
|
accessController = await OrbitDBAccessController()({ orbitdb: orbitdb1, identities: identities1 })
|
|
})
|
|
|
|
it('creates an access controller', () => {
|
|
notStrictEqual(accessController, null)
|
|
notStrictEqual(accessController, undefined)
|
|
})
|
|
|
|
it('sets the controller type', () => {
|
|
strictEqual(accessController.type, 'orbitdb')
|
|
})
|
|
|
|
it('sets default capabilities', async () => {
|
|
const expected = []
|
|
expected.admin = new Set([testIdentity1.id])
|
|
|
|
deepStrictEqual(await accessController.capabilities(), expected)
|
|
})
|
|
|
|
it('allows owner to append after creation', async () => {
|
|
const mockEntry = {
|
|
identity: testIdentity1.hash
|
|
// ...
|
|
// doesn't matter what we put here, only identity is used for the check
|
|
}
|
|
const canAppend = await accessController.canAppend(mockEntry)
|
|
strictEqual(canAppend, true)
|
|
})
|
|
})
|
|
|
|
describe('grant', function () {
|
|
let accessController
|
|
|
|
before(async () => {
|
|
accessController = await OrbitDBAccessController()({ orbitdb: orbitdb1, identities: identities1, address: 'testdb/add' })
|
|
})
|
|
|
|
it('adds a capability', async () => {
|
|
try {
|
|
await accessController.grant('write', testIdentity1.id)
|
|
} catch (e) {
|
|
strictEqual(e, null)
|
|
}
|
|
|
|
const expected = []
|
|
expected.admin = new Set([testIdentity1.id])
|
|
expected.write = new Set([testIdentity1.id])
|
|
deepStrictEqual(await accessController.capabilities(), expected)
|
|
})
|
|
|
|
it('adds more capabilities', async () => {
|
|
try {
|
|
await accessController.grant('read', 'ABCD')
|
|
await accessController.grant('delete', 'ABCD')
|
|
} catch (e) {
|
|
strictEqual(e, null)
|
|
}
|
|
|
|
const expected = []
|
|
expected.admin = new Set([testIdentity1.id])
|
|
expected.write = new Set([testIdentity1.id])
|
|
expected.read = new Set(['ABCD'])
|
|
expected.delete = new Set(['ABCD'])
|
|
|
|
deepStrictEqual(await accessController.capabilities(), expected)
|
|
})
|
|
|
|
it('emit \'update\' event when a capability was added', async () => {
|
|
let update = false
|
|
const onUpdate = (entry) => {
|
|
update = true
|
|
}
|
|
|
|
accessController.events.on('update', onUpdate)
|
|
|
|
await accessController.grant('read', 'AXES')
|
|
|
|
strictEqual(update, true)
|
|
})
|
|
|
|
it('can append after acquiring capability', async () => {
|
|
try {
|
|
await accessController.grant('write', testIdentity1.id)
|
|
await accessController.grant('write', testIdentity2.id)
|
|
} catch (e) {
|
|
strictEqual(e, null)
|
|
}
|
|
|
|
const mockEntry1 = {
|
|
identity: testIdentity1.hash
|
|
}
|
|
|
|
const mockEntry2 = {
|
|
identity: testIdentity2.hash
|
|
}
|
|
|
|
const canAppend1 = await accessController.canAppend(mockEntry1)
|
|
|
|
const accessController2 = await OrbitDBAccessController()({ orbitdb: orbitdb2, identities: identities2, address: 'testdb/add' })
|
|
const canAppend2 = await accessController2.canAppend(mockEntry2)
|
|
|
|
strictEqual(canAppend1, true)
|
|
strictEqual(canAppend2, true)
|
|
})
|
|
})
|
|
|
|
describe('revoke', function () {
|
|
let accessController
|
|
|
|
before(async () => {
|
|
accessController = await OrbitDBAccessController()({ orbitdb: orbitdb1, identities: identities1, address: 'testdb/remove' })
|
|
})
|
|
|
|
it('removes a capability', async () => {
|
|
try {
|
|
await accessController.grant('write', testIdentity1.id)
|
|
await accessController.grant('write', 'AABB')
|
|
await accessController.revoke('write', 'AABB')
|
|
} catch (e) {
|
|
strictEqual(e, null)
|
|
}
|
|
|
|
const expected = []
|
|
expected.admin = new Set([testIdentity1.id])
|
|
expected.write = new Set([testIdentity1.id])
|
|
|
|
deepStrictEqual(await accessController.capabilities(), expected)
|
|
})
|
|
|
|
it('can remove the creator\'s write access', async () => {
|
|
try {
|
|
await accessController.revoke('write', testIdentity1.id)
|
|
} catch (e) {
|
|
strictEqual(e, null)
|
|
}
|
|
|
|
const expected = []
|
|
expected.admin = new Set([testIdentity1.id])
|
|
|
|
deepStrictEqual(await accessController.capabilities(), expected)
|
|
})
|
|
|
|
it('can\'t remove the creator\'s admin access', async () => {
|
|
try {
|
|
await accessController.revoke('admin', testIdentity1.id)
|
|
} catch (e) {
|
|
strictEqual(e, null)
|
|
}
|
|
|
|
const expected = []
|
|
expected.admin = new Set([testIdentity1.id])
|
|
|
|
deepStrictEqual(await accessController.capabilities(), expected)
|
|
})
|
|
|
|
it('removes more capabilities', async () => {
|
|
try {
|
|
await accessController.grant('read', 'ABCD')
|
|
await accessController.grant('delete', 'ABCD')
|
|
await accessController.grant('write', testIdentity1.id)
|
|
await accessController.revoke('read', 'ABCDE')
|
|
await accessController.revoke('delete', 'ABCDE')
|
|
} catch (e) {
|
|
strictEqual(e, null)
|
|
}
|
|
|
|
const expected = []
|
|
expected.admin = new Set([testIdentity1.id])
|
|
expected.write = new Set([testIdentity1.id])
|
|
expected.read = new Set(['ABCD'])
|
|
expected.delete = new Set(['ABCD'])
|
|
|
|
deepStrictEqual(await accessController.capabilities(), expected)
|
|
})
|
|
|
|
it('can\'t append after revoking capability', async () => {
|
|
try {
|
|
await accessController.grant('write', testIdentity2.id)
|
|
await accessController.revoke('write', testIdentity2.id)
|
|
} catch (e) {
|
|
strictEqual(e, null)
|
|
}
|
|
const mockEntry1 = {
|
|
identity: testIdentity1.hash
|
|
}
|
|
const mockEntry2 = {
|
|
identity: testIdentity2.hash
|
|
}
|
|
const canAppend = await accessController.canAppend(mockEntry1)
|
|
const noAppend = await accessController.canAppend(mockEntry2)
|
|
strictEqual(canAppend, true)
|
|
strictEqual(noAppend, false)
|
|
})
|
|
|
|
it('emits \'update\' event when a capability was removed', async () => {
|
|
await accessController.grant('admin', 'cats')
|
|
await accessController.grant('admin', 'dogs')
|
|
|
|
let update = false
|
|
const onUpdate = (entry) => {
|
|
update = true
|
|
}
|
|
|
|
accessController.events.on('update', onUpdate)
|
|
|
|
await accessController.revoke('admin', 'cats')
|
|
|
|
strictEqual(update, true)
|
|
})
|
|
})
|
|
})
|
|
// TODO: use two separate peers for testing the AC
|
|
// TODO: add tests for revocation correctness with a database (integration tests)
|