Skip to content

Commit

Permalink
use service auth admin reqs
Browse files Browse the repository at this point in the history
  • Loading branch information
dholms committed Dec 26, 2023
1 parent 0422450 commit fdb312a
Show file tree
Hide file tree
Showing 25 changed files with 391 additions and 284 deletions.
15 changes: 0 additions & 15 deletions packages/bsky/src/auth-verifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,21 +284,6 @@ export const parseBasicAuth = (
return { username, password }
}

export const ensureValidAdminAud = (
auth: RoleOutput | AdminServiceOutput,
subjectDid: string,
) => {
if (
auth.credentials.type === 'admin_service' &&
auth.credentials.aud !== subjectDid
) {
throw new AuthRequiredError(
'jwt audience does not match account did',
'BadJwtAudience',
)
}
}

export const buildBasicAuth = (username: string, password: string): string => {
return (
BASIC +
Expand Down
14 changes: 6 additions & 8 deletions packages/bsky/src/auto-moderator/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,12 @@ export class AutoModerator {
)
}

if (ctx.cfg.moderationPushUrl) {
const url = new URL(ctx.cfg.moderationPushUrl)
this.pushAgent = new AtpAgent({ service: url.origin })
this.pushAgent.api.setHeader(
'authorization',
buildBasicAuth(url.username, url.password),
)
}
const url = new URL(ctx.cfg.moderationPushUrl)
this.pushAgent = new AtpAgent({ service: url.origin })
this.pushAgent.api.setHeader(
'authorization',
buildBasicAuth(url.username, url.password),
)
}

