Merge pull request #392 from matrix-org/dbkr/scalar

Dbkr/scalar
pull/21833/head
David Baker 2016-08-05 15:43:57 +01:00 committed by GitHub
commit 98e89d4293
6 changed files with 119 additions and 7 deletions

View File

@ -24,6 +24,7 @@
"test-multi": "karma start $KARMAFLAGS --single-run=false"
},
"dependencies": {
"browser-request": "^0.3.3",
"classnames": "^2.1.2",
"draft-js": "^0.7.0",
"draft-js-export-html": "^0.2.2",

47
src/ScalarAuthClient.js Normal file
View File

@ -0,0 +1,47 @@
/*
Copyright 2016 OpenMarket Ltd
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.
*/
var q = require("q");
var request = require('browser-request');
var SdkConfig = require('./SdkConfig');
class ScalarAuthClient {
getScalarToken(openid_token_object) {
var defer = q.defer();
var scalar_rest_url = SdkConfig.get().integrations_rest_url;
request({
method: 'POST',
uri: scalar_rest_url+'/register',
body: openid_token_object,
json: true,
}, (err, response, body) => {
if (err) {
defer.reject(err);
} else if (response.statusCode / 100 !== 2) {
defer.reject({statusCode: response.statusCode});
} else {
defer.resolve(body.access_token);
}
});
return defer.promise;
}
}
module.exports = ScalarAuthClient;

View File

@ -16,11 +16,9 @@ limitations under the License.
var DEFAULTS = {
// URL to a page we show in an iframe to configure integrations
//integrations_ui_url: "https://scalar.vector.im/",
integrations_ui_url: "http://127.0.0.1:5051/",
integrations_ui_url: "https://scalar.vector.im/",
// Base URL to the REST interface of the integrations server
//integrations_rest_url: "https://scalar.vector.im/api",
integrations_rest_url: "http://127.0.0.1:5050",
integrations_rest_url: "https://scalar.vector.im/api",
};
class SdkConfig {

View File

@ -19,6 +19,7 @@ var url = require('url');
var Favico = require('favico.js');
var MatrixClientPeg = require("../../MatrixClientPeg");
var SdkConfig = require("../../SdkConfig");
var Notifier = require("../../Notifier");
var ContextualMenu = require("./ContextualMenu");
var RoomListSorter = require("../../RoomListSorter");
@ -140,6 +141,7 @@ module.exports = React.createClass({
},
componentWillMount: function() {
SdkConfig.put(this.props.config);
this.favicon = new Favico({animation: 'none'});
// Stashed guest credentials if the user logs out

View File

@ -34,7 +34,11 @@ const LABS_FEATURES = [
{
name: 'End-to-End Encryption',
id: 'e2e_encryption'
}
},
{
name: 'Integration Management',
id: 'integration_management'
},
];
// if this looks like a release, use the 'version' from package.json; else use

View File

@ -17,10 +17,12 @@ limitations under the License.
var q = require("q");
var React = require('react');
var MatrixClientPeg = require('../../../MatrixClientPeg');
var SdkConfig = require('../../../SdkConfig');
var sdk = require('../../../index');
var Modal = require('../../../Modal');
var ObjectUtils = require("../../../ObjectUtils");
var dis = require("../../../dispatcher");
var ScalarAuthClient = require("../../../ScalarAuthClient");
var UserSettingsStore = require('../../../UserSettingsStore');
// parse a string as an integer; if the input is undefined, or cannot be parsed
@ -73,6 +75,8 @@ module.exports = React.createClass({
// Default to false if it's undefined, otherwise react complains about changing
// components from uncontrolled to controlled
isRoomPublished: this._originalIsRoomPublished || false,
scalar_token: null,
scalar_error: null,
};
},
@ -86,6 +90,12 @@ module.exports = React.createClass({
console.error("Failed to get room visibility: " + err);
});
this.getScalarToken().done((token) => {
this.setState({scalar_token: token});
}, (err) => {
this.setState({scalar_error: err});
});
dis.dispatch({
action: 'ui_opacity',
sideOpacity: 0.3,
@ -398,6 +408,37 @@ module.exports = React.createClass({
roomState.mayClientSendStateEvent("m.room.guest_access", cli))
},
getScalarInterfaceUrl: function() {
var url = SdkConfig.get().integrations_ui_url;
url += "?scalar_token=" + encodeURIComponent(this.state.scalar_token);
url += "&room_id=" + encodeURIComponent(this.props.room.roomId);
return url;
},
getScalarToken() {
var tok = window.localStorage.getItem("mx_scalar_token");
if (tok) return q(tok);
// No saved token, so do the dance to get one. First, we
// need an openid bearer token from the HS.
return MatrixClientPeg.get().getOpenIdToken().then((token_object) => {
// Now we can send that to scalar and exchange it for a scalar token
var scalar_auth_client = new ScalarAuthClient();
return scalar_auth_client.getScalarToken(token_object);
}).then((token_object) => {
window.localStorage.setItem("mx_scalar_token", token_object);
return token_object;
});
},
onManageIntegrations(ev) {
ev.preventDefault();
var IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager");
Modal.createDialog(IntegrationsManager, {
src: this.state.scalar_token ? this.getScalarInterfaceUrl() : null
}, "");
},
_renderEncryptionSection: function() {
if (!UserSettingsStore.isFeatureEnabled("e2e_encryption")) {
return null;
@ -430,7 +471,6 @@ module.exports = React.createClass({
);
},
render: function() {
// TODO: go through greying out things you don't have permission to change
// (or turning them into informative stuff)
@ -440,6 +480,7 @@ module.exports = React.createClass({
var UrlPreviewSettings = sdk.getComponent("room_settings.UrlPreviewSettings");
var EditableText = sdk.getComponent('elements.EditableText');
var PowerSelector = sdk.getComponent('elements.PowerSelector');
var Loader = sdk.getComponent("elements.Spinner")
var cli = MatrixClientPeg.get();
var roomState = this.props.room.currentState;
@ -577,6 +618,23 @@ module.exports = React.createClass({
</div>
}
var integrations_section;
if (UserSettingsStore.isFeatureEnabled("integration_management")) {
if (this.state.scalar_token) {
integrations_section = (
<div className="mx_RoomSettings_settings">
<a href="#" onClick={ this.onManageIntegrations }>Manage integrations</a>
</div>
);
} else if (this.state.scalar_error) {
integrations_section = <div className="error">
Unable to contact integrations server
</div>;
} else {
integrations_section = <Loader />;
}
}
return (
<div className="mx_RoomSettings">
@ -661,6 +719,9 @@ module.exports = React.createClass({
<ColorSettings ref="color_settings" room={this.props.room} />
</div>
<h3>Integrations</h3>
{ integrations_section }
<a id="addresses"/>
<AliasSettings ref="alias_settings"
@ -725,7 +786,6 @@ module.exports = React.createClass({
<div className="mx_RoomSettings_settings">
This room's internal ID is <code>{ this.props.room.roomId }</code>
</div>
</div>
);
}