forked from bluesky-social/atproto
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bsky appview admin and moderation endpoints (bluesky-social#840)
* Add moderation and labeling model to bsky appview * Carry over moderation service from pds * Pass over bsky moderation service to get it working, missing blob support * Carry over label service from pds to bsky * Reorg bsky http auth, implement admin auth * Carry over relevant admin endpoints pds to bsky * Retrofit bsky admin routes from pds impls * Implement resolve handle on appview * Avoid loop in bsky handle resolution * Add bsky appview to dev-env, opt-in * Fix bsky searchRepos with empty term, tidy * Include blobs on bsky admin views * Stop resolving taken-down blobs on appview * Tidy * Carry over pds moderation tests to bsky * Support image cache invalidation on bsky appview * Add missing changes for bsky tests * Test takedowns in bsky views * Test takedowns on bsky notifs * In bsky appview ensure label.neg is modeled as a boolean, not an integer bit. Add select column when checking blob takedown.
- Loading branch information
Showing
65 changed files
with
5,217 additions
and
105 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import express from 'express' | ||
import * as uint8arrays from 'uint8arrays' | ||
import { AuthRequiredError } from '@atproto/xrpc-server' | ||
|
||
const BASIC = 'Basic ' | ||
const BEARER = 'Bearer ' | ||
|
||
// @TODO(bsky) treating did as a bearer, just a placeholder for now. | ||
export const authVerifier = (ctx: { | ||
req: express.Request | ||
res: express.Response | ||
}) => { | ||
const { authorization = '' } = ctx.req.headers | ||
if (!authorization.startsWith(BEARER)) { | ||
throw new AuthRequiredError() | ||
} | ||
const did = authorization.replace(BEARER, '').trim() | ||
if (!did.startsWith('did:')) { | ||
throw new AuthRequiredError() | ||
} | ||
return { credentials: { did } } | ||
} | ||
|
||
export const authOptionalVerifier = (ctx: { | ||
req: express.Request | ||
res: express.Response | ||
}) => { | ||
if (!ctx.req.headers.authorization) { | ||
return { credentials: { did: null } } | ||
} | ||
return authVerifier(ctx) | ||
} | ||
|
||
export const adminVerifier = | ||
(adminPassword: string) => | ||
(ctx: { req: express.Request; res: express.Response }) => { | ||
const { authorization = '' } = ctx.req.headers | ||
const parsed = parseBasicAuth(authorization) | ||
if (!parsed) { | ||
throw new AuthRequiredError() | ||
} | ||
const { username, password } = parsed | ||
if (username !== 'admin' || password !== adminPassword) { | ||
throw new AuthRequiredError() | ||
} | ||
return { credentials: { admin: true } } | ||
} | ||
|
||
export const parseBasicAuth = ( | ||
token: string, | ||
): { username: string; password: string } | null => { | ||
if (!token.startsWith(BASIC)) return null | ||
const b64 = token.slice(BASIC.length) | ||
let parsed: string[] | ||
try { | ||
parsed = uint8arrays | ||
.toString(uint8arrays.fromString(b64, 'base64pad'), 'utf8') | ||
.split(':') | ||
} catch (err) { | ||
return null | ||
} | ||
const [username, password] = parsed | ||
if (!username || !password) return null | ||
return { username, password } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
packages/bsky/src/api/com/atproto/admin/getModerationAction.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { Server } from '../../../../lexicon' | ||
import AppContext from '../../../../context' | ||
import { adminVerifier } from '../../../auth' | ||
|
||
export default function (server: Server, ctx: AppContext) { | ||
server.com.atproto.admin.getModerationAction({ | ||
auth: adminVerifier(ctx.cfg.adminPassword), | ||
handler: async ({ params }) => { | ||
const { db, services } = ctx | ||
const { id } = params | ||
const moderationService = services.moderation(db) | ||
const result = await moderationService.getActionOrThrow(id) | ||
return { | ||
encoding: 'application/json', | ||
body: await moderationService.views.actionDetail(result), | ||
} | ||
}, | ||
}) | ||
} |
26 changes: 26 additions & 0 deletions
26
packages/bsky/src/api/com/atproto/admin/getModerationActions.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { Server } from '../../../../lexicon' | ||
import AppContext from '../../../../context' | ||
import { adminVerifier } from '../../../auth' | ||
|
||
export default function (server: Server, ctx: AppContext) { | ||
server.com.atproto.admin.getModerationActions({ | ||
auth: adminVerifier(ctx.cfg.adminPassword), | ||
handler: async ({ params }) => { | ||
const { db, services } = ctx | ||
const { subject, limit = 50, cursor } = params | ||
const moderationService = services.moderation(db) | ||
const results = await moderationService.getActions({ | ||
subject, | ||
limit, | ||
cursor, | ||
}) | ||
return { | ||
encoding: 'application/json', | ||
body: { | ||
cursor: results.at(-1)?.id.toString() ?? undefined, | ||
actions: await moderationService.views.action(results), | ||
}, | ||
} | ||
}, | ||
}) | ||
} |
19 changes: 19 additions & 0 deletions
19
packages/bsky/src/api/com/atproto/admin/getModerationReport.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { Server } from '../../../../lexicon' | ||
import AppContext from '../../../../context' | ||
import { adminVerifier } from '../../../auth' | ||
|
||
export default function (server: Server, ctx: AppContext) { | ||
server.com.atproto.admin.getModerationReport({ | ||
auth: adminVerifier(ctx.cfg.adminPassword), | ||
handler: async ({ params }) => { | ||
const { db, services } = ctx | ||
const { id } = params | ||
const moderationService = services.moderation(db) | ||
const result = await moderationService.getReportOrThrow(id) | ||
return { | ||
encoding: 'application/json', | ||
body: await moderationService.views.reportDetail(result), | ||
} | ||
}, | ||
}) | ||
} |
27 changes: 27 additions & 0 deletions
27
packages/bsky/src/api/com/atproto/admin/getModerationReports.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { Server } from '../../../../lexicon' | ||
import AppContext from '../../../../context' | ||
import { adminVerifier } from '../../../auth' | ||
|
||
export default function (server: Server, ctx: AppContext) { | ||
server.com.atproto.admin.getModerationReports({ | ||
auth: adminVerifier(ctx.cfg.adminPassword), | ||
handler: async ({ params }) => { | ||
const { db, services } = ctx | ||
const { subject, resolved, limit = 50, cursor } = params | ||
const moderationService = services.moderation(db) | ||
const results = await moderationService.getReports({ | ||
subject, | ||
resolved, | ||
limit, | ||
cursor, | ||
}) | ||
return { | ||
encoding: 'application/json', | ||
body: { | ||
cursor: results.at(-1)?.id.toString() ?? undefined, | ||
reports: await moderationService.views.report(results), | ||
}, | ||
} | ||
}, | ||
}) | ||
} |
Oops, something went wrong.