processRecord(uri: AtUri, cid: CID, obj: unknown) {
Expand Down
24 changes: 16 additions & 8 deletions packages/bsky/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ export interface ServerConfigValues {
adminPassword: string
moderatorPassword: string
triagePassword: string
moderationPushUrl?: string
modServiceDid: string
modServiceUrl: string
rateLimitsEnabled: boolean
rateLimitBypassKey?: string
rateLimitBypassIps?: string[]
Expand Down Expand Up @@ -117,10 +118,12 @@ export class ServerConfig {
const triagePassword = process.env.TRIAGE_PASSWORD || undefined
assert(triagePassword)
const labelerDid = process.env.LABELER_DID || 'did:example:labeler'
const moderationPushUrl =
overrides?.moderationPushUrl ||
process.env.MODERATION_PUSH_URL ||
undefined
const modServiceUrl =
overrides?.modServiceUrl || process.env.MODERATION_PUSH_URL || undefined
const modServiceDid =
overrides?.modServiceDid || process.env.MODERATION_PUSH_DID || undefined
assert(modServiceUrl)
assert(modServiceDid)
const rateLimitsEnabled = process.env.RATE_LIMITS_ENABLED === 'true'
const rateLimitBypassKey = process.env.RATE_LIMIT_BYPASS_KEY
const rateLimitBypassIps = process.env.RATE_LIMIT_BYPASS_IPS
Expand Down Expand Up @@ -157,7 +160,8 @@ export class ServerConfig {
adminPassword,
moderatorPassword,
triagePassword,
moderationPushUrl,
modServiceUrl,
modServiceDid,
rateLimitsEnabled,
rateLimitBypassKey,
rateLimitBypassIps,
Expand Down Expand Up @@ -286,8 +290,12 @@ export class ServerConfig {
return this.cfg.triagePassword
}

get moderationPushUrl() {
return this.cfg.moderationPushUrl
get modServiceUrl() {
return this.cfg.modServiceUrl
}

get modServiceDid() {
return this.cfg.modServiceDid
}

get rateLimitsEnabled() {
Expand Down
13 changes: 2 additions & 11 deletions packages/bsky/src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { BackgroundQueue } from './background'
import { MountedAlgos } from './feed-gen/types'
import { NotificationServer } from './notifications'
import { Redis } from './redis'
import { AuthVerifier, buildBasicAuth } from './auth-verifier'
import { AuthVerifier } from './auth-verifier'

export class AppContext {
public moderationPushAgent: AtpAgent | undefined
Expand All @@ -32,16 +32,7 @@ export class AppContext {
notifServer: NotificationServer
authVerifier: AuthVerifier
},
) {
if (opts.cfg.moderationPushUrl) {
const url = new URL(opts.cfg.moderationPushUrl)
this.moderationPushAgent = new AtpAgent({ service: url.origin })
this.moderationPushAgent.api.setHeader(
'authorization',
buildBasicAuth(url.username, url.password),
)
}
}
) {}

get db(): DatabaseCoordinator {
return this.opts.db
Expand Down
3 changes: 2 additions & 1 deletion packages/bsky/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export { PeriodicModerationEventReversal } from './db/periodic-moderation-event-
export { Redis } from './redis'
export { ViewMaintainer } from './db/views'
export { AppContext } from './context'
export type { ImageInvalidator } from './image/invalidator'
export { makeAlgos } from './feed-gen'
export * from './daemon'
export * from './indexer'
Expand Down Expand Up @@ -130,7 +131,7 @@ export class BskyAppView {

const authVerifier = new AuthVerifier(idResolver, {
ownDid: config.serverDid,
adminDid: 'did:example:admin',
adminDid: config.modServiceDid,
adminPass: config.adminPassword,
moderatorPass: config.moderatorPassword,
triagePass: config.triagePassword,
Expand Down
3 changes: 2 additions & 1 deletion packages/bsky/src/indexer/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export interface IndexerConfigValues {
fuzzyMatchB64?: string
fuzzyFalsePositiveB64?: string
labelerKeywords: Record<string, string>
moderationPushUrl?: string
moderationPushUrl: string
indexerConcurrency?: number
indexerPartitionIds: number[]
indexerPartitionBatchSize?: number
Expand Down Expand Up @@ -71,6 +71,7 @@ export class IndexerConfig {
overrides?.moderationPushUrl ||
process.env.MODERATION_PUSH_URL ||
undefined
assert(moderationPushUrl)
const hiveApiKey = process.env.HIVE_API_KEY || undefined
const abyssEndpoint = process.env.ABYSS_ENDPOINT
const abyssPassword = process.env.ABYSS_PASSWORD
Expand Down
6 changes: 5 additions & 1 deletion packages/dev-env/src/bsky.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ export class TestBsky {
didCacheMaxTTL: DAY,
labelCacheStaleTTL: 30 * SECOND,
labelCacheMaxTTL: MINUTE,
modServiceUrl: cfg.modServiceUrl ?? 'https://modservice.handle',
modServiceDid: cfg.modServiceDid ?? 'did:example:invalidMod',
...cfg,
// Each test suite gets its own lock id for the repo subscription
adminPassword: ADMIN_PASSWORD,
Expand Down Expand Up @@ -109,7 +111,8 @@ export class TestBsky {
abyssEndpoint: '',
abyssPassword: '',
imgUriEndpoint: 'img.example.com',
moderationPushUrl: cfg.moderationPushUrl,
moderationPushUrl:
cfg.indexer?.moderationPushUrl ?? 'https://modservice.invalid',
indexerPartitionIds: [0],
indexerNamespace: `ns${ns}`,
indexerSubLockId: uniqueLockId(),
Expand Down Expand Up @@ -269,6 +272,7 @@ export async function getIndexers(
indexerPartitionIds: [0],
indexerNamespace: `ns${ns}`,
ingesterPartitionCount: config.ingesterPartitionCount ?? 1,
moderationPushUrl: config.moderationPushUrl ?? 'https://modservice.invalid',
...config,
}
const db = new bsky.PrimaryDatabase({
Expand Down
44 changes: 32 additions & 12 deletions packages/dev-env/src/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import * as uint8arrays from 'uint8arrays'
import getPort from 'get-port'
import { wait } from '@atproto/common-web'
import { createServiceJwt } from '@atproto/xrpc-server'
import { Client as PlcClient } from '@did-plc/lib'
import { TestServerParams } from './types'
import { TestPlc } from './plc'
import { TestPds } from './pds'
import { TestBsky } from './bsky'
import { TestOzone } from './ozone'
import { mockNetworkUtilities } from './util'
import { TestNetworkNoAppView } from './network-no-appview'
import { Secp256k1Keypair } from '@atproto/crypto'

const ADMIN_USERNAME = 'admin'
const ADMIN_PASSWORD = 'admin-pass'
Expand Down Expand Up @@ -39,6 +41,16 @@ export class TestNetwork extends TestNetworkNoAppView {
const bskyPort = params.bsky?.port ?? (await getPort())
const pdsPort = params.pds?.port ?? (await getPort())
const ozonePort = params.ozone?.port ?? (await getPort())

const ozoneKey = await Secp256k1Keypair.create()
const ozoneDid = await new PlcClient(plc.url).createDid({
signingKey: ozoneKey.did(),
rotationKeys: [ozoneKey.did()],
handle: 'ozone.test',
pds: `http://pds.invalid`,
signer: ozoneKey,
})

const bsky = await TestBsky.create({
port: bskyPort,
plcUrl: plc.url,
Expand All @@ -48,30 +60,38 @@ export class TestNetwork extends TestNetworkNoAppView {
dbPostgresSchema: `appview_${dbPostgresSchema}`,
dbPrimaryPostgresUrl: dbPostgresUrl,
redisHost,
moderationPushUrl: `http://admin:${ADMIN_PASSWORD}@localhost:${ozonePort}`,
modServiceUrl: `http://localhost:${ozonePort}`,
modServiceDid: ozoneDid,
indexer: {
moderationPushUrl: `http://admin:${ADMIN_PASSWORD}@localhost:${ozonePort}`,
},
...params.bsky,
})

const pds = await TestPds.create({
port: pdsPort,
didPlcUrl: plc.url,
bskyAppViewUrl: bsky.url,
bskyAppViewDid: bsky.ctx.cfg.serverDid,
modServiceUrl: `http://localhost:${ozonePort}`,
modServiceDid: ozoneDid,
...params.pds,
})

const ozone = await TestOzone.create({
port: ozonePort,
plcUrl: plc.url,
signingKey: ozoneKey,
serverDid: ozoneDid,
dbPostgresSchema: `ozone_${dbPostgresSchema}`,
dbPostgresUrl,
appviewUrl: bsky.url,
moderationPushUrl: `http://admin:${ADMIN_PASSWORD}@localhost:${pdsPort}`, // @TODO fix this
appviewDid: bsky.ctx.cfg.serverDid,
pdsUrl: pds.url,
pdsDid: pds.ctx.cfg.service.did,
...params.ozone,
})

const pds = await TestPds.create({
port: pdsPort,
didPlcUrl: plc.url,
bskyAppViewUrl: bsky.url,
bskyAppViewDid: bsky.ctx.cfg.serverDid,
modServiceUrl: ozone.url,
modServiceDid: ozone.ctx.cfg.serverDid,
...params.pds,
})

mockNetworkUtilities(pds, bsky)

return new TestNetwork(plc, pds, bsky, ozone)
Expand Down
22 changes: 12 additions & 10 deletions packages/dev-env/src/ozone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,21 @@ export class TestOzone {
) {}

static async create(cfg: OzoneConfig): Promise<TestOzone> {
const serviceKeypair = await Secp256k1Keypair.create()
const plcClient = new PlcClient(cfg.plcUrl)
const serviceKeypair = cfg.signingKey ?? (await Secp256k1Keypair.create())
let serverDid = cfg.serverDid
if (!serverDid) {
const plcClient = new PlcClient(cfg.plcUrl)
serverDid = await plcClient.createDid({
signingKey: serviceKeypair.did(),
rotationKeys: [serviceKeypair.did()],
handle: 'ozone.test',
pds: `https://pds.invalid`,
signer: serviceKeypair,
})
}

const port = cfg.port || (await getPort())
const url = `http://localhost:${port}`
const serverDid = await plcClient.createDid({
signingKey: serviceKeypair.did(),
rotationKeys: [serviceKeypair.did()],
handle: 'bsky.test',
pds: `http://localhost:${port}`,
signer: serviceKeypair,
})

const config = new ozone.ServerConfig({
version: '0.0.0',
port,
Expand Down
4 changes: 3 additions & 1 deletion packages/dev-env/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as pds from '@atproto/pds'
import * as bsky from '@atproto/bsky'
import * as ozone from '@atproto/ozone'
import { ImageInvalidator } from '@atproto/bsky/src/image/invalidator'
import { ImageInvalidator } from '@atproto/bsky'
import { Keypair } from '@atproto/crypto'

export type PlcConfig = {
port?: number
Expand Down Expand Up @@ -32,6 +33,7 @@ export type OzoneConfig = Partial<ozone.ServerConfig> & {
appviewUrl: string
dbPostgresUrl: string
migration?: string
signingKey?: Keypair
}

export type TestServerParams = {
Expand Down
1 change: 1 addition & 0 deletions packages/ozone/src/api/admin/searchRepos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export default function (server: Server, ctx: AppContext) {
handler: async ({ params }) => {
const res = await ctx.appviewAgent.api.com.atproto.admin.searchRepos(
params,
await ctx.appviewAuth(),
)
const db = ctx.db
const modService = ctx.modService(db)
Expand Down
7 changes: 5 additions & 2 deletions packages/ozone/src/api/admin/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ export const getPdsAccountInfo = async (
ctx: AppContext,
did: string,
): Promise<AccountView | null> => {
const agent = ctx.moderationPushAgent
const agent = ctx.pdsAgent
if (!agent) return null
const auth = await ctx.pdsAuth()
if (!auth) return null
try {
const res = await agent.api.com.atproto.admin.getAccountInfo({ did })
const res = await agent.api.com.atproto.admin.getAccountInfo({ did }, auth)
return res.data
} catch (err) {
console.log('ERR: ', err)
return null
}
}
Expand Down
Loading

0 comments on commit fdb312a

Please sign in to comment.