Skip to content

Commit

Permalink
bsky moderation test
Browse files Browse the repository at this point in the history
  • Loading branch information
dholms committed Dec 21, 2023
1 parent 23ea84d commit c8312f5
Show file tree
Hide file tree
Showing 6 changed files with 291 additions and 908 deletions.
73 changes: 73 additions & 0 deletions packages/bsky/src/api/com/atproto/admin/getSubjectStatus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { InvalidRequestError } from '@atproto/xrpc-server'
import { Server } from '../../../../lexicon'
import AppContext from '../../../../context'
import { OutputSchema } from '../../../../lexicon/types/com/atproto/admin/getSubjectStatus'

export default function (server: Server, ctx: AppContext) {
server.com.atproto.admin.getSubjectStatus({
auth: ctx.roleVerifier,
handler: async ({ params }) => {
const { did, uri, blob } = params
const modService = ctx.services.moderation(ctx.db.getPrimary())
let body: OutputSchema | null = null
if (blob) {
if (!did) {
throw new InvalidRequestError(
'Must provide a did to request blob state',
)
}
const takedown = await modService.getBlobTakedownRef(did, blob)
if (takedown) {
body = {
subject: {
$type: 'com.atproto.admin.defs#repoBlobRef',
did: did,
cid: blob,
},
takedown,
}
}
} else if (uri) {
const [takedown, cidRes] = await Promise.all([
modService.getRecordTakedownRef(uri),
ctx.db
.getPrimary()
.db.selectFrom('record')
.where('uri', '=', uri)
.select('cid')
.executeTakeFirst(),
])
if (cidRes && takedown) {
body = {
subject: {
$type: 'com.atproto.repo.strongRef',
uri,
cid: cidRes.cid,
},
takedown,
}
}
} else if (did) {
const takedown = await modService.getRepoTakedownRef(did)
if (takedown) {
body = {
subject: {
$type: 'com.atproto.admin.defs#repoRef',
did: did,
},
takedown,
}
}
} else {
throw new InvalidRequestError('No provided subject')
}
if (body === null) {
throw new InvalidRequestError('Subject not found', 'NotFound')
}
return {
encoding: 'application/json',
body,
}
},
})
}
2 changes: 2 additions & 0 deletions packages/bsky/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import registerPush from './app/bsky/notification/registerPush'
import getPopularFeedGenerators from './app/bsky/unspecced/getPopularFeedGenerators'
import getTimelineSkeleton from './app/bsky/unspecced/getTimelineSkeleton'
import createReport from './com/atproto/moderation/createReport'
import getSubjectStatus from './com/atproto/admin/getSubjectStatus'
import updateSubjectStatus from './com/atproto/admin/updateSubjectStatus'
import emitModerationEvent from './com/atproto/admin/emitModerationEvent'
import searchRepos from './com/atproto/admin/searchRepos'
Expand Down Expand Up @@ -104,6 +105,7 @@ export default function (server: Server, ctx: AppContext) {
getTimelineSkeleton(server, ctx)
// com.atproto
createReport(server, ctx)
getSubjectStatus(server, ctx)
updateSubjectStatus(server, ctx)
emitModerationEvent(server, ctx)
searchRepos(server, ctx)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ export async function up(db: Kysely<unknown>): Promise<void> {
.alterTable('record')
.dropConstraint('record_takedown_id_fkey')
.execute()
await db.schema
.alterTable('actor')
.alterColumn('takedownId')
.setDataType('varchar')
.execute()
await db.schema
.alterTable('record')
.alterColumn('takedownId')
.setDataType('varchar')
.execute()
}

export async function down(db: Kysely<unknown>): Promise<void> {
Expand All @@ -38,4 +48,14 @@ export async function down(db: Kysely<unknown>): Promise<void> {
['id'],
)
.execute()
await db.schema
.alterTable('actor')
.alterColumn('takedownId')
.setDataType('integer')
.execute()
await db.schema
.alterTable('record')
.alterColumn('takedownId')
.setDataType('integer')
.execute()
}
38 changes: 38 additions & 0 deletions packages/bsky/src/services/moderation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
isModEventEmail,
RepoRef,
RepoBlobRef,
StatusAttr,
} from '../../lexicon/types/com/atproto/admin/defs'
import { addHoursToDate } from '../../util/date'
import {
Expand Down Expand Up @@ -666,6 +667,39 @@ export class ModerationService {
return { statuses: results, cursor: keyset.packFromResult(results) }
}

async getRepoTakedownRef(did: string): Promise<StatusAttr | null> {
const res = await this.db.db
.selectFrom('actor')
.where('did', '=', did)
.selectAll()
.executeTakeFirst()
return res ? formatStatus(res.takedownId) : null
}

async getRecordTakedownRef(uri: string): Promise<StatusAttr | null> {
const res = await this.db.db
.selectFrom('record')
.where('uri', '=', uri)
.selectAll()
.executeTakeFirst()
return res ? formatStatus(res.takedownId) : null
}

async getBlobTakedownRef(
did: string,
cid: string,
): Promise<StatusAttr | null> {
const res = await this.db.db
.selectFrom('blob_takedown')
.where('did', '=', did)
.where('cid', '=', cid)
.selectAll()
.executeTakeFirst()
// this table only tracks takedowns not all blobs
// so if no result is returned then the blob is not taken down (rather than not found)
return formatStatus(res?.takedownId ?? null)
}

async isSubjectTakendown(
subject: { did: string } | { uri: AtUri },
): Promise<boolean> {
Expand All @@ -683,6 +717,10 @@ export class ModerationService {
}
}

const formatStatus = (ref: string | null): StatusAttr => {
return ref ? { applied: true, ref } : { applied: false }
}

export type TakedownSubjects = {
did: string
subjects: (RepoRef | RepoBlobRef | StrongRef)[]
Expand Down
55 changes: 0 additions & 55 deletions packages/bsky/tests/admin/__snapshots__/moderation.test.ts.snap

This file was deleted.

Loading

0 comments on commit c8312f5

Please sign in to comment.