diff --git a/docker-compose.yml b/docker-compose.yml index ec7069f..165f4cf 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -108,15 +108,22 @@ services: - redis nostr-relay: - image: pluja/strfry:latest + image: gitea.kosmos.org/kosmos/strfry-deno:1.0.0 volumes: - ./docker/strfry/strfry.conf:/etc/strfry.conf + - ./extras/strfry/ldap-policy.ts:/opt/ldap-policy.ts + - ./extras/strfry/strfry-policy.ts:/opt/strfry-policy.ts - strfry-data:/app/strfry-db networks: - external_network - internal_network ports: - "4777:7777" + environment: + LDAP_URL: 'ldap://ldap:3389' + LDAP_BIND_DN: 'cn=Directory Manager' + LDAP_PASSWORD: passthebutter + LDAP_SEARCH_DN: 'ou=kosmos.org,cn=users,dc=kosmos,dc=org' # phpldapadmin: # image: osixia/phpldapadmin:0.9.0 diff --git a/docker/strfry/strfry.conf b/docker/strfry/strfry.conf index 9342387..b142ca7 100644 --- a/docker/strfry/strfry.conf +++ b/docker/strfry/strfry.conf @@ -54,7 +54,7 @@ relay { info { # NIP-11: Name of this server. Short/descriptive (< 30 characters) - name = "akkounts-nostr-relay" + name = "Akkounts Nostr Relay" # NIP-11: Detailed information about relay, free-form description = "Local strfry instance for akkounts development" @@ -86,7 +86,7 @@ relay { writePolicy { # If non-empty, path to an executable script that implements the writePolicy plugin logic - plugin = "" + plugin = "/opt/strfry-policy.ts" } compression { diff --git a/extras/strfry/ldap-policy.ts b/extras/strfry/ldap-policy.ts new file mode 100644 index 0000000..6ac8fda --- /dev/null +++ b/extras/strfry/ldap-policy.ts @@ -0,0 +1,46 @@ +import type { Policy } from 'https://gitlab.com/soapbox-pub/strfry-policies/-/raw/develop/mod.ts'; +import { Client } from 'npm:ldapts'; +import { load } from "https://deno.land/std@0.224.0/dotenv/mod.ts"; + +const env = await load({ export: true }); +const url = Deno.env.get("LDAP_URL"); +const bindDN = Deno.env.get("LDAP_BIND_DN"); +const password = Deno.env.get("LDAP_PASSWORD"); +const searchDN = Deno.env.get("LDAP_SEARCH_DN"); + +const ldapPolicy: Policy = async (msg) => { + const client = new Client({ url }); + const { pubkey, kind, tags } = msg.event; + let out = { id: msg.event.id } + + try { + await client.bind(bindDN, password); + + const { searchEntries } = await client.search(searchDN, { + filter: `(nostrKey=${pubkey})`, + attributes: ['nostrKey'] + }); + + const memberKey = searchEntries[0]?.nostrKey; + + const accepted = (memberKey === pubkey); + // TODO if kind is 9735, check that "description" tag contains valid 9734 event, + // signed by memberKey and with "p" tag being the same as pubkey (receipt sender) + + if (accepted) { + out['action'] = 'accept'; + out['msg'] = ''; + } else { + out['action'] = 'reject'; + out['msg'] = 'Only members can publish notes on this relay'; + } + } catch (ex) { + out['action'] = 'reject'; + out['msg'] = 'Auth service temporarily unavailable'; + } finally { + await client.unbind(); + return out; + } +}; + +export default ldapPolicy; diff --git a/extras/strfry/strfry-policy.ts b/extras/strfry/strfry-policy.ts new file mode 100755 index 0000000..0838170 --- /dev/null +++ b/extras/strfry/strfry-policy.ts @@ -0,0 +1,23 @@ +#!/bin/sh +//bin/true; exec deno run -A "$0" "$@" +import { + antiDuplicationPolicy, + hellthreadPolicy, + pipeline, + rateLimitPolicy, + readStdin, + writeStdout, +} from 'https://gitlab.com/soapbox-pub/strfry-policies/-/raw/develop/mod.ts'; + +import ldapPolicy from './ldap-policy.ts'; + +for await (const msg of readStdin()) { + const result = await pipeline(msg, [ + [hellthreadPolicy, { limit: 10 }], + [antiDuplicationPolicy, { ttl: 60000, minLength: 50 }], + [rateLimitPolicy, { whitelist: ['127.0.0.1'] }], + [ldapPolicy], + ]); + + writeStdout(result); +}