Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove admin/pm rooms when the matrix-side user leaves to allow server to GC #1258

Merged
merged 2 commits into from
Mar 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/1258.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Leave DM rooms and admin rooms if the Matrix user leaves so that a homeserver may clear them up later.
27 changes: 26 additions & 1 deletion src/bridge/MatrixHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -719,9 +719,34 @@ export class MatrixHandler {
serverLookup[ircClient.server.domain] = ircClient;
});

const store = this.ircBridge.getStore();

// which channels should the connected client leave?
const ircRooms = await this.ircBridge.getStore().getIrcChannelsForRoomId(event.room_id);
const ircRooms = await store.getIrcChannelsForRoomId(event.room_id);

if (!ircRooms) {
const adminRoom = await store.getAdminRoomById(event.room_id);
if (adminRoom) {
await store.removeAdminRoom(adminRoom);
// The user left the admin room, let's also leave.
// XXX: The typing of .leave is wrong, it should
// allow undefined.
await this.membershipQueue.leave(event.room_id, "", req);
return null;
}

const pmRoom = await store.getMatrixPmRoomById(event.room_id);
if (pmRoom) {
await store.removePmRoom(pmRoom.roomId);
// The user left the pm room, let's also leave.
const members = await this.ircBridge.getAppServiceBridge().getBot().getJoinedMembers(pmRoom.roomId);
await Promise.all(Object.keys(members).map((u) => {
this.membershipQueue.leave(event.room_id, u, req);
}));
return null;
}

}

// ========== Client Parting ==========
// for each room, if we're connected to it, leave the channel.
Expand Down
4 changes: 4 additions & 0 deletions src/datastore/DataStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ export interface DataStore {

getMatrixPmRoom(realUserId: string, virtualUserId: string): Promise<MatrixRoom|null>;

getMatrixPmRoomById(roomId: string): Promise<MatrixRoom|null>;

getTrackedChannelsForServer(domain: string): Promise<string[]>;

getRoomIdsFromConfig(): Promise<string[]>;
Expand All @@ -138,6 +140,8 @@ export interface DataStore {

storeAdminRoom(room: MatrixRoom, userId: string): Promise<void>;

removeAdminRoom(room: MatrixRoom): Promise<void>;

upsertMatrixRoom(room: MatrixRoom): Promise<void>;

getAdminRoomByUserId(userId: string): Promise<MatrixRoom|null>;
Expand Down
18 changes: 18 additions & 0 deletions src/datastore/NedbDataStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,18 @@ export class NeDBDataStore implements DataStore {
return entry.matrix || null;
}

public async getMatrixPmRoomById(roomId: string) {
const entry = await this.roomStore.getEntriesByMatrixId(roomId);
if (!entry) {
return null;
}
if (entry.length > 1) {
log.warn(`More than one PM room assigned to Matrix room ${roomId}, returning first`);
}
return entry[0].matrix || null;
}


public async getTrackedChannelsForServer(domain: string) {
const entries: Entry[] = await this.roomStore.getEntriesByRemoteRoomData({ domain });
const channels = new Set<string>();
Expand Down Expand Up @@ -480,6 +492,12 @@ export class NeDBDataStore implements DataStore {
});
}

public async removeAdminRoom(room: MatrixRoom): Promise<void> {
await this.roomStore.delete({
matrix: room,
});
}

public async upsertMatrixRoom(room: MatrixRoom): Promise<void> {
await this.roomStore.setMatrixRoom(room);
}
Expand Down
16 changes: 16 additions & 0 deletions src/datastore/postgres/PgDataStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,18 @@ export class PgDataStore implements DataStore {
return new MatrixRoom(res.rows[0].room_id);
}

public async getMatrixPmRoomById(roomId: string): Promise<MatrixRoom|null> {
log.debug(`getMatrixPmRoom (roomId=${roomId})`);
const res = await this.pgPool.query(
"SELECT room_id, matrix_user_id, virtual_user_id FROM pm_rooms WHERE room_id = $1", [
roomId,
]);
if (res.rowCount === 0) {
return null;
}
return new MatrixRoom(res.rows[0].room_id);
}

public async getTrackedChannelsForServer(domain: string): Promise<string[]> {
if (!this.serverMappings[domain]) {
// Return empty if we don't know the server.
Expand Down Expand Up @@ -410,6 +422,10 @@ export class PgDataStore implements DataStore {
return new MatrixRoom(res.rows[0].room_id);
}

public async removeAdminRoom(room: MatrixRoom): Promise<void> {
await this.pgPool.query("DELETE FROM admin_rooms WHERE room_id = $1", [room.roomId]);
}

public async storeMatrixUser(matrixUser: MatrixUser): Promise<void> {
const parameters = {
user_id: matrixUser.getId(),
Expand Down