mirror of
https://github.com/turt2live/matrix-dimension.git
synced 2024-10-01 05:05:53 +00:00
Use the right scalar route for the request
This commit is contained in:
parent
cf212d8f4e
commit
18ee47fa49
@ -51,9 +51,10 @@ export default class AccountController {
|
||||
/**
|
||||
* Registers an account to use the Integration Manager
|
||||
* @param {OpenId} openId The OpenID request information.
|
||||
* @param {string} scalarKind The kind of scalar client to use.
|
||||
* @returns {Promise<IAccountRegisteredResponse>} Resolves when registered.
|
||||
*/
|
||||
public async registerAccount(openId: OpenId): Promise<IAccountRegisteredResponse> {
|
||||
public async registerAccount(openId: OpenId, scalarKind: string): Promise<IAccountRegisteredResponse> {
|
||||
if (!openId || !openId.matrix_server_name || !openId.access_token) {
|
||||
throw new ApiError(400, "Missing OpenID information");
|
||||
}
|
||||
@ -76,7 +77,7 @@ export default class AccountController {
|
||||
|
||||
const upstreams = await Upstream.findAll();
|
||||
await Promise.all(upstreams.map(async upstream => {
|
||||
if (!await ScalarStore.isUpstreamOnline(upstream)) {
|
||||
if (!await ScalarStore.isUpstreamOnline(upstream, scalarKind)) {
|
||||
LogService.warn("AccountController", `Skipping registration for ${mxUserId} on upstream ${upstream.id} (${upstream.name}) because it is offline`);
|
||||
return null;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import { OpenId } from "../../models/OpenId";
|
||||
import AccountController, { IAccountInfoResponse, IAccountRegisteredResponse } from "../controllers/AccountController";
|
||||
import { AutoWired, Inject } from "typescript-ioc/es6";
|
||||
import { IMSCUser, ROLE_MSC_USER } from "../security/MSCSecurity";
|
||||
import { ScalarClient } from "../../scalar/ScalarClient";
|
||||
|
||||
/**
|
||||
* API for account management
|
||||
@ -20,7 +21,7 @@ export class MSCAccountService {
|
||||
@POST
|
||||
@Path("register")
|
||||
public async register(request: OpenId): Promise<IAccountRegisteredResponse> {
|
||||
return this.accountController.registerAccount(request);
|
||||
return this.accountController.registerAccount(request, ScalarClient.KIND_MATRIX_V1);
|
||||
}
|
||||
|
||||
@GET
|
||||
|
@ -7,6 +7,7 @@ import AccountController from "../controllers/AccountController";
|
||||
import { ROLE_MSC_USER } from "../security/MSCSecurity";
|
||||
import TermsController, { ITermsNotSignedResponse } from "../controllers/TermsController";
|
||||
import { SignTermsRequest } from "../msc/MSCTermsService";
|
||||
import { ScalarClient } from "../../scalar/ScalarClient";
|
||||
|
||||
/**
|
||||
* API for the minimum Scalar API we need to implement to be compatible with clients. Used for registration
|
||||
@ -32,7 +33,7 @@ export class ScalarService {
|
||||
throw new ApiError(401, "Invalid API version.");
|
||||
}
|
||||
|
||||
const response = await this.accountController.registerAccount(request);
|
||||
const response = await this.accountController.registerAccount(request, ScalarClient.KIND_LEGACY);
|
||||
return {scalar_token: response.token};
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import AccountController from "../controllers/AccountController";
|
||||
import TermsController from "../controllers/TermsController";
|
||||
import config from "../../config";
|
||||
import { ScalarStore } from "../../db/ScalarStore";
|
||||
import { ScalarClient } from "../../scalar/ScalarClient";
|
||||
|
||||
export interface IMSCUser {
|
||||
userId: string;
|
||||
@ -74,7 +75,8 @@ export default class MSCSecurity implements ServiceAuthenticator {
|
||||
|
||||
const needUpstreams = !this.matchesAnyRoute(req, ADMIN_ROUTES);
|
||||
if (needUpstreams) {
|
||||
const hasUpstreams = await ScalarStore.doesUserHaveTokensForAllUpstreams(req.user.userId);
|
||||
const scalarKind = req.path.startsWith("/_matrix/integrations/v1/") ? ScalarClient.KIND_MATRIX_V1 : ScalarClient.KIND_LEGACY;
|
||||
const hasUpstreams = await ScalarStore.doesUserHaveTokensForAllUpstreams(req.user.userId, scalarKind);
|
||||
if (!hasUpstreams) {
|
||||
return res.status(401).json({errcode: "M_INVALID_TOKEN", error: "Invalid token"});
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import { Cache, CACHE_SCALAR_ONLINE_STATE } from "../MemoryCache";
|
||||
|
||||
export class ScalarStore {
|
||||
|
||||
public static async doesUserHaveTokensForAllUpstreams(userId: string): Promise<boolean> {
|
||||
public static async doesUserHaveTokensForAllUpstreams(userId: string, scalarKind: string): Promise<boolean> {
|
||||
const scalarTokens = await UserScalarToken.findAll({where: {userId: userId}});
|
||||
const upstreamTokenIds = scalarTokens.filter(t => !t.isDimensionToken).map(t => t.upstreamId);
|
||||
const hasDimensionToken = scalarTokens.filter(t => t.isDimensionToken).length >= 1;
|
||||
@ -20,7 +20,7 @@ export class ScalarStore {
|
||||
|
||||
const upstreams = await Upstream.findAll();
|
||||
for (const upstream of upstreams) {
|
||||
if (!await ScalarStore.isUpstreamOnline(upstream)) {
|
||||
if (!await ScalarStore.isUpstreamOnline(upstream, scalarKind)) {
|
||||
LogService.warn("ScalarStore", `Upstream ${upstream.apiUrl} is offline - assuming token is valid`);
|
||||
continue;
|
||||
}
|
||||
@ -43,7 +43,7 @@ export class ScalarStore {
|
||||
return tokens[0].user;
|
||||
}
|
||||
|
||||
public static async isUpstreamOnline(upstream: Upstream): Promise<boolean> {
|
||||
public static async isUpstreamOnline(upstream: Upstream, scalarKind: string): Promise<boolean> {
|
||||
const cache = Cache.for(CACHE_SCALAR_ONLINE_STATE);
|
||||
const cacheKey = `Upstream ${upstream.id}`;
|
||||
const result = cache.get(cacheKey);
|
||||
@ -51,17 +51,17 @@ export class ScalarStore {
|
||||
return result;
|
||||
}
|
||||
|
||||
const state = ScalarStore.checkIfUpstreamOnline(upstream);
|
||||
const state = ScalarStore.checkIfUpstreamOnline(upstream, scalarKind);
|
||||
cache.put(cacheKey, state, 60 * 60 * 1000); // 1 hour
|
||||
return state;
|
||||
}
|
||||
|
||||
private static async checkIfUpstreamOnline(upstream: Upstream): Promise<boolean> {
|
||||
private static async checkIfUpstreamOnline(upstream: Upstream, scalarKind: string): Promise<boolean> {
|
||||
try {
|
||||
// The sticker bot can be used for this for now
|
||||
|
||||
const testUserId = await MatrixStickerBot.getUserId();
|
||||
const scalarClient = new ScalarClient(upstream);
|
||||
const scalarClient = new ScalarClient(upstream, scalarKind);
|
||||
|
||||
// First see if we have a token for the upstream so we can try it
|
||||
const existingTokens = await UserScalarToken.findAll({
|
||||
|
@ -5,4 +5,8 @@ export interface ScalarRegisterResponse {
|
||||
export interface ScalarAccountResponse {
|
||||
user_id: string;
|
||||
// credit: number; // present on scalar-web
|
||||
}
|
||||
|
||||
export interface ScalarLogoutResponse {
|
||||
// Nothing of interest
|
||||
}
|
@ -1,21 +1,58 @@
|
||||
import { OpenId } from "../models/OpenId";
|
||||
import { ScalarAccountResponse, ScalarRegisterResponse } from "../models/ScalarResponses";
|
||||
import { ScalarAccountResponse, ScalarLogoutResponse, ScalarRegisterResponse } from "../models/ScalarResponses";
|
||||
import * as request from "request";
|
||||
import { LogService } from "matrix-js-snippets";
|
||||
import Upstream from "../db/models/Upstream";
|
||||
import { SCALAR_API_VERSION } from "../utils/common-constants";
|
||||
import * as url from "url";
|
||||
|
||||
const REGISTER_ROUTE = "/register";
|
||||
const ACCOUNT_INFO_ROUTE = "/account";
|
||||
const LOGOUT_ROUTE = "/logout";
|
||||
|
||||
export class ScalarClient {
|
||||
constructor(private upstream: Upstream) {
|
||||
public static readonly KIND_LEGACY = "legacy";
|
||||
public static readonly KIND_MATRIX_V1 = "matrix_v1";
|
||||
|
||||
constructor(private upstream: Upstream, private kind = ScalarClient.KIND_LEGACY) {
|
||||
}
|
||||
|
||||
private makeRequestArguments(path: string, token: string): { scalarUrl: string, headers: any, queryString: any } {
|
||||
if (this.kind === ScalarClient.KIND_LEGACY) {
|
||||
const addlQuery = {};
|
||||
if (token) addlQuery['scalar_token'] = token;
|
||||
return {
|
||||
scalarUrl: this.upstream.scalarUrl + path,
|
||||
headers: {},
|
||||
queryString: {
|
||||
v: SCALAR_API_VERSION,
|
||||
...addlQuery,
|
||||
},
|
||||
};
|
||||
} else {
|
||||
const parsed = url.parse(this.upstream.scalarUrl);
|
||||
parsed.path = '/_matrix/integrations/v1' + (path === ACCOUNT_INFO_ROUTE ? path : `${ACCOUNT_INFO_ROUTE}${path}`);
|
||||
|
||||
const headers = {};
|
||||
if (token) headers['Authorization'] = `Bearer ${token}`;
|
||||
|
||||
return {
|
||||
scalarUrl: parsed.toString(),
|
||||
headers: headers,
|
||||
queryString: {},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public register(openId: OpenId): Promise<ScalarRegisterResponse> {
|
||||
LogService.info("ScalarClient", "Doing upstream scalar request: " + this.upstream.scalarUrl + "/register");
|
||||
const {scalarUrl, headers, queryString} = this.makeRequestArguments(REGISTER_ROUTE, null);
|
||||
LogService.info("ScalarClient", "Doing upstream scalar request: " + scalarUrl);
|
||||
return new Promise((resolve, reject) => {
|
||||
request({
|
||||
method: "POST",
|
||||
url: this.upstream.scalarUrl + "/register",
|
||||
qs: {v: SCALAR_API_VERSION},
|
||||
url: scalarUrl,
|
||||
qs: queryString,
|
||||
headers: headers,
|
||||
json: openId,
|
||||
}, (err, res, _body) => {
|
||||
if (err) {
|
||||
@ -33,12 +70,39 @@ export class ScalarClient {
|
||||
}
|
||||
|
||||
public getAccount(token: string): Promise<ScalarAccountResponse> {
|
||||
LogService.info("ScalarClient", "Doing upstream scalar request: " + this.upstream.scalarUrl + "/account");
|
||||
const {scalarUrl, headers, queryString} = this.makeRequestArguments(ACCOUNT_INFO_ROUTE, token);
|
||||
LogService.info("ScalarClient", "Doing upstream scalar request: " + scalarUrl);
|
||||
return new Promise((resolve, reject) => {
|
||||
request({
|
||||
method: "GET",
|
||||
url: this.upstream.scalarUrl + "/account",
|
||||
qs: {v: SCALAR_API_VERSION, scalar_token: token},
|
||||
url: scalarUrl,
|
||||
qs: queryString,
|
||||
headers: headers,
|
||||
json: true,
|
||||
}, (err, res, _body) => {
|
||||
if (err) {
|
||||
LogService.error("ScalarClient", "Error getting information for token");
|
||||
LogService.error("ScalarClient", err);
|
||||
reject(err);
|
||||
} else if (res.statusCode !== 200) {
|
||||
LogService.error("ScalarClient", "Got status code " + res.statusCode + " while getting information for token");
|
||||
reject(res.statusCode);
|
||||
} else {
|
||||
resolve(res.body);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public logout(token: string): Promise<ScalarLogoutResponse> {
|
||||
const {scalarUrl, headers, queryString} = this.makeRequestArguments(LOGOUT_ROUTE, token);
|
||||
LogService.info("ScalarClient", "Doing upstream scalar request: " + scalarUrl);
|
||||
return new Promise((resolve, reject) => {
|
||||
request({
|
||||
method: "POST",
|
||||
url: scalarUrl,
|
||||
qs: queryString,
|
||||
headers: headers,
|
||||
json: true,
|
||||
}, (err, res, _body) => {
|
||||
if (err) {
|
||||
|
Loading…
Reference in New Issue
Block a user