Skip to content

Commit

Permalink
Use orbitdb identity id instead of individual pubkey for access
Browse files Browse the repository at this point in the history
  • Loading branch information
haadcode committed Aug 1, 2024
1 parent f3ad586 commit 05138d2
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 36 deletions.
22 changes: 15 additions & 7 deletions src/lib/handle-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,38 @@ import { createResponseMessage, parseMessage, Requests, Responses } from './mess
export const handleRequest = (orbiter) => source => {
return (async function * () {
for await (const chunk of source) {
const { type, signature, pubkey, addresses } = parseMessage(chunk.subarray())
const { type, signature, id, addresses } = parseMessage(chunk.subarray())

let response

try {
// check that the user is authorized to store their dbs on this orbiter.
if (!await orbiter.auth.hasAccess(pubkey)) {
// check that the given identity is valid
const identity = await orbiter.orbitdb.identities.getIdentity(id)
if (!identity) {
throw Object.assign(new Error('invalid identity'), { type: Responses.E_INVALID_IDENTITY })
} else {
await orbiter.orbitdb.identities.verifyIdentity(identity)
}

// check that the identity is authorized to store their dbs on this orbiter.
if (!await orbiter.auth.hasAccess(identity.id)) {
throw Object.assign(new Error('user is not authorized to pin'), { type: Responses.E_NOT_AUTHORIZED })
}

// verify that the params have come from the user who owns the pubkey.
if (!await orbiter.orbitdb.identity.verify(signature, pubkey, JSON.stringify(addresses))) {
// verify that the params have come from the user who owns the identity's pubkey.
if (!await orbiter.orbitdb.identity.verify(signature, identity.publicKey, JSON.stringify(addresses))) {
throw Object.assign(new Error('invalid signature'), { type: Responses.E_INVALID_SIGNATURE })
}

const { orbitdb, pins, dbs } = orbiter

switch (type) {
case Requests.PIN:
await handlePinRequest({ orbitdb, pins, dbs, pubkey, addresses })
await handlePinRequest({ orbitdb, pins, dbs, id, addresses })
response = createResponseMessage(Responses.OK)
break
case Requests.UNPIN:
await handleUnpinRequest({ orbitdb, pins, dbs, pubkey, addresses })
await handleUnpinRequest({ orbitdb, pins, dbs, id, addresses })
response = createResponseMessage(Responses.OK)
break
default:
Expand Down
14 changes: 7 additions & 7 deletions src/lib/handlers/pin.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@ const waitForReplication = (db) => {
})
}

export default async ({ orbitdb, pins, dbs, pubkey, addresses }) => {
export default async ({ orbitdb, pins, dbs, id, addresses }) => {
for (const address of addresses) {
log('pin ', address)

let pubkeys = await pins.get(address)
const hasDb = pubkeys !== undefined
let identities = await pins.get(address)
const hasDb = identities !== undefined

if (pubkeys) {
pubkeys.push(pubkey)
if (identities) {
identities.push(id)
} else {
pubkeys = [pubkey]
identities = [id]
}

const db = await orbitdb.open(address)
Expand All @@ -29,7 +29,7 @@ export default async ({ orbitdb, pins, dbs, pubkey, addresses }) => {
await waitForReplication(db)
}

await pins.set(address, pubkeys)
await pins.set(address, identities)

log('pinned', address)
}
Expand Down
13 changes: 7 additions & 6 deletions src/lib/handlers/unpin.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@ import { logger } from '@libp2p/logger'

const log = logger('voyager:orbiter:unpin')

export default async ({ orbitdb, pins, dbs, pubkey, addresses }) => {
export default async ({ orbitdb, pins, dbs, id, addresses }) => {
for (const address of addresses) {
log('unpin ', address)
const pubkeys = await pins.get(address)

if (pubkeys && pubkeys.length > 1) {
const index = pubkeys.indexOf(pubkey)
const identities = await pins.get(address)

if (identities && identities.length > 1) {
const index = identities.indexOf(id)

if (index > -1) {
pubkeys.splice(index, 1)
identities.splice(index, 1)
}

await pins.set(address, pubkeys)
await pins.set(address, identities)
} else {
await pins.del(address)
}
Expand Down
5 changes: 3 additions & 2 deletions src/lib/messages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const Requests = Object.freeze({
export const Responses = Object.freeze({
OK: 0,
E_INVALID_SIGNATURE: 101,
E_INVALID_IDENTITY: 102,
E_NOT_AUTHORIZED: 200,
E_INTERNAL_ERROR: 300
})
Expand All @@ -26,11 +27,11 @@ export const parseMessage = (bytes) => {
}

export const createRequestMessage = async (type, addresses, identity, signer) => {
const pubkey = identity.publicKey
const id = identity.hash
const signature = signer
? await signer.sign(JSON.stringify(addresses))
: await identity.sign(identity, JSON.stringify(addresses))
return serialize({ type, pubkey, signature, addresses })
return serialize({ type, id, signature, addresses })
}

export const createResponseMessage = async (type, message) => {
Expand Down
6 changes: 3 additions & 3 deletions test/messages.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe('Messages', function () {
})

it('pins a database with OK response', async function () {
await orbiter.auth.add(lander.orbitdb.identity.publicKey)
await orbiter.auth.add(lander.orbitdb.identity.id)

const sink = async source => {
for await (const chunk of source) {
Expand All @@ -60,7 +60,7 @@ describe('Messages', function () {
})

it('pins a database with E_INVALID_SIGNATURE response', async function () {
await orbiter.auth.add(lander.orbitdb.identity.publicKey)
await orbiter.auth.add(lander.orbitdb.identity.id)

const identities = await Identities({ path: './lander/identities', ipfs: lander.ipfs })
const invalidIdentity = await identities.createIdentity({ id: 'lander2' })
Expand All @@ -77,7 +77,7 @@ describe('Messages', function () {
})

it('tries to pin a database with non-existent message', async function () {
await orbiter.auth.add(lander.orbitdb.identity.publicKey)
await orbiter.auth.add(lander.orbitdb.identity.id)

const sink = async source => {
for await (const chunk of source) {
Expand Down
2 changes: 1 addition & 1 deletion test/orbiter.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe('Orbiter', function () {
beforeEach(async function () {
orbiter = await launchOrbiter()
lander = await launchLander({ orbiterAddress: orbiter.orbitdb.ipfs.libp2p.getMultiaddrs().pop() })
await orbiter.auth.add(lander.orbitdb.identity.publicKey)
await orbiter.auth.add(lander.orbitdb.identity.id)
})

afterEach(async function () {
Expand Down
8 changes: 4 additions & 4 deletions test/pin.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ describe('Pin', function () {

beforeEach(async function () {
lander = await launchLander({ orbiterAddress: orbiter.orbitdb.ipfs.libp2p.getMultiaddrs().pop() })
await orbiter.auth.add(lander.orbitdb.identity.publicKey)
await orbiter.auth.add(lander.orbitdb.identity.id)
})

afterEach(async function () {
Expand All @@ -47,7 +47,7 @@ describe('Pin', function () {
})

it('tries to pin a database when not authorized', async function () {
await orbiter.auth.del(lander.orbitdb.identity.publicKey)
await orbiter.auth.del(lander.orbitdb.identity.id)
const db = await lander.orbitdb.open('db')
const pinned = await lander.pin(db.address)

Expand All @@ -60,10 +60,10 @@ describe('Pin', function () {

beforeEach(async function () {
lander1 = await launchLander({ orbiterAddress: orbiter.orbitdb.ipfs.libp2p.getMultiaddrs().pop(), directory: './lander1' })
await orbiter.auth.add(lander1.orbitdb.identity.publicKey)
await orbiter.auth.add(lander1.orbitdb.identity.id)

lander2 = await launchLander({ orbiterAddress: orbiter.orbitdb.ipfs.libp2p.getMultiaddrs().pop(), directory: './lander2' })
await orbiter.auth.add(lander2.orbitdb.identity.publicKey)
await orbiter.auth.add(lander2.orbitdb.identity.id)
})

afterEach(async function () {
Expand Down
2 changes: 1 addition & 1 deletion test/unpin.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ describe('Unpin', function () {

beforeEach(async function () {
lander = await launchLander({ orbiterAddress: orbiter.orbitdb.ipfs.libp2p.getMultiaddrs().pop() })
await orbiter.auth.add(lander.orbitdb.identity.publicKey)
await orbiter.auth.add(lander.orbitdb.identity.id)
})

afterEach(async function () {
Expand Down
7 changes: 2 additions & 5 deletions test/utils/launch-orbiter.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'
import { webSockets } from '@libp2p/websockets'
import { gossipsub } from '@chainsafe/libp2p-gossipsub'
import { createOrbitDB, Identities, KeyStore } from '@orbitdb/core'
import { createOrbitDB } from '@orbitdb/core'
import Orbiter from '../../src/lib/orbiter.js'
import { orbiter as orbiterId } from '../../src/utils/id.js'

Expand Down Expand Up @@ -39,16 +39,13 @@ export const launchOrbiter = async ({ directory } = {}) => {
directory = directory || './orbiter'

const id = orbiterId
const path = join(directory, '/', 'keystore')
const keystore = await KeyStore({ path })
const identities = await Identities({ keystore })

const blockstore = new LevelBlockstore(join(directory, '/', 'ipfs', '/', 'blocks'))
const datastore = new LevelDatastore(join(directory, '/', 'ipfs', '/', 'data'))

const libp2p = await createLibp2p({ ...options })
const ipfs = await createHelia({ libp2p, datastore, blockstore })
const orbitdb = await createOrbitDB({ ipfs, directory, identities, id })
const orbitdb = await createOrbitDB({ ipfs, directory, id })
const orbiter = await Orbiter({ orbitdb })

// Helper function for tests
Expand Down

0 comments on commit 05138d2

Please sign in to comment.