From 0571008a352bcb6f88bc75383bff46f015aa0039 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Fri, 25 Nov 2022 13:37:44 +0000 Subject: [PATCH 1/2] use matrix-appservice-bridge support for postgres --- mx-tester.yml | 2 - src/appservice/AppService.ts | 3 +- src/appservice/datastore.ts | 50 ------------------- src/appservice/postgres/PgDataStore.ts | 68 ++++++++++++++++++++++++++ src/appservice/postgres/schema/v1.ts | 8 +++ 5 files changed, 78 insertions(+), 53 deletions(-) create mode 100644 src/appservice/postgres/PgDataStore.ts create mode 100644 src/appservice/postgres/schema/v1.ts diff --git a/mx-tester.yml b/mx-tester.yml index 79feba98..ba0af398 100644 --- a/mx-tester.yml +++ b/mx-tester.yml @@ -5,8 +5,6 @@ up: - docker run --rm --network $MX_TEST_NETWORK_NAME --name mjolnir-test-postgres --domainname mjolnir-test-postgres -e POSTGRES_PASSWORD=mjolnir-test -e POSTGRES_USER=mjolnir-tester -e POSTGRES_DB=mjolnir-test-db -d -p 127.0.0.1:8083:5432 postgres # Wait until postgresql is ready - until psql postgres://mjolnir-tester:mjolnir-test@localhost:8083/mjolnir-test-db -c ""; do echo "Waiting for psql..."; sleep 1s; done - # Make table in postgres - - psql postgres://mjolnir-tester:mjolnir-test@localhost:8083/mjolnir-test-db -c "CREATE TABLE mjolnir (local_part VARCHAR(255), owner VARCHAR(255), management_room TEXT)" # Launch the reverse proxy, listening for connections *only* on the local host. - docker run --rm --network host --name mjolnir-test-reverse-proxy -p 127.0.0.1:8081:80 -v $MX_TEST_CWD/test/nginx.conf:/etc/nginx/nginx.conf:ro -d nginx - yarn install diff --git a/src/appservice/AppService.ts b/src/appservice/AppService.ts index 7669ad51..52aa4c58 100644 --- a/src/appservice/AppService.ts +++ b/src/appservice/AppService.ts @@ -16,7 +16,8 @@ limitations under the License. import { AppServiceRegistration, Bridge, Request, WeakEvent, BridgeContext, MatrixUser, Logger } from "matrix-appservice-bridge"; import { MjolnirManager } from ".//MjolnirManager"; -import { DataStore, PgDataStore } from ".//datastore"; +import { DataStore } from ".//datastore"; +import { PgDataStore } from "./postgres/PgDataStore"; import { Api } from "./Api"; import { IConfig } from "./config/config"; import { AccessControl } from "./AccessControl"; diff --git a/src/appservice/datastore.ts b/src/appservice/datastore.ts index 848e2106..af823bc5 100644 --- a/src/appservice/datastore.ts +++ b/src/appservice/datastore.ts @@ -13,7 +13,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -import { Client } from "pg"; export interface MjolnirRecord { local_part: string, @@ -56,53 +55,4 @@ export interface DataStore { lookupByLocalPart(localPart: string): Promise; } -export class PgDataStore implements DataStore { - private pgClient: Client; - constructor(connectionString: string) { - this.pgClient = new Client({ connectionString: connectionString }); - } - - public async init(): Promise { - await this.pgClient.connect(); - } - - public async close(): Promise { - await this.pgClient.end() - } - - public async list(): Promise { - const result = await this.pgClient.query("SELECT local_part, owner, management_room FROM mjolnir"); - - if (!result.rowCount) { - return []; - } - - return result.rows; - } - - public async store(mjolnirRecord: MjolnirRecord): Promise { - await this.pgClient.query( - "INSERT INTO mjolnir (local_part, owner, management_room) VALUES ($1, $2, $3)", - [mjolnirRecord.local_part, mjolnirRecord.owner, mjolnirRecord.management_room], - ); - } - - public async lookupByOwner(owner: string): Promise { - const result = await this.pgClient.query( - "SELECT local_part, owner, management_room FROM mjolnir WHERE owner = $1", - [owner], - ); - - return result.rows; - } - - public async lookupByLocalPart(localPart: string): Promise { - const result = await this.pgClient.query( - "SELECT local_part, owner, management_room FROM mjolnir WHERE local_part = $1", - [localPart], - ); - - return result.rows; - } -} diff --git a/src/appservice/postgres/PgDataStore.ts b/src/appservice/postgres/PgDataStore.ts new file mode 100644 index 00000000..3360be1d --- /dev/null +++ b/src/appservice/postgres/PgDataStore.ts @@ -0,0 +1,68 @@ +/* +Copyright 2022 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { PostgresStore, SchemaUpdateFunction } from "matrix-appservice-bridge"; +import { DataStore, MjolnirRecord } from "../datastore"; + +function getSchema(): SchemaUpdateFunction[] { + const nSchema = 1; + const schema = []; + for (let schemaID = 1; schemaID < nSchema + 1; schemaID++) { + schema.push(require(`./schema/v${schemaID}`).runSchema); + } + return schema; +} + +export class PgDataStore extends PostgresStore implements DataStore { + + constructor(connectionString: string) { + super(getSchema(), { url: connectionString }) + } + + public async init(): Promise { + await this.ensureSchema(); + } + + public async close(): Promise { + await this.destroy(); + } + + public async list(): Promise { + const result = await this.sql`SELECT local_part, owner, management_room FROM mjolnir`; + if (!result.count) { + return []; + } + + return result.flat() as MjolnirRecord[]; + } + + public async store(mjolnirRecord: MjolnirRecord): Promise { + await this.sql`INSERT INTO mjolnir (local_part, owner, management_room) + VALUES (${mjolnirRecord.local_part}, ${mjolnirRecord.owner}, ${mjolnirRecord.management_room})`; + } + + public async lookupByOwner(owner: string): Promise { + const result = await this.sql`SELECT local_part, owner, management_room FROM mjolnir + WHERE owner = ${owner}`; + return result.flat() as MjolnirRecord[]; + } + + public async lookupByLocalPart(localPart: string): Promise { + const result = await this.sql`SELECT local_part, owner, management_room FROM mjolnir + WHERE local_part = ${localPart}`; + return result.flat() as MjolnirRecord[]; + } +} diff --git a/src/appservice/postgres/schema/v1.ts b/src/appservice/postgres/schema/v1.ts new file mode 100644 index 00000000..4972208b --- /dev/null +++ b/src/appservice/postgres/schema/v1.ts @@ -0,0 +1,8 @@ + +import postgres from 'postgres'; + +export async function runSchema(sql: postgres.Sql) { + await sql.begin(s => [ + s`CREATE TABLE mjolnir (local_part VARCHAR(255), owner VARCHAR(255), management_room TEXT);` + ]); +} From f4a25496cd2a303c5a2dfa831b0f55a3b57dfa4b Mon Sep 17 00:00:00 2001 From: gnuxie Date: Wed, 7 Dec 2022 11:39:31 +0000 Subject: [PATCH 2/2] upgrade matrix-appservice-bridge to include postgres fixes. These are unreleased and a specific develop commit, but we're the only ones who have made changes so far to the develop branch, so should be fine. --- package.json | 2 +- yarn.lock | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index ea1705a5..461a664b 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "humanize-duration-ts": "^2.1.1", "js-yaml": "^4.1.0", "jsdom": "^16.6.0", - "matrix-appservice-bridge": "8.0.0", + "matrix-appservice-bridge": "https://github.com/matrix-org/matrix-appservice-bridge.git#61d81e1cab395020b8540db2e437d5b25a443d0c", "parse-duration": "^1.0.2", "pg": "^8.8.0", "shell-quote": "^1.7.3", diff --git a/yarn.lock b/yarn.lock index 02d18747..3d73a1e2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2263,10 +2263,9 @@ make-error@^1.1.1: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== -matrix-appservice-bridge@8.0.0: +"matrix-appservice-bridge@https://github.com/matrix-org/matrix-appservice-bridge.git#61d81e1cab395020b8540db2e437d5b25a443d0c": version "8.0.0" - resolved "https://registry.yarnpkg.com/matrix-appservice-bridge/-/matrix-appservice-bridge-8.0.0.tgz#6849ac05c281399b2c2b35daba784f8291d3b35d" - integrity sha512-XFo3avVfKb34d7kalXcsi0vThlnqmrwvewcfhjintmpbFlwu54/lvdbykFSyu2kT8BY1zUtDz7iQ3Q3RAyaN1g== + resolved "https://github.com/matrix-org/matrix-appservice-bridge.git#61d81e1cab395020b8540db2e437d5b25a443d0c" dependencies: "@alloc/quick-lru" "^5.2.0" "@types/pkginfo" "^0.4.0"