OverviewFilesCommitsIssuesDocsReleasesPeers

pear-git-v3 / test / gip-repo-acl.test.js

42 lines · javascript ref:
// gip-overlay P4 — admin revoke of repo push authority over RPC.
//
// Grant happens via create-repo-invite/join-repo (addWriter during pairing).
// This covers the revoke half: an admin removes a writer from a repo's
// autobase via repo-revoke-writer, after which that writer is out of the
// push-authority set. repo-list-writers exposes the set. (The authority
// SEMANTICS — forged/post-revoke ops not applied — are proven in
// hyper-issues basic.test.js "refs authority".)

import test from 'brittle'
import { mkdtempSync } from '#node:fs'
import { join } from '#node:path'
import { tmpdir } from '#node:os'
import { Client } from 'hyper-svc'

import { startPearGit } from '../index.js'

function tmpStorage () { return mkdtempSync(join(tmpdir(), 'pgv3-acl-')) }
function tmpSock () { return join(mkdtempSync(join(tmpdir(), 'pgv3-acl-sock-')), 'svc.sock') }

test('admin revokes a repo writer via RPC; writer-set reflects it', async (t) => {
  const node = await startPearGit({ storage: tmpStorage(), uds: tmpSock(), http: { port: 0 }, swarm: false, autoImportSSH: false })
  t.teardown(async () => { try { await node.close() } catch {} })

  // grant: stand in for join-repo by adding a writer directly
  const tracker = await node.svc.issueRegistry.getForRepo('gip-acl')
  const bobKey = '1'.padStart(64, 'b')
  await tracker.addWriter('bob', { writerKey: bobKey, role: 'writer' })

  const client = await Client.discover({ uds: node.svc.uds.path })
  t.teardown(async () => { try { await client.close() } catch {} })

  const before = await client.call('repo-list-writers', { name: 'gip-acl' })
  t.ok(before.writers.some((w) => w.userId === 'bob'), 'bob is in the push-authority set')

  const rev = await client.call('repo-revoke-writer', { name: 'gip-acl', userId: 'bob' })
  t.ok(rev && rev.revoked, 'repo-revoke-writer succeeded')

  const after = await client.call('repo-list-writers', { name: 'gip-acl' })
  t.absent(after.writers.some((w) => w.userId === 'bob'), 'bob removed from the writer set')
})