mirror of
https://gitlab.com/soapbox-pub/ditto.git
synced 2025-12-06 03:19:46 +00:00
always run custom policy
This commit is contained in:
parent
3d1ece7ec8
commit
aede53e9a9
7 changed files with 49 additions and 71 deletions
8
deno.lock
generated
8
deno.lock
generated
|
|
@ -7,6 +7,7 @@
|
|||
"jsr:@denosaurs/plug@1.0.3": "1.0.3",
|
||||
"jsr:@esroyo/scoped-performance@^3.1.0": "3.1.0",
|
||||
"jsr:@gfx/canvas-wasm@~0.4.2": "0.4.2",
|
||||
"jsr:@gleasonator/policy@*": "0.9.0",
|
||||
"jsr:@hono/hono@^4.4.6": "4.7.5",
|
||||
"jsr:@negrel/http-ece@0.6.0": "0.6.0",
|
||||
"jsr:@negrel/webpush@0.3": "0.3.0",
|
||||
|
|
@ -133,6 +134,13 @@
|
|||
"jsr:@std/encoding@1.0.5"
|
||||
]
|
||||
},
|
||||
"@gleasonator/policy@0.9.0": {
|
||||
"integrity": "483f87c3a18fb39f795495d3388453193f1115ab7e130981121f7828ce6b51bb",
|
||||
"dependencies": [
|
||||
"jsr:@nostrify/nostrify@0.36",
|
||||
"jsr:@nostrify/policies"
|
||||
]
|
||||
},
|
||||
"@hono/hono@4.7.5": {
|
||||
"integrity": "36a7e1b3db8a58e5dc2bd36a76be53346f0966e04c24c635c4d6f58875575b0a"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { HashtagPolicy } from '@nostrify/policies';
|
|||
|
||||
export default class TestPolicy implements NPolicy {
|
||||
call(event: NostrEvent): Promise<NostrRelayOK> {
|
||||
return new HashtagPolicy(['porn']).call(event);
|
||||
return new HashtagPolicy(['other-blocked-tag']).call(event);
|
||||
}
|
||||
info?: NostrRelayInfo | undefined;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -368,10 +368,6 @@ export class DittoConf {
|
|||
return this.env.get('DITTO_POLICY') || path.join(this.dataDir, 'policy.ts');
|
||||
}
|
||||
|
||||
get policyMode(): 'script' | 'event' {
|
||||
return this.env.get('DITTO_CUSTOM_POLICY') ? 'script' : 'event';
|
||||
}
|
||||
|
||||
/** Absolute path to the data directory used by Ditto. */
|
||||
get dataDir(): string {
|
||||
return this.env.get('DITTO_DATA_DIR') || path.join(Deno.cwd(), 'data');
|
||||
|
|
|
|||
|
|
@ -26,10 +26,10 @@ export const adminCurrentPolicyController: AppController = async (c) => {
|
|||
kinds: [11984],
|
||||
}]).then((events) => events[0]);
|
||||
|
||||
if (current) return c.json({ mode: conf.policyMode, spec: JSON.parse(current.content) });
|
||||
if (current) return c.json({ spec: JSON.parse(current.content) });
|
||||
|
||||
await relay.event(await createPolicyEvent(conf, DEFAULT_POLICY_SPEC));
|
||||
return c.json({ mode: conf.policyMode, spec: DEFAULT_POLICY_SPEC });
|
||||
return c.json({ spec: DEFAULT_POLICY_SPEC });
|
||||
};
|
||||
|
||||
const PolicySpecSchema = z.object({
|
||||
|
|
@ -41,13 +41,6 @@ const PolicySpecSchema = z.object({
|
|||
|
||||
export const adminUpdatePolicyController: AppController = async (c) => {
|
||||
const { relay, conf } = c.var;
|
||||
if (conf.policyMode === 'script') {
|
||||
return c.json({
|
||||
error:
|
||||
"The Ditto policy mode is set to 'script'. You will not be able to use the Policy UI until you change it to 'event'.",
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const req = await c.req.json();
|
||||
const parsed = PolicySpecSchema.parse(req);
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ const blocked = {
|
|||
id: '19afd70437944671e7f5a02b29221ad444ef7cf60113a5731667e272e59a3979',
|
||||
pubkey: '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
|
||||
kind: 1,
|
||||
tags: [['t', 'porn']],
|
||||
content: 'this is a test of the policy system #porn',
|
||||
tags: [['t', 'porn'], ['t', 'other-blocked-tag']],
|
||||
content: 'this is a test of the policy system',
|
||||
sig:
|
||||
'1d73a7480cfd737b89dc1e0e7175dff67119915f31d24a279a45d56622f4b991b01e431d07b693ee6cd652f3f27274d9e203ee43ae44af7e70ce8647e5326196',
|
||||
created_at: 1743685015,
|
||||
|
|
@ -20,7 +20,6 @@ Deno.test('PolicyWorker with script policy', async () => {
|
|||
const conf = new DittoConf(
|
||||
new Map([
|
||||
['DITTO_NSEC', nip19.nsecEncode(generateSecretKey())],
|
||||
['DITTO_CUSTOM_POLICY', '1'],
|
||||
['DATABASE_URL', Deno.env.get('DATABASE_URL')],
|
||||
['DITTO_POLICY', join(Deno.cwd(), 'fixtures', 'policy.ts')],
|
||||
]),
|
||||
|
|
|
|||
|
|
@ -53,28 +53,15 @@ export class PolicyWorker implements NPolicy {
|
|||
path: conf.policy,
|
||||
databaseUrl: conf.databaseUrl,
|
||||
pubkey: await conf.signer.getPublicKey(),
|
||||
mode: conf.policyMode,
|
||||
});
|
||||
logi({
|
||||
level: 'info',
|
||||
ns: 'ditto.system.policy',
|
||||
msg: `Using ${conf.policyMode === 'script' ? 'custom' : 'event'} policy`,
|
||||
path: conf.policyMode === 'script' ? conf.policy : undefined,
|
||||
msg: `Initialising custom policy`,
|
||||
path: conf.policy,
|
||||
enabled: true,
|
||||
});
|
||||
} catch (e) {
|
||||
if (e instanceof Error && e.message.includes('Module not found')) {
|
||||
logi({
|
||||
level: 'info',
|
||||
ns: 'ditto.system.policy',
|
||||
msg: 'Custom policy not found <https://docs.soapbox.pub/ditto/policies/>',
|
||||
path: null,
|
||||
enabled: false,
|
||||
});
|
||||
this.enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (e instanceof Error && e.message.includes('PGlite is not supported in worker threads')) {
|
||||
logi({
|
||||
level: 'warn',
|
||||
|
|
|
|||
|
|
@ -13,26 +13,14 @@ import { logi } from '@soapbox/logi';
|
|||
// @ts-ignore Don't try to access the env from this worker.
|
||||
Deno.env = new Map<string, string>();
|
||||
|
||||
interface PolicyInitCommon {
|
||||
interface PolicyInit {
|
||||
/** Database URL to connect to. */
|
||||
databaseUrl: string;
|
||||
/** Admin pubkey to use for DittoPgStore checks. */
|
||||
pubkey: string;
|
||||
mode: 'script' | 'event';
|
||||
}
|
||||
|
||||
interface ScriptPolicyInit {
|
||||
/** Path to the policy module (https, jsr, file, etc) */
|
||||
path: string;
|
||||
mode: 'script';
|
||||
}
|
||||
|
||||
interface EventPolicyInit {
|
||||
mode: 'event';
|
||||
}
|
||||
|
||||
type PolicyInit = PolicyInitCommon & (ScriptPolicyInit | EventPolicyInit);
|
||||
|
||||
export class CustomPolicy implements NPolicy {
|
||||
private policy: NPolicy = new ReadOnlyPolicy();
|
||||
|
||||
|
|
@ -55,40 +43,47 @@ export class CustomPolicy implements NPolicy {
|
|||
},
|
||||
});
|
||||
|
||||
const policies: NPolicy[] = [];
|
||||
const store = new DittoPgStore({
|
||||
db,
|
||||
conf,
|
||||
timeout: 5_000,
|
||||
});
|
||||
|
||||
if (opts.mode === 'script') {
|
||||
try {
|
||||
const Policy = (await import(opts.path)).default;
|
||||
this.policy = new Policy({ db, store, pubkey });
|
||||
} else {
|
||||
const registry = new PolicyRegistry({ store, antiDuplicationPolicyStore: await Deno.openKv() });
|
||||
const policies: NPolicy[] = [];
|
||||
const event = await store
|
||||
.query([{ kinds: [11984], authors: [await conf.signer.getPublicKey()] }])
|
||||
.then((results) => results[0]);
|
||||
|
||||
const spec: PolicySpec = event ? JSON.parse(event.content) : DEFAULT_POLICY_SPEC;
|
||||
|
||||
for (const item of spec.policies) {
|
||||
const policy = registry.available[item.name];
|
||||
if (!policy) continue;
|
||||
try {
|
||||
policies.push(policy.instantiate(item.params || {}));
|
||||
} catch (e) {
|
||||
logi({
|
||||
level: 'error',
|
||||
ns: 'ditto.system.policy.worker',
|
||||
msg: `Error instantiating policy ${item.name} with params \`${JSON.stringify(item.params)}\`: ${e}`,
|
||||
});
|
||||
}
|
||||
policies.push(new Policy({ db, store, pubkey }));
|
||||
} catch (e) {
|
||||
if (e instanceof Error && e.message.includes('Module not found')) {
|
||||
logi({
|
||||
level: 'info',
|
||||
ns: 'ditto.system.policy',
|
||||
msg: 'Custom policy not found <https://docs.soapbox.pub/ditto/policies/>',
|
||||
path: null,
|
||||
});
|
||||
}
|
||||
|
||||
this.policy = new PipePolicy(policies);
|
||||
}
|
||||
const registry = new PolicyRegistry({ store, antiDuplicationPolicyStore: await Deno.openKv() });
|
||||
const event = await store
|
||||
.query([{ kinds: [11984], authors: [await conf.signer.getPublicKey()] }])
|
||||
.then((results) => results[0]);
|
||||
|
||||
const spec: PolicySpec = event ? JSON.parse(event.content) : DEFAULT_POLICY_SPEC;
|
||||
|
||||
for (const item of spec.policies) {
|
||||
const policy = registry.available[item.name];
|
||||
if (!policy) continue;
|
||||
try {
|
||||
policies.push(policy.instantiate(item.params || {}));
|
||||
} catch (e) {
|
||||
logi({
|
||||
level: 'error',
|
||||
ns: 'ditto.system.policy.worker',
|
||||
msg: `Error instantiating policy ${item.name} with params \`${JSON.stringify(item.params)}\`: ${e}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.policy = new PipePolicy(policies);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue