Add basic pan support

This commit is contained in:
Will Hunt 2021-09-07 22:55:29 +01:00
parent 7beb955a92
commit 5f32f0bb6c
7 changed files with 71 additions and 17 deletions

View File

@ -51,6 +51,11 @@ interface BridgeConfigBridge {
mediaUrl?: string;
port: number;
bindAddress: string;
pantalaimon?: {
url: string;
username: string;
password: string;
}
}
interface BridgeConfigWebhook {

View File

@ -149,7 +149,6 @@ export class GitHubUserSpace implements IConnection {
public async ensureDiscussionInSpace(discussion: GitHubDiscussionSpace) {
// TODO: Optimise
const children = await this.space.getChildEntities();
console.log("Foo", children);
if (!children[discussion.roomId]) {
await this.space.addChildRoom(discussion.roomId);
}

View File

@ -1,4 +1,4 @@
import { Appservice, IAppserviceRegistration, RichRepliesPreprocessor, IRichReplyMetadata, StateEvent } from "matrix-bot-sdk";
import { Appservice, IAppserviceRegistration, RichRepliesPreprocessor, IRichReplyMetadata, StateEvent, PantalaimonClient, MatrixClient } from "matrix-bot-sdk";
import { BridgeConfig, GitLabInstance } from "./Config/Config";
import { OAuthRequest, OAuthTokens, NotificationsEnableEvent, NotificationsDisableEvent,} from "./Webhooks";
import { CommentProcessor } from "./CommentProcessor";
@ -12,7 +12,7 @@ import { UserNotificationsEvent } from "./Notifications/UserNotificationWatcher"
import { RedisStorageProvider } from "./Stores/RedisStorageProvider";
import { MemoryStorageProvider } from "./Stores/MemoryStorageProvider";
import { NotificationProcessor } from "./NotificationsProcessor";
import { IStorageProvider } from "./Stores/StorageProvider";
import { IBridgeStorageProvider } from "./Stores/StorageProvider";
import { retry } from "./PromiseUtil";
import { IConnection, GitHubDiscussionSpace, GitHubDiscussionConnection, GitHubUserSpace
} from "./Connections";
@ -35,6 +35,7 @@ const log = new LogWrapper("GithubBridge");
export class GithubBridge {
private github?: GithubInstance;
private as!: Appservice;
private encryptedMatrixClient?: MatrixClient;
private adminRooms: Map<string, AdminRoom> = new Map();
private commentProcessor!: CommentProcessor;
private notifProcessor!: NotificationProcessor;
@ -215,7 +216,7 @@ export class GithubBridge {
await this.github.start();
}
let storage: IStorageProvider;
let storage: IBridgeStorageProvider;
if (this.config.queue.host && this.config.queue.port) {
log.info(`Initialising Redis storage (on ${this.config.queue.host}:${this.config.queue.port})`);
storage = new RedisStorageProvider(this.config.queue.host, this.config.queue.port);
@ -235,6 +236,23 @@ export class GithubBridge {
registration: this.registration,
storage,
});
if (this.config.bridge.pantalaimon) {
log.info(`Loading pantalaimon client`);
const pan = new PantalaimonClient(
this.config.bridge.pantalaimon.url,
storage,
);
this.encryptedMatrixClient = await pan.createClientWithCredentials(
this.config.bridge.pantalaimon.username,
this.config.bridge.pantalaimon.password
);
this.encryptedMatrixClient.on("room.message", async (roomId, event) => {
return this.onRoomMessage(roomId, event);
});
// TODO: Filter
await this.encryptedMatrixClient.start();
log.info(`Pan client is syncing`);
}
this.widgetApi = new BridgeWidgetApi(this.adminRooms);
@ -558,9 +576,7 @@ export class GithubBridge {
// Handle spaces
for (const discussion of this.connections.filter((c) => c instanceof GitHubDiscussionSpace) as GitHubDiscussionSpace[]) {
console.log(discussion);
const user = this.getConnectionForGithubUser(discussion.owner);
console.log("user:", user);
if (user) {
await user.ensureDiscussionInSpace(discussion);
}
@ -598,8 +614,9 @@ export class GithubBridge {
/* We ignore messages from our users */
return;
}
log.info(`Got message roomId=${roomId} from=${event.sender}`);
log.debug(event);
log.info(`Got message roomId=${roomId} type=${event.type} from=${event.sender}`);
console.log(event);
log.debug("Content:", JSON.stringify(event));
const adminRoom = this.adminRooms.get(roomId);
if (adminRoom) {

View File

@ -1,5 +1,5 @@
import { MessageSenderClient } from "./MatrixSender";
import { IStorageProvider } from "./Stores/StorageProvider";
import { IBridgeStorageProvider } from "./Stores/StorageProvider";
import { UserNotificationsEvent } from "./Notifications/UserNotificationWatcher";
import LogWrapper from "./LogWrapper";
import { AdminRoom } from "./AdminRoom";
@ -106,7 +106,7 @@ export class NotificationProcessor {
}
}
constructor(private storage: IStorageProvider, private matrixSender: MessageSenderClient) {
constructor(private storage: IBridgeStorageProvider, private matrixSender: MessageSenderClient) {
}

View File

@ -1,8 +1,8 @@
import { MemoryStorageProvider as MSP } from "matrix-bot-sdk";
import { IStorageProvider } from "./StorageProvider";
import { IBridgeStorageProvider } from "./StorageProvider";
import { IssuesGetResponseData } from "../Github/Types";
export class MemoryStorageProvider extends MSP implements IStorageProvider {
export class MemoryStorageProvider extends MSP implements IBridgeStorageProvider {
private issues: Map<string, IssuesGetResponseData> = new Map();
private issuesLastComment: Map<string, string> = new Map();
private reviewData: Map<string, string> = new Map();

View File

@ -2,8 +2,12 @@ import { IssuesGetResponseData } from "../Github/Types";
import { Redis, default as redis } from "ioredis";
import LogWrapper from "../LogWrapper";
import { IStorageProvider } from "./StorageProvider";
import { IBridgeStorageProvider } from "./StorageProvider";
import { IFilterInfo } from "matrix-bot-sdk";
const BOT_SYNC_TOKEN_KEY = "bot.sync_token.";
const BOT_FILTER_KEY = "bot.filter.";
const BOT_VALUE_KEY = "bot.value.";
const REGISTERED_USERS_KEY = "as.registered_users";
const COMPLETED_TRANSACTIONS_KEY = "as.completed_transactions";
const GH_ISSUES_KEY = "gh.issues";
@ -15,16 +19,45 @@ const ISSUES_LAST_COMMENT_EXPIRE_AFTER = 14 * 24 * 60 * 60; // 7 days
const log = new LogWrapper("RedisASProvider");
export class RedisStorageProvider implements IStorageProvider {
export class RedisStorageProvider implements IBridgeStorageProvider {
private redis: Redis;
constructor(host: string, port: number) {
constructor(host: string, port: number, private contextSuffix = '') {
this.redis = new redis(port, host);
this.redis.expire(COMPLETED_TRANSACTIONS_KEY, COMPLETED_TRANSACTIONS_EXPIRE_AFTER).catch((ex) => {
log.warn("Failed to set expiry time on as.completed_transactions", ex);
});
}
public setSyncToken(token: string|null){
if (token === null) {
this.redis.del(BOT_SYNC_TOKEN_KEY + this.contextSuffix);
} else {
this.redis.set(BOT_SYNC_TOKEN_KEY + this.contextSuffix, token);
}
}
public getSyncToken() {
return this.redis.get(BOT_SYNC_TOKEN_KEY + this.contextSuffix);
}
public setFilter(filter: IFilterInfo) {
this.redis.set(BOT_FILTER_KEY + this.contextSuffix, JSON.stringify(filter));
}
public async getFilter() {
const value = await this.redis.get(BOT_FILTER_KEY + this.contextSuffix);
return value && JSON.parse(value);
}
public storeValue(key: string, value: string) {
this.redis.set(`${BOT_VALUE_KEY}${this.contextSuffix}.${key}`, value);
}
public readValue(key: string) {
return this.redis.get(`${BOT_VALUE_KEY}${this.contextSuffix}.${key}`);
}
public async addRegisteredUser(userId: string) {
this.redis.sadd(REGISTERED_USERS_KEY, [userId]);
}

View File

@ -1,7 +1,7 @@
import { IAppserviceStorageProvider } from "matrix-bot-sdk";
import { IAppserviceStorageProvider, IStorageProvider } from "matrix-bot-sdk";
import { IssuesGetResponseData } from "../Github/Types";
export interface IStorageProvider extends IAppserviceStorageProvider {
export interface IBridgeStorageProvider extends IAppserviceStorageProvider, IStorageProvider {
setGithubIssue(repo: string, issueNumber: string, data: IssuesGetResponseData, scope?: string): Promise<void>;
getGithubIssue(repo: string, issueNumber: string, scope?: string): Promise<IssuesGetResponseData|null>;
setLastNotifCommentUrl(repo: string, issueNumber: string, url: string, scope?: string): Promise<void>;