mirror of
https://github.com/turt2live/matrix-dimension.git
synced 2024-10-01 01:05:53 -04:00
Support saving of travis-ci configuration
For both upstream and self-hosted. What's left is: * Webhooks (magic proxy through Dimension) * More instructions on the frontend.
This commit is contained in:
parent
606b6d9f56
commit
3a8167a57a
@ -19,3 +19,13 @@ export interface RssBotConfiguration {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TravisCiConfiguration {
|
||||||
|
webhookUrl: string;
|
||||||
|
repos: {
|
||||||
|
[repoKey: string]: {
|
||||||
|
addedByUserId: string;
|
||||||
|
template: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,7 +10,18 @@ import { ModularIntegrationInfoResponse } from "../models/ModularResponses";
|
|||||||
import { AppserviceStore } from "../db/AppserviceStore";
|
import { AppserviceStore } from "../db/AppserviceStore";
|
||||||
import { MatrixAppserviceClient } from "../matrix/MatrixAppserviceClient";
|
import { MatrixAppserviceClient } from "../matrix/MatrixAppserviceClient";
|
||||||
import NebIntegrationConfig from "../db/models/NebIntegrationConfig";
|
import NebIntegrationConfig from "../db/models/NebIntegrationConfig";
|
||||||
import { RssBotConfiguration } from "../integrations/ComplexBot";
|
import { RssBotConfiguration, TravisCiConfiguration } from "../integrations/ComplexBot";
|
||||||
|
|
||||||
|
interface InternalTravisCiConfig {
|
||||||
|
webhookUrl: string;
|
||||||
|
rooms: {
|
||||||
|
[roomId: string]: {
|
||||||
|
[repoKey: string]: {
|
||||||
|
template: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export class NebProxy {
|
export class NebProxy {
|
||||||
constructor(private neb: NebConfig, private requestingUserId: string) {
|
constructor(private neb: NebConfig, private requestingUserId: string) {
|
||||||
@ -55,13 +66,13 @@ export class NebProxy {
|
|||||||
if (integration.nebId !== this.neb.id) throw new Error("Integration is not for this NEB proxy");
|
if (integration.nebId !== this.neb.id) throw new Error("Integration is not for this NEB proxy");
|
||||||
|
|
||||||
if (this.neb.upstreamId) {
|
if (this.neb.upstreamId) {
|
||||||
// TODO: Verify
|
|
||||||
try {
|
try {
|
||||||
const response = await this.doUpstreamRequest<ModularIntegrationInfoResponse>("/integrations/" + NebClient.getNebType(integration.type), {
|
const response = await this.doUpstreamRequest<ModularIntegrationInfoResponse>("/integrations/" + NebClient.getNebType(integration.type), {
|
||||||
room_id: inRoomId,
|
room_id: inRoomId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (integration.type === "rss") return this.parseUpstreamRssConfiguration(response.integrations);
|
if (integration.type === "rss") return this.parseUpstreamRssConfiguration(response.integrations);
|
||||||
|
else if (integration.type === "travisci") return this.parseUpstreamTravisCiConfiguration(response.integrations);
|
||||||
else return {};
|
else return {};
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
LogService.error("NebProxy", err);
|
LogService.error("NebProxy", err);
|
||||||
@ -101,11 +112,12 @@ export class NebProxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (integration.type === "rss") await this.updateRssConfiguration(inRoomId, newConfig);
|
if (integration.type === "rss") await this.updateRssConfiguration(inRoomId, newConfig);
|
||||||
|
else if (integration.type === "travisci") await this.updateTravisCiConfiguration(inRoomId, newConfig);
|
||||||
else throw new Error("Cannot update go-neb: unrecognized type");
|
else throw new Error("Cannot update go-neb: unrecognized type");
|
||||||
}
|
}
|
||||||
|
|
||||||
private parseUpstreamRssConfiguration(integrations: any[]): any {
|
private parseUpstreamRssConfiguration(integrations: any[]): RssBotConfiguration {
|
||||||
if (!integrations) return {};
|
if (!integrations) return {feeds: {}};
|
||||||
|
|
||||||
const result: RssBotConfiguration = {feeds: {}};
|
const result: RssBotConfiguration = {feeds: {}};
|
||||||
for (const integration of integrations) {
|
for (const integration of integrations) {
|
||||||
@ -120,6 +132,33 @@ export class NebProxy {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private parseUpstreamTravisCiConfiguration(integrations: any[]): InternalTravisCiConfig {
|
||||||
|
if (!integrations) return {rooms: {}, webhookUrl: null};
|
||||||
|
|
||||||
|
const result: InternalTravisCiConfig = {rooms: {}, webhookUrl: "https://example.org/nowhere"};
|
||||||
|
for (const integration of integrations) {
|
||||||
|
if (!integration.user_id || !integration.config || !integration.config.rooms) continue;
|
||||||
|
|
||||||
|
const userId = integration.user_id;
|
||||||
|
if (userId === this.requestingUserId && integration.config.webhook_url && !result.webhookUrl)
|
||||||
|
result.webhookUrl = integration.config.webhook_url;
|
||||||
|
|
||||||
|
const roomIds = Object.keys(integration.config.rooms);
|
||||||
|
for (const roomId of roomIds) {
|
||||||
|
if (!result.rooms[roomId]) result.rooms[roomId] = {};
|
||||||
|
|
||||||
|
const repoKeys = Object.keys(integration.config.rooms[roomId].repos || {});
|
||||||
|
for (const repoKey of repoKeys) {
|
||||||
|
result.rooms[roomId][repoKey] = {
|
||||||
|
template: integration.config.rooms[roomId].repos[repoKey].template,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private async updateRssConfiguration(roomId: string, newOpts: RssBotConfiguration): Promise<any> {
|
private async updateRssConfiguration(roomId: string, newOpts: RssBotConfiguration): Promise<any> {
|
||||||
const feedUrls = Object.keys(newOpts.feeds).filter(f => newOpts.feeds[f].addedByUserId === this.requestingUserId);
|
const feedUrls = Object.keys(newOpts.feeds).filter(f => newOpts.feeds[f].addedByUserId === this.requestingUserId);
|
||||||
const newConfig = {feeds: {}};
|
const newConfig = {feeds: {}};
|
||||||
@ -175,6 +214,44 @@ export class NebProxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async updateTravisCiConfiguration(roomId: string, newOpts: TravisCiConfiguration): Promise<any> {
|
||||||
|
const repoKeys = Object.keys(newOpts.repos).filter(f => newOpts.repos[f].addedByUserId === this.requestingUserId);
|
||||||
|
let newConfig = {rooms: {}};
|
||||||
|
|
||||||
|
if (!this.neb.upstreamId) {
|
||||||
|
if (repoKeys.length === 0) {
|
||||||
|
const notifUser = await NebStore.getOrCreateNotificationUser(this.neb.id, "travisci", this.requestingUserId);
|
||||||
|
const appserviceClient = new MatrixAppserviceClient(await AppserviceStore.getAppservice(this.neb.appserviceId));
|
||||||
|
await appserviceClient.leaveRoom(notifUser.appserviceUserId, roomId);
|
||||||
|
}
|
||||||
|
|
||||||
|
const client = new NebClient(this.neb);
|
||||||
|
const notifUser = await NebStore.getOrCreateNotificationUser(this.neb.id, "travisci", this.requestingUserId);
|
||||||
|
newConfig = await client.getServiceConfig(notifUser.serviceId); // So we don't accidentally clear other rooms
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the current room's configuration so we don't keep artifacts.
|
||||||
|
newConfig.rooms[roomId] = {repos: {}};
|
||||||
|
const roomReposConf = newConfig.rooms[roomId].repos;
|
||||||
|
|
||||||
|
for (const repoKey of repoKeys) {
|
||||||
|
roomReposConf[repoKey] = {
|
||||||
|
template: newOpts.repos[repoKey].template,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.neb.upstreamId) {
|
||||||
|
await this.doUpstreamRequest<ModularIntegrationInfoResponse>("/integrations/travis-ci/configureService", {
|
||||||
|
room_id: roomId,
|
||||||
|
rooms: newConfig.rooms,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const client = new NebClient(this.neb);
|
||||||
|
const notifUser = await NebStore.getOrCreateNotificationUser(this.neb.id, "travisci", this.requestingUserId);
|
||||||
|
await client.setServiceConfig(notifUser.serviceId, notifUser.appserviceUserId, "travis-ci", newConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async removeBotFromRoom(integration: NebIntegration, roomId: string): Promise<any> {
|
public async removeBotFromRoom(integration: NebIntegration, roomId: string): Promise<any> {
|
||||||
if (integration.nebId !== this.neb.id) throw new Error("Integration is not for this NEB proxy");
|
if (integration.nebId !== this.neb.id) throw new Error("Integration is not for this NEB proxy");
|
||||||
|
|
||||||
@ -213,6 +290,7 @@ export class NebProxy {
|
|||||||
reject(err);
|
reject(err);
|
||||||
} else if (res.statusCode !== 200) {
|
} else if (res.statusCode !== 200) {
|
||||||
LogService.error("NebProxy", "Got status code " + res.statusCode + " when calling " + url);
|
LogService.error("NebProxy", "Got status code " + res.statusCode + " when calling " + url);
|
||||||
|
LogService.error("NebProxy", res.body);
|
||||||
reject(new Error("Request failed"));
|
reject(new Error("Request failed"));
|
||||||
} else {
|
} else {
|
||||||
if (typeof(res.body) === "string") res.body = JSON.parse(res.body);
|
if (typeof(res.body) === "string") res.body = JSON.parse(res.body);
|
||||||
|
Loading…
Reference in New Issue
Block a user