Skip to content

Commit

Permalink
Do not enforce deleted lists (#2038)
Browse files Browse the repository at this point in the history
* do not enforce deleted lists

* tests
  • Loading branch information
dholms authored Jan 11, 2024
1 parent ff2f9db commit 07a9c89
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 3 deletions.
5 changes: 4 additions & 1 deletion packages/bsky/src/db/util.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import {
DummyDriver,
DynamicModule,
ExpressionBuilder,
RawBuilder,
SelectQueryBuilder,
sql,
SqliteAdapter,
SqliteIntrospector,
SqliteQueryCompiler,
} from 'kysely'
import DatabaseSchema from './database-schema'
import DatabaseSchema, { DatabaseSchemaType } from './database-schema'

export const actorWhereClause = (actor: string) => {
if (actor.startsWith('did:')) {
Expand Down Expand Up @@ -58,4 +59,6 @@ export const dummyDialect = {

export type DbRef = RawBuilder | ReturnType<DynamicModule['ref']>

export type Subquery = ExpressionBuilder<DatabaseSchemaType, any>

export type AnyQb = SelectQueryBuilder<any, any, any>
25 changes: 24 additions & 1 deletion packages/bsky/src/services/graph/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { sql } from 'kysely'
import { Database } from '../../db'
import { ImageUriBuilder } from '../../image/uri'
import { valuesList } from '../../db/util'
import { DbRef, Subquery, valuesList } from '../../db/util'
import { ListInfo } from './types'
import { ActorInfoMap } from '../actor'
import {
Expand Down Expand Up @@ -143,6 +143,9 @@ export class GraphService {
.innerJoin('list_block', 'list_block.subjectUri', 'list_item.listUri')
.whereRef('list_block.creator', '=', sourceRef)
.whereRef('list_item.subjectDid', '=', targetRef)
.whereExists((qb) =>
this.modListSubquery(qb, ref('list_item.listUri')),
)
.select('list_item.listUri')
.limit(1)
.as('blockingViaList'),
Expand All @@ -157,6 +160,9 @@ export class GraphService {
.innerJoin('list_block', 'list_block.subjectUri', 'list_item.listUri')
.whereRef('list_block.creator', '=', targetRef)
.whereRef('list_item.subjectDid', '=', sourceRef)
.whereExists((qb) =>
this.modListSubquery(qb, ref('list_item.listUri')),
)
.select('list_item.listUri')
.limit(1)
.as('blockedByViaList'),
Expand All @@ -171,6 +177,9 @@ export class GraphService {
.innerJoin('list_mute', 'list_mute.listUri', 'list_item.listUri')
.whereRef('list_mute.mutedByDid', '=', sourceRef)
.whereRef('list_item.subjectDid', '=', targetRef)
.whereExists((qb) =>
this.modListSubquery(qb, ref('list_item.listUri')),
)
.select('list_item.listUri')
.limit(1)
.as('mutingViaList'),
Expand All @@ -181,6 +190,14 @@ export class GraphService {
return result
}

modListSubquery(qb: Subquery, ref: DbRef) {
return qb
.selectFrom('list')
.select('uri')
.where('list.purpose', '=', 'app.bsky.graph.defs#modlist')
.whereRef('list.uri', '=', ref)
}

async getBlockState(pairs: RelationshipPair[], bam?: BlockAndMuteState) {
pairs = bam ? pairs.filter((pair) => !bam.has(pair)) : pairs
const result = bam ?? new BlockAndMuteState()
Expand All @@ -205,6 +222,9 @@ export class GraphService {
.innerJoin('list_block', 'list_block.subjectUri', 'list_item.listUri')
.whereRef('list_block.creator', '=', sourceRef)
.whereRef('list_item.subjectDid', '=', targetRef)
.whereExists((qb) =>
this.modListSubquery(qb, ref('list_item.listUri')),
)
.select('list_item.listUri')
.limit(1)
.as('blockingViaList'),
Expand All @@ -219,6 +239,9 @@ export class GraphService {
.innerJoin('list_block', 'list_block.subjectUri', 'list_item.listUri')
.whereRef('list_block.creator', '=', targetRef)
.whereRef('list_item.subjectDid', '=', sourceRef)
.whereExists((qb) =>
this.modListSubquery(qb, ref('list_item.listUri')),
)
.select('list_item.listUri')
.limit(1)
.as('blockedByViaList'),
Expand Down
68 changes: 67 additions & 1 deletion packages/bsky/tests/views/block-lists.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import AtpAgent from '@atproto/api'
import AtpAgent, { AtUri } from '@atproto/api'
import { TestNetwork, SeedClient, RecordRef, basicSeed } from '@atproto/dev-env'
import { forSnapshot } from '../_util'
import { BlockedActorError } from '@atproto/api/src/client/types/app/bsky/feed/getAuthorFeed'
Expand Down Expand Up @@ -430,4 +430,70 @@ describe('pds views with blocking from block lists', () => {
const combined = [...first.data.lists, ...second.data.lists]
expect(combined).toEqual(full.data.lists)
})

it('does not apply "curate" blocklists', async () => {
const parsedUri = new AtUri(listUri)
await pdsAgent.api.com.atproto.repo.putRecord(
{
repo: parsedUri.hostname,
collection: parsedUri.collection,
rkey: parsedUri.rkey,
record: {
name: 'curate list',
purpose: 'app.bsky.graph.defs#curatelist',
createdAt: new Date().toISOString(),
},
},
{ headers: sc.getHeaders(alice), encoding: 'application/json' },
)
await network.processAll()

const resCarol = await agent.api.app.bsky.feed.getTimeline(
{ limit: 100 },
{ headers: await network.serviceHeaders(carol) },
)
expect(
resCarol.data.feed.some((post) => post.post.author.did === dan),
).toBeTruthy()

const resDan = await agent.api.app.bsky.feed.getTimeline(
{ limit: 100 },
{ headers: await network.serviceHeaders(dan) },
)
expect(
resDan.data.feed.some((post) =>
[bob, carol].includes(post.post.author.did),
),
).toBeTruthy()
})

it('does not apply deleted blocklists (whose items are still around)', async () => {
const parsedUri = new AtUri(listUri)
await pdsAgent.api.app.bsky.graph.list.delete(
{
repo: parsedUri.hostname,
rkey: parsedUri.rkey,
},
sc.getHeaders(alice),
)
await network.processAll()

const resCarol = await agent.api.app.bsky.feed.getTimeline(
{ limit: 100 },
{ headers: await network.serviceHeaders(carol) },
)
expect(
resCarol.data.feed.some((post) => post.post.author.did === dan),
).toBeTruthy()

const resDan = await agent.api.app.bsky.feed.getTimeline(
{ limit: 100 },
{ headers: await network.serviceHeaders(dan) },
)
expect(
resDan.data.feed.some((post) =>
[bob, carol].includes(post.post.author.did),
),
).toBeTruthy()
})
})
46 changes: 46 additions & 0 deletions packages/bsky/tests/views/mute-lists.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -379,4 +379,50 @@ describe('bsky views with mutes from mute lists', () => {
expect(res.data.posts.length).toBe(1)
expect(forSnapshot(res.data.posts[0])).toMatchSnapshot()
})

it('does not apply "curate" blocklists', async () => {
const parsedUri = new AtUri(listUri)
await pdsAgent.api.com.atproto.repo.putRecord(
{
repo: parsedUri.hostname,
collection: parsedUri.collection,
rkey: parsedUri.rkey,
record: {
name: 'curate list',
purpose: 'app.bsky.graph.defs#curatelist',
createdAt: new Date().toISOString(),
},
},
{ headers: sc.getHeaders(alice), encoding: 'application/json' },
)
await network.processAll()

const res = await agent.api.app.bsky.feed.getTimeline(
{ limit: 100 },
{ headers: await network.serviceHeaders(dan) },
)
expect(
res.data.feed.some((post) => [bob, carol].includes(post.post.author.did)),
).toBeTruthy()
})

it('does not apply deleted blocklists (whose items are still around)', async () => {
const parsedUri = new AtUri(listUri)
await pdsAgent.api.app.bsky.graph.list.delete(
{
repo: parsedUri.hostname,
rkey: parsedUri.rkey,
},
sc.getHeaders(alice),
)
await network.processAll()

const res = await agent.api.app.bsky.feed.getTimeline(
{ limit: 100 },
{ headers: await network.serviceHeaders(dan) },
)
expect(
res.data.feed.some((post) => [bob, carol].includes(post.post.author.did)),
).toBeTruthy()
})
})

0 comments on commit 07a9c89

Please sign in to comment.