From a8d51cdf58f047ca539e27e626a29fd9839ee13d Mon Sep 17 00:00:00 2001 From: Steven Hammerton Date: Thu, 8 Oct 2015 22:42:09 +0100 Subject: [PATCH 1/6] Add support for CAS auth --- src/skins/vector/skindex.js | 1 + src/skins/vector/views/organisms/CasLogin.js | 50 ++++++++++++++++++++ src/skins/vector/views/templates/Login.js | 5 ++ src/vector/index.js | 29 +++++++----- 4 files changed, 74 insertions(+), 11 deletions(-) create mode 100644 src/skins/vector/views/organisms/CasLogin.js diff --git a/src/skins/vector/skindex.js b/src/skins/vector/skindex.js index dbc161fa14..faf1e2b067 100644 --- a/src/skins/vector/skindex.js +++ b/src/skins/vector/skindex.js @@ -64,6 +64,7 @@ skin['molecules.UserSelector'] = require('./views/molecules/UserSelector'); skin['molecules.voip.CallView'] = require('./views/molecules/voip/CallView'); skin['molecules.voip.IncomingCallBox'] = require('./views/molecules/voip/IncomingCallBox'); skin['molecules.voip.VideoView'] = require('./views/molecules/voip/VideoView'); +skin['organisms.CasLogin'] = require('./views/organisms/CasLogin'); skin['organisms.CreateRoom'] = require('./views/organisms/CreateRoom'); skin['organisms.ErrorDialog'] = require('./views/organisms/ErrorDialog'); skin['organisms.LeftPanel'] = require('./views/organisms/LeftPanel'); diff --git a/src/skins/vector/views/organisms/CasLogin.js b/src/skins/vector/views/organisms/CasLogin.js new file mode 100644 index 0000000000..2a73fd3c1b --- /dev/null +++ b/src/skins/vector/views/organisms/CasLogin.js @@ -0,0 +1,50 @@ +/* +Copyright 2015 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. +*/ + +'use strict'; + +var React = require('react'); + +var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg'); + +module.exports = React.createClass({ + displayName: 'CasLogin', + + getInitialState: function() { + var splitLocation = window.location.href.split('/'); + return {serviceUrl: splitLocation[0] + "//" + splitLocation[2]}; + }, + + onCasClicked: function(ev) { + var serviceRedirectUrl = this.state.serviceUrl + "/#/login/cas"; + var self = this; + MatrixClientPeg.get().getCasServer().done(function(data) { + var serverUrl = data.serverUrl + "/login?service=" + encodeURIComponent(serviceRedirectUrl); + window.location.href=serverUrl + }, function(error) { + self.setStep("stage_m.login.cas"); + self.setState({errorText: 'Login failed.'}); + }); + }, + + render: function() { + return ( +
+ +
+ ); + } +}); \ No newline at end of file diff --git a/src/skins/vector/views/templates/Login.js b/src/skins/vector/views/templates/Login.js index 4e78dce91d..0378153a7f 100644 --- a/src/skins/vector/views/templates/Login.js +++ b/src/skins/vector/views/templates/Login.js @@ -141,6 +141,11 @@ module.exports = React.createClass({ ); + case 'stage_m.login.cas': + var CasLogin = sdk.getComponent('organisms.CasLogin'); + return ( + + ); } }, diff --git a/src/vector/index.js b/src/vector/index.js index 1f6585f721..8a6a3448c9 100644 --- a/src/vector/index.js +++ b/src/vector/index.js @@ -23,22 +23,29 @@ sdk.loadModule(require('../modules/VectorConferenceHandler')); var lastLocationHashSet = null; + +function parseQueryParams(location) { + var hashparts = location.hash.split('?'); + var params = {}; + if (hashparts.length == 2) { + var pairs = hashparts[1].split('&'); + for (var i = 0; i < pairs.length; ++i) { + var parts = pairs[i].split('='); + if (parts.length != 2) continue; + params[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]); + } + } + return params +} + // Here, we do some crude URL analysis to allow // deep-linking. We only support registration // deep-links in this example. function routeUrl(location) { if (location.hash.indexOf('#/register') == 0) { - var hashparts = location.hash.split('?'); - var params = {}; - if (hashparts.length == 2) { - var pairs = hashparts[1].split('&'); - for (var i = 0; i < pairs.length; ++i) { - var parts = pairs[i].split('='); - if (parts.length != 2) continue; - params[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]); - } - } - window.matrixChat.showScreen('register', params); + window.matrixChat.showScreen('register', parseQueryParams(location)); + } else if (location.hash.indexOf('#/login/cas') == 0) { + window.matrixChat.showScreen('cas_login', parseQueryParams(location)); } else { window.matrixChat.showScreen(location.hash.substring(2)); } From 353af6c647ae99d50f69fcaeecfee481a8cf468f Mon Sep 17 00:00:00 2001 From: Steven Hammerton Date: Mon, 12 Oct 2015 10:10:26 +0100 Subject: [PATCH 2/6] Move CasLogin logic to controller class and logic object in react-sdk --- src/skins/vector/views/organisms/CasLogin.js | 23 +++++--------------- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/src/skins/vector/views/organisms/CasLogin.js b/src/skins/vector/views/organisms/CasLogin.js index 2a73fd3c1b..80b4cae111 100644 --- a/src/skins/vector/views/organisms/CasLogin.js +++ b/src/skins/vector/views/organisms/CasLogin.js @@ -20,25 +20,11 @@ var React = require('react'); var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg'); +var CasLoginController = require('matrix-react-sdk/lib/controllers/organisms/CasLogin'); + module.exports = React.createClass({ displayName: 'CasLogin', - - getInitialState: function() { - var splitLocation = window.location.href.split('/'); - return {serviceUrl: splitLocation[0] + "//" + splitLocation[2]}; - }, - - onCasClicked: function(ev) { - var serviceRedirectUrl = this.state.serviceUrl + "/#/login/cas"; - var self = this; - MatrixClientPeg.get().getCasServer().done(function(data) { - var serverUrl = data.serverUrl + "/login?service=" + encodeURIComponent(serviceRedirectUrl); - window.location.href=serverUrl - }, function(error) { - self.setStep("stage_m.login.cas"); - self.setState({errorText: 'Login failed.'}); - }); - }, + mixins: [CasLoginController], render: function() { return ( @@ -47,4 +33,5 @@ module.exports = React.createClass({ ); } -}); \ No newline at end of file + +}); From f5039ac9af1d8af52bae2246b24372ea10a8f287 Mon Sep 17 00:00:00 2001 From: Steven Hammerton Date: Mon, 12 Oct 2015 10:11:02 +0100 Subject: [PATCH 3/6] Use node querystring module to parse query string like name value pairs from fragment --- src/vector/index.js | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/vector/index.js b/src/vector/index.js index 8a6a3448c9..1be71052c2 100644 --- a/src/vector/index.js +++ b/src/vector/index.js @@ -21,21 +21,20 @@ var sdk = require("matrix-react-sdk"); sdk.loadSkin(require('../skins/vector/skindex')); sdk.loadModule(require('../modules/VectorConferenceHandler')); +var qs = require("querystring"); + var lastLocationHashSet = null; -function parseQueryParams(location) { +// We want to support some name / value pairs in the fragment +// so we're re-using query string ike format +function parseQsFromFragment(location) { var hashparts = location.hash.split('?'); - var params = {}; - if (hashparts.length == 2) { - var pairs = hashparts[1].split('&'); - for (var i = 0; i < pairs.length; ++i) { - var parts = pairs[i].split('='); - if (parts.length != 2) continue; - params[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]); - } + if (hashparts.length > 1) { + console.log(qs.parse(hashparts[1])); + return qs.parse(hashparts[1]); } - return params + return {}; } // Here, we do some crude URL analysis to allow @@ -43,9 +42,9 @@ function parseQueryParams(location) { // deep-links in this example. function routeUrl(location) { if (location.hash.indexOf('#/register') == 0) { - window.matrixChat.showScreen('register', parseQueryParams(location)); + window.matrixChat.showScreen('register', parseQsFromFragment(location)); } else if (location.hash.indexOf('#/login/cas') == 0) { - window.matrixChat.showScreen('cas_login', parseQueryParams(location)); + window.matrixChat.showScreen('cas_login', parseQsFromFragment(location)); } else { window.matrixChat.showScreen(location.hash.substring(2)); } From c561647460edc6dd37b23971dd033effee15dbfe Mon Sep 17 00:00:00 2001 From: Steven Hammerton Date: Mon, 12 Oct 2015 10:11:19 +0100 Subject: [PATCH 4/6] Add missing comma --- src/skins/vector/views/organisms/CasLogin.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/skins/vector/views/organisms/CasLogin.js b/src/skins/vector/views/organisms/CasLogin.js index 80b4cae111..9782549b12 100644 --- a/src/skins/vector/views/organisms/CasLogin.js +++ b/src/skins/vector/views/organisms/CasLogin.js @@ -32,6 +32,7 @@ module.exports = React.createClass({ ); - } + }, }); + From b5357d32989ab1ddfc012e3151a80713ed124003 Mon Sep 17 00:00:00 2001 From: Steven Hammerton Date: Mon, 12 Oct 2015 10:28:39 +0100 Subject: [PATCH 5/6] Remove whitespace --- src/skins/vector/views/organisms/CasLogin.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/skins/vector/views/organisms/CasLogin.js b/src/skins/vector/views/organisms/CasLogin.js index 9782549b12..ae41e9555c 100644 --- a/src/skins/vector/views/organisms/CasLogin.js +++ b/src/skins/vector/views/organisms/CasLogin.js @@ -33,6 +33,5 @@ module.exports = React.createClass({ ); }, - -}); +}); From 293ee1bbcb787480be8acfda095ca3d56419d982 Mon Sep 17 00:00:00 2001 From: Steven Hammerton Date: Mon, 12 Oct 2015 17:41:56 +0100 Subject: [PATCH 6/6] Fix typo in comment and remove console.log leftover from debugging --- src/vector/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vector/index.js b/src/vector/index.js index 1be71052c2..22db05a38f 100644 --- a/src/vector/index.js +++ b/src/vector/index.js @@ -27,11 +27,10 @@ var lastLocationHashSet = null; // We want to support some name / value pairs in the fragment -// so we're re-using query string ike format +// so we're re-using query string like format function parseQsFromFragment(location) { var hashparts = location.hash.split('?'); if (hashparts.length > 1) { - console.log(qs.parse(hashparts[1])); return qs.parse(hashparts[1]); } return {